TensorFlow 基本操作

Tensorflow基本概念

  • 图(Graph):图描述了计算的过程,TensorFlow使用图来表示计算任务。
  • 张量(Tensor):TensorFlow使用tensor表示数据。每个Tensor是一个类型化的多维数组。
  • 操作(op):图中的节点被称为op(opearation的缩写),一个op获得/输入0个或多个Tensor,执行计算,产生0个或多个Tensor。
  • 会话(Session):图必须在称之为“会话”的上下文中执行。会话将图的op分发到诸如CPU或GPU之类的设备上执行。
  • 变量(Variable):运行过程中可以被改变,用于维护状态

边的概念

TensorFlow的边即有两种连接关系:数据依赖,控制依赖。

  • 实线边表示数据依赖,代表数据,即张量。任意维度的数据统称为张量。在机器学习算法中,张量在数据流图中从前往后流一遍就完成一次前向传播,而残差从后向前流动一遍就完成一次反向传播。
  • 虚线边表示控制依赖,可以用于控制操作的运行,这被用来确保happens-before关系,这类边上没有数据流过,但源节点必须在目的节点开始执行前完成。

Tensorflow数据属性

数据类型Python类型描述
DT_FLOATtf.float3232位浮点型
DT_DOUBLEtf.float64

64位浮点型

DT_INT64tf.int6464位有符号整型
DT_INT32tf.int3232位有符号整型
DT_INT16tf.int1616位有符号整型
DT_INT8tf.int88位有符号整型
DT_UNIT8tf.unit88位无符号整型
DT_STRINGtf.string可变长度的字节数组,每一个张量元素是一个字节数组
DT_BOOLtf.bool布尔型
DT_COMPLEX64tf.complex64由两个32位浮点数组成的复数:实部和虚部
DT_QINT32tf.qint32用于量化操作的32 位有符号整型
DT_QINT8tf.qint8用于量化操作的8 位有符号整型
DT_QUINT8 tf.quint8用于量化操作的8 位无符号整型

节点

节点又称为算子,它代表一个操作,一般用来表示施加的数字运算,也可以表示数据输入的起点以及输出的重点,或者是读取/写出持久化变量的终点

类别示例
数学运算操作Add、Subtract、Multiply、Div、Exp、Log、Greater、Less、Equal ...
数组运算操作Concat、Slice、Split、Constant、Rank、Shape、Shuffle ...
矩阵运算操作MatMul、MatrixInverse、MatrixDeterminant …
有状态的操作Variable、Assign、AssignAdd …
神经网络构建操作SoftMax、Sigmoid、ReLU、Convolution2D、MaxPool …
检查点操作Save、Restore
队列和同步操作Enqueue、Dequeue、MutexAcquire、MutexRelease …
控制张量流动的操作Merge、Switch、Enter、Leave、NextIteration

使用Tensorflow必须理解下列概念:

TensorFlow可以认为是一种编程工具,使用TensorFlow来实现具体的业务需求,所以我们可以认为TensorFlow就是一个“工具箱”,然后我们使用TensorFlow这个“工具箱”中的各种“工具”(方法/API)来实现各种功能,比如使用TensorFlow实现基本的数值计算、机器学习、深度学习等;使用TensorFlow必须理解下列概念

  • 使用图(graph)来表示计算任务;
  • 在会话(session)的上下文中执行图;
  • 使用tensor表示数据;
  • 通过变量(Variable)来维护状态 ;
  • 使用feed和fetch可以为任意的操作(Operation/op)赋值或者从其中获取数据。

TensorFlow 的程序一般分为两个阶段:构建阶段 和 执行阶段:

  • 构建阶段:op的执行步骤被描述称为一个图,然后使用 TensorFlow 提供的API构建这个 图。
  • 执行阶段:将构建好的执行图(Operation Graph)在给定的 会话 中执行,并得到执行结果。

图(Graph)

TensorFlow 编程的重点是根据业务需求,使用 TensorFlow 的API将业务转换为执行图(有向无环图)。

图中的节点是Tensor,节点之间的连线是节点之间的操作,连线前的节点可以认为是操作的输入,连线后的节点可以认为操作的输出;根据节点的特性(是否有输入输出),可以将节点分为源节点、中间节点和最终的结果节点。

图构建的第一步就是创建源op(source op); 源op不需要任何的输入。op构造器的返回值代表被构造出的op的输出,这些返回值可以传递给其它op构造器作为输入或者直接获取结果。
TensorFlow 库中有一个默认图(default graph),op构造器可以直接为其添加节点,一般情况下,使用默认的Graph即可完成程序代码的实现。不过 TensorFlow 也支持通过Graph类管理多个图。

使用默认图

