TensorFlow的名字已经说明了它最重要的两个基本概念:Tensor(张量)和Flow(流)。张量可以在TensorFlow中理解为多维数组,Flow体现了计算模型,表达了张量之间的计算转化过程。
本篇将介绍TensorFlow中三个最基本的概念:计算图,张量和会话,并在基本介绍的基础上介绍如何使用TensorFlow来实现神经网络的训练过程。
1. 计算图(Graph)
计算图是TensorFlow最基本的一个概念,所有的计算都会被转化为计算图上的节点,节点之前的先后依赖关系通过边来表示。如下图所示,我们有x1, x2两个特征向量作为输入,有两组神经网络全连接层,最后有一组输出。其中,每一个节点都是一个运算,每一条边代表了计算之间的依赖关系。
既然计算图中包含张量包含边,就可以将计算图理解为一个张量和边的容器。在没有指定计算图的时候,TensorFlow会使用默认的计算图:
import tensorflow as tf
# 一阶张量相加
a = tf.constant([1.0, 2.0, 3.0], name='a')
b = tf.constant([2.0, 3.0, 4.0], name='b')
result = a + b
print(a.graph is tf.get_default_graph())
print(b.graph)
print(a.graph)
输出:
True
<tensorflow.python.framework.ops.Graph object at 0x000002A5152EC908>
<tensorflow.python.framework.ops.Graph object at 0x000002A5152EC908>
也可以显示指定计算图,不同计算图上的张量和运算都不会共享。
# 不同计算图张量不共享
import tensorflow as tf
g1 = tf.Graph()
with g1.as_default():
v = tf.get_variable("v", shape=[1], initializer=tf.zeros_initializer)
g2 = tf.Graph()
with g2.as_default():
v = tf.get_variable("v", shape=[1], initializer=tf.ones_initializer)
with tf.Session(graph=g1) as sess:
tf.global_variables_initializer().run()
with tf.variable_scope("", reuse=True):
print(sess.run(tf.get_variable("v")))
with tf.Session(graph=g2) as sess:
tf.global_variables_initializer().run()
with tf.variable_scope("", reuse=True):
print(sess.run(tf.get_variable("v")))
输出:
[0.]
[1.]
可以看出,虽然都是变量v,但是不同的计算图取到的结果是不一样的。
2. 张量(Tensor)
在TensorFlow程序中,所有的数据都通过张量的形式来表示。从功能上来看,张量可以被简单的理解为多维数组。其中零阶张量表示标量(scalar),也就是一个数;第一阶张量为向量(vector),也就是一个一维数组;第n阶张量可以理解为一个n维数组。
1.2 三种张量详解
Tensorflow有三种特殊的张量:
- tf.Variable
- tf.constant
- tf.placeholder
1.2.1 tf.constant
tf.constant是一个计算,这个计算的结果是一个张量。在张量中没有真正保存数字,它保存的是如何得到这些数字的计算过程。
import tensorflow as tf
a = tf.constant([1.0, 2.0], name='a')
b = tf.constant([2.0, 3.0], name='b')
result = tf.add(a, b, name="add")
print(result)
输出:
Tensor("add:0", shape=(3,), dtype=float32)
从上面的结果可以看出,一个张量中主要保存了三个属性:名字(name),维度(shape),类型(type)。第一个属性是一个张量的唯一标识符,它同样给出了张量是如何计算出来的。”add:0”说明了result这个张量是计算节点”add”输出的第一个结果(编号从0开始);第二个属性是张量的维度,shape=(2,)说明了张量result是一个一维数组,这数组的长度是2;张量的第三个属性是类型(type),每一个张量会有一个唯一的类型。TensorFlow会对参与运算的所有张量进行类型的检查,当发现类型不匹配时会报错。
1.2.2 tf.Variable
tf.Variable(变量)的作用是保存和更新神经网络中的参数,和其他编程语言类似,变量也需要指定初始值。例如,声明一个2*3的矩阵变量:
weights = tf.Variable(tf.random_normal([2, 3], stddev=2))
该矩阵的数值满足正态分布,均值为0,标准差为2。
1.2.3 tf.placeholder
如果训练集中的每一次输入都用一个常量来表示,那么TensorFlow的计算图将非常庞大。因为每生成一个常量,TensorFlow都会在计算图中增加一个节点。为了避免这个问题,TensorFlow提供了placeholder机制用于提供输入数据。placeholder相当于定义了一个位置,这个位置中的数据在程序运行时再指定。
注意:定义placeholder的时候,类型是必须要指定的,维度信息可以推断出来,所以不一定要给出。
s