新手学习Tensorflow 笔记
Tensorflow 计算模型————计算图
Tensor 张量
Flow 流
- 导入Tensorflow一般使用
import tensorflow as tf
- 获取当前默认的计算图可以用
tf.get_default_graph()
函数 - 还支持
tf.Graph()
函数来生成新的计算图
Tensorflow 数据模型————张量
Tensor
张量在Tensorflow中实现并不是采用数组的形式,它只是对Tensorflow中的运算结果的引用。
张量中主要保存了三个属性:姓名(name),维度(shape),类型(type)。
Tensor("add:0",shape=(2,),dtype=float32)
其中,add:0
中add为节点名称,0表示这个张量是计算节点add
输出的第一个输出结果;shape=(2,)
说明该张量是一个一维数组,长度为2;后面dtype
为类型,每个张量会有一个唯一的类型。
Tensorflow 运行模型————会话
# 创建一个会话
sess = tf.session()
# 用会话获取运行结果,例如
sess.run(...)
# 还要关闭会话,不然可能出现资源泄露
sess.close()
# 所以一般用下面这种来管理
with tf.Session() as sess:
sess.run(....)
# 这种不需要关闭会话
Tensorflow会自动生成一个默认的计算图,如果没有特殊的指定,运算会自动加入这个计算图中;然而
,Tensorflow不会自动生成默认的会话,需要手动指定。
当默认的会话被指定后,可以通过tf.Tensor.eval函数
来计算一个张量的取值。
eg:
sess =tf.Session()
with sess.as_default():
print(myTensor.eval)
---------------------------------------------------------------------
#以下的代码完成同样的功能
sess = tf.Session()
print(sess.run(myTensor))
print(myTensor.eval(session=sess))
Tensorflow 实现神经网络
前向传播算法简介
神经元也包括偏置(bias)、激活函数(activate function)等
矩阵乘法a = tf.matmul(x,w1)
神经网络参数与Tensorflow变量
weights = tf.Variable(tf.random_normal([2,3],stddev=2))
tf.random_normal([2,3],stddev=2)
产生一个2*3的矩阵,矩阵中的元素是均值为0,标准差为2的随机数。(其实可以通过参数mean来指定平均值,没有指定时默认为0)。
随机数生成函数表:
函数名字 | 随机数分布 | 主要参数 |
---|---|---|
tf.random_normal | 正态分布 | 平均值、标准差、取值类型 |
tf.truncated_normal | 正态分布,但是如果随机出的值偏高平均值超过2个标准差,那么这个数将会被重新分配 | 平均值、标准差、取值类型 |
tf.random_uniform | 均值分布 | 最小、最大取值、取值类型 |
tf.random_gamma | Gamma分布 | 形状参数 α \alpha α、尺度取值 β \beta β、取值类型 |
常数生成函数:
函数名称 | 功能 | eg |
---|---|---|
tf.zeros | 产生全零数组 | tf.zero([2,3],int32)->[[0,0,0],[0,0,0]] |
tf.ones | 全1 | 同上 |
tf.fill | 产生一个全部为给定数字的数组 | tf.fill([2,3],9) |
tf.constant | 产生一个给定常量 | tf.constant([1,2,3])->[1,2,3] |
Tensorflow程序:
- 第一步为定义Tensorflow计算图中的计算(其实并不真正运行)
- 第二步会声明一个会话,并
通过会话计算结果
。但是在声明会话后、计算前,需要将所有用的变量初始化。
(初始化可以单个变量分开操作,但是一般全部一起初始化,使用tf.global_varilables_initalizer()函数
)
#整体初始化
init_op = tf.global_variables_initalizer()
sess.run(init_op)
Tensor张量的维度
和类型
也是很重要的:
- 一个变量在构建后类型就不可以再改变了;
- 维度在程序运行中是可能改变的,但是需要通过设置参数
validate_shape=False
(事实上第2点是比较罕见的)
Tensorflow中集合的概念,所有的变量都会被自动加入到
GraphKeys.VARIABLES
这个集合中。还可以通过变量声明函数中的trainable
参数来区分需要优化的参数和其他参数。如果trainable参数为True,那么这个参数将会被加入到GraphKeys.TRAINABLE_VARIABLES
集合中。在Tensorflow中可以通过tf.trainable_variables函数
得到所有需要优化的参数。
通过Tensorflow迅练神经网络模型
监督学习:使用监督学习的方式设置神经网络参数需要有一个标注好的训练数据集。
反向传播算法(backpropagation):一个迭代的过程。首先需要选取一小部分训练数据,这一小部分数据叫做一个
batch
;然后,前向传播算法,再计算出预测答案与正确答案之间的差距;最后,基于这个差距,反向传播算法会相应更新神经网络参数的取值,使得再这个batch
上神经网络模型的预测结果和真实答案更加接近。
Tensorflow提供了
placeholder
机制用于提供输入数据。再placeholder定义时,这个位置上的数据类型是需要指定的。和其他张量一样,placeholder的类型也是不可以改变的。placeholder中的数据的维度信息可以根据提供的数据推导得出,所以不一定要给出。
# 传入3条数据
x = tf.placeholder(tf.float32, shape=(3,2),name="input")
使用了placeholder,在启用会话跑数据的时候就要进行喂数据操作了。eg:
sess.run(y,feed_dict={x:X,y:Y})
feed_dict
是一个字典(map)。
在得到一个batch的前向传播结束之后,需要定义一个损失函数
来刻画当前的预测值和真实答案之间的差距。
还有个学习率
Tensorflow支持10种优化方法,常用的:
tf.train.DradientDescentOptimizer
,tf.train.AdamOptimizer
,tf.train.MomentumOptimizer
三种。
一个完整的神经网络样例程序
import tensorflow as tf
from numpy.random import RandomState
batch_size = 8
w1= tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2= tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
x = tf.placeholder(tf.float32, shape=(None, 2), name="x-input")
y_= tf.placeholder(tf.float32, shape=(None, 1), name='y-input')
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
y = tf.sigmoid(y)
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0))
+ (1 - y_) * tf.log(tf.clip_by_value(1 - y, 1e-10, 1.0)))
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
rdm = RandomState(1)
X = rdm.rand(128,2)
Y = [[int(x1+x2 < 1)] for (x1, x2) in X]
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 输出目前(未经训练)的参数取值。
print(sess.run(w1))
print(sess.run(w2))
print("\n")
# 训练模型。
STEPS = 5000
for i in range(STEPS):
start = (i * batch_size) % 128
end = (i * batch_size) % 128 + batch_size
sess.run([train_step, y, y_], feed_dict={x: X[start:end], y_: Y[start:end]})
if i % 1000 == 0:
total_cross_entropy = sess.run(cross_entropy, feed_dict={x: X, y_: Y})
print("After %d training step(s), cross entropy on all data is %g" % (i, total_cross_entropy))
# 输出训练后的参数取值。
print("\n")
print(sess.run(w1))
print(sess.run(w2))
总结
训练神经网络的三个步骤:
- 定义神经网络的结构和前向传播的输出结果
- 定义损失函数以及选择反向传播优化的算法
- 生成会话并且在训练数据上反复运行反向传播优化算法