Graph理解
Tensorflow的程序一般都分为2个阶段,(1)定义计算图中的所有计算;(2)执行计算;
系统默认计算图
在tf程序中,系统会自动维护一个默认的计算图,通过tf.get_default_graph()可以获取当前默认的计算图;
|
|
比如上面这段代码的输出为:
可以看到,定义的这些节点都在系统默认的计算图中。
新建计算图
tf支持通过tf.Graph生成新的计算图,不同计算图上的张量和运算不会共享,也就是说,tf通过计算图来隔离资源。
Variable及name_space理解
对于一个复杂的tensorflow模型可能会有很多变量:
- tf.variable_scope():提供了简单的命名空间以避免冲突;
- tf.get_variable():从同一个变量范围内获取或者创建变量;
- tf.Variable()用于定义一个变量;tf.get_variable()根据name值,返回该变量,如果name不存在的话,则会创建一个变量;
tf.variable_scope && tf.get_variable
tf.variable_scope和tf.get_variable,这两个函数通常放在一起使用,tf.variable_scope用于指定变量范围,如果在同一变量范围内,通过tf.get_variable获取已经定义的变量,在没有设置reuse=True时会报错:
上面代码给出了通常情况下tf.get_variable和tf.variable_scope用法。reuse=True表示tf.get_variable得到的变量可以在其他地方重复使用,只在需要时设置为True,不设置为False,其中variable_scope的名字可以为空。
特别说明一点,将参数设置为True,这样tf.get_variable()将只能获取已将创建过的变量。
具体说明可以参考这里:http://blog.csdn.net/lanchunhui/article/details/61914287
tf.Graph
|
|
以上代码的结果为:
可以看到,变量v在不同的计算图中,它们之间的值也互相不影响。
tf.Graph.device
可以通过tf.Graph.device函数来指定运行计算的设备,这为tf提供了GPU的支持,下面的代码可以在GPU上执行:
tf.global_variable_initializer()
这个函数作用是初始化当前计算图中的全局变量,关于一个tf.global_variable_initializer()用法一个注意的地方:
上面这段代码可以正确执行,再看下面这段代码:
这段代码执行时会报错,错误信息如下:
不难发现,tf.global_variable_initializer()须在所有变量都定义之后再去定义。
tf.get_collection()
在使用get_collection()时有个地方需要注意,在一次训练过程中,一直出现了这个错误:
刚开始也是百思不得其解,后来一检查,发现是regularizer为None,导致tf.get_collection()得到的tensor没有维度,因此tf.add_n时报错。
tf.softmax_cross_entropy_with_logits && tf.sparse_softmax_cross_entropy_with_logits
这两个函数都是用来直接计算交叉熵的,不同的地方是tf.sparse_sotfmax_cross_entropy_with_logits是直接用来处理稀疏性质的数据。
先来看下sotfmax_cross_entropy_with_logits,顾名思义,这个函数是将计算softmax和cross_entropy的过程融合起来了,看下面的代码:
再来看看tf.nn.sparse_softmax_cross_entropy_with_logits,
可以看到,同上面函数相比,只对label进行了一次加工,而这次加工,正是说明了sparse的特性,tf.argmax(tensor)目的是获取稀疏的tensor中正确答案对应的编号,这个编号是一个整数
tf.app.flags.FLAGS
tf.app.flags.FLAGS主要用来处理相关输入,特别是在训练中需要动态指定训练数据目录时特别有用。典型用法如下:
这里指定FLAGS.train_dir默认目录为”./data/train/clsm”,如果训练过程中,需要另外指定目录,则通过以下命令即可实现:
上面命令将train_dir目录改为./data/xdrush/clsm,但log_dir依旧时默认值。
tf.gfile相关
tf封装的文件处理相关模块。
tf.records文件读写
tf.TFRecordReader & tf.FixedLengthRecordReader
上面2个方法都是创建一个Reader来读取TFRecord文件中的样例。其中不同的reader对应不同的文件结构。对于二进制文件,FixedLengthRecordReader就比较好,因为每次读等长的一段数据。
tf.slice()的理解
函数原型:
tf.slice(inputs, begin, size, name=’’)
函数的用途是从inputs中抽取部分内容
inputs:可以是list,array,tensor
begin:n维列表,begin[i]表示从inputs中的第i维抽取数据时,相对0的起始偏移量,也就是从第i维的begin[i]开始抽取数据
size:n维列表,size[i]表示要抽取的第i维元素的数目
输出为:
begin_y = [1, 0, 1]分别表示从第一维的第二个元素开始抽取,0表示从第二维的第一个元素开始抽取,1表示从第三维的第1个元素开始抽取;
size_y = [1, 2, 3]表示第一维抽取一个,第二维抽取2个,第三维抽取3个;不难得出最终的结果。
如果数据不足,则会报错。比如如果将begin_y = [1, 0, 2],表示从第三位的第三个元素开始抽取,抽取个数维3,而此时第三维只剩下2个元素,因此会报错。
tf.transpose()的理解
tr.transpose(a, perm=None, name=’’)
默认情况下,如果不指定perm值,则该函数完成矩阵转置功能:
接下来主要看下perm的含义:
对于多维矩阵,当perm=[0, 1, 2]时,输出结果与原矩阵一样;
当perm=[2, 1, 0]时,实现的就是标准的矩阵转置。由此可知,perm控制的转置的维度。
tf.split()的理解
沿着某一维度将输入切割成多等份。
tf.split(value, num_or_size_split, axis=0, num=None, name=’’)
value:输入的tensor
num_or_size_split:切割的数量,可以是矩阵
axis:切割的维度,0表示按行切分,1表示案列切分
num:默认值不用管
当num_or_size_split为矩阵时,
tensorflow与GPU
tf.ConfigProto
tf.ConfigProto在多GPU机器上的配置信息,比较重要。
tensorflow与layers
tf.layers模块里面包含tf定义的一些层,包括全连接层,池化层等。
tf.layers.max_pooling2d
|
|
类似的还包括max_pooling1d, max_pooling3d,用法可查文档。
tf.layers.dense
定义的是全连接层。