import tensorflow as tf# 1. 定义常量矩阵a和矩阵b
# name属性只是给定这个操作一个名称而已
# 如果给定[[1, 2], [3, 4]],形状已定,可以不指定shape参数
a = tf.constant([[1, 2], [3, 4]], dtype=tf.int32, name='a')
print(type(a))
# 如果给定[5, 6, 7, 8],后面可以通过参数shape来确定形状
b = tf.constant([5, 6, 7, 8], dtype=tf.int32, shape=[2, 2], name='b')# 2. 以a和b作为输入,进行矩阵的乘法操作
c = tf.matmul(a, b, name='matmul')
print(type(c))# 3. 以a和c作为输入,进行矩阵的相加操作
g = tf.add(a, c, name='add')
print(type(g))print("变量a是否在默认图中:{}".format(a.graph is tf.get_default_graph()))

不使用默认图

注意:操作必须属于同一个图,不同图中的节点不能相连

# 使用新的构建的图
graph = tf.Graph()
with graph.as_default():# 此时在这个代码块中,使用的就是新的定义的图graph(相当于把默认图换成了graph)d = tf.constant(5.0, name='d')print("变量d是否在新图graph中:{}".format(d.graph is graph))with tf.Graph().as_default() as g2:e = tf.constant(6.0)print("变量e是否在新图g2中:{}".format(e.graph is g2))# 这段代码是错误的用法,记住:不能使用两个图中的变量进行操作,只能对同一个图中的变量对象(张量)进行操作(op)
# f = tf.add(d, e)
# 报出:Tensor("Const:0", shape=(), dtype=float32) must be from the same graph as Tensor("d:0", shape=(), dtype=float32).

会话(Session)

当执行图构建完成后,才能启动图,进入到执行阶段;启动图的第一步就是创建一个 Session 对象,如果无任何参数的情况下,会话构造器将启动默认图。

Session 会话

# 会话构建&启动(默认情况下(不给定Session的graph参数的情况下),创建的Session属于默认的图)
sess = tf.Session()
result = sess.run(fetches=[c])
# result = sess.run(fetches=[c, g])
print("type:{}, value:\n{}".format(type(result), result))# 会话关闭
sess.close()# 当一个会话关闭后,不能再使用了,所以下面两行代码错误
# result2 = sess.run(c)
# print(result2)
  • 调用 sess 的 run 方法来执行矩阵的乘法,得到c的结果值(所以将c作为参数传递进去)
  • 不需要考虑图中间的运算,在运行的时候只需要关注最终结果对应的对象以及所需要的输入数据值
  • 只需要传递进去所需要得到的结果对象,会自动的根据图中的依赖关系触发所有相关的OP操作的执行
  • 如果op之间没有依赖关系,tensorflow 底层会并行的执行op(有资源) --> 自动进行
  • 如果传递的 fetches 是一个列表,那么返回值是一个 list 集合
  • fetches:表示获取那个op操作的结果值

c的结果:

\left[ \begin{matrix} 1 &\amp2 \\ 3 &\amp 4 \end{matrix} \right] \times \left[ \begin{matrix} 5 &\amp 6 \\ 7 &\amp 8 \end{matrix} \right] = \left[ \begin{matrix} 19 &\amp 22 \\ 43 &\amp 50 \end{matrix} \right]

g的结果:

\left[ \begin{matrix} 1 &\amp 2 \\ 3 &\amp 4 \end{matrix} \right] + \left[ \begin{matrix} 19 &\amp 22 \\ 43 &\amp 50 \end{matrix} \right]= \left[ \begin{matrix} 20 &\amp 24 \\ 46 &\amp 54 \end{matrix} \right]

补充:(可以使用with语句块来开启会话,自动关闭会话)

# 使用with语句块,会在with语句块执行完成后,自动的关闭session
# allow_soft_placement:是否允许动态使用CPU和GPU,默认为False;
# 当我们的安装方式为GPU的时候,建议该参数设置为True,因为TensorFlow中的部分op只能在CPU上运行。
# log_device_placement: 是否打印日志,默认为False,不打印日志
with tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)) as sess2:print(sess2)# 获取张量c的结果: 通过Session的run方法获取print("sess2 run:{}".format(sess2.run(c)))# 获取张量g的结果:通过张量对象的eval方法获取,和Session的run方法一致print("c eval:{}".format(g.eval()))

tf.Session 在构建会话的时候,如果不给定任何参数,那么构建出来的 Session 对应内部的 Graph,其实就是默认 Graph,不过我们可以通过参数给定具体对应的是那一个 Graph 以及当前 Session 对应的配合参数。

Session 的构造主要有三个参数,作用如下:

  • target:给定连接的url,只有当分布式运行的时候需要给定;
  • graph:给定当前Session对应的图,默认为TensorFlow中的默认图;
  • config:给定当前Session的相关参数,详见https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/prot
    obuf/config.proto中的[ConfigProto]

通过Session的config参数可以对TensorFlow的应用的执行进行一些优化调整,主要涉及到的参数如下:

