tensorflow相当于是一个通过计算图的形式来表述计算的编程系统。
3.1计算图使用
tf.get_default_graph函数可以获取当前默认的计算图。
.graph可以查看张量所属的计算图,g=**tf.Graph()**函数用来生成新的计算图。
一定紧跟with g.as_default():
tf.get_variable()(官方解释说明)
**tf.constant_initializer()**也可以简写为tf.Constant()初始化为常数,这个非常有用,通常偏置项就是用它初始化的。
由它衍生出的两个初始化方法:
tf.zeros_initializer(), 也可以简写为tf.Zeros()初始化为0
tf.ones_initializer(), 也可以简写为tf.Ones()初始化为1
如下图中的get_variable_scope如何实现变量重名,以及变量共享:
在不同的计算图运行时候,变量v的值也是不同的。
可以用tf.Graph.device来指定运算跑在什么设备上面。(此部分展示略去)
3.2数据模型张量
张量中并不保存真正的数组,而是对运算结果进行引用,保存这些数字的计算过程。
张量通常保存了三个属性:名字,维度,类型(注意不能出现一个实数加一个整数的情况)。同时注意node节点的名称命名方式,如:add:0表示add这个运算输出的第一个结果。
可以用result.get_shape()函数来获取结果张量的维度信息。
.eval()是返回计算结果,注意使用之前需要保证tensor的图必须已经投入到session里面,或者一个默认的session是有效的,或者显式指定session;
tf.InteractiveSession():它能让你在运行图的时候,插入一些计算图,这些计算图是由某些操作(operations)构成的。这对于工作在交互式环境中的人们来说非常便利,比如使用IPython。
tf.Session():需要在启动session之前构建整个计算图,然后启动该计算图。
3.3会话的使用
1.可以采用明确会话创建和关闭的方式,但是每一次需要调用Session.close()来手动是否那个资源,所以当程序异常退出时,可能关闭会话函数就不会执行从而导致资源泄漏,所以我们可以采用通过python上下文管理器来使用会话;
2.只需要将所有计算放在“with”内部:
with tf.Session() as sess:
print(sess.run(result))
tensorflow有默认的计算图,但是没有默认的会话,所以一旦制定默认的会话之后,tf.Tensor.eval()函数可以用来计算一个特定张量的取值。下面有两种eval的用法:
sess = tf.Session()
with sess.as_default():
print(result.eval())
#下面三行等同于上面三行
sess = tf.Session()
#下面的两个命令有相同的功能。
print(sess.run(result))
print(result.eval(session=sess))
交互式环境下直接构建默认会话的函数:tf.InteractiveSession(),通过这个函数可以省去将产生的会话注册为默认会话的过程
3.3tensorflow实现神经网络
http://playground.tensorflow.org/ 这个网站是简答可视化神经网络并实现可视化训练过程的工具
3.4向前传播算法
用矩阵相乘实现正向传播:(注意单元的顺序)
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
初始化参数的方法:1随机数,2用常熟来指定 3通过其他变量的初始值来指定
w1= tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2= tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
#或者用下面的方法
weight = tf.Variable(tf.random_nrmal([2,3],stddev=2))
w2 = tf.Variable(wight.initialized_value()*2.0)
bias偏置量通常用来设置初始值
sess = tf.Session()
sess.run(w1.initializer)
sess.run(w2.initializer)
print(sess.run(y))
sess.close()
运行之前先初始化w1和w2,可以单独运行初始化,但如果是变量较多并且相互依赖就显得比较麻烦,所以使用
init_op = tf.global_variables_initializer()
sess.run(init_op)
tensorflow中有集合GraphKeys.VARIABLES,包含了所有计算图中的变量可以通过tg.global_variables(),如果标记了trainable为true,则表示这个变量时在优化神经网络中自动优化的对象。
注意张量赋值.assign()时候,维度和类型都不可变,否则会报错。
3.4.4使用监督学习合理设置参数取值
在神经网络优化算法中,常用反向传播算法backpropagation,利用标记过的训练集数据。(具体会在4.3节讲到)
每一次迭代开始都会选取一小部分训练数据,这一小部分叫做一个batch。每一次迭代先采用前向传播和正确答案比较,再通过反向传播更新参数的取值,使这个batch的预测和真实结果更加接近。
为了防止每次迭代新生成一个变量,即一个节点使计算图变得无比大,利用率很低,所以引入了一个placeholder来传入tensorflow的计算图。
x = tf.placeholder(tf.float32, shape=(1, 2), name="input")
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)
sess = tf.Session()
init_op = tf.global_variables_initializer()
sess.run(init_op)
print(sess.run(y, feed_dict={x: [[0.7,0.9]]}))
其中feed_dict是用来指定x的取值,他是一个字典map,必须有!
下面是指明多个输入batch的程序:(一次多个样例向前传播的结果)
x = tf.placeholder(tf.float32, shape=(3, 2), name="input")
#......
print(sess.run(y, feed_dict={x: [[0.7,0.9],[0.1,0.4],[0.5,0.8]]}))
可以通过一个损失函数来刻画当前预测值和真实答案之间的差距(见下面的完整程序)
import tensorflow as tf
from numpy.random import RandomState
#这里使用numpy数据包生成模拟数据集
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')
#none表示batch的大小不确定
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))
以下是输出结果: