Numpy介绍
TensorFlow是python语言框架。
Numpy是TensorFlow用到的核心库。
ndarray对象
ndarray(n-dimensional array object)
指储存单一数据类型的多维数组。可以是一维数组,二维矩阵,也可以是高维的数组。
创建ndarray
对象
通过array
函数创建一个ndarray
对象,输入形式灵活多变,可以创建不同数据类型的ndarray
对象。
>>> import numpy as np
>>> a = np.array([1,2,3,4])
>>> b = np.array((5,6,7,8))
>>> c = np.array([[1,2,3,4],[5,6,7,8],[7,8,9,5]])
>>> a
array([1, 2, 3, 4])
>>> b
array([5, 6, 7, 8])
>>> c
array([[1, 2, 3, 4],
[5, 6, 7, 8],
[7, 8, 9, 5]])
>>> a.dtype
dtype('int64')
>>> b = np.array([1,2,3,4],dtype=np.float)
>>> b
array([ 1., 2., 3., 4.])
>>> b.dtype
dtype('float64')
>>> c.shape #改变原来数据结构
(3, 4)
>>> d = c.reshape(2,6)
>>> d
array([[1, 2, 3, 4, 5, 6],
[7, 8, 7, 8, 9, 5]])
>>> c #创建新的数组,保留原来数组,但是共享存储
array([[1, 2, 3, 4],
[5, 6, 7, 8],
[7, 8, 9, 5]])
>>> a = np.arange(0,1,0.1) #arange(开始,结束,步长)
>>> a
array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
>>> b = np.linspace(0,1,10) #(开始,结束,元素个数)
>>> b
array([ 0. , 0.11111111, 0.22222222, 0.33333333, 0.44444444,
0.55555556, 0.66666667, 0.77777778, 0.88888889, 1. ])
ndarray
切片
切片:[开始位置:结束位置:步长]
>>> a = np.arange(10) #等价于np.arange(0,10,1)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[5]
5
>>> a[3:5]
array([3, 4])
>>> a[:5]
array([0, 1, 2, 3, 4])
>>> a[:-1]
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> a[1:-1:2]
array([1, 3, 5, 7])
>>> a[::-1]
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
>>> a[5:1:-2]
array([5, 3])
>>> b = a[3:7] #通过切片产生新的数组,共享存储空间
>>> b
array([3, 4, 5, 6])
>>> b[2]=-10
>>> b
array([ 3, 4, -10, 6])
>>> a
array([ 0, 1, 2, 3, 4, -10, 6, 7, 8, 9])
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b=a[[2,3,7,8]] #通过列表切片产生新的数组,不共享存储空间
>>> b
array([2, 3, 7, 8])
>>> b[2] = -10
>>> b
array([ 2, 3, -10, 8])
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
多维数组的切片是在每个维度切片的组合,用逗号隔开即可,示例如下图所示。
通过整数元组,列表,整数数组,布尔数组进行切片得到的数组不与原始数组共享存储空间。
ufunc运算
ufunc( universal function )
指一-种能对数组每个元素进行运算的函数。NumPy的许多ufunc函数都是用C语言实现的,因此它们的运算速度非常快。
ufunc四则运算
>>> a=np.arange(0,4)
>>> a
array([0, 1, 2, 3])
>>> b=np.arange(1,5)
>>> b
array([1, 2, 3, 4])
>>> np.add(a, b) #等价于a+b
array([1, 3, 5, 7])
>>> np.subtract(a,b) #等价于a-b
array([-1, -1, -1, -1])
>>> np.multiply(a,b) #等价于a*b
array([ 0, 2, 6, 12])
>>> np.divide(a,b) #等价于a/b
array([0, 0, 0, 0])
>>> np.power(a,b) #等价于a**b
array([ 0, 1, 8, 81])
ufunc布尔运算
>>> a = np.array([1,2,3])
>>> b = np.array([3,2,1])
>>> a
array([1, 2, 3])
>>> b
array([3, 2, 1])
>>> np.less(a,b) #等价于a<b
array([ True, False, False])
>>> np.equal(a,b) #等价于a==b
array([False, True, False])
>>> np.not_equal(a,b) #等价于a!=b
array([ True, False, True])
>>> np.less_equal(a,b) #等价于a<=b
array([ True, True, False])
>>> np.greater(a,b) #等价于a>b
array([False, False, True])
>>> np.greater_equal(a,b) #等价于a>=b
array([False, True, True])
ufunc广播运算
广播简而言之,就是向两个数组每一维度上的最大值靠齐。当参与运算的两个数组形状不同时,会自动进行广播,保证形状一致后再计算。
具体的广播处理:
1.让所有输入数组都向其中维度最多的数组看齐,shape属性中不足的部分通过前面加1补齐。
2.输出数组的shape属性是输入数组的shape属性在各个轴上的最大值。
3.如果输入数组的某个轴长度为1或与输出数组对应轴上的长度相同,这个数组就能够用来计算,否则出错。
4.当输入数组的某个轴长度为1时,沿着此轴运算时都用此轴上的第一-组值(复制)
Tensorflow框架
计算框架介绍
theanO
第一个深度学习框架,2008年诞生于加拿大蒙特利尔理工学院的bengio团队。被认为是深度学习研究和发展的行业标准。
keras
以TensorFlow、theano、CNTKE为后端的高级框架,是初学者快速入门的首选。已被TensorFlow收编。
Pytorch
是众多深度学习框架中较灵活的,有Facebook公司做技术支持。它的灵活性满足了科研人员对模型深入理解和多角度探索的需求。
TensorFlow
是当前最流行的深度学习框架,由Google公司做技术支持。官方文档完整,社区活跃,更新快速。以上优势让TensorFlow成为工业界首选框架。
计算图结构
Tensorflow概念
TensorFlow是一个采用数据流图, 用于数值计算的开源软件库。图中节点在图中表示数学操作,线则表示在节点间相互联系的多维数据数组,即张量。
相关性指用于计算一个节点需要的节点。
基本运行流程
定义计算图
Graph = Operation + Tensor
Operation: Graph中的节点,表示计算
Tensor: Graph中的边, 表示数据
张量(Tensor)
多维数据
零阶张量表示标量(scalar)、一阶张量表示向量(vector)、…、N阶张量表示N维数组
三个属性
名称(name)、维度(shape)、类型(type)
>>> import tensorflow as tf
>>> a = tf.constant(1.0, name="a")
>>> b = tf.constant(2.0, name="b")
>>> add = tf.add(a,b, name="add")
>>> print(add)
Tensor("add:0", shape=(), dtype=float32)
张量只是计算结果的引用,并不存储数据。通过张量引用,可以方便地获取中间结果。
如何输出计算结果?
会话(Session)
会话(session) 用于执行定义好的运算,会话拥有TensorFlow程序运行时所有的资源,因此计算完之后要回收资源。
import tensorflow as tf
a = tf.constant(1.0, name="a")
b = tf.constant(2.0, name="b")
add = tf.add(a,b, name="add")
with tf.Session() as sess:
result = sess.run(add)
print(result)
#输出结果 3.0
变量(Variable)
变量(Variable) 用于保存神经网络模型中要训练的参数。Variable定义中包含变量数值类型和变量维度,使用前需要初始化。
随机数
>>> tf.Variable(tf.random_normal([1]), name="weights") #[1]表示维度
<tf.Variable 'weights:0' shape=(1,) dtype=float32_ref>
常数
>>> tf.Variable(tf.zeros([1]), name="bias") #[1]表示维度
<tf.Variable 'bias:0' shape=(1,) dtype=float32_ref>
线性回归示例
import tensorflow as tf
#输入数据
x_train = tf.constant([1, 2, 3], dtype=float)
y_train = tf.constant([1, 2, 3])
#模型结构+变量初始化操作
w = tf.Variable(tf.random_normal([1]), name="weights")
b = tf.Variable(tf.zeros([1]), name="bias")
y = x_train * w + b
init_op = tf.global_variables_initializer()
#模型运行
with tf.Session() as sess:
sess.run(init_op)
print(sess.run(y))
#输出结果:[-0.41663885 -0.8332777 -1.2499166 ]
如何实现批处理?如何避免生成大量常量?
placeholder+feed_dict
placeholder的使用避免的将输入数据声明成大量的常量,而是通过placeholder在程序运行时实时传入数据。数据类型必须指定,数据维度可以不给出。
X = tf.placeho1der(tf.f1oat32, name='i nput’)
feed_ dict是一个字典,表示placeholder和对应取值的键值对,在程序运行的时候,通过给出每个placeholder对应的真实取值,输入到Placeholder对应的位置。
feed_dict={x:0.3}
上边的线性回归代码改进示例:
#输入数据
x_train = tf.placeholder(tf.float32, shape=(2, 1), name='input')
y_train = tf.placeholder(tf.float32, shape=(2, 1), name='output')
#模型结构+变量初始化操作
w = tf.Variable(tf.random_normal([1]), name="weights")
b = tf.Variable(tf.zeros([1]), name="bias")
y = x_train * w + b
init_op = tf.global_variables_initializer()
#模型运行
with tf.Session() as sess:
sess.run(init_op)
print(sess.run(y, feed_dict={x_train: [[1], [2]]}))
#输出结果:[[0.2872567][0.5745134]]
经典损失函数
分类问题
交叉熵损失函数(cross entropy)
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(label=y_label, logits=y_out)
回归问题
均方误差损失函数(MSE, mean squared error)
mse = tf.reduce_mean(tf.square(y_label-y_out))
优化方法
梯度下降方法
train = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost)
整合示例代码
# 输入数据
x = tf.placeholder(tf.float32, shape=(2, 1), name='input')
y_ = tf.placeholder(tf.float32, shape=(2, 1), name='output')
# 模型结构+变量初始化操作
w = tf.Variable(tf.random_normal([1]), name="weights")
b = tf.Variable(tf.zeros([1]), name="bias")
y = x * w + b
init_op = tf.global_variables_initializer()
# 模型优化
mse = tf.reduce_mean(tf.square(y_ - y)) # 损失函数
opt = tf.train.GradientDescentOptimizer(learning_rate=0.01) # 优化方法
train = opt.minimize(mse) # 优化操作
# 模型运行
with tf.Session() as sess:
sess.run(init_op) # 初始化
x_train = tf.constant([1, 2, 3, ...]) # 真实训练集数据
y_train = tf.constant([1, 2, 3, ...]) # 真实训练集标签
steps = 1000 # 训练次数
batch_size = 10 # 批大小
dataset_size = 52 # 训练集大小
for i in range(steps):
start = (i * batch_size) % dataset_size
end = min(start + batch_size, dataset_size)
sess.run(train, feed_dict={x: x_train[start:end], y: y_train[start:end]})
# 模型预测
x_test = tf.constant([2, 1, 5, ...]) # 真实的测试集数据
steps = 1000
for i in range(steps):
start = (i * batch_size) % dataset_size
end = min(start + batch_size, dataset_size)
Predicts = sess.run(y, feed_dict={x:x_test[start:end]})
输入表示
图片输入表示
#输入数据,二维图片
x = tf.placeholder(tf.f1oat32,#数据类型
[batch_size,#批大小
img_width, #图片宽度
img_height, #图片长度
img_channe1s],#图片深度,RGB为3,灰度图为0
name='input')
#输入数据,二维图片
x = tf.placeholder(tf.f1oat32,[None, 14, 14], name='input')
y_ = tf.placeholder(tf.f1oat32,#数据类型
[batch_size,# 批大小
class_size],#目标类别数目
name='output')
y_ = tf.placeholder(tf.f1oat32, [None,10], name='output')
文本输入表示
#输入数据,文本序列
x = tf.p1aceho1der(tf.int32,#数据类型
[batch_ size,#批大小
seq_1en],#词序列长度
name='input')
#示例
x = tf.placeholder(tf.int32,[None,30],name=’input‘)
y_ = tf. placeholder(tf. f1oat32,#数据类型
[batch_size,# 批大小
class_size],#目标类别数目
name='output')
#示例
y_ = tf.placeholder(tf.f1oat32, [None,2],name= 'output')
emb = tf.get_variab1e(“emb”,
[vocab_size, #词汇表大小
emb_size]) #词向量维度
#示例
emb = tf.get_variable(“emb”,[8, 6]) #词向量维度
inputs = tf.nn.embedding_1ookup(emb,x) #向量映射
# get_variable
# 根据变量名称直接获取,如果不存在就创建一个新的
emb = tf. get_variable(name=“emb”,#变量名称(必填)
[vocab_size, #词汇表大小
emb_ size ],#词向量维度
initializer) #词向量矩阵,训练好的
# Variable
#创建一个新的变量,用具体的值初始化,变量名称可选
emb = tf . Variable(initializer,#词向量矩阵,训练好的
name=“emb”#变量名称(可选)
多层感知机
import tensorflow as tf
# 输入表示,一维向量
x = tf.placeholder(tf.float32, [None, in_dim], name='input')
# 初始化模块参数
w1 = tf.Variable(tf.random_normal([in_dim, h1_dim]))
w2 = tf.Variable(tf.random_normal([h1_dim, h2_dim]))
w3 = tf.Variable(tf.random_normal([h2_dim, out_dim]))
# 模型结构,忽略偏置项
h1 = tf.nn.relu(tf.matmul(x, w1))
h2 = tf.nn.relu(tf.matmul(h1, w2))
y = tf.nn.relu(tf.matmul(h2, w3))
卷积神经网络
二维卷积
卷积神经网络的两种写法
--- 第一种
# 输入表示,图片
x = tf.placeholder(tf.float32, [None, width, height, channels], name='input')
# 模型参数
filter = tf.get_variable("weight", [filter_w, filter_h, filter_c, filter_num], initializer=tf.random_normal_initializer)
# 卷积操作
conv = tf.nn.conv2d(x, filter, strides=[1, stride_w, stride_h, 1], padding='SAME')
# 池化操作
pool = tf.nn.max_pool(conv, ksize=[1, pool_w, pool_h, 1], strides=[1, stride_w, stride_h, 1], padding='SAME')
---第二种
conv = tf.layers.conv2d(x, filters=filter_num, kernel_size=(filter_w, filter_h), strides=(stride_w, stride_h), padding='SAME')
pool = tf.layers.max_pooling2d(conv, pool_size=(pool_w, pool_h), strides=(stride_w, stride_h), padding='SAME')
一维卷积
#输入数据,文本序列
x = tf.p1aceho1der(tf.int32,[batch_ size,seq_1en],name='input')
emb = tf.get_variab1e(“emb”,[vocab_size, emb_size])
input = tf.nn.embedding_1ookup(emb,x)
# 卷积操作
conv = tf.layers.conv1d(input, filter_num, filter_size, stride, padding='valid', name='conv1')
# 池化操作
pool = tf.layers.max_pooling1d(conv, filter, stride, padding='SAME')