属性作用
gpu_optionsGPU相关参数,主要参数:per_process_gpu_memory_fraction和allow_growth
allow_soft_placement是否允许动态使用CPU和GPU,默认为False;当我们的安装方式为GPU的时候,
建议该参数设置为True,因为TensorFlow中的部分op只能在CPU上运行
log_device_placement是否打印日志,默认为False,不打印日志
graph_optionsGraph优化相关参数,一般不需要给定,默认即可,主要参数:
optimizer_options(do_common_subexpression_elimination、do_constant_folding和opt_level)
import tensorflow as tf# 构建一个图
a = tf.constant('10', tf.string, name='a_const')
b = tf.string_to_number(a, out_type=tf.float64, name='str_2_double')
c = tf.to_double(5.0, name='to_double')
d = tf.add(b, c, name='add')# 构建Session并执行图
# 1、构建GPU相关参数
gpu_options = tf.GPUOptions()
# per_process_gpu_memory_fraction:给定对于每一个进程,分配多少的GPU内存,默认为1
# 设置为0.5表示分配50%的GPU内存
gpu_options.per_process_gpu_memory_fraction = 0.5
# allow_growth:设置为True表示在GPU内存分配的时候,采用动态分配方式,默认为False
# 动态分配的意思是指,在启动之前,不分配全部的内存,根据需要后面动态的进行分配
# 在开启动态分配后,GPU内存部分自动释放,所以复杂、长时间运行的任务不建议开启
gpu_options.allow_growth = True# 2、构建Graph优化的相关参数
optimizer = tf.OptimizerOptions(do_common_subexpression_elimination=True,  # 设置为True表示开启公共执行子句优化do_constant_folding=True,  # 设置为True表示开始常数折叠优化opt_level=0  # 设置为0,表示开启上述两个优化,默认为0
)graph_options = tf.GraphOptions(optimizer_options=optimizer)# 3、构建Session的Config相关参数
config_proto = tf.ConfigProto(allow_soft_placement=True, log_device_placement=True,graph_options=graph_options, gpu_options=gpu_options)# 4、构建Session并运行
with tf.Session(config=config_proto) as sess:print(sess.run(d))

InteractiveSession会话(交互式会话)

使用交互式会话可以降低代码的复杂度,使用 Tensor.eval() 或者 Operation.run() 来代替 Session.run() 方法,这样可以避免一个变量来维持会话;

备注:Session也可以使用Tensor.eval()和Operation.run()获取数据/执行操作(只要明确当前会话)。

import tensorflow as tf# 构建一个图
a = tf.constant(4)
b = tf.constant(3)
c = tf.multiply(a, b)# 运行
with tf.Session():print(c.eval())# 进入交互式会话
sess = tf.InteractiveSession()# 定义变量和常量
x = tf.constant([1.0, 2.0])
a = tf.constant([2.0, 4.0])# 进行减操作
sub = tf.subtract(x, a)# 输出结果
print(sub.eval())
print(sess.run(sub))

张量(Tensor)

TensorFlow 使用 Tensor 数据结构来代表所有数据,计算图中,操作间传递的数据都是 Tensor。Tensor 可以看作是一个 N 维的数组或者列表,一个 Tensor 主要由一个静态数据类型和动态类型的维数(Rank、Shape)组成。Tensor 可以在图中的节点之间流通。

变量(Variables)

变量(Variables)是维护图执行过程中的状态信息。在训练模型过程中,可以通过变量来存储和更新参数。变量包含张量(Tensor)存放于内存的缓存区。建模的时候变量必须被明确的初始化,模型训练后变量必须被存储到磁盘。这些变量的值可以在之后的模型训练和分析中被加载。

在构建变量的时候,必须将一个 张量 或者 可以转化为张量的 Python对象 作为初始值传入构造函数Variable中

import tensorflow as tf# 创建一个变量,初始化值为变量3.0
a = tf.Variable(3.0)# 创建一个常量
b = tf.constant(2.0)
c = tf.add(a, b)# 启动图后,变量必须先进行初始化操作
# 增加一个初始化变量的op到图中
init_op = tf.initialize_all_variables()# 启动图
with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)) as sess:# 运行init_opsess.run(init_op)# 获取值print("a = {}".format(sess.run(a)))print("c = {}".format(c.eval))

变量依赖案例:

import tensorflow as tf# 创建一个变量
w1 = tf.Variable(tf.random_normal([10], stddev=0.5, dtype=tf.float32), name='w1')
# 基于第一个变量创建第二个变量
a = tf.constant(2, dtype=tf.float32)
w2 = tf.Variable(w1.initialized_value() * a, name='w2')# 进行全局初始化
init_op = tf.initialize_all_variables()# 启动图
with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)) as sess:# 运行init_opsess.run(init_op)# 获取值result = sess.run([w1, w2])print("w1 = {}\nw2 = {}".format(result[0], result[1]))

取回(fetch)

为了取回操作的输出内容,可以在使用 Session 对象的 run 方法调用执行图的时候,传入一些tensor,通过 run 方法就可以获取这些 tensor 对应的结果值。

如果需要获取多个tensor的值,那么尽量一次运行就获取所有的结果值,而不是采用逐个获取的方式。

with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)) as sess:# 运行init_opsess.run(init_op)# 获取值result = sess.run(fetches=[w1, w2])print("w1 = {}\nw2 = {}".format(result[0], result[1]))

