本文已参与「新人创作礼」活动,一起开启掘金创作之路。
TensorFlow概述
首先简单回顾一下 中张量的概念与通俗解释,在 中,所有的数据都通过张量的形式来表示 从功能的角度,张量可以简单理解为多维数组,张量并没有真正保存数字,它保存的是计算过程。通俗理解如下:
- 零阶张量表示标量(scalar),也就是一个数
- 一阶张量表示向量(vector),也就是一维数组
- n 阶张量可以理解为一个n维数组 会对参与运算的所有张量进行类型的检查,发现类型不匹配时会报错,因此TensorFlow对数据类型的要求比较严格。
中最基本的单位是常量(Constant)、变量(Variable)和占位符(Placeholder)。
简而言之常量与变量的区别:
- 常量在定义后,常量的值和维度不可变。
- 变量被定义后,变量的值可变,但是维度不可变。
- 在神经网络中,变量一般可用来保存训练参数,作为储存权重和其他信息的矩阵,而常量可作为储存超参数或其他结构信息的变量。
下面将重点介绍中占位符的理解与使用。
占位符
中的Variable变量类型,在定义时需要初始化,但有些变量定义时并不知道其数值,只有当真正开始运行程序时,才由外部输入,比如训练数据,这时候需要用到占位符。这也是Tensorflow特有的一种数据结构。
TensorFlow占位符Placeholder,先定义一种数据,其参数为数据的Type和Shape
tf.placeholder(dtype, shape=None, name=None),其中dtype必须填写。
注意:如果构建了一个包含placeholder操作的计算图,当在session中调用run方法时,placeholder占用的变量必须通过feed_dict参数传递进去,否则报错。
具体程序演示代码如下所示:
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() # 解决方案:注释tf的引用,换为兼容模式。
a = tf.placeholder(tf.float32, name='a')
b = tf.placeholder(tf.float32, name='b')
c = tf.multiply(a, b, name='c')
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
# 通过feed_dict的参数传值,按字典格式
result = sess.run(c, feed_dict={a: 8.0, b: 3.5})
print(result)
# 一次返回多个值分别赋给多个变量方法1
a1 = tf.placeholder(tf.float32, name='a1')
b1 = tf.placeholder(tf.float32, name='b1')
c1 = tf.multiply(a1, b1, name='c1')
d1 = tf.subtract(a1, b1, name='d1')
init1 = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init1)
result = sess.run([c1, d1], feed_dict={a1: [8.0, 2.0, 3.5], b1: [1.5, 2.0, 4.]}) # 向量
print(result)
# 取结果中的第一个
print(result[0])
# 一次返回多个值分别赋给多个变量方法2
with tf.Session() as sess:
sess.run(init1)
# 返回两个值分别赋给两个变量
rc, rd = sess.run([c1, d1], feed_dict={a1: [8.0, 2.0, 3.5], b1: [1.5, 2.0, 4.]})
print("Value of c=", rc, "value of d=", rd)
操作
计算图中的节点就是操作(Operation)
- 一次加法是一个操作
- 一次乘法也是一个操作
- 构建一些变量的初始值也是一个操作
每个运算操作都有属性,它在构建图的时候需要确定下来。操作可以和计算设备绑定,指定操作在某个设备上执行,例如某个操作运行在哪个GPU上。操作之间存在顺序关系,这些操作之间的依赖就是边。如果操作A的输入是操作B执行的结果,那么这个操作A就依赖于操作B。