TensorFlow使用图 (graph) 来表示计算任务.
在被称之为 会话 (Session) 的上下文 (context) 中执行图.
使用张量(tensor) 表示数据.
通过变量 (Variable) 维护状态.
使用feed和fetch可以为任意的操作(arbitrary operation) 赋值或者从其中获取数据.
TensorFlow 是一个编程系统, 使用图来表示计算任务. 图中的节点被称之为 op (operation 的缩写). 一个 op 获得 0 个或多个 Tensor, 执行计算, 产生 0 个或多个 Tensor
一个 TensorFlow 图描述了计算的过程. 为了进行计算, 图必须在 会话 里被启动. 会话 将图的 op 分发到诸如 CPU 或 GPU 之类的 设备 上, 同时提供执行 op 的方法. 这些方法执行后, 将产生的 tensor 返回. 在 Python 语言中, 返回的 tensor 是 numpy ndarray 对象; 在 C 和 C++ 语言中, 返回的 tensor 是 tensorflow::Tensor 实例.
计算图
TensorFlow 程序通常被组织成一个构建阶段和一个执行阶段. 在构建阶段, op 的执行步骤 被描述成一个图. 在执行阶段, 使用会话执行执行图中的 op.
例如, 通常在构建阶段创建一个图来表示和训练神经网络, 然后在执行阶段反复执行图中的训练 op.
TensorFlow 支持 C, C++, Python 编程语言. 目前, TensorFlow 的 Python 库更加易用
构建图
构建图的第一步, 是创建源 op (source op). 源 op 不需要任何输入, 例如 常量 (Constant). 源 op 的输出被传递给其它 op 做运算.
Python 库中, op 构造器的返回值代表被构造出的 op 的输出, 这些返回值可以传递给其它 op 构造器作为输入.
TensorFlow Python 库有一个默认图 (default graph), op 构造器可以为其增加节点. 这个默认图对 许多程序来说已经足够用了.
import tensorflow as tf
# 创建一个常量 op, 产生一个 1×2 矩阵. 这个 op 被作为一个节点
# 加到默认图中.
# 构造器的返回值代表该常量 op 的返回值.
matrix1 = tf.constant([[3., 3.]])
# 创建另外一个常量 op, 产生一个 2×1 矩阵.
matrix2 = tf.constant([[2.],[2.]])
# 创建一个矩阵乘法 matmul op , 把 ‘matrix1’ 和 ‘matrix2’ 作为输入.
# 返回值 ‘product’ 代表矩阵乘法的结果.
product = tf.matmul(matrix1, matrix2)
默认图现在有三个节点, 两个 constant() op, 和一个matmul() op. 为了真正进行矩阵相乘运算, 并得到矩阵乘法的 结果, 你必须在会话里启动这个图.
在一个会话中启动图
构造阶段完成后, 才能启动图. 启动图的第一步是创建一个 Session 对象, 如果无任何创建参数, 会话构造器将启动默认图.
# 启动默认图.
sess = tf.Session()
# 调用 sess 的 ‘run()’ 方法来执行矩阵乘法 op, 传入 ‘product’ 作为该方法的参数.
# 上面提到, ‘product’ 代表了矩阵乘法 op 的输出, 传入它是向方法表明, 我们希望取回
# 矩阵乘法 op 的输出.
# 整个执行过程是自动化的, 会话负责传递 op 所需的全部输入. op 通常是并发执行的.
# 函数调用 ‘run(product)’ 触发了图中三个 op (两个常量 op 和一个矩阵乘法 op) 的执行.
# 返回值 ‘result’ 是一个 numpy `ndarray` 对象.
result = sess.run(product)
print result
# ==> [[ 12.]]
# 任务完成, 关闭会话.
sess.close()
Session 对象在使用完后需要关闭以释放资源. 除了显式调用 close 外, 也可以使用 “with” 代码块 来自动完成关闭动作.
with tf.Session() as sess:
result = sess.run([product])
print result
在实现上, TensorFlow 将图形定义转换成分布式执行的操作, 以充分利用可用的计算资源(如 CPU 或 GPU). 一般你不需要显式指定使用 CPU 还是 GPU, TensorFlow 能自动检测. 如果检测到 GPU, TensorFlow 会尽可能地利用找到的第一个 GPU 来执行操作.
如果机器上有超过一个可用的 GPU, 除第一个外的其它 GPU 默认是不参与计算的. 为了让 TensorFlow 使用这些 GPU, 你必须将 op 明确指派给它们执行. with…Device 语句用来指派特定的 CPU 或 GPU 执行操作:
with tf.Session() as sess:
with tf.device(“/gpu:1”):
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
product = tf.matmul(matrix1, matrix2)
…
设备用字符串进行标识. 目前支持的设备包括:
“/cpu:0”: 机器的 CPU.
“/gpu:0”: 机器的第一个 GPU, 如果有的话.
“/gpu:1”: 机器的第二个 GPU, 以此类推.
交互式使用
文档中的 Python 示例使用一个会话 Session 来 启动图, 并调用 Session.run() 方法执行操作.
为了便于使用诸如 IPython 之类的 Python 交互环境, 可以使用 InteractiveSession 代替 Session 类, 使用 Tensor.eval() 和 Operation.run() 方法代替 Session.run(). 这样可以避免使用一个变量来持有会话
# 进入一个交互式 TensorFlow 会话.
import tensorflow as tf
sess = tf.InteractiveSession()
x = tf.Variable([1.0, 2.0])
a = tf.constant([3.0, 3.0])
# 使用初始化器 initializer op 的 run() 方法初始化 ‘x’
x.initializer.run()
# 增加一个减法 sub op, 从 ‘x’ 减去 ‘a’. 运行减法 op, 输出结果
sub = tf.sub(x, a)
print sub.eval()
# ==> [-2. -1.]
生成constant(常量)
生成全0数组
# 语法:
tf.zeros(shape, dtype, name)
# 样例:
tf.zeros([2, 3], int32) # ==> [[0, 0, 0], [0, 0, 0]]
生成一个与给定tensor类型、形状一致的常量,其所有元素为0
# 语法:
tf.zeros_like(tensor, dtype, name)
# 样例
a = tf.constant([[1, 2, 3], [4, 5, 6]] )
tf.zeros_like(a) # ==> [[0, 0, 0], [0, 0, 0]]
生成全1数组
# 语法:
tf.ones(shape, dtype, name)
# 样例:
tf.ones([2, 3], int32) # ==> [[1, 1, 1], [1, 1, 1]]
生成一个与给定tensor类型、形状一致的常量,其所有元素为1
# 语法:
tf.ones_like(tensor, dtype, name)
# 样例:
a = tf.constant([[1, 2, 3], [4, 5, 6]])
tf.ones_like(a) # ==> [[1, 1, 1], [1, 1, 1]]
生成一个给定值的常量
# 语法:
tf.constant(value, dtype, shape, name)
# 样例:
a = tf.constant([[1, 2, 3], [4, 5, 6]], int32)
# ==> [[1, 2, 3], [4, 5, 6]]
生成一个全部为给定数字的数组
# 语法:
tf.fill(dims, value, name)
# 样例:
a = tf.fill([2, 3], 9) # ==> [[9, 9, 9], [9, 9, 9]]
变量
在TensorFlow中,变量(tf.Variable)用于保存,更新神经网络的参数张量。
2.1 变量常见的属性与方法
tf.constant是一个op(算子),而tf.Variable是一个类,用于实例化对象,然后用对象初始化多个op。变量常见的属性与方法:
x = tf.Variable()
x.initializer # 初始化单个变量
x.value() # 读取op
x.assign() # 写入op
x.assign_add() # 更多op
x.eval() # 输出变量内容
变量初始化
虽然在定义变量时,我们给出了变量初始化的方法,但这个方法并没有被真正运行。一个变量的值在被使用之前,这个变量的初始化过程需要被明确地调用。
初始化全部变量
这个方法最简单。通过tf.global_variables_initializer函数,我们就不需要将变量一个一个初始化了。
init = tf.global_variables_initializer()
# -*- coding: utf-8 -*- import tensorflow as tf a = tf.constant([1.0, 2.0, 3.0], shape=[3], name='a') b = tf.constant([1.0, 2.0, 3.0], shape=[3], name='b') c = a + b sess = tf.Session() print(sess.run(c)) hello = tf.constant("Hello, TensorFlow!") sess = tf.Session() print(sess.run(hello)) a = tf.constant(10) b = tf.constant(32) print(sess.run(a+b)) # 创建一个常量 op, 产生一个 1x2 矩阵. 这个 op 被作为一个节点 # 加到默认图中. # 构造器的返回值代表该常量 op 的返回值. matrix1 = tf.constant([[3,3]]) # 创建另外一个常量 op, 产生一个 2x1 矩阵. matrix2 = tf.constant([[2], [2]]) # 创建一个矩阵乘法 matmul op , 把 'matrix1' 和 'matrix2' 作为输入. # 返回值 'product' 代表矩阵乘法的结果. product = tf.matmul(matrix1, matrix2) with tf.Session() as sess: result2 = sess.run(product) print(result2) # 创建一个变量, 初始化为标量 0. state = tf.Variable(0, name='counter') # 创建一个 op, 其作用是使 state 增加 1 one = tf.constant(1) # 定义加法步骤 (注: 此步并没有直接计算) new_value = tf.add(state, one) # 将 State 更新成 new_value update = tf.assign(state, new_value) # 变量Variable需要初始化并激活,并且打印的话只能通过sess.run(): # 启动图后, 变量必须先经过`初始化` (init) op 初始化, # 首先必须增加一个`初始化` op 到图中. init = tf.global_variables_initializer() # 启动图, 运行 op, 使用 Session 计算 with tf.Session() as sess: # 运行 'init' op sess.run(init) # fetch打印 'state' 的初始值 print(sess.run(state)) # 运行 op, 更新 'state', 并打印 'state' for _ in range(3): sess.run(update) print(sess.run(state)) input1 = tf.constant(3.0) input2 = tf.constant(2.0) input3 = tf.constant(5.0) intermed = tf.add(input2, input3) mul = tf.multiply(input1, intermed) with tf.Session() as sess: # fetch获取多个 tensor 值,在 op 的一次运行中一起获得(而不是逐个去获取 tensor) result = sess.run([mul, intermed]) print("result:", result) #result: [21.0, 7.0] #Feed #feed 使用一个 tensor 值临时替换一个操作的输出结果. 你可以提供 feed 数据作为 run() 调用的参数. #feed 只在调用它的方法内有效, 方法结束, feed 就会消失. 最常见的用例是将某些特殊的操作指定为 # "feed" 操作, 标记的方法是使用 tf.placeholder() 为这些操作创建占位符. # 如果要传入值,用tensorflow的占位符,暂时存储变量, # 以这种形式feed数据:sess.run(***, feed_dict={input: **}) #在 Tensorflow 中需要定义 placeholder 的 type ,一般为 float32 形式 input1 = tf.placeholder(tf.float32) input2 = tf.placeholder(tf.float32) # mul = multiply 是将input1和input2 做乘法运算,并输出为 output ouput = tf.multiply(input1, input2) with tf.Session() as sess: print(sess.run(ouput, feed_dict={input1: [7], input2: [2]})) # 输出[ 14.] #用Tensorflow计算a=(b+c)*(c+2) # 首先,创建一个TensorFlow常量=>2 const = tf.constant(2.0, name='const') # 创建TensorFlow变量b和c b = tf.Variable(2.0, name='b') #Tensorflow可以自动进行数据类型检测,比如:赋值2.0就默认为tf.float32,但最好还是显式地定义。 c = tf.Variable(1.0, dtype=tf.float32, name='c') # 创建operation #在TensorFlow中,+−×÷都有其特殊的函数表示。实际上,TensorFlow定义了足够多的函数来表示所有的数学运算, #当然也对部分数学运算进行了运算符重载,但保险起见,我还是建议你使用函数代替运算符。 d = tf.add(b, c, name='d') e = tf.add(c, const, name='e') a = tf.multiply(d, e, name='a') init_op = tf.global_variables_initializer() #运行graph需要先调用tf.Session()函数创建一个会话(session)。session就是我们与graph交互的handle。 # session with tf.Session() as sess: # 2. 运行init operation sess.run(init_op) # 计算 a_out = sess.run(a) print("Variable a is {}".format(a_out))
D:\python>python tt.py
[2. 4. 6.]
b’Hello, TensorFlow!’
42
[[12]]
0
1
2
3
result: [21.0, 7.0]
[14.]
Variable a is 9.0
import numpy as np import pandas as pd import tensorflow as tf def main(): testNormal() testPlaceholder() testPlaceholder1() def testNormal(): mylist = [2, 4, 6, 8] sq = tf.square(mylist) sess = tf.Session() result = sess.run(sq) print(result) # [ 4 16 36 64] def testPlaceholder1(): input1 = tf.placeholder(tf.float32) input2 = tf.placeholder(tf.float32) output = tf.multiply(input1, input2) with tf.Session() as sess: print(sess.run([output], feed_dict={input1:7., input2:2.})) print(sess.run([output], feed_dict={input1:[7.], input2:[2.]})) #A Simple TensorFlow example #用Tensorflow计算a=(b+c)∗(c+2) def testPlaceholder(): #1. 定义数据: # 首先,创建一个TensorFlow常量=>2 const = tf.constant(2.0, name='const') # 创建TensorFlow变量b和c #b = tf.Variable(2.0, name='b') # 创建placeholder b = tf.placeholder(tf.float32, [None, 1], name='b') c = tf.Variable(1.0, dtype=tf.float32, name='c') #2. 定义运算(也称TensorFlow operation): d = tf.add(b, c, name='d') e = tf.add(c, const, name='e') a = tf.multiply(d, e, name='a') #TensorFlow中所有的变量必须经过初始化才能使用,初始化方式分两步: #<1. 定义初始化operation init_op = tf.global_variables_initializer() # session with tf.Session() as sess: #<2. 运行init operation sess.run(init_op) # 计算 #a_out = sess.run(a) a_out = sess.run(a, feed_dict={b: np.arange(0, 10)[:, np.newaxis]}) print("Variable a is {}".format(a_out)) if __name__ == '__main__': main()
[ 4 16 36 64]
Variable a is [[ 3.]
[ 6.]
[ 9.]
[12.]
[15.]
[18.]
[21.]
[24.]
[27.]
[30.]]
[14.0]
[array([14.], dtype=float32)]
# 算术操作符:+ – * / %
tf.add(x, y, name=None) # 加法(支持 broadcasting)
tf.subtract(x, y, name=None) # 减法
tf.multiply(x, y, name=None) # 乘法
tf.divide(x, y, name=None) # 浮点除法, 返回浮点数(python3 除法)
tf.mod(x, y, name=None) # 取余
# 幂指对数操作符:^ ^2 ^0.5 e^ ln
tf.pow(x, y, name=None) # 幂次方
tf.square(x, name=None) # 平方
tf.sqrt(x, name=None) # 开根号,必须传入浮点数或复数
tf.exp(x, name=None) # 计算 e 的次方
tf.log(x, name=None) # 以 e 为底,必须传入浮点数或复数
# 取符号、负、倒数、绝对值、近似、两数中较大/小的
tf.negative(x, name=None) # 取负(y = -x).
tf.sign(x, name=None) # 返回 x 的符号
tf.reciprocal(x, name=None) # 取倒数
tf.abs(x, name=None) # 求绝对值
tf.round(x, name=None) # 四舍五入
tf.ceil(x, name=None) # 向上取整
tf.floor(x, name=None) # 向下取整
tf.rint(x, name=None) # 取最接近的整数
tf.maximum(x, y, name=None) # 返回两tensor中的最大值 (x > y ? x : y)
tf.minimum(x, y, name=None) # 返回两tensor中的最小值 (x < y ? x : y)
# 三角函数和反三角函数
tf.cos(x, name=None)
tf.sin(x, name=None)
tf.tan(x, name=None)
tf.acos(x, name=None)
tf.asin(x, name=None)
tf.atan(x, name=None)
# 其它
tf.div(x, y, name=None) # python 2.7 除法, x/y–>int or x/float(y)–>float
tf.truediv(x, y, name=None) # python 3 除法, x/y–>float
tf.floordiv(x, y, name=None) # python 3 除法, x//y–>int
tf.realdiv(x, y, name=None)
tf.truncatediv(x, y, name=None)
tf.floor_div(x, y, name=None)
tf.truncatemod(x, y, name=None)
tf.floormod(x, y, name=None)
tf.cross(x, y, name=None)
tf.add_n(inputs, name=None) # inputs: A list of Tensor objects, each with same shape and type
tf.squared_difference(x, y, name=None)