填充(feed)

在构建图时使用 placeholder 类型的 API 临时替代任意操作的张量(占位符),在调用 Session 对象的run() 方法去执行图时,使用填充数据作为调用的参数,调用结束后,填充数据就消失了。

  feed 使用一个 tensor 值临时替换一个操作的输出结果,在获取数据的时候必须给定对应的 feed 数据作为参数。feed 只有在调用它的方法内有效,方法结束,feed 就消失了。

  feed 可以使用 placeholder 类型的API创建占位符,常见API:tf.placeholder、tf.placeholder_with_default

import tensorflow as tf# 创建占位符,创建图
m1 = tf.placeholder(tf.float32)
m2 = tf.placeholder(tf.float32)
m3 = tf.placeholder_with_default(4.0, shape=None)
output = tf.multiply(m1, m2)
ot1 = tf.add(m1, m3)# 运行图
with tf.Session() as sess:print(sess.run(output, feed_dict={m1: 3, m2: 4}))print(output.eval(feed_dict={m1: 8, m2: 10}))print(sess.run(ot1, feed_dict={m1: 3, m3: 3}))print(sess.run(ot1, feed_dict={m1: 3}))

变量更新(assign)

实例1:累加器

import tensorflow as tf# 1. 定义一个变量
x = tf.Variable(0, dtype=tf.int32, name='v_x')# 2. 变量的更新
assign_op = tf.assign(ref=x, value=x + 1)# 3. 变量初始化操作
x_init_op = tf.global_variables_initializer()# 3. 运行
with tf.Session(config=tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)) as sess:# 变量初始化sess.run(x_init_op)# 模拟迭代更新累加器for i in range(5):# 执行更新操作sess.run(assign_op)r_x = sess.run(x)print(r_x)

实例二:动态的更新变量的维度数目

import tensorflow as tf# 1. 定义一个不定形状的变量
x = tf.Variable(initial_value=[],dtype=tf.float32,trainable=False,validate_shape=False # 设置为True,表示在变量更新的时候,进行shape的检查,默认为True
)# 2. 变量更改
concat = tf.concat([x, [0.0, 0.0]], axis=0)
assign_op = tf.assign(x, concat, validate_shape=False)  # validate_shape 允许改变形状# 3. 变量初始化操作
x_init_op = tf.global_variables_initializer()# 3. 运行
with tf.Session(config=tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)) as sess:# 变量初始化sess.run(x_init_op)# 模拟迭代更新累加器for i in range(5):sess.run(assign_op)r_x = sess.run(x)print(r_x)

控制依赖

实例三:求阶乘(控制依赖)

我们可以通过 Variable 和 assign 完成变量的定义和更新,但是如果在更新变量之前需要更新其它变量,那么会导致一个比较严重的问题:也就是需要多次调用 sess.run 方法来进行变量的更新。通过这种方式,代码复杂程度上升,同时也没有执行效率。

解决该问题的方案就是:控制依赖。

通过 TensorFlow 中提供的一组函数来处理不完全依赖的情况下的操作排序问题(即给定哪个操作先执行的问题), 通过 tf.control_dependencies API完成。

import tensorflow as tf# 1. 定义一个变量
sum = tf.Variable(1, dtype=tf.int32)
# 2. 定义一个占位符
i = tf.placeholder(dtype=tf.int32)# 3. 更新操作
tmp_sum = sum * i
# tmp_sum = tf.multiply(sum, i)
assign_op = tf.assign(sum, tmp_sum)
with tf.control_dependencies([assign_op]):# 如果需要执行这个代码块中的内容,必须先执行control_dependencies中给定的操作/tensorsum = tf.Print(sum, data=[sum, sum.read_value()], message='sum:')# 4. 变量初始化操作
x_init_op = tf.global_variables_initializer()# 5. 运行
with tf.Session(config=tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)) as sess:# 变量初始化sess.run(x_init_op)# 模拟迭代更新累加器for j in range(1, 6):# 执行更新操作# sess.run(assign_op, feed_dict={i: j})# 通过control_dependencies可以指定依赖关系,这样的话,就不用管内部的更新操作了r = sess.run(sum, feed_dict={i: j})print("5!={}".format(r))

设备(device)

设备 是指一块可以用来运算并且拥有自己的地址空间的硬件,如 CPU 和 GPU 。Tensorflow 为了在执行操作的时候,充分利用计算资源,可以明确指定操作在哪个设备上执行。

一般情况下,不需要显示指定使用 CPU 还是 GPU ,TensorFlow 会自动检测。如果检测到 GPU,TensorFlow会尽可能地利用第一个GPU来执行操作。

注意:如果机器上有超过一个可用的 GPU,那么除了第一个外其它GPU默认是不参与计算的。所以,在实际TensorFlow编程中,经常需要明确给定使用的 CPU 和 GPU。

  • “/cpu:0”:表示使用机器CPU运算,cpu默认只有0个
  • “/gpu:0”:表示使用第一个GPU运算,如果有的话
  • “/gpu:1”:表示使用第二个GPU运算,以此类推
