程序 = 数据结构 + 算法。
TensorFlow程序 = 张量数据结构 + 计算图算法语言
- 张量:即Tensorflow的基本数据结构,张量(Tensor)即多维数组
- 计算图:TensorFlow的所有计算都会被转化为计算图上的节点
前面已经介绍过,张量即多维数组。
标量为0维张量,向量为1维张量,矩阵为2维张量。彩色图像有rgb三个通道,可以表示为3维张量。视频还有时间维,可以表示为4维张量。
可以简单地总结为:有几层中括号,就是多少维的张量。
scalar = tf.constant(True) # 标量, 0维张量
vector = tf.constant([1.0, 2.0, 3.0, 4.0]) # 向量, 1维张量
matrix = tf.constant([[1.0, 2.0], [3.0, 4.0]]) # 矩阵, 2维张量
tensor3 = tf.constant([[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0], [7.0, 8.0]]]) # 3维张量
tf.rank()
用来返回张量的秩。需要注意的是,张量的秩与矩阵的秩不一样。张量的秩是唯一选择张量的每个元素所需的索引的数量。秩也被称为 “order”,“degree” 或 “ndims”。这里张量的秩,可以直接理解维度,就是说这个张量是几维的,它不是矩阵的秩也不是数组的shape,简单的理解,可以它就是中括号的层数。
with tf.Session() as sess:
print(sess.run(tf.rank(scalar)))
print(sess.run(tf.rank(vector)))
print(sess.run(tf.rank(matrix)))
print(sess.run(tf.rank(tensor3)))
输出
0
1
2
3
从行为特性来看,有两种类型的张量,常量constant和变量Variable
1. 张量的概念
前面介绍过,张量(tensor)可以被简单理解为多维数组。
但张量在 TensorFlow 中的实现并不是直接采用数组的形式,它只是对 TensorFlow 中运算结果的引用。在张量中并没有真正保存数字,它保存的是如何得到这些数字的计算过程。
import tensorflow as tf
matrix1 = tf.constant([[3, 3]])
matrix2 = tf.constant([[2],
[2]])
product = tf.matmul(matrix1, matrix2)
print(product)
输出
Tensor("MatMul:0", shape=(1, 1), dtype=int32)
从上面代码的运行结果可以看出,一 个张量中主要保存了三个属性:名字(name)、维度(shape)和类型(type)。
张量的第一个属性名字不仅是一个张量的唯一标识符,它同样也给出了这个张量是如何计算出来的。张量的命名就可以通过“node:src_output”的 形式来给出。其中 node 为节点的名称,src_output 表示当前张量来自节点的第几个输出。 比如上面代码打出来的“MatMul:0”就说明了 result 这个张量是计算节点“MatMul”输出的第一个 结果(编号从 0 开始)。
dtype:TensorFlow 会给出默认的类型, 比如不带小数点的数会被默认为 int32,带小数点的会默认为 float32
2. 常量张量
常量张量:计算图中不可以被重新赋值
常量,使用tf.constant()
定义
import tensorflow as tf
i = tf.constant(1) # tf.int32 类型常量
l = tf.constant(1, dtype=tf.int64) # tf.int64 类型常量
f = tf.constant(1.23) #tf.float32 类型常量
d = tf.constant(3.14, dtype=tf.double) # tf.double 类型常量
s = tf.constant("hello world") # tf.string类型常量
b = tf.constant(True) #tf.bool类型常量
可以用tf.cast()
改变张量的数据类型。
h = tf.constant([123, 456], dtype=tf.int32)
f = tf.cast(h, tf.float32)
print(h.dtype)
print(f.dtype)
<dtype: 'int32'>
<dtype: 'float32'>
进行类型转换时,需要保证转换操作的合法性,例如将高精度的张量转换为低精度的张量时,可能发生数据溢出隐患:
num = tf.constant(123456789, dtype=tf.int32)
tf.cast(num, tf.int16))
可以用 shape属性查看张量的尺寸。
import tensorflow as tf
h = tf.constant([123, 456], dtype=tf.int32)
print(len(h.shape))
print(h.shape)
1
2
1 表示 h 是一维度张量
2 表示 h 的元素有 2 个
shape=(2,)说明了张量 result 是一个一维数组,这个数组的长度为 2。
3. 变量张量
变量张量:TensorFlow里创建变量的两种方式有tf.get_variable()
和 tf.Variable()
计算图中可以用assign()
,assign_add()
等算子重新赋值。
模型中需要被训练的参数一般被设置成变量。
Variable类型对象不能直接输出,因为当前对象只是一个定义。这里还需要解释一下。
x = tf.Variable(tf.constant(0.0), dtype=tf.float32)
y = tf.assign(x, 20)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(x))
print(sess.run(y))
输出
0.0
20.0
2.1 tf.Variable()
tf.Variable()
用于生成一个初始值为initial-value的变量。必须指定初始化值
W = tf.Variable(<initial-value>, name=<optional-name>)
2.2 tf.get_variable()
tf.get_variable()
会检查当前命名空间下是否存在同样name的变量,可以方便共享变量。而tf.Variable 每次都会新建一个变量。
import tensorflow as tf
v1 = tf.get_variable("v", [0])
v2 = tf.get_variable("v", [1])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
result = sess.run(v2)
print(result)
上面的代码会报错:ValueError: Variable v already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?