0%

Something about TensorFlow

1. TensorFlow中tf.train.slice_input_producer和tf.train.batch函数

TensorFlow数据读取机制

TensorFlow中为了充分利用GPU,减少GPU等待数据的空闲时间,使用了两个线程分别执行数据读入和数据计算。

具体来说就是使用一个线程源源不断的将硬盘中的图片数据读入到一个内存队列中,另一个线程负责计算任务,所需数据直接从内存队列中获取。

tf在内存队列之前,还设立了一个文件名队列,文件名队列存放的是参与训练的文件名,要训练N个epoch,则文件名队列中就含有N个批次的所有文件名。

img

在N个epoch的文件名最后是一个结束标志,当tf读到这个结束标志的时候,会抛出一个AutoRange的异常,外部捕获到之歌异常之后皆可以结束进程了。而创建tf的文件名队列就需要使用到tf.train.slice_input_producer函数

tf.train.slice_input_producer

tf.train.slice_input_producer是一个tensor生成器,作用是按照规定,每次从一个tensor列表中按顺序或者随机抽取出一个tensor放入文件名队列。

1
slice_input_producer(tensor_list, num_epochs=None, shuffle=True, seed=None,                         capacity=32, shared_name=None, name=None)
  • 第一个参数 tensor_list:包含一系列tensor的列表,表中tensor的第一维度的值必须相等,即个数必须相等,有多少个图像,就应该有多少个对应的标签。

  • 第二个参数num_epochs: 可选参数,是一个整数值,代表迭代的次数,如果设置 num_epochs=None,生成器可以无限次遍历tensor列表,如果设置为 num_epochs=N,生成器只能遍历tensor列表N次。

  • 第三个参数shuffle: bool类型,设置是否打乱样本的顺序。一般情况下,如果shuffle=True,生成的样本顺序就被打乱了,在批处理的时候不需要再次打乱样本,使用 tf.train.batch函数就可以了;如果shuffle=False,就需要在批处理时候使用 tf.train.shuffle_batch函数打乱样本。

  • 第四个参数seed: 可选的整数,是生成随机数的种子,在第三个参数设置为shuffle=True的情况下才有用。

  • 第五个参数capacity:设置tensor列表的容量。

  • 第六个参数shared_name:可选参数,如果设置一个‘shared_name’,则在不同的上下文环境(Session)中可以通过这个名字共享生成的tensor。

  • 第七个参数name:可选,设置操作的名称。

tf.train.slice_input_producer定义了样本放入文件名队列的方式,包括迭代次数,是否乱序等,要真正将文件放入文件名队列,还需要调用tf.train.start_queue_runners 函数来启动执行文件名队列填充的线程,之后计算单元才可以把数据读出来,否则文件名队列为空的,计算单元就会处于一直等待状态,导致系统阻塞。

tf.contrib.layers.batch_norm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

tf.contrib.layers.batch_norm(
inputs,
decay=0.999,
center=True,
scale=False,
epsilon=0.001,
activation_fn=None,
param_initializers=None,
param_regularizers=None,
updates_collections=tf.GraphKeys.UPDATE_OPS,
is_training=True,
reuse=None,
variables_collections=None,
outputs_collections=None,
trainable=True,
batch_weights=None,
fused=None,
data_format=DATA_FORMAT_NHWC,
zero_debias_moving_mean=False,
scope=None,
renorm=False,
renorm_clipping=None,
renorm_decay=0.99,
adjustment=None
)

Batch Normalization 通过减少内部使用协变量加速神经网络的训练

可以用作conv2d或fully_connected的标准化函数

参数:

1 inputs: 输入

2 decay :衰减系数。合适的衰减系数值接近1.0,特别是含多个9的值:0.999,0.99,0.9。如果训练集表现很好而验证/测试集表现得不好,选择小的系数(推荐使用0.9)。如果想要提高稳定性,zero_debias_moving_mean设为True

3 center:如果为True,有beta偏移量;如果为False,无beta偏移量

4 scale:如果为True,则乘以gamma。如果为False,gamma则不使用。当下一层是线性的时(例如nn.relu),由于缩放可以由下一层完成,所以可以禁用该层。

5 epsilon:避免被零除

6 activation_fn:用于激活,默认为线性激活函数

7 param_initializers : beta, gamma, moving mean and moving variance的优化初始化

8 param_regularizers : beta and gamma正则化优化

9 updates_collections :Collections来收集计算的更新操作。updates_ops需要使用train_op来执行。如果为None,则会添加控件依赖项以确保更新已计算到位。

10 is_training:图层是否处于训练模式。在训练模式下,它将积累转入的统计量moving_mean并 moving_variance使用给定的指数移动平均值 decay。当它不是在训练模式,那么它将使用的数值moving_mean和moving_variance。
11 scope:可选范围variable_scope

tf.contrib.layers.convolution2d

tf.reduce_mean

用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的平均值,主要用作降维或者计算tensor(图像)的平均值

1
2
3
4
5
6
reduce_mean(
input_tensor,
axis=None,
keep_dims=False,
name=None,
reduction_indices=None)
  • 参数:
    • axis:指定的轴,如果不指定,则计算所有元素的均值
    • keep_dims:是否降维度,设置为True, 则输出的结果保持输入tensor的结果,设置为False, 输出结果会降低维度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import tensorflow as tf 

x = [[1, 2, 3],
[1, 2, 3]]

xx = tf.cast(x, tf.float32)
mean_all = tf.reduce_mean(xx, keep_dims=False)
mean_0 = tf.reduce_mean(xx, axis=0, keep_dims=False)
mean_1 = tf.reduce_mean(xx, axis=1, keep_dims=False)

with tf.Session() as sess:
m_a, m_0, m_1 = sess.run([mean_all, mean_0, mean_1])

print(mean_a)
print(mean_0)
print(mean_1)
"""
output:
2.0
[ 1. 2. 3.]
[ 2. 2.]
"""
"""
如果keep_dims=True,则结果为
[[ 2.]]
[[ 1. 2. 3.]]
[[ 2.], [ 2.]]
"""