import tensorflow as tf# with tf.device("/cpu:0"):
with tf.device("/gpu:0"):a = tf.constant([1, 2, 3], name='a')b = tf.constant(2, name='b')c = tf.multiply(a, b)# 新建Seesion,并将log_device_placement设置为True
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))# 运行这个op
print(sess.run(c))

变量作用域(scope)

通过 tf.Variable 我们可以创建变量,但是当模型复杂的时候,需要构建大量的变量集,这样会导致我们对于变量管理的复杂性,而且没法共享变量(存在多个相似的变量)。针对这个问题,可以通过 TensorFlow 提供的变量作用域机制来解决,在构建一个图的时候,就可以非常容易的使用共享命名过的变量。

Tensorflow中有两个作用域:一个是 name_scope,另一个是 variable_scope

variable_scope

变量作用域机制在 TensorFlow 中主要通过两部分组成:

  • tf.get_variable:通过所给定的名字创建或者返回一个对应的变量
  • tf.variable_scope:为通过创建的变量或者操作Operation指定命名空间

get_variable方法:

  • tf.get_variable 方法在调用的时候,主要需要给定参数名称name,形状shape,数据类型dtype以及初始化方式initializer四个参数。
  • 该API底层执行的时候,根据variable score的属性reuse的值决定采用何种方式来获取变量。
  • 当reuse值为False的时候(不允许设置),作用域就是创建新变量设置的,此时要求对应的变量不存在,否则报错;
  • 当reuse值为True的时候,作用域就是为重用变量所设置的,此时要求对应的变量必须存在,否则报错。
  • 当reuse的值为tf.AUTO_REUSE的时候,表示如果变量存在就重用变量,如果变量不存在,就创建新变量返回。
  • (备注:reuse一般设置在variable score对象上)

 

import tensorflow as tf# 方式一:不加作用域的
def my_func1(x):w1 = tf.Variable(tf.random_normal([1]))[0]b1 = tf.Variable(tf.random_normal([1]))[0]result1 = w1 * x + b1w2 = tf.Variable(tf.random_normal([1]))[0]b2 = tf.Variable(tf.random_normal([1]))[0]result2 = w2 * x + b2return result1, w1, b1, result2, w2, b2# 下面两行代码还是属于图的构建
x = tf.constant(3, dtype=tf.float32)
r = my_func1(x)with tf.Session(config=tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)) as sess:# 初始化tf.global_variables_initializer().run()# 执行结果print(sess.run(r))# 方式二:加作用域
def my_func2(x):# initializer:初始化器w = tf.get_variable('weight', [1], initializer=tf.random_normal_initializer())[0]b = tf.get_variable('bias', [1], initializer=tf.random_normal_initializer())[0]result = w * x + breturn result, w, bdef func(x):with tf.variable_scope('op1', reuse=tf.AUTO_REUSE):r1 = my_func2(x)with tf.variable_scope('op2', reuse=tf.AUTO_REUSE):r2 = my_func2(x)return r1, r2# 下面两行代码还是属于图的构建
x1 = tf.constant(3, dtype=tf.float32, name='x1')
x2 = tf.constant(4, dtype=tf.float32, name='x2')
with tf.variable_scope('func1'):  # 支持嵌套r1 = func(x1)
with tf.variable_scope('func2'):r2 = func(x2)with tf.Session(config=tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)) as sess:# 初始化tf.global_variables_initializer().run()# 执行结果print(sess.run([r1, r2]))

TF底层使用 '变量作用域/变量名称:0'的方式标志变量(eg: func/op1/weight:0)

tf.get_variable 常用的 initializer 初始化器:

初始化器描述
tf.constant_initializer(value)初始化为给定的常数值value
tf.random_uniform_initializer(a, b)初始化为从a到b的均匀分布的随机值
tf.random_normal_initializer(mean, stddev) 初始化为均值为mean、方差为stddev的服从高斯分布的随机值
tf.orthogonal_initializer(gini=1.0) 初始化一个正交矩阵,gini参数作用是最终返回的矩阵是随机矩阵乘以gini的结果
tf.identity_initializer(gini=1.0) 初始化一个单位矩阵,gini参数作用是最终返回的矩阵是随机矩阵乘以gini的结果

tf.variable_score

tf.variable_score方法的作用就是定义一个作用域,定义在 variable_score 作用域中的变量和操作,会将variable score 的名称作为前缀添加到变量/操作名称前,支持嵌套的作用域,添加前缀规则和文件目录路径的规则类似。

  tf.variable_score参数如果给定的是一个已经存在的作用域对象的时候,那么构建变量的时候表示直接跳过当前作用域前缀,直接成为一个完全不同与现在的作用域(直接创建给定作用域下的变量)。但是构建操作的时候,还是和嵌套的方式一样,直接添加子作用域。

  tf.variable_score参数中,可以给定当前作用域中默认的初始化器initializer,并且子作用域会直接继承父作用域的相关参数(是否重用、默认初始化器等)

