TensorFlow是基于计算图的框架:
- 使用图(Graph)来表示计算任务.
- 使用tensor表示数据.
- 在被称之为会话(session)的上下文 (context) 中执行图.
- 通过变量(variable)维护状态.
- 使用feed和fetch可以为任意的操作(Operation)赋值或者从其中获取数据.
TensorFlow程序通常可以分为两个阶段: 图的构建阶段和图的执行阶段
一、计算图(Graph)
一个session中可以有多个图,每个图都是由节点和线组成,线表示数据(可以是变量、常量、矩阵等等),即Tensor,节点表示操作(可以是加减乘除或者矩阵乘法等等),即Operation。Op的输入可以为多个Tensor,但是输出仅有一个
二、Tensor
在TensorFlow中,数据用tensor
表示,在计算图中,所有operation之间传递的数据都是tensor
。其实一个tensor
可以看成一个多维数组,里面可以存放不同类型的数据。将tensor
在控制台输出,里面有3个属性:
import tensorflow as tf #创建常量OP a=tf.constant([[2,3]]) #创建常量OP b=tf.constant([[1],[2]]) #创建矩阵乘法OP result=tf.matmul(a,b) print(result)
输出:
Tensor("MatMul:0", shape=(1, 1), dtype=int32)
括号里第一个属性是操作的类型(后面那个数字好像是设备号还是什么,这个问题先放在这,以后遇到再去查),第二个是tensor
的维度,第三个是tensor
的类型。
三、会话(Session)
构造阶段完成后,才能启动图。启动图的第一步是创建一个 Session
对象,如果无任何创建参数,会话构造器将启动默认图。
import tensorflow as tf #创建常量OP a=tf.constant([[2,3]]) #创建常量OP b=tf.constant([[1],[2]]) #创建矩阵乘法OP result=tf.matmul(a,b)
#定义一个会话,启动默认图 sess=tf.Session()
#调用session的run方法来执行matmul节点操作 result=sess.run(result) print(result) sess.close()
输出:
[[8]]
在实现上, TensorFlow 将图形定义转换成分布式执行的操作, 以充分利用可用的计算资源(如 CPU 或 GPU). 一般你不需要显式指定使用 CPU 还是 GPU, TensorFlow 能自动检测. 如果检测到 GPU, TensorFlow 会尽可能地利用找到的第一个 GPU 来执行操作.
四、Variable
变量维护图执行过程中的状态信息。tensor一旦拥有Variable的指向就不会随session的多次载入而丢失。在session中Variable是单独保存的,在使用时必须进行初始化。
import tensorflow as tf #创建一个变量,初始化为0 counter=tf.Variable(0,name='counter') #创建一个OP,使counter加1 add=tf.add(counter, 1) #将加1后的值赋值给counter update=tf.assign(counter, add) #初始化变量 init=tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) print(sess.run(counter)) for _ in range(5): #执行加1、赋值操作 sess.run(update) print(sess.run(counter))
输出:0 1 2 3 4 5
五、placeholder和feed_dict
当我们定义一张graph时,有时候并不知道需要计算的值,比如模型的输入数据,其只有在训练与预测时才会有值。这时就需要placeholder与feed_dict的帮助。
import tensorflow as tf
def fetch():
input1=tf.constant(1.0)
input2=tf.constant(2.0)
input3=tf.constant(3.0)
add=tf.add(input1,input2)
multiply=tf.multiply(input2, input3)
with tf.Session() as sess:
#fetch指可同时计算多个OP的结果
result=sess.run([add,multiply])
print(result)
def feed():
input1=tf.placeholder(tf.float32)
input2=tf.placeholder(tf.float32)
multiply=tf.multiply(input1,input2)
with tf.Session() as sess:
#feed的数据以字典的形式传入
result=sess.run(multiply,feed_dict={input1:7.0,input2:2.0})
print(result)
if __name__=='__main__':
fetch()
feed()
#输出:
[3.0, 6.0]
14.0
在上面程序中,input1
和input2
开始的值是未知的,在sess.run()中才传给它们实际的值,feed_dict={input1:7.0, input2:2.0}
中input1和input2是索引名,默认等于tensor的名字,也可以在定义占位符时自己定义索引名。
注意,在计算图中,可以用feed_dict
来替换任何tensor
,并不局限于占位符。
六、小练习
import tensorflow as tf
import numpy as np
x_data=np.random.rand(100)
# print(x_data)
y=x_data*0.3+0.2
#构造线性模型
W=tf.Variable(0.)
b=tf.Variable(0.)
y_pre=W*x_data+b
#二次代价函数
loss=tf.reduce_mean(tf.square(y_pre-y))
#定义一个优化器,学习率为0.2
optimizer=tf.train.GradientDescentOptimizer(0.2)
#优化目标为使loss值最小
train=optimizer.minimize(loss)
init=tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for step in range(201):
sess.run(train)
if step%20==0:
print(step,sess.run([W,b]))
#输出:
0 [0.073843427, 0.13591674]
20 [0.21287213, 0.2437014]
40 [0.25102881, 0.22456299]
60 [0.27247521, 0.2138059]
80 [0.28452939, 0.20775977]
100 [0.29130453, 0.20436148]
120 [0.29511258, 0.20245144]
140 [0.29725295, 0.20137787]
160 [0.29845598, 0.20077445]
180 [0.29913217, 0.2004353]
200 [0.29951221, 0.20024467]