import tensorflow as tfwith tf.Session(config=tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)) as sess:with tf.variable_scope('foo', initializer=tf.constant_initializer(4.0)) as foo:v = tf.get_variable("v", [1])w = tf.get_variable("w", [1], initializer=tf.constant_initializer(3.0))with tf.variable_scope('bar'):l = tf.get_variable("l", [1])with tf.variable_scope(foo):h = tf.get_variable('h', [1])g = v + w + l + hwith tf.variable_scope('abc'):a = tf.get_variable('a', [1], initializer=tf.constant_initializer(5.0))b = a + gsess.run(tf.global_variables_initializer())print("{},{}".format(v.name, v.eval()))print("{},{}".format(w.name, w.eval()))print("{},{}".format(l.name, l.eval()))print("{},{}".format(h.name, h.eval()))print("{},{}".format(g.name, g.eval()))print("{},{}".format(a.name, a.eval()))print("{},{}".format(b.name, b.eval()))

å¨è¿éæå¥å¾çæè¿°

name_scope

name_score 的主要作用是为 op_name 前加前缀,variable_score 是为 get_variable 创建的变量的名字加前缀。

name_score 的主要作用就是:Tensorflow 中常常会有数以千计的节点,在可视化的过程中很难一下子展示出来,因此用 name_scope 为变量划分范围,在可视化中,这表示在计算图中的一个层级。name_scope 会影响op_name,不会影响用get_variable()创建的变量,而会影响通过Variable()创建的变量。

简单来讲:使用 tf.Variable 创建的变量受 name_score 和 variable_score 的影响,会给变量添加前缀,但是使用 tf.get_variable 创建变量只受 variable_score 的影响。

import tensorflow as tfwith tf.Session() as sess:with tf.name_scope('name1'):with tf.variable_scope('variable1'):v = tf.Variable(1.0, name='v')w = tf.get_variable(name='w', shape=[1], initializer=tf.constant_initializer(2.0))h = v + wwith tf.variable_scope('variable2'):with tf.name_scope('name2'):v2 = tf.Variable(2.0, name='v2')w2 = tf.get_variable(name='w2', shape=[1], initializer=tf.constant_initializer(2.0))h2 = v2 + w2sess.run(tf.global_variables_initializer())print("{},{}".format(v.name, v.eval()))print("{},{}".format(w.name, w.eval()))print("{},{}".format(h.name, h.eval()))print("{},{}".format(v2.name, v2.eval()))print("{},{}".format(w2.name, w2.eval()))print("{},{}".format(h2.name, h2.eval()))

可视化(Tensorboard)

TensorFlow提供了一套可视化工具:TensorBoard,在通过pip安装 TensorFlow 的情况下,默认也会安装TensorBoard。通过TensorBoard可以展示TensorFlow的图像、绘制图像生成的定量指标以及附加数据等信息。

TensorBoard 通过读取 TensorFlow 的事件文件来运行,TensorFlow 的事件文件包括了在 TensorFlow运行中涉及到的主要数据,比如:scalar、image、audio、histogram和graph等。

通过 tf.summary 相关API,将数据添加 summary 中,然后在 Session 中执行这些操作得到一个序列化Summary protobuf 对象,然后使用 FileWriter 对象将汇总的序列数据写入到磁盘,然后使用 tensorboard 命令进行图标展示,默认访问端口是:6006

TensorBoard中支持结构视图和设备视图。

import tensorflow as tfwith tf.variable_scope("foo"):with tf.device("/cpu:0"):x_init1 = tf.get_variable('init_x', [10], tf.float32, initializer=tf.random_normal_initializer())[0]x = tf.Variable(initial_value=x_init1, name='x')y = tf.placeholder(dtype=tf.float32, name='y')z = x + ywith tf.variable_scope("bar"):a = tf.constant(3.0) + 4.0# update xassign_op = tf.assign(x, x + 1)with tf.control_dependencies([assign_op]):with tf.device('/gpu:0'):out = x * ywith tf.device('/cpu:0'):with tf.variable_scope("bar"):a = tf.constant(3.0) + 4.0w = z * a# 开始记录信息(需要展示的信息的输出)
tf.summary.scalar('scalar_init_x', x_init1)
tf.summary.scalar(name='scalar_x', tensor=x)
tf.summary.scalar('scalar_y', y)
tf.summary.scalar('scalar_z', z)
tf.summary.scalar('scala_w', w)
tf.summary.scalar('scala_out', out)with tf.Session(config=tf.ConfigProto(log_device_placement=True, allow_soft_placement=True)) as sess:# merge all summarymerged_summary = tf.summary.merge_all()# 得到输出到文件的对象writer = tf.summary.FileWriter('./result', sess.graph)# 初始化sess.run(tf.global_variables_initializer())for i in range(1, 5):summary, r_out, r_x, r_w = sess.run([merged_summary, out, x, w], feed_dict={y: i})writer.add_summary(summary, i)print("{},{},{}".format(r_out, r_x, r_w))# 关闭操作writer.close()

API

API描述
tf.summary.scalar添加一个标量
tf.summary.audio添加一个音频变量
tf.summary.image添加一个图片变量
tf.summary.histogram添加一个直方图变量
tf.summary.text添加一个字符串类型的变量(一般很少用)

查看可视化结果步骤:

  • 打开cmd命令行输入:tensorboard --helpfull 可以查看相关帮助命名
  • 输入:tensorboard --logdir F:\All_worlspace\Pycharm_workspace\DeepLearning\Tensorflow-basic\result 这里的路径是你保存输出文件对象的路径

å¨è¿éæå¥å¾çæè¿°

  • 在浏览器中输入上图红色框内的

å¨è¿éæå¥å¾çæè¿°

å¨è¿éæå¥å¾çæè¿°

  • 双击图中的foo或bar会打开,如下图

å¨è¿éæå¥å¾çæè¿°

模型保存、提取(Saver)

TensorFlow 使用 tf.train.Saver 类实现模型的保存和提取。

Saver对象的saver方法将TensorFlow模型保存到指定路径中。

通过Saver对象的restore方法可以加载模型,并通过保存好的模型变量相关值重新加载完全加载进来。

如果不希望重复定义计算图上的运算,可以直接加载已经持久化的图,通过 tf.train.import_meta_graph 方法直接加载

备注:在加载的时候,可以在Saver对象构建的时候,明确给定变量名之间的映射关系

import tensorflow as tf# # 模型保存
# v1 = tf.Variable(tf.constant(3.0), name='v1')
# v2 = tf.Variable(tf.constant(4.0), name='v2')
# result = v1 + v2
#
# saver = tf.train.Saver()
# with tf.Session() as sess:
#     sess.run(tf.global_variables_initializer())
#     sess.run(result)
#     # 模型保存到model文件夹下,文件前缀为:model.ckpt
#     saver.save(sess, './model/model.ckpt')# 模型的提取(完整提取:需要完整恢复保存之前的数据格式)
v1 = tf.Variable(tf.constant(1.0), name='v1')
v2 = tf.Variable(tf.constant(4.0), name='v2')
result = v1 + v2saver = tf.train.Saver()
with tf.Session() as sess:# 会从对应的文件夹中加载变量、图等相关信息saver.restore(sess, './model/model.ckpt')print(sess.run([result]))# 直接加载图,不需要定义变量了
saver = tf.train.import_meta_graph('./model/model.ckpt.meta')with tf.Session() as sess:saver.restore(sess, './model/model.ckpt')print(sess.run(tf.get_default_graph().get_tensor_by_name("add:0")))# 模型的提取(给定映射关系)
a = tf.Variable(tf.constant(1.0), name='a')
b = tf.Variable(tf.constant(2.0), name='b')
result = a + bsaver = tf.train.Saver({"v1": a, "v2": b})
with tf.Session() as sess:# 会从对应的文件夹中加载变量、图等相关信息saver.restore(sess, './model/model.ckpt')print(sess.run([result]))

总结

至此,关于Tensorflow的基础入门大概就这么多,此外还会涉及到线程和队列、数据读取、分布式训练等,可以在以后深入学习,理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/454203.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TensorFlow 分布式

一、简介 使用单台机器或者单个GPU/CPU来进行模型训练,训练速度会受资源的影响,因为毕竟单个的设备的计算能力和存储能力具有一定的上限的,针对这个问题,TensorFlow支持分布式模型运算,支持多机器、多GPU、多CPU各种模…

第五周测试

---恢复内容开始--- 一 视频知识 1 linux系统下如何区分内核态与用户态 在内核态:cs:eip可以是任意的地址,4G的内存地址空间 在用户态:cs:eip只能访问0x00000000—0xbfffffff的地址空间 2 系统调用的三层皮:xyz、system_call和sys…

latex公式对齐_Word 写公式最方便的方法

自从用上了word 2016之后,发现他的公式编辑器真香!真香!!他有了latex的优雅,又有了Mathtype的可视化效果,甚至更好哈,当编辑大量公式时也不会因为插件问题卡掉当前的努力。学起来也不复杂,反正是word. 强烈推荐。我们最…

路要怎么走?关于程序员成长的一点思考

程序员的我们,是否想过今后的路该怎么走、如何发展、技术怎样提高?其实这也是我一直在思考的问题。下面就此问题,分享下我的看法。因为我阅历有限,有什么说的不对的,大家见谅,千万不要喷…… 一、程序员应该打好基础 …

TensorFlow 常见API

数据类型转换相关API Tensor Shape获取以及设置相关API Tensor合并、分割相关API Error相关类API 常量类型的Tensor对象相关API 序列和随机Tensor对象相关API Session相关API 逻辑运算符相关API 比较运算符相关API 调试相关API 图像处理-编码解码相关API 图像处理-调整大小相关…

8.2 命令历史

2019独角兽企业重金招聘Python工程师标准>>> 命令历史 history //查看之前的命令.bash_history //存放之前敲过的命令,在 /root/ 目录下最大1000条 //默认参数值是1000条变量HISTSIZE/etc/profile中修改 //在其中可编辑HISTSIZE参数HISTTIMEFORMAT"…

TensorFlow 实例一:线性回归模型

代码 # -- encoding:utf-8 -- """ Create by ibf on 2018/5/6 """import numpy as np import tensorflow as tf# 1. 构造一个数据 np.random.seed(28) N 100 x np.linspace(0, 6, N) np.random.normal(loc0.0, scale2, sizeN) y 14 * x - …

Dapper的基本使用

Dapper是.NET下一个micro的ORM,它和Entity Framework或Nhibnate不同,属于轻量级的,并且是半自动的。也就是说实体类都要自己写。它没有复杂的配置文件,一个单文件就可以了。给出官方地址。 http://code.google.com/p/dapper-dot-n…

易语言神经网络验证码识别_递归神经网络 GRU+CTC+CNN 教会验证码识别

利用 NLP 技术做简单数据可视化分析Chat 简介:用递归神经网络采用端到端识别图片文字,递归神经网络大家最早用 RNN ,缺陷造成梯度消失问题;然后采用了 LSTM,解决 RNN 问题,并且大大提高准确率;现…

Android4.0蓝牙使能的详细解析

毫无疑问,bluetooth的打开是在Settings中进行的操作。因此,冤有头,债有主,我们来到了Settings.java中,果然发现了相关的代码如下: mBluetoothEnabler new BluetoothEnabler(context, new Switch(context));…

移动端导出excel_连载系列【4】Excel开发移动端quot;APPquot;

前三篇文章介绍了百度地图生成器、源代码编辑器、GPS经纬度批量转换工具、源代码编辑器中添加自定义功能按钮和地图控件。这些写好的Java Script代码虽然可以实现所有期望的结果,但毕竟不是一个HTML文件,不便于传播和使用,更无法变成一个类似…

《操作系统》OS学习(二):启动、中断、异常

Bootloader:加载OS。操作系统一开始是放在DISK(硬盘)中,并不是放在内存中。 BIOS:基本I/O处理系统。存放在ROMRead-Only Memory)只读存储中 BIOS(Basic Input/Output System)基本输入输出系统。…

常用css属性集(持续更新…)

禁止换行,超出部分显示…:a. 代码:.hide_word{ max-width: 100px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } b. 效果: 本文转自 bilinyee博客,原文链接: http://blog.51cto.co…

parallels网络初始化失败_33 个神经网络「炼丹」技巧

自然语言处理Andrej Karpathy 是深度学习计算机视觉领域、与领域的研究员。博士期间师从李飞飞。在读博期间,两次在谷歌实习,研究在 Youtube 视频上的大规模特征学习,2015 年在 DeepMind 实习,研究深度强化学习。毕业后&#xff0…

《操作系统》OS学习(三):系统调用

例子 首先看一个标准C库的例子:当我们程序中使用了C库中的printf()函数,实际在底层是在内核态中调用了write()函数。图中右侧则是将程序代码与C库都算到应用程序中,内核提供了一个系统调用接口。 从这个例子我们可以得到以下几点&#xff1a…

JavaScript服务器端开发技术(对象属性的枚举与查询)

既然对象是属性的集合,那么检测与枚举集合中的属性就是一项重要任务。对此,我们来分别看一下ES3和ES5提供的解决方案。 1) ES3枚举方案 示例代码: var contacts{ ID:[0,1,2,3,4,5], names:["Zero","One","Two&q…

treelistview 所有节点失去焦点_垃圾询盘过滤,焦点科技的 Milvus 实践

文章作者:黎阳,焦点科技软件开发工程师李成龙,Zilliz 数据工程师Milvus (https://milvus.io/) 向量搜索引擎开源半年以来,全球已经有数百家企业或组织用户。焦点科技是一家以 B2B 外贸交易为主营业务的科技公司,也是 M…

《操作系统》OS学习(四):计算机体系结构、内存层次和地址生成

计算机除了计算能力之外还有存储能力,存储能力即计算机拥有一系列的存储介质,我们可以在存储介质上存储我们的代码和数据。计算机体系结构中约定了哪些地方可以用来存储数据:CPU内的寄存器、内存和外存。不同的存储介质,容量、速度…

GCC中SIMD指令的应用方法

X86架构上的多媒体应用开发,如果能够使用SIMD指令进行优化, 性能将大大提高。目前,IA-32的SIMD指令包括MMX,SSE,SSE2等几级。 在GCC的开发环境中,有几种使用SIMD指令的方式,本文逐一介绍。X86的…

使用angular4和asp.net core 2 web api做个练习项目(二), 这部分都是angular

上一篇: http://www.cnblogs.com/cgzl/p/7755801.html 完成client.service.ts: import { Injectable } from angular/core; import { Http, Headers } from angular/http; import { Observable } from rxjs/Observable; import { ErrorHandler } from angular/core; import rxj…