为了快速的熟悉TensorFlow编程,下面从一段简单的代码开始:html
import tensorflow as tf #定义‘符号’变量,也称为占位符 a = tf.placeholder("float") b = tf.placeholder("float") y = tf.mul(a, b) #构造一个op节点 sess = tf.Session()#创建会话 #运行会话,输入数据,并计算节点,同时打印结果 print sess.run(y, feed_dict={a: 3, b: 3}) # 任务完成, 关闭会话. sess.close()
其中tf.mul(a, b)函数即是tf的一个基本的算数运算,接下来介绍跟多的相关函数。node
TensorFlow 将图形定义转换成分布式执行的操做, 以充分利用可用的计算资源(如 CPU 或 GPU。通常你不须要显式指定使用 CPU 仍是 GPU, TensorFlow 能自动检测。若是检测到 GPU, TensorFlow 会尽量地利用找到的第一个 GPU 来执行操做. 并行计算能让代价大的算法计算加速执行,TensorFlow也在实现上对复杂操做进行了有效的改进。大部分核相关的操做都是设备相关的实现,好比GPU。下面是一些重要的操做/核:
操做组 | 操做 |
---|---|
Maths | Add, Sub, Mul, Div, Exp, Log, Greater, Less, Equal |
Array | Concat, Slice, Split, Constant, Rank, Shape, Shuffle |
Matrix | MatMul, MatrixInverse, MatrixDeterminant |
Neuronal Network | SoftMax, Sigmoid, ReLU, Convolution2D, MaxPool |
Checkpointing | Save, Restore |
Queues and syncronizations | Enqueue, Dequeue, MutexAcquire, MutexRelease |
Flow control | Merge, Switch, Enter, Leave, NextIteration |
操做 | 描述 |
---|---|
tf.add(x, y, name=None) | 求和 |
tf.sub(x, y, name=None) | 减法 |
tf.mul(x, y, name=None) | 乘法 |
tf.div(x, y, name=None) | 除法 |
tf.mod(x, y, name=None) | 取模 |
tf.abs(x, name=None) | 求绝对值 |
tf.neg(x, name=None) | 取负 (y = -x). |
tf.sign(x, name=None) | 返回符号 y = sign(x) = -1 if x < 0; 0 if x == 0; 1 if x > 0. |
tf.inv(x, name=None) | 取反 |
tf.square(x, name=None) | 计算平方 (y = x * x = x^2). |
tf.round(x, name=None) | 舍入最接近的整数 # ‘a’ is [0.9, 2.5, 2.3, -4.4] tf.round(a) ==> [ 1.0, 3.0, 2.0, -4.0 ] |
tf.sqrt(x, name=None) | 开根号 (y = \sqrt{x} = x^{1/2}). |
tf.pow(x, y, name=None) | 幂次方 # tensor ‘x’ is [[2, 2], [3, 3]] # tensor ‘y’ is [[8, 16], [2, 3]] tf.pow(x, y) ==> [[256, 65536], [9, 27]] |
tf.exp(x, name=None) | 计算e的次方 |
tf.log(x, name=None) | 计算log,一个输入计算e的ln,两输入以第二输入为底 |
tf.maximum(x, y, name=None) | 返回最大值 (x > y ? x : y) |
tf.minimum(x, y, name=None) | 返回最小值 (x < y ? x : y) |
tf.cos(x, name=None) | 三角函数cosine |
tf.sin(x, name=None) | 三角函数sine |
tf.tan(x, name=None) | 三角函数tan |
tf.atan(x, name=None) | 三角函数ctan |
操做 | 描述 |
---|---|
tf.string_to_number (string_tensor, out_type=None, name=None) |
字符串转为数字 |
tf.to_double(x, name=’ToDouble’) | 转为64位浮点类型–float64 |
tf.to_float(x, name=’ToFloat’) | 转为32位浮点类型–float32 |
tf.to_int32(x, name=’ToInt32’) | 转为32位整型–int32 |
tf.to_int64(x, name=’ToInt64’) | 转为64位整型–int64 |
tf.cast(x, dtype, name=None) | 将x或者x.values转换为dtype # tensor a is [1.8, 2.2], dtype=tf.floattf.cast(a, tf.int32) ==> [1, 2] # dtype=tf.int32 |
操做 | 描述 |
---|---|
tf.shape(input, name=None) | 返回数据的shape # ‘t’ is [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]] shape(t) ==> [2, 2, 3] |
tf.size(input, name=None) | 返回数据的元素数量 # ‘t’ is [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]] size(t) ==> 12 |
tf.rank(input, name=None) | 返回tensor的rank 注意:此rank不一样于矩阵的rank, tensor的rank表示一个tensor须要的索引数目来惟一表示任何一个元素 也就是一般所说的 “order”, “degree”或”ndims” #’t’ is [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]] # shape of tensor ‘t’ is [2, 2, 3] rank(t) ==> 3 |
tf.reshape(tensor, shape, name=None) | 改变tensor的形状 # tensor ‘t’ is [1, 2, 3, 4, 5, 6, 7, 8, 9] # tensor ‘t’ has shape [9] reshape(t, [3, 3]) ==> [[1, 2, 3], [4, 5, 6], [7, 8, 9]] #若是shape有元素[-1],表示在该维度打平至一维 # -1 将自动推导得为 9: reshape(t, [2, -1]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3], [4, 4, 4, 5, 5, 5, 6, 6, 6]] |
tf.expand_dims(input, dim, name=None) | 插入维度1进入一个tensor中 #该操做要求-1-input.dims() # ‘t’ is a tensor of shape [2] shape(expand_dims(t, 0)) ==> [1, 2] shape(expand_dims(t, 1)) ==> [2, 1] shape(expand_dims(t, -1)) ==> [2, 1] <= dim <= input.dims() |
操做 | 描述 |
---|---|
tf.slice(input_, begin, size, name=None) | 对tensor进行切片操做 其中size[i] = input.dim_size(i) - begin[i] 该操做要求 0 <= begin[i] <= begin[i] + size[i] <= Di for i in [0, n] #’input’ is #[[[1, 1, 1], [2, 2, 2]],[[3, 3, 3], [4, 4, 4]],[[5, 5, 5], [6, 6, 6]]] tf.slice(input, [1, 0, 0], [1, 1, 3]) ==> [[[3, 3, 3]]] tf.slice(input, [1, 0, 0], [1, 2, 3]) ==> [[[3, 3, 3], [4, 4, 4]]] tf.slice(input, [1, 0, 0], [2, 1, 3]) ==> [[[3, 3, 3]], [[5, 5, 5]]] |
tf.split(split_dim, num_split, value, name=’split’) | 沿着某一维度将tensor分离为num_split tensors # ‘value’ is a tensor with shape [5, 30] # Split ‘value’ into 3 tensors along dimension 1 split0, split1, split2 = tf.split(1, 3, value) tf.shape(split0) ==> [5, 10] |
tf.concat(concat_dim, values, name=’concat’) | 沿着某一维度连结tensor t1 = [[1, 2, 3], [4, 5, 6]] t2 = [[7, 8, 9], [10, 11, 12]] tf.concat(0, [t1, t2]) ==> [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] tf.concat(1, [t1, t2]) ==> [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]] 若是想沿着tensor一新轴连结打包,那么能够: tf.concat(axis, [tf.expand_dims(t, axis) for t in tensors]) 等同于tf.pack(tensors, axis=axis) |
tf.pack(values, axis=0, name=’pack’) | 将一系列rank-R的tensor打包为一个rank-(R+1)的tensor # ‘x’ is [1, 4], ‘y’ is [2, 5], ‘z’ is [3, 6] pack([x, y, z]) => [[1, 4], [2, 5], [3, 6]] # 沿着第一维pack pack([x, y, z], axis=1) => [[1, 2, 3], [4, 5, 6]] 等价于tf.pack([x, y, z]) = np.asarray([x, y, z]) |
tf.reverse(tensor, dims, name=None) | 沿着某维度进行序列反转 其中dim为列表,元素为bool型,size等于rank(tensor) # tensor ‘t’ is [[[[ 0, 1, 2, 3], #[ 4, 5, 6, 7], #[ 8, 9, 10, 11]], #[[12, 13, 14, 15], #[16, 17, 18, 19], #[20, 21, 22, 23]]]] # tensor ‘t’ shape is [1, 2, 3, 4] # ‘dims’ is [False, False, False, True] reverse(t, dims) ==> [[[[ 3, 2, 1, 0], [ 7, 6, 5, 4], [ 11, 10, 9, 8]], [[15, 14, 13, 12], [19, 18, 17, 16], [23, 22, 21, 20]]]] |
tf.transpose(a, perm=None, name=’transpose’) | 调换tensor的维度顺序 按照列表perm的维度排列调换tensor顺序, 如为定义,则perm为(n-1…0) # ‘x’ is [[1 2 3],[4 5 6]] tf.transpose(x) ==> [[1 4], [2 5],[3 6]] # Equivalently tf.transpose(x, perm=[1, 0]) ==> [[1 4],[2 5], [3 6]] |
tf.gather(params, indices, validate_indices=None, name=None) | 合并索引indices所指示params中的切片![]() |
tf.one_hot (indices, depth, on_value=None, off_value=None, axis=None, dtype=None, name=None) |
indices = [0, 2, -1, 1] depth = 3 on_value = 5.0 off_value = 0.0 axis = -1 #Then output is [4 x 3]: output = [5.0 0.0 0.0] // one_hot(0) [0.0 0.0 5.0] // one_hot(2) [0.0 0.0 0.0] // one_hot(-1) [0.0 5.0 0.0] // one_hot(1) |
操做 | 描述 |
---|---|
tf.diag(diagonal, name=None) | 返回一个给定对角值的对角tensor # ‘diagonal’ is [1, 2, 3, 4] tf.diag(diagonal) ==> [[1, 0, 0, 0] [0, 2, 0, 0] [0, 0, 3, 0] [0, 0, 0, 4]] |
tf.diag_part(input, name=None) | 功能与上面相反 |
tf.trace(x, name=None) | 求一个2维tensor足迹,即对角值diagonal之和 |
tf.transpose(a, perm=None, name=’transpose’) | 调换tensor的维度顺序 按照列表perm的维度排列调换tensor顺序, 如为定义,则perm为(n-1…0) # ‘x’ is [[1 2 3],[4 5 6]] tf.transpose(x) ==> [[1 4], [2 5],[3 6]] # Equivalently tf.transpose(x, perm=[1, 0]) ==> [[1 4],[2 5], [3 6]] |
tf.matmul(a, b, transpose_a=False, transpose_b=False, a_is_sparse=False, b_is_sparse=False, name=None) |
矩阵相乘 |
tf.matrix_determinant(input, name=None) | 返回方阵的行列式 |
tf.matrix_inverse(input, adjoint=None, name=None) | 求方阵的逆矩阵,adjoint为True时,计算输入共轭矩阵的逆矩阵 |
tf.cholesky(input, name=None) | 对输入方阵cholesky分解, 即把一个对称正定的矩阵表示成一个下三角矩阵L和其转置的乘积的分解A=LL^T |
tf.matrix_solve(matrix, rhs, adjoint=None, name=None) | 求解tf.matrix_solve(matrix, rhs, adjoint=None, name=None) matrix为方阵shape为[M,M],rhs的shape为[M,K],output为[M,K] |
操做 | 描述 |
---|---|
tf.complex(real, imag, name=None) | 将两实数转换为复数形式 # tensor ‘real’ is [2.25, 3.25] # tensor imag is [4.75, 5.75]tf.complex(real, imag) ==> [[2.25 + 4.75j], [3.25 + 5.75j]] |
tf.complex_abs(x, name=None) | 计算复数的绝对值,即长度。 # tensor ‘x’ is [[-2.25 + 4.75j], [-3.25 + 5.75j]] tf.complex_abs(x) ==> [5.25594902, 6.60492229] |
tf.conj(input, name=None) | 计算共轭复数 |
tf.imag(input, name=None) tf.real(input, name=None) |
提取复数的虚部和实部 |
tf.fft(input, name=None) | 计算一维的离散傅里叶变换,输入数据类型为complex64 |
操做 | 描述 |
---|---|
tf.reduce_sum(input_tensor, reduction_indices=None, keep_dims=False, name=None) |
计算输入tensor元素的和,或者安照reduction_indices指定的轴进行求和 # ‘x’ is [[1, 1, 1] # [1, 1, 1]] tf.reduce_sum(x) ==> 6 tf.reduce_sum(x, 0) ==> [2, 2, 2] tf.reduce_sum(x, 1) ==> [3, 3] tf.reduce_sum(x, 1, keep_dims=True) ==> [[3], [3]] tf.reduce_sum(x, [0, 1]) ==> 6 |
tf.reduce_prod(input_tensor, reduction_indices=None, keep_dims=False, name=None) |
计算输入tensor元素的乘积,或者安照reduction_indices指定的轴进行求乘积 |
tf.reduce_min(input_tensor, reduction_indices=None, keep_dims=False, name=None) |
求tensor中最小值 |
tf.reduce_max(input_tensor, reduction_indices=None, keep_dims=False, name=None) |
求tensor中最大值 |
tf.reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None) |
求tensor中平均值 |
tf.reduce_all(input_tensor, reduction_indices=None, keep_dims=False, name=None) |
对tensor中各个元素求逻辑’与’ # ‘x’ is # [[True, True] # [False, False]] tf.reduce_all(x) ==> False tf.reduce_all(x, 0) ==> [False, False] tf.reduce_all(x, 1) ==> [True, False] |
tf.reduce_any(input_tensor, reduction_indices=None, keep_dims=False, name=None) |
对tensor中各个元素求逻辑’或’ |
tf.accumulate_n(inputs, shape=None, tensor_dtype=None, name=None) |
计算一系列tensor的和 # tensor ‘a’ is [[1, 2], [3, 4]] # tensor b is [[5, 0], [0, 6]]tf.accumulate_n([a, b, a]) ==> [[7, 4], [6, 14]] |
tf.cumsum(x, axis=0, exclusive=False, reverse=False, name=None) |
求累积和 tf.cumsum([a, b, c]) ==> [a, a + b, a + b + c] tf.cumsum([a, b, c], exclusive=True) ==> [0, a, a + b] tf.cumsum([a, b, c], reverse=True) ==> [a + b + c, b + c, c] tf.cumsum([a, b, c], exclusive=True, reverse=True) ==> [b + c, c, 0] |
操做 | 描述 |
---|---|
tf.segment_sum(data, segment_ids, name=None) | 根据segment_ids的分段计算各个片断的和 其中segment_ids为一个size与data第一维相同的tensor 其中id为int型数据,最大id不大于size c = tf.constant([[1,2,3,4], [-1,-2,-3,-4], [5,6,7,8]]) tf.segment_sum(c, tf.constant([0, 0, 1])) ==>[[0 0 0 0] [5 6 7 8]] 上面例子分为[0,1]两id,对相同id的data相应数据进行求和, 并放入结果的相应id中, 且segment_ids只升不降 |
tf.segment_prod(data, segment_ids, name=None) | 根据segment_ids的分段计算各个片断的积 |
tf.segment_min(data, segment_ids, name=None) | 根据segment_ids的分段计算各个片断的最小值 |
tf.segment_max(data, segment_ids, name=None) | 根据segment_ids的分段计算各个片断的最大值 |
tf.segment_mean(data, segment_ids, name=None) | 根据segment_ids的分段计算各个片断的平均值 |
tf.unsorted_segment_sum(data, segment_ids, num_segments, name=None) |
与tf.segment_sum函数相似, 不一样在于segment_ids中id顺序能够是无序的 |
tf.sparse_segment_sum(data, indices, segment_ids, name=None) |
输入进行稀疏分割求和 c = tf.constant([[1,2,3,4], [-1,-2,-3,-4], [5,6,7,8]]) # Select two rows, one segment. tf.sparse_segment_sum(c, tf.constant([0, 1]), tf.constant([0, 0])) ==> [[0 0 0 0]] 对原data的indices为[0,1]位置的进行分割, 并按照segment_ids的分组进行求和 |
操做 | 描述 |
---|---|
tf.argmin(input, dimension, name=None) | 返回input最小值的索引index |
tf.argmax(input, dimension, name=None) | 返回input最大值的索引index |
tf.listdiff(x, y, name=None) | 返回x,y中不一样值的索引 |
tf.where(input, name=None) | 返回bool型tensor中为True的位置 # ‘input’ tensor is #[[True, False] #[True, False]] # ‘input’ 有两个’True’,那么输出两个坐标值. # ‘input’的rank为2, 因此每一个坐标为具备两个维度. where(input) ==> [[0, 0], [1, 0]] |
tf.unique(x, name=None) | 返回一个元组tuple(y,idx),y为x的列表的惟一化数据列表, idx为x数据对应y元素的index # tensor ‘x’ is [1, 1, 2, 4, 4, 4, 7, 8, 8] y, idx = unique(x) y ==> [1, 2, 4, 7, 8] idx ==> [0, 0, 1, 2, 2, 2, 3, 4, 4] |
tf.invert_permutation(x, name=None) | 置换x数据与索引的关系 # tensor x is [3, 4, 0, 2, 1]invert_permutation(x) ==> [2, 4, 3, 0, 1] |
操做 | 描述 |
---|---|
tf.nn.relu(features, name=None) | 整流函数:max(features, 0) |
tf.nn.relu6(features, name=None) | 以6为阈值的整流函数:min(max(features, 0), 6) |
tf.nn.elu(features, name=None) | elu函数,exp(features) - 1 if < 0,不然features Exponential Linear Units (ELUs) |
tf.nn.softplus(features, name=None) | 计算softplus:log(exp(features) + 1) |
tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None) |
计算dropout,keep_prob为keep几率 noise_shape为噪声的shape |
tf.nn.bias_add(value, bias, data_format=None, name=None) | 对value加一偏置量 此函数为tf.add的特殊状况,bias仅为一维, 函数经过广播机制进行与value求和, 数据格式能够与value不一样,返回为与value相同格式 |
tf.sigmoid(x, name=None) | y = 1 / (1 + exp(-x)) |
tf.tanh(x, name=None) | 双曲线切线激活函数 |
操做 | 描述 |
---|---|
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None) |
在给定的4D input与 filter下计算2D卷积 输入shape为 [batch, height, width, in_channels] |
tf.nn.conv3d(input, filter, strides, padding, name=None) | 在给定的5D input与 filter下计算3D卷积 输入shape为[batch, in_depth, in_height, in_width, in_channels] |
操做 | 描述 |
---|---|
tf.nn.avg_pool(value, ksize, strides, padding, data_format=’NHWC’, name=None) |
平均方式池化 |
tf.nn.max_pool(value, ksize, strides, padding, data_format=’NHWC’, name=None) |
最大值方法池化 |
tf.nn.max_pool_with_argmax(input, ksize, strides, padding, Targmax=None, name=None) |
返回一个二维元组(output,argmax),最大值pooling,返回最大值及其相应的索引 |
tf.nn.avg_pool3d(input, ksize, strides, padding, name=None) |
3D平均值pooling |
tf.nn.max_pool3d(input, ksize, strides, padding, name=None) |
3D最大值pooling |
操做 | 描述 |
---|---|
tf.nn.l2_normalize(x, dim, epsilon=1e-12, name=None) | 对维度dim进行L2范式标准化 output = x / sqrt(max(sum(x**2), epsilon)) |
tf.nn.sufficient_statistics(x, axes, shift=None, keep_dims=False, name=None) |
计算与均值和方差有关的彻底统计量 返回4维元组,*元素个数,*元素总和,*元素的平方和,*shift结果 参见算法介绍 |
tf.nn.normalize_moments(counts, mean_ss, variance_ss, shift, name=None) | 基于彻底统计量计算均值和方差 |
tf.nn.moments(x, axes, shift=None, name=None, keep_dims=False) |
直接计算均值与方差 |
操做 | 描述 |
---|---|
tf.nn.l2_loss(t, name=None) | output = sum(t ** 2) / 2 |
操做 | 描述 |
---|---|
tf.nn.sigmoid_cross_entropy_with_logits (logits, targets, name=None)* |
计算输入logits, targets的交叉熵 |
tf.nn.softmax(logits, name=None) | 计算softmax softmax[i, j] = exp(logits[i, j]) / sum_j(exp(logits[i, j])) |
tf.nn.log_softmax(logits, name=None) | logsoftmax[i, j] = logits[i, j] - log(sum(exp(logits[i]))) |
tf.nn.softmax_cross_entropy_with_logits (logits, labels, name=None) |
计算logits和labels的softmax交叉熵 logits, labels必须为相同的shape与数据类型 |
tf.nn.sparse_softmax_cross_entropy_with_logits (logits, labels, name=None) |
计算logits和labels的softmax交叉熵 |
tf.nn.weighted_cross_entropy_with_logits (logits, targets, pos_weight, name=None) |
与sigmoid_cross_entropy_with_logits()类似, 但给正向样本损失加了权重pos_weight |
操做 | 描述 |
---|---|
tf.nn.embedding_lookup (params, ids, partition_strategy=’mod’, name=None, validate_indices=True) |
根据索引ids查询embedding列表params中的tensor值 若是len(params) > 1,id将会安照partition_strategy策略进行分割 一、若是partition_strategy为”mod”, id所分配到的位置为p = id % len(params) 好比有13个ids,分为5个位置,那么分配方案为: [[0, 5, 10], [1, 6, 11], [2, 7, 12], [3, 8], [4, 9]] 二、若是partition_strategy为”div”,那么分配方案为: [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10], [11, 12]] |
tf.nn.embedding_lookup_sparse(params, sp_ids, sp_weights, partition_strategy=’mod’, name=None, combiner=’mean’) |
对给定的ids和权重查询embedding 一、sp_ids为一个N x M的稀疏tensor, N为batch大小,M为任意,数据类型int64 二、sp_weights的shape与sp_ids的稀疏tensor权重, 浮点类型,若为None,则权重为全’1’ |
操做 | 描述 |
---|---|
tf.nn.rnn(cell, inputs, initial_state=None, dtype=None, sequence_length=None, scope=None) |
基于RNNCell类的实例cell创建循环神经网络 |
tf.nn.dynamic_rnn(cell, inputs, sequence_length=None, initial_state=None, dtype=None, parallel_iterations=None, swap_memory=False, time_major=False, scope=None) |
基于RNNCell类的实例cell创建动态循环神经网络 与通常rnn不一样的是,该函数会根据输入动态展开 返回(outputs,state) |
tf.nn.state_saving_rnn(cell, inputs, state_saver, state_name, sequence_length=None, scope=None) |
可储存调试状态的RNN网络 |
tf.nn.bidirectional_rnn(cell_fw, cell_bw, inputs, initial_state_fw=None, initial_state_bw=None, dtype=None, sequence_length=None, scope=None) |
双向RNN, 返回一个3元组tuple (outputs, output_state_fw, output_state_bw) |
— tf.nn.rnn简要介绍—
cell: 一个RNNCell实例
inputs: 一个shape为[batch_size, input_size]的tensor
initial_state: 为RNN的state设定初值,可选
sequence_length:制定输入的每个序列的长度,size为[batch_size],值范围为[0, T)的int型数据
其中T为输入数据序列的长度
@
@针对输入batch中序列长度不一样,所设置的动态计算机制
@对于在时间t,和batch的b行,有
(output, state)(b, t) = ? (zeros(cell.output_size), states(b, sequence_length(b) - 1)) : cell(input(b, t), state(b, t - 1))python
操做 | 描述 |
---|---|
tf.nn.top_k(input, k=1, sorted=True, name=None) | 返回前k大的值及其对应的索引 |
tf.nn.in_top_k(predictions, targets, k, name=None) | 返回判断是否targets索引的predictions相应的值 是否在在predictions前k个位置中, 返回数据类型为bool类型,len与predictions同 |
对于有巨大量的多分类与多标签模型,若是使用全链接softmax将会占用大量的时间与空间资源,因此采用候选采样方法仅使用一小部分类别与标签做为监督以加速训练。git
操做 | 描述 |
---|---|
Sampled Loss Functions | |
tf.nn.nce_loss(weights, biases, inputs, labels, num_sampled, num_classes, num_true=1, sampled_values=None, remove_accidental_hits=False, partition_strategy=’mod’, name=’nce_loss’) |
返回noise-contrastive的训练损失结果 |
tf.nn.sampled_softmax_loss(weights, biases, inputs, labels, num_sampled, num_classes, num_true=1, sampled_values=None, remove_accidental_hits=True, partition_strategy=’mod’, name=’sampled_softmax_loss’) |
返回sampled softmax的训练损失 参考- Jean et al., 2014第3部分 |
Candidate Samplers | |
tf.nn.uniform_candidate_sampler(true_classes, num_true, num_sampled, unique, range_max, seed=None, name=None) |
经过均匀分布的采样集合 返回三元tuple 一、sampled_candidates 候选集合。 二、指望的true_classes个数,为浮点值 三、指望的sampled_candidates个数,为浮点值 |
tf.nn.log_uniform_candidate_sampler(true_classes, num_true, num_sampled, unique, range_max, seed=None, name=None) |
经过log均匀分布的采样集合,返回三元tuple |
tf.nn.learned_unigram_candidate_sampler (true_classes, num_true, num_sampled, unique, range_max, seed=None, name=None) |
根据在训练过程当中学习到的分布情况进行采样 返回三元tuple |
tf.nn.fixed_unigram_candidate_sampler(true_classes, num_true, num_sampled, unique, range_max, vocab_file=”, distortion=1.0, num_reserved_ids=0, num_shards=1, shard=0, unigrams=(), seed=None, name=None) |
基于所提供的基本分布进行采样 |
操做 | 描述 |
---|---|
类tf.train.Saver(Saving and Restoring Variables) | |
tf.train.Saver.__init__(var_list=None, reshape=False, sharded=False, max_to_keep=5, keep_checkpoint_every_n_hours=10000.0, name=None, restore_sequentially=False, saver_def=None, builder=None) |
建立一个存储器Saver var_list定义须要存储和恢复的变量 |
tf.train.Saver.save(sess, save_path, global_step=None, latest_filename=None, meta_graph_suffix=’meta’, write_meta_graph=True) |
保存变量 |
tf.train.Saver.restore(sess, save_path) | 恢复变量 |
tf.train.Saver.last_checkpoints | 列出最近未删除的checkpoint 文件名 |
tf.train.Saver.set_last_checkpoints(last_checkpoints) | 设置checkpoint文件名列表 |
tf.train.Saver.set_last_checkpoints_with_time(last_checkpoints_with_time) | 设置checkpoint文件名列表和时间戳 |
为了快速的熟悉TensorFlow编程,下面从一段简单的代码开始:github
import tensorflow as tf #定义‘符号’变量,也称为占位符 a = tf.placeholder("float") b = tf.placeholder("float") y = tf.mul(a, b) #构造一个op节点 sess = tf.Session()#创建会话 #运行会话,输入数据,并计算节点,同时打印结果 print sess.run(y, feed_dict={a: 3, b: 3}) # 任务完成, 关闭会话. sess.close()
其中tf.mul(a, b)函数即是tf的一个基本的算数运算,接下来介绍跟多的相关函数。算法
TensorFlow 将图形定义转换成分布式执行的操做, 以充分利用可用的计算资源(如 CPU 或 GPU。通常你不须要显式指定使用 CPU 仍是 GPU, TensorFlow 能自动检测。若是检测到 GPU, TensorFlow 会尽量地利用找到的第一个 GPU 来执行操做. 并行计算能让代价大的算法计算加速执行,TensorFlow也在实现上对复杂操做进行了有效的改进。大部分核相关的操做都是设备相关的实现,好比GPU。本文主要涉及的相关概念或操做有如下内容:
操做组 | 操做 |
---|---|
Building Graphs | Core graph data structures,Tensor types,Utility functions |
Inputs and Readers | Placeholders,Readers,Converting,Queues,Input pipeline |
本节主要介绍创建tensorflow图的相关类或函数shell
tf.Graph编程
操做 | 描述 |
---|---|
class tf.Graph | tensorflow中的计算以图数据流的方式表示 一个图包含一系列表示计算单元的操做对象 以及在图中流动的数据单元以tensor对象表现 |
tf.Graph.__init__() | 创建一个空图 |
tf.Graph.as_default() | 一个将某图设置为默认图,并返回一个上下文管理器 若是不显式添加一个默认图,系统会自动设置一个全局的默认图。 所设置的默认图,在模块范围内所定义的节点都将默认加入默认图中 |
tf.Graph.as_graph_def (from_version=None, add_shapes=False) |
返回一个图的序列化的GraphDef表示 序列化的GraphDef能够导入至另外一个图中(使用 import_graph_def()) 或者使用C++ Session API |
tf.Graph.finalize() | 完成图的构建,即将其设置为只读模式 |
tf.Graph.finalized | 返回True,若是图被完成 |
tf.Graph.control_dependencies(control_inputs) | 定义一个控制依赖,并返回一个上下文管理器 with g.control_dependencies([a, b, c]): # `d` 和 `e` 将在 `a`, `b`, 和`c`执行完以后运行. d = … e = … |
tf.Graph.device(device_name_or_function) | 定义运行图所使用的设备,并返回一个上下文管理器with g.device('/gpu:0'): ... with g.device('/cpu:0'): ... |
tf.Graph.name_scope(name) | 为节点建立层次化的名称,并返回一个上下文管理器 |
tf.Graph.add_to_collection(name, value) | 将value以name的名称存储在收集器(collection)中 |
tf.Graph.get_collection(name, scope=None) | 根据name返回一个收集器中所收集的值的列表 |
tf.Graph.as_graph_element (obj, allow_tensor=True, allow_operation=True) |
返回一个图中与obj相关联的对象,为一个操做节点或者tensor数据 |
tf.Graph.get_operation_by_name(name) | 根据名称返回操做节点 |
tf.Graph.get_tensor_by_name(name) | 根据名称返回tensor数据 |
tf.Graph.get_operations() | 返回图中的操做节点列表 |
tf.Graph.gradient_override_map(op_type_map) | 用于覆盖梯度函数的上下文管理器 |
#class tf.Graph #tensorflow运行时须要设置默认的图 g = tf.Graph() with g.as_default(): # Define operations and tensors in `g`. c = tf.constant(30.0) assert c.graph is g ##也可使用tf.get_default_graph()得到默认图,也可在基础上加入节点或子图 c = tf.constant(4.0) assert c.graph is tf.get_default_graph()
#tf.Graph.as_default #如下两段代码功能相同 #一、使用Graph.as_default(): g = tf.Graph() with g.as_default(): c = tf.constant(5.0) assert c.graph is g #二、构造和设置为默认 with tf.Graph().as_default() as g: c = tf.constant(5.0) assert c.graph is g
#tf.Graph.control_dependencies(control_inputs) # 错误代码 def my_func(pred, tensor): t = tf.matmul(tensor, tensor) with tf.control_dependencies([pred]): # 乘法操做(op)没有建立在该上下文,因此没有被加入依赖控制 return t # 正确代码 def my_func(pred, tensor): with tf.control_dependencies([pred]): # 乘法操做(op)建立在该上下文,因此被加入依赖控制中 #执行完pred以后再执行matmul return tf.matmul(tensor, tensor)
# tf.Graph.name_scope(name) # 一个图中包含有一个名称范围的堆栈,在使用name_scope(...)以后,将压(push)新名称进栈中, #并在下文中使用该名称 with tf.Graph().as_default() as g: c = tf.constant(5.0, name="c") assert c.op.name == "c" c_1 = tf.constant(6.0, name="c") assert c_1.op.name == "c_1" # Creates a scope called "nested" with g.name_scope("nested") as scope: nested_c = tf.constant(10.0, name="c") assert nested_c.op.name == "nested/c" # Creates a nested scope called "inner". with g.name_scope("inner"): nested_inner_c = tf.constant(20.0, name="c") assert nested_inner_c.op.name == "nested/inner/c" # Create a nested scope called "inner_1". with g.name_scope("inner"): nested_inner_1_c = tf.constant(30.0, name="c") assert nested_inner_1_c.op.name == "nested/inner_1/c" # Treats `scope` as an absolute name scope, and # switches to the "nested/" scope. with g.name_scope(scope): nested_d = tf.constant(40.0, name="d") assert nested_d.op.name == "nested/d" with g.name_scope(""): e = tf.constant(50.0, name="e") assert e.op.name == "e"
tf.Operationjson
操做 | 描述 |
---|---|
class tf.Operation | 表明图中的一个节点,用于计算tensors数据 该类型将由python节点构造器产生(好比tf.matmul()) 或者Graph.create_op() 例如c = tf.matmul(a, b)建立一个Operation类 为类型为”MatMul”,输入为’a’,’b’,输出为’c’的操做类 |
tf.Operation.name | 操做节点(op)的名称 |
tf.Operation.type | 操做节点(op)的类型,好比”MatMul” |
tf.Operation.inputs tf.Operation.outputs |
操做节点的输入与输出 |
tf.Operation.control_inputs | 操做节点的依赖 |
tf.Operation.run(feed_dict=None, session=None) | 在会话(Session)中运行该操做 |
tf.Operation.get_attr(name) | 获取op的属性值 |
tf.Tensorapi
操做 | 描述 |
---|---|
class tf.Tensor | 表示一个由操做节点op产生的值, TensorFlow程序使用tensor数据结构来表明全部的数据, 计算图中, 操做间传递的数据都是 tensor,一个tensor是一个符号handle, 里面并无表示实际数据,而至关于数据流的载体 |
tf.Tensor.dtype | tensor中数据类型 |
tf.Tensor.name | 该tensor名称 |
tf.Tensor.value_index | 该tensor输出外op的index |
tf.Tensor.graph | 该tensor所处在的图 |
tf.Tensor.op | 产生该tensor的op |
tf.Tensor.consumers() | 返回使用该tensor的op列表 |
tf.Tensor.eval(feed_dict=None, session=None) | 在会话中求tensor的值 须要使用 with sess.as_default() 或者 eval(session=sess) |
tf.Tensor.get_shape() | 返回用于表示tensor的shape的类TensorShape |
tf.Tensor.set_shape(shape) | 更新tensor的shape |
tf.Tensor.device | 设置计算该tensor的设备 |
#tf.Tensor.get_shape() c = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) print(c.get_shape()) ==> TensorShape([Dimension(2), Dimension(3)])
#如今有个用于图像处理的tensor->image print(image.get_shape()) ==> TensorShape([Dimension(None), Dimension(None), Dimension(3)]) # 假如咱们知道数据集中图像尺寸为28 x 28,那么能够设置 image.set_shape([28, 28, 3]) print(image.get_shape()) ==> TensorShape([Dimension(28), Dimension(28), Dimension(3)])
tf.DType
操做 | 描述 |
---|---|
class tf.DType | 数据类型主要包含 tf.float16,tf.float16,tf.float32,tf.float64, tf.bfloat16,tf.complex64,tf.complex128, tf.int8,tf.uint8,tf.uint16,tf.int16,tf.int32, tf.int64,tf.bool,tf.string |
tf.DType.is_compatible_with(other) | 判断other的数据类型是否将转变为该DType |
tf.DType.name | 数据类型名称 |
tf.DType.base_dtype | 返回该DType的基础DType,而非参考的数据类型(non-reference) |
tf.DType.as_ref | 返回一个基于DType的参考数据类型 |
tf.DType.is_floating | 判断是否为浮点类型 |
tf.DType.is_complex | 判断是否为复数 |
tf.DType.is_integer | 判断是否为整数 |
tf.DType.is_unsigned | 判断是否为无符号型数据 |
tf.DType.as_numpy_dtype | 返回一个基于DType的numpy.dtype类型 |
tf.DType.max tf.DType.min |
返回这种数据类型能表示的最大值及其最小值 |
tf.as_dtype(type_value) | 返回由type_value转变得的相应tf数据类型 |
操做 | 描述 |
---|---|
tf.device(device_name_or_function) | 基于默认的图,其功能便为Graph.device() |
tf.container(container_name) | 基于默认的图,其功能便为Graph.container() |
tf.name_scope(name) | 基于默认的图,其功能便为 Graph.name_scope() |
tf.control_dependencies(control_inputs) | 基于默认的图,其功能便为Graph.control_dependencies() |
tf.convert_to_tensor (value, dtype=None, name=None, as_ref=False) |
将value转变为tensor数据类型 |
tf.get_default_graph() | 返回返回当前线程的默认图 |
tf.reset_default_graph() | 清除默认图的堆栈,并设置全局图为默认图 |
tf.import_graph_def(graph_def, input_map=None, return_elements=None, name=None, op_dict=None, producer_op_list=None) |
将graph_def的图导入到python中 |
操做 | 描述 |
---|---|
tf.add_to_collection(name, value) | 基于默认的图,其功能便为Graph.add_to_collection() |
tf.get_collection(key, scope=None) | 基于默认的图,其功能便为Graph.get_collection() |
tf.RegisterGradient
操做 | 描述 |
---|---|
class tf.RegisterGradient | 返回一个用于寄存op类型的梯度函数的装饰器 |
tf.NoGradient(op_type) | 设置操做节点类型op_type的节点没有指定的梯度 |
class tf.RegisterShape | 返回一个用于寄存op类型的shape函数的装饰器 |
class tf.TensorShape | 表示tensor的shape |
tf.TensorShape.merge_with(other) | 与other合并shape信息,返回一个TensorShape类 |
tf.TensorShape.concatenate(other) | 与other的维度相连结 |
tf.TensorShape.ndims | 返回tensor的rank |
tf.TensorShape.dims | 返回tensor的维度 |
tf.TensorShape.as_list() | 以list的形式返回tensor的shape |
tf.TensorShape.is_compatible_with(other) | 判断shape是否为兼容 TensorShape(None)与其余任何shape值兼容 |
class tf.Dimension | |
tf.Dimension.is_compatible_with(other) | 判断dims是否为兼容 |
tf.Dimension.merge_with(other) | 与other合并dims信息 |
tf.op_scope(values, name, default_name=None) | 在python定义op时,返回一个上下文管理器 |
#tf.RegisterGradient #该装饰器只使用于定义一个新的op类型时候,若是一个op有m个输入,n个输出。那么该梯度函数应该设置原始的 #操做类型,以及n个Tensor对象(表示每个op输出的梯度),以及m个对象(表示每个op输入的偏梯度) #以操做节点类型为'Sub'为例,两输入为x,y。为一个输出x-y @tf.RegisterGradient("Sub") def _sub_grad(unused_op, grad): return grad, tf.neg(grad)
#tf.op_scope #定义一个名称为my_op的python操做节点op def my_op(a, b, c, name=None): with tf.op_scope([a, b, c], name, "MyOp") as scope: a = tf.convert_to_tensor(a, name="a") b = tf.convert_to_tensor(b, name="b") c = tf.convert_to_tensor(c, name="c") # Define some computation that uses `a`, `b`, and `c`. return foo_op(..., name=scope)
本节主要介绍tensorflow中数据的读入相关类或函数
tf提供一种占位符操做,在执行时须要为其提供数据data。
操做 | 描述 |
---|---|
tf.placeholder(dtype, shape=None, name=None) | 为一个tensor插入一个占位符 eg:x = tf.placeholder(tf.float32, shape=(1024, 1024)) |
tf.placeholder_with_default(input, shape, name=None) | 当输出没有fed时,input经过一个占位符op |
tf.sparse_placeholder(dtype, shape=None, name=None) | 为一个稀疏tensor插入一个占位符 |
tf提供一系列读取各类数据格式的类。对于多文件输入,可使用函数tf.train.string_input_producer,该函数将建立一个保持文件的FIFO队列,以供reader使用。或者若是输入的这些文件名有相雷同的字符串,也可使用函数tf.train.match_filenames_once。
操做 | 描述 |
---|---|
class tf.ReaderBase | 不一样的读取器类型的基本类 |
tf.ReaderBase.read(queue, name=None) | 返回下一个记录对(key, value),queue为tf文件队列FIFOQueue |
tf.ReaderBase.read_up_to(queue, num_records, name=None) | 返回reader产生的num_records对(key, value) |
tf.ReaderBase.reader_ref | 返回应用在该reader上的Op |
tf.ReaderBase.reset(name=None) | 恢复reader为初始状态 |
tf.ReaderBase.restore_state(state, name=None) | 恢复reader为以前的保存状态state |
tf.ReaderBase.serialize_state(name=None) | 返回一个reader解码后产生的字符串tansor |
class tf.TextLineReader | |
tf.TextLineReader.num_records_produced(name=None) | 返回reader已经产生的记录(records )数目 |
tf.TextLineReader.num_work_units_completed(name=None) | 返回该reader已经完成的处理的work数目 |
tf.TextLineReader.read(queue, name=None) | 返回reader所产生的下一个记录对 (key, value),该reader能够限定新产生输出的行数 |
tf.TextLineReader.reader_ref | 返回应用在该reader上的Op |
tf.TextLineReader.reset(name=None) | 恢复reader为初始状态 |
tf.TextLineReader.restore_state(state, name=None) | 恢复reader为以前的保存状态state |
tf.TextLineReader.serialize_state(name=None) | 返回一个reader解码后产生的字符串tansor |
class tf.WholeFileReader | 一个阅读器,读取整个文件,返回文件名称key,以及文件中全部的内容value,该类的方法同上,不赘述 |
class tf.IdentityReader | 一个reader,以key和value的形式,输出一个work队列。该类其余方法基本同上 |
class tf.TFRecordReader | 读取TFRecord格式文件的reader。该类其余方法基本同上 |
class tf.FixedLengthRecordReader | 输出 |
tf提供一系列方法将各类格式数据转换为tensor表示。
操做 | 描述 |
---|---|
tf.decode_csv(records, record_defaults, field_delim=None, name=None) |
将csv转换为tensor,与tf.TextLineReader搭配使用 |
tf.decode_raw(bytes, out_type, little_endian=None, name=None) |
将bytes转换为一个数字向量表示,bytes为一个字符串类型的tensor 与函数 tf.FixedLengthRecordReader搭配使用,详见tf的CIFAR-10例子 |
选取与要输入的文件格式相匹配的reader,并将文件队列提供给reader的读方法( read method)。读方法将返回文件惟一标识的key,以及一个记录(record)(有助于对出现一些另类的records时debug),以及一个标量的字符串值。再使用一个(或多个)解码器(decoder) 或转换操做(conversion ops)将字符串转换为tensor类型。
#读取文件队列,使用reader中read的方法,返回key与value filename_queue = tf.train.string_input_producer(["file0.csv", "file1.csv"]) reader = tf.TextLineReader() key, value = reader.read(filename_queue) record_defaults = [[1], [1], [1], [1], [1]] col1, col2, col3, col4, col5 = tf.decode_csv( value, record_defaults=record_defaults) features = tf.pack([col1, col2, col3, col4]) with tf.Session() as sess: # Start populating the filename queue. coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(coord=coord) for i in range(1200): # Retrieve a single instance: example, label = sess.run([features, col5]) coord.request_stop() coord.join(threads)
提供了一些Example protocol buffers,tf所推荐的用于训练样本的数据格式,它们包含特征信息,详情可见。
这是一种与前述将手上现有的各类数据类型转换为支持的格式的方法,这种方法更容易将网络结构与数据集融合或匹配。这种tensorflow所推荐的数据格式是一个包含tf.train.Example protocol buffers (包含特征Features域)的TFRecords文件。
一、获取这种格式的文件方式为,首先将通常的数据格式填入Example protocol buffer中,再将 protocol buffer序列化为一个字符串,而后使用tf.python_io.TFRecordWriter类的相关方法将字符串写入一个TFRecords文件中,参见MNIST例子,将MNIST 数据转换为该类型数据。
二、读取TFRecords格式文件的方法为,使用tf.TFRecordReader读取器和tf.parse_single_example解码器。parse_single_example操做将 example protocol buffers解码为tensor形式。参见MNIST例子
操做 | 描述 |
---|---|
class tf.VarLenFeature | 解析变长的输入特征feature相关配置 |
class tf.FixedLenFeature | 解析定长的输入特征feature相关配置 |
class tf.FixedLenSequenceFeature | 序列项目中的稠密(dense )输入特征的相关配置 |
tf.parse_example(serialized, features, name=None, example_names=None) |
将一组Example protos解析为tensor的字典形式 解析serialized所给予的序列化的一些Example protos 返回一个由特征keys映射Tensor和SparseTensor值的字典 |
tf.parse_single_example(serialized, features, name=None, example_names=None) |
解析一个单独的Example proto,与tf.parse_example方法雷同 |
tf.decode_json_example(json_examples, name=None) | 将JSON编码的样本记录转换为二进制protocol buffer字符串 |
#tf.parse_example的使用举例 #输入序列化数据以下: serialized = [ features { feature { key: "ft" value { float_list { value: [1.0, 2.0] } } } }, features { feature []}, features { feature { key: "ft" value { float_list { value: [3.0] } } } ] #那么输出为一个字典(dict),以下: {"ft": SparseTensor(indices=[[0, 0], [0, 1], [2, 0]], values=[1.0, 2.0, 3.0], shape=(3, 2)) } ######### #再来看一个例子,给定两个序列化的原始输入样本: [ features { feature { key: "kw" value { bytes_list { value: [ "knit", "big" ] } } } feature { key: "gps" value { float_list { value: [] } } } }, features { feature { key: "kw" value { bytes_list { value: [ "emmy" ] } } } feature { key: "dank" value { int64_list { value: [ 42 ] } } } feature { key: "gps" value { } } } ] #相关参数以下: example_names: ["input0", "input1"], features: { "kw": VarLenFeature(tf.string), "dank": VarLenFeature(tf.int64), "gps": VarLenFeature(tf.float32), } #那么有以下输出: { "kw": SparseTensor( indices=[[0, 0], [0, 1], [1, 0]], values=["knit", "big", "emmy"] shape=[2, 2]), "dank": SparseTensor( indices=[[1, 0]], values=[42], shape=[2, 1]), "gps": SparseTensor( indices=[], values=[], shape=[2, 0]), } ######### #对于两个样本的输出稠密结果状况 [ features { feature { key: "age" value { int64_list { value: [ 0 ] } } } feature { key: "gender" value { bytes_list { value: [ "f" ] } } } }, features { feature { key: "age" value { int64_list { value: [] } } } feature { key: "gender" value { bytes_list { value: [ "f" ] } } } } ] #咱们可使用如下参数 example_names: ["input0", "input1"], features: { "age": FixedLenFeature([], dtype=tf.int64, default_value=-1), "gender": FixedLenFeature([], dtype=tf.string), } #指望的结果以下 { "age": [[0], [-1]], "gender": [["f"], ["f"]], }
##Example protocol buffer相关使用的例子 #将mnist的数据转换为TFRecords文件格式 import os import tensorflow as tf from tensorflow.contrib.learn.python.learn.datasets import mnist SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/' TRAIN_IMAGES = 'train-images-idx3-ubyte.gz' # MNIST filenames TRAIN_LABELS = 'train-labels-idx1-ubyte.gz' TEST_IMAGES = 't10k-images-idx3-ubyte.gz' TEST_LABELS = 't10k-labels-idx1-ubyte.gz' tf.app.flags.DEFINE_string('directory', '/tmp/data', 'Directory to download data files and write the ' 'converted result') tf.app.flags.DEFINE_integer('validation_size', 5000, 'Number of examples to separate from the training ' 'data for the validation set.') FLAGS = tf.app.flags.FLAGS def _int64_feature(value): return tf.train.Feature(int64_list=tf.train.Int64List(value=[value])) def _bytes_feature(value): return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value])) def convert_to(data_set, name): images = data_set.images labels = data_set.labels num_examples = data_set.num_examples if images.shape[0] != num_examples: raise ValueError('Images size %d does not match label size %d.' % (images.shape[0], num_examples)) rows = images.shape[1] cols = images.shape[2] depth = images.shape[3] filename = os.path.join(FLAGS.directory, name + '.tfrecords') print('Writing', filename) writer = tf.python_io.TFRecordWriter(filename) for index in range(num_examples): image_raw = images[index].tostring() example = tf.train.Example(features=tf.train.Features(feature={ 'height': _int64_feature(rows), 'width': _int64_feature(cols), 'depth': _int64_feature(depth), 'label': _int64_feature(int(labels[index])), 'image_raw': _bytes_feature(image_raw)})) writer.write(example.SerializeToString()) writer.close() def main(argv): # Get the data. data_sets = mnist.read_data_sets(FLAGS.directory, dtype=tf.uint8, reshape=False) # Convert to Examples and write the result to TFRecords. convert_to(data_sets.train, 'train') convert_to(data_sets.validation, 'validation') convert_to(data_sets.test, 'test') if __name__ == '__main__': tf.app.run()
tensorflow提供了几个队列应用,用来将tf计算图与tensors的阶段流水组织到一块儿。队列是使用tensorflow计算的一个强大的机制,正如其余Tensorflow的元素同样,一个队列也是tf图中的一个节点(node),它是一个有状态的node,就像一个变量:其余节点能够改变其内容。
咱们来看一个简单的例子,以下gif图,咱们将建立一个先入先出队列(FIFOQueue)而且将值全设为0,而后咱们构建一个图以获取队列出来的元素,对该元素加1操做,并将结果再放入队列末尾。渐渐地,队列中的数字便增长。
操做 | 描述 |
---|---|
class tf.QueueBase | 基本的队列应用类.队列(queue)是一种数据结构, 该结构经过多个步骤存储tensors, 而且对tensors进行入列(enqueue)与出列(dequeue)操做 |
tf.QueueBase.enqueue(vals, name=None) | 将一个元素编入该队列中。若是在执行该操做时队列已满, 那么将会阻塞直到元素编入队列之中 |
tf.QueueBase.enqueue_many(vals, name=None) | 将零个或多个元素编入该队列中 |
tf.QueueBase.dequeue(name=None) | 将元素从队列中移出。若是在执行该操做时队列已空, 那么将会阻塞直到元素出列,返回出列的tensors的tuple |
tf.QueueBase.dequeue_many(n, name=None) | 将一个或多个元素从队列中移出 |
tf.QueueBase.size(name=None) | 计算队列中的元素个数 |
tf.QueueBase.close (cancel_pending_enqueues=False, name=None) |
关闭该队列 |
f.QueueBase.dequeue_up_to(n, name=None) | 从该队列中移出n个元素并将之链接 |
tf.QueueBase.dtypes | 列出组成元素的数据类型 |
tf.QueueBase.from_list(index, queues) | 根据queues[index]的参考队列建立一个队列 |
tf.QueueBase.name | 返回最队列下面元素的名称 |
tf.QueueBase.names | 返回队列每个组成部分的名称 |
class tf.FIFOQueue | 在出列时依照先入先出顺序,其余方法与tf.QueueBase雷同 |
class tf.PaddingFIFOQueue | 一个FIFOQueue ,同时根据padding支持batching变长的tensor |
class tf.RandomShuffleQueue | 该队列将随机元素出列,其余方法与tf.QueueBase雷同 |
操做 | 描述 |
---|---|
tf.matching_files(pattern, name=None) | 返回与pattern匹配模式的文件名称 |
tf.read_file(filename, name=None) | 读取并输出输入文件的整个内容 |
用于设置输入预取数的管道TF函数,函数 “producer”添加一个队列至图中,同时一个相应用于运行队列中子图(subgraph)的QueueRunner
操做 | 描述 |
---|---|
tf.train.match_filenames_once(pattern, name=None) | 保存与pattern的文件列表 |
tf.train.limit_epochs(tensor, num_epochs=None, name=None) | 返回一个num_epochs次数,而后报告OutOfRange错误 |
tf.train.input_producer(input_tensor, element_shape=None, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, summary_name=None, name=None) |
为一个输入管道输出input_tensor中的多行至一个队列中 |
tf.train.range_input_producer(limit, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None) |
产生一个从1至limit-1的整数至队列中 |
tf.train.slice_input_producer(tensor_list, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None) |
对tensor_list中的每个tensor切片 |
tf.train.string_input_producer(string_tensor, num_epochs=None, shuffle=True, seed=None, capacity=32, shared_name=None, name=None) |
为一个输入管道输出一组字符串(好比文件名)至队列中 |
该相关函数增添一个队列至图中以将数据同样本打包为batch。它们也会添加 一个QueueRunner,以便执行的已经被填满队列的子图
操做 | 描述 |
---|---|
tf.train.batch(tensors, batch_size, num_threads=1, capacity=32, enqueue_many=False, shapes=None, dynamic_pad=False, allow_smaller_final_batch=False, shared_name=None, name=None) |
在输入的tensors中建立一些tensor数据格式的batch, 若输入为shape[*, x, y, z],那么输出则为[batch_size, x, y, z] 返回一个列表或者一个具备与输入tensors相同类型tensors的字典 |
tf.train.batch_join(tensors_list, batch_size, capacity=32, enqueue_many=False, shapes=None, dynamic_pad=False, allow_smaller_final_batch=False, shared_name=None, name=None) |
将一个tensors的列表添加至一个队列中以建立样本的batches len(tensors_list)个线程将启动, 线程i将tensors_list[i]的tensors入列 tensors_list[i1][j]与tensors_list[i2][j]有相同的类型和shape |
tf.train.shuffle_batch(tensors, batch_size, capacity, min_after_dequeue, num_threads=1, seed=None, enqueue_many=False, shapes=None, allow_smaller_final_batch=False, shared_name=None, name=None) |
使用随机乱序的方法建立batches tensors:用于入列的一个list或者dict capacity:一个整数,表示队列中元素最大数目 |
tf.train.shuffle_batch_join(tensors_list, batch_size, capacity, min_after_dequeue, seed=None, enqueue_many=False, shapes=None, allow_smaller_final_batch=False, shared_name=None, name=None) |
随机乱序的tensors建立batches, 其中tensors_list参数为tensors元组或tensors字典的列表 len(tensors_list)个线程将启动, 线程i将tensors_list[i]的tensors入列 tensors_list[i1][j]与tensors_list[i2][j]有相同的类型和shape |
# 一个简单例子,使用tf.train.shuffle_batch建立一个具备32张图像和32个标签的batches. image_batch, label_batch = tf.train.shuffle_batch( [single_image, single_label], batch_size=32, num_threads=4, capacity=50000, min_after_dequeue=10000)
#Batching函数相关例子,以函数tf.train.shuffle_batch为例 #为training, evaluation等操做将样本batching,如下代码使用随机顺序打包样本 def read_my_file_format(filename_queue): reader = tf.SomeReader() key, record_string = reader.read(filename_queue) example, label = tf.some_decoder(record_string) processed_example = some_processing(example) return processed_example, label def input_pipeline(filenames, batch_size, num_epochs=None): filename_queue = tf.train.string_input_producer( filenames, num_epochs=num_epochs, shuffle=True) example, label = read_my_file_format(filename_queue) # min_after_dequeue defines how big a buffer we will randomly sample # from -- bigger means better shuffling but slower start up and more # memory used. # capacity must be larger than min_after_dequeue and the amount larger # determines the maximum we will prefetch. Recommendation: # min_after_dequeue + (num_threads + a small safety margin) * batch_size min_after_dequeue = 10000 capacity = min_after_dequeue + 3 * batch_size example_batch, label_batch = tf.train.shuffle_batch( [example, label], batch_size=batch_size, capacity=capacity, min_after_dequeue=min_after_dequeue) return example_batch, label_batch
#若是须要跟多的并行或文件之间的样本乱序操做,可使用函数tf.train.shuffle_batch_join多实例化reader def read_my_file_format(filename_queue): # 与上例子相同 def input_pipeline(filenames, batch_size, read_threads, num_epochs=None): filename_queue = tf.train.string_input_producer( filenames, num_epochs=num_epochs, shuffle=True) example_list = [read_my_file_format(filename_queue) for _ in range(read_threads)] min_after_dequeue = 10000 capacity = min_after_dequeue + 3 * batch_size example_batch, label_batch = tf.train.shuffle_batch_join( example_list, batch_size=batch_size, capacity=capacity, min_after_dequeue=min_after_dequeue)
摘要:本系列主要对tf的一些经常使用概念与方法进行描述。本文主要针对tensorflow的数据IO、图的运行等相关函数进行讲解。为‘Tensorflow一些经常使用基本概念与函数’系列之三。
本文所讲的内容主要为如下相关函数:
操做组 | 操做 |
---|---|
Data IO (Python functions) | TFRecordWrite,rtf_record_iterator |
Running Graphs | Session management,Error classes |
一个TFRecords 文件为一个字符串序列。这种格式并不是随机获取,它比较适合大规模的数据流,而不太适合须要快速分区或其余非序列获取方式。
操做 | 描述 |
---|---|
class tf.python_io.TFRecordWriter | 一个用于将记录(records)写入TFRecords文件的类 |
tf.python_io.TFRecordWriter.__init__(path, options=None) | 打开文件路径,并建立一个TFRecordWriter以供写入 |
tf.python_io.TFRecordWriter.write(record) | 将一个字符串records写入文件中 |
tf.python_io.TFRecordWriter.close() | 关闭文件 |
tf.python_io.tf_record_iterator(path, options=None) | 从TFRecords文件中读取记录的迭代器 |
操做 | 描述 |
---|---|
class tf.Session | 运行TF操做的类, 一个Session对象将操做节点op封装在必定的环境内运行, 同时tensor对象将被计算求值 |
tf.Session.__init__(target=”, graph=None, config=None) | 建立一个新的会话 |
tf.Session.run(fetches, feed_dict=None, options=None, run_metadata=None) |
运行fetches中的操做节点并求其值 |
tf.Session.close() | 关闭会话 |
tf.Session.graph | 返回加载值该会话的图(graph) |
tf.Session.as_default() | 设置该对象为默认会话,并返回一个上下文管理器 |
tf.Session.reset(target, containers=None, config=None) | 重设target的资源容器,并关闭全部链接的会话 在0.10版本该功能仅应用在分布会话中 target:为执行引擎所链接的目标,其包含有资源容器, 该资源容器分布在同一个集群的全部works上 |
class tf.InteractiveSession | 使用在交互式上下文环境的tf会话,好比shell,ipython |
tf.InteractiveSession.close() | 关闭一个InteractiveSession |
tf.get_default_session() | 返回当前线程的默认会话 |
tf.Session
#一个简单的tf.Session例子 # 创建一个graph. a = tf.constant(5.0) b = tf.constant(6.0) c = a * b # 将graph载入到一个会话session中 sess = tf.Session() # 计算tensor `c`. print(sess.run(c))
#一个会话可能会占用一些资源,好比变量、队列和读取器(reader)。释放这些再也不使用的资源很是重要。 #使用close()方法关闭会话,或者使用上下文管理器,释放资源。 # 使用`close()`方法. sess = tf.Session() sess.run(...) sess.close() # 使用上下文管理器 with tf.Session() as sess: sess.run(...)
tf.Session()的变量设置, ConfigProto protocol buffer为会话提供了不一样的配置选项。好比,建立一个会话,对设备布局使用软约束条件,以及对分布
# Launch the graph in a session that allows soft device placement and # logs the placement decisions. sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True))
tf.Session.run
a = tf.constant([10, 20]) b = tf.constant([1.0, 2.0]) # 'fetches' 能够为单个数 v = session.run(a) # v is the numpy array [10, 20] # 'fetches' 能够为一个list. v = session.run([a, b]) # v a Python list with 2 numpy arrays: the numpy array [10, 20] and the # 1-D array [1.0, 2.0] # 'fetches' 能够是 lists, tuples, namedtuple, dicts中的任意: MyData = collections.namedtuple('MyData', ['a', 'b']) v = session.run({'k1': MyData(a, b), 'k2': [b, a]}) # v 为一个dict,并有 # v['k1'] is a MyData namedtuple with 'a' the numpy array [10, 20] and # 'b' the numpy array [1.0, 2.0] # v['k2'] is a list with the numpy array [1.0, 2.0] and the numpy array # [10, 20].
tf.Session.as_default()
使用关键字with指定会话, 能够在会话中执行Operation.run()或Tensor.eval(),以获得运行的tensor结果
c = tf.constant(..)
sess = tf.Session()
with sess.as_default(): assert tf.get_default_session() is sess print(c.eval())
使用函数tf.get_default_session()来获得当前默认的会话
须要注意的是,退出该as_default上下文管理器时,并无关闭该会话(session ),必须明确的关闭会话
c = tf.constant(...)
sess = tf.Session()
with sess.as_default(): print(c.eval()) # ... with sess.as_default(): print(c.eval()) #关闭会话 sess.close() #使用 with tf.Session()方式能够建立并自动关闭会话
tf.InteractiveSession
sess = tf.InteractiveSession()
a = tf.constant(5.0) b = tf.constant(6.0) c = a * b # 咱们直接使用'c.eval()' 而没有经过'sess' print(c.eval()) sess.close()
以上的例子,在非交互会话的版本中为,
a = tf.constant(5.0) b = tf.constant(6.0) c = a * b with tf.Session(): # We can also use 'c.eval()' here. print(c.eval())
操做 | 描述 |
---|---|
class tf.OpError | 一个基本的错误类型,在当TF执行失败时候报错 |
tf.OpError.op | 返回执行失败的操做节点, 有的操做如Send或Recv可能不会返回,那就要用用到node_def方法 |
tf.OpError.node_def | 以NodeDef proto形式表示失败的op |
tf.OpError.error_code | 描述该错误的整数错误代码 |
tf.OpError.message | 返回错误信息 |
class tf.errors.CancelledError | 当操做或者阶段呗取消时候报错 |
class tf.errors.UnknownError | 未知错误类型 |
class tf.errors.InvalidArgumentError | 在接收到非法参数时候报错 |
class tf.errors.NotFoundError | 当发现不存在所请求的一个实体时候,好比文件或目录 |
class tf.errors.AlreadyExistsError | 当建立的实体已经存在的时候报错 |
class tf.errors.PermissionDeniedError | 没有执行权限作某操做的时候报错 |
class tf.errors.ResourceExhaustedError | 资源耗尽时报错 |
class tf.errors.FailedPreconditionError | 系统没有条件执行某个行为时候报错 |
class tf.errors.AbortedError | 操做停止时报错,经常发生在并发情形 |
class tf.errors.OutOfRangeError | 超出范围报错 |
class tf.errors.UnimplementedError | 某个操做没有执行时报错 |
class tf.errors.InternalError | 当系统经历了一个内部错误时报出 |
class tf.errors.DataLossError | 当出现不可恢复的错误 例如在运行 tf.WholeFileReader.read()读取整个文件的同时文件被删减 |
tf.errors.XXXXX.__init__(node_def, op, message) | 使用该形式方法建立以上各类错误类 |
摘要:本系列主要对tf的一些经常使用概念与方法进行描述。本文主要针对tensorflow的模型训练Training与测试Testing等相关函数进行讲解。为‘Tensorflow一些经常使用基本概念与函数’系列之四。
本文所讲的内容主要为如下列表中相关函数。函数training()经过梯度降低法为最小化损失函数增长了相关的优化操做,在训练过程当中,先实例化一个优化函数,好比 tf.train.GradientDescentOptimizer,并基于必定的学习率进行梯度优化训练:
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
而后,能够设置 一个用于记录全局训练步骤的单值。以及使用minimize()操做,该操做不只能够优化更新训练的模型参数,也能够为全局步骤(global step)计数。与其余tensorflow操做相似,这些训练操做都须要在tf.session会话中进行
global_step = tf.Variable(0, name='global_step', trainable=False) train_op = optimizer.minimize(loss, global_step=global_step)
操做组 | 操做 |
---|---|
Training | Optimizers,Gradient Computation,Gradient Clipping,Distributed execution |
Testing | Unit tests,Utilities,Gradient checking |
一个TFRecords 文件为一个字符串序列。这种格式并不是随机获取,它比较适合大规模的数据流,而不太适合须要快速分区或其余非序列获取方式。
tf中各类优化类提供了为损失函数计算梯度的方法,其中包含比较经典的优化算法,好比GradientDescent 和Adagrad。
▶▶class tf.train.Optimizer
操做 | 描述 |
---|---|
class tf.train.Optimizer | 基本的优化类,该类不经常被直接调用,而较多使用其子类, 好比GradientDescentOptimizer, AdagradOptimizer 或者MomentumOptimizer |
tf.train.Optimizer.__init__(use_locking, name) | 建立一个新的优化器, 该优化器必须被其子类(subclasses)的构造函数调用 |
tf.train.Optimizer.minimize(loss, global_step=None, var_list=None, gate_gradients=1, aggregation_method=None, colocate_gradients_with_ops=False, name=None, grad_loss=None) |
添加操做节点,用于最小化loss,并更新var_list 该函数是简单的合并了compute_gradients()与apply_gradients()函数 返回为一个优化更新后的var_list,若是global_step非None,该操做还会为global_step作自增操做 |
tf.train.Optimizer.compute_gradients(loss,var_list=None, gate_gradients=1, aggregation_method=None, colocate_gradients_with_ops=False, grad_loss=None) |
对var_list中的变量计算loss的梯度 该函数为函数minimize()的第一部分,返回一个以元组(gradient, variable)组成的列表 |
tf.train.Optimizer.apply_gradients(grads_and_vars, global_step=None, name=None) | 将计算出的梯度应用到变量上,是函数minimize()的第二部分,返回一个应用指定的梯度的操做Operation,对global_step作自增操做 |
tf.train.Optimizer.get_name() | 获取名称 |
▷ class tf.train.Optimizer
用法
# Create an optimizer with the desired parameters. opt = GradientDescentOptimizer(learning_rate=0.1) # Add Ops to the graph to minimize a cost by updating a list of variables. # "cost" is a Tensor, and the list of variables contains tf.Variable objects. opt_op = opt.minimize(cost, var_list=<list of variables>) # Execute opt_op to do one step of training: opt_op.run()
▶▶在使用它们以前处理梯度
使用minimize()操做,该操做不只能够计算出梯度,并且还能够将梯度做用在变量上。若是想在使用它们以前处理梯度,能够按照如下三步骤使用optimizer :
一、使用函数compute_gradients()计算梯度 二、按照本身的愿望处理梯度 三、使用函数apply_gradients()应用处理事后的梯度
例如:
# 建立一个optimizer. opt = GradientDescentOptimizer(learning_rate=0.1) # 计算<list of variables>相关的梯度 grads_and_vars = opt.compute_gradients(loss, <list of variables>) # grads_and_vars为tuples (gradient, variable)组成的列表。 #对梯度进行想要的处理,好比cap处理 capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars] # 令optimizer运用capped的梯度(gradients) opt.apply_gradients(capped_grads_and_vars)
▶▶选通梯度(Gating Gradients)
函数minimize() 与compute_gradients()都含有一个参数gate_gradient,用于控制在应用这些梯度时并行化的程度。
其值能够取:GATE_NONE, GATE_OP 或 GATE_GRAPH
GATE_NONE : 并行地计算和应用梯度。提供最大化的并行执行,可是会致使有的数据结果没有再现性。好比两个matmul操做的梯度依赖输入值,使用GATE_NONE可能会出现有一个梯度在其余梯度以前便应用到某个输入中,致使出现不可再现的(non-reproducible)结果
GATE_OP: 对于每一个操做Op,确保每个梯度在使用以前都已经计算完成。这种作法防止了那些具备多个输入,而且梯度计算依赖输入情形中,多输入Ops之间的竞争状况出现。
GATE_GRAPH: 确保全部的变量对应的全部梯度在他们任何一个被使用前计算完成。该方式具备最低级别的并行化程度,可是对于想要在应用它们任何一个以前处理完全部的梯度计算时颇有帮助的。
一些optimizer的之类,好比 MomentumOptimizer 和 AdagradOptimizer 分配和管理着额外的用于训练的变量。这些变量称之为’Slots’,Slots有相应的名称,能够向optimizer访问的slots名称。有助于在log debug一个训练算法以及报告slots状态
操做 | 描述 |
---|---|
tf.train.Optimizer.get_slot_names() | 返回一个由Optimizer所建立的slots的名称列表 |
tf.train.Optimizer.get_slot(var, name) | 返回一个name所对应的slot,name是由Optimizer为var所建立 var为用于传入 minimize() 或 apply_gradients()的变量 |
class tf.train.GradientDescentOptimizer | 使用梯度降低算法的Optimizer |
tf.train.GradientDescentOptimizer.__init__(learning_rate, use_locking=False, name=’GradientDescent’) |
构建一个新的梯度降低优化器(Optimizer) |
class tf.train.AdadeltaOptimizer | 使用Adadelta算法的Optimizer |
tf.train.AdadeltaOptimizer.__init__(learning_rate=0.001, rho=0.95, epsilon=1e-08, use_locking=False, name=’Adadelta’) |
建立Adadelta优化器 |
class tf.train.AdagradOptimizer | 使用Adagrad算法的Optimizer |
tf.train.AdagradOptimizer.__init__(learning_rate, initial_accumulator_value=0.1, use_locking=False, name=’Adagrad’) |
建立Adagrad优化器 |
class tf.train.MomentumOptimizer | 使用Momentum算法的Optimizer |
tf.train.MomentumOptimizer.__init__(learning_rate, momentum, use_locking=False, name=’Momentum’, use_nesterov=False) |
建立momentum优化器 momentum:动量,一个tensor或者浮点值 |
class tf.train.AdamOptimizer | 使用Adam 算法的Optimizer |
tf.train.AdamOptimizer.__init__(learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08, use_locking=False, name=’Adam’) |
建立Adam优化器 |
class tf.train.FtrlOptimizer | 使用FTRL 算法的Optimizer |
tf.train.FtrlOptimizer.__init__(learning_rate, learning_rate_power=-0.5, initial_accumulator_value=0.1, l1_regularization_strength=0.0, l2_regularization_strength=0.0, use_locking=False, name=’Ftrl’) |
建立FTRL算法优化器 |
class tf.train.RMSPropOptimizer | 使用RMSProp算法的Optimizer |
tf.train.RMSPropOptimizer.__init__(learning_rate, decay=0.9, momentum=0.0, epsilon=1e-10, use_locking=False, name=’RMSProp’) |
建立RMSProp算法优化器 |
▷ tf.train.AdamOptimizer
Adam 的基本运行方式,首先初始化:
m_0 <- 0 (Initialize initial 1st moment vector) v_0 <- 0 (Initialize initial 2nd moment vector) t <- 0 (Initialize timestep)
在论文中的 section2 的末尾所描述了更新规则,该规则使用梯度g来更新变量:
t <- t + 1 lr_t <- learning_rate * sqrt(1 - beta2^t) / (1 - beta1^t) m_t <- beta1 * m_{t-1} + (1 - beta1) * g v_t <- beta2 * v_{t-1} + (1 - beta2) * g * g variable <- variable - lr_t * m_t / (sqrt(v_t) + epsilon)
其中epsilon 的默认值1e-8可能对于大多数状况都不是一个合适的值。例如,当在ImageNet上训练一个 Inception network时比较好的选择为1.0或者0.1。
须要注意的是,在稠密数据中即使g为0时, m_t, v_t 以及variable都将会更新。而在稀疏数据中,m_t, v_t 以及variable不被更新且值为零。
TensorFlow 提供了计算给定tf计算图的求导函数,并在图的基础上增长节点。优化器(optimizer )类能够自动的计算网络图的导数,可是优化器中的建立器(creators )或者专业的人员能够经过本节所述的函数调用更底层的方法。
操做 | 描述 |
---|---|
tf.gradients(ys, xs, grad_ys=None, name=’gradients’, colocate_gradients_with_ops=False, gate_gradients=False, aggregation_method=None) |
构建一个符号函数,计算ys关于xs中x的偏导的和, 返回xs中每一个x对应的sum(dy/dx) |
tf.stop_gradient(input, name=None) | 中止计算梯度, 在EM算法、Boltzmann机等可能会使用到 |
tf.clip_by_value(t, clip_value_min, clip_value_max, name=None) | 基于定义的min与max对tesor数据进行截断操做, 目的是为了应对梯度爆发或者梯度消失的状况 |
tf.clip_by_norm(t, clip_norm, axes=None, name=None) | 使用L2范式标准化tensor最大值为clip_norm 返回 t * clip_norm / l2norm(t) |
tf.clip_by_average_norm(t, clip_norm, name=None) | 使用平均L2范式规范tensor数据t, 并以clip_norm为最大值 返回 t * clip_norm / l2norm_avg(t) |
tf.clip_by_global_norm(t_list, clip_norm, use_norm=None, name=None) |
返回t_list[i] * clip_norm / max(global_norm, clip_norm) 其中global_norm = sqrt(sum([l2norm(t)**2 for t in t_list])) |
tf.global_norm(t_list, name=None) | 返回global_norm = sqrt(sum([l2norm(t)**2 for t in t_list])) |
操做 | 描述 |
---|---|
tf.train.exponential_decay(learning_rate, global_step, decay_steps, decay_rate, staircase=False, name=None) |
对学习率进行指数衰退 |
▷ tf.train.exponential_decay
#该函数返回如下结果 decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps) ##例: 以0.96为基数,每100000 步进行一次学习率的衰退 global_step = tf.Variable(0, trainable=False) starter_learning_rate = 0.1 learning_rate = tf.train.exponential_decay(starter_learning_rate, global_step, 100000, 0.96, staircase=True) # Passing global_step to minimize() will increment it at each step. learning_step = ( tf.train.GradientDescentOptimizer(learning_rate) .minimize(...my loss..., global_step=global_step) )
一些训练优化算法,好比GradientDescent 和Momentum 在优化过程当中即可以使用到移动平均方法。使用移动平均经常能够较明显地改善结果。
操做 | 描述 |
---|---|
class tf.train.ExponentialMovingAverage | 将指数衰退加入到移动平均中 |
tf.train.ExponentialMovingAverage.apply(var_list=None) | 对var_list变量保持移动平均 |
tf.train.ExponentialMovingAverage.average_name(var) | 返回var均值的变量名称 |
tf.train.ExponentialMovingAverage.average(var) | 返回var均值变量 |
tf.train.ExponentialMovingAverage.variables_to_restore(moving_avg_variables=None) | 返回用于保存的变量名称的映射 |
▷ tf.train.ExponentialMovingAverage
# Example usage when creating a training model: # Create variables. var0 = tf.Variable(...) var1 = tf.Variable(...) # ... use the variables to build a training model... ... # Create an op that applies the optimizer. This is what we usually # would use as a training op. opt_op = opt.minimize(my_loss, [var0, var1]) # Create an ExponentialMovingAverage object ema = tf.train.ExponentialMovingAverage(decay=0.9999) # Create the shadow variables, and add ops to maintain moving averages # of var0 and var1. maintain_averages_op = ema.apply([var0, var1]) # Create an op that will update the moving averages after each training # step. This is what we will use in place of the usual training op. with tf.control_dependencies([opt_op]): training_op = tf.group(maintain_averages_op) ...train the model by running training_op... #Example of restoring the shadow variable values: # Create a Saver that loads variables from their saved shadow values. shadow_var0_name = ema.average_name(var0) shadow_var1_name = ema.average_name(var1) saver = tf.train.Saver({shadow_var0_name: var0, shadow_var1_name: var1}) saver.restore(...checkpoint filename...) # var0 and var1 now hold the moving average values
▷ tf.train.ExponentialMovingAverage.variables_to_restore
variables_to_restore = ema.variables_to_restore() saver = tf.train.Saver(variables_to_restore)
查看queue中,queue相关的内容,了解tensorflow中队列的运行方式。
操做 | 描述 |
---|---|
class tf.train.Coordinator | 线程的协调器 |
tf.train.Coordinator.clear_stop() | 清除中止标记 |
tf.train.Coordinator.join(threads=None, stop_grace_period_secs=120) | 等待线程终止 threads:一个threading.Threads的列表,启动的线程,将额外加入到registered的线程中 |
tf.train.Coordinator.register_thread(thread) | Register一个用于join的线程 |
tf.train.Coordinator.request_stop(ex=None) | 请求线程结束 |
tf.train.Coordinator.should_stop() | 检查是否被请求中止 |
tf.train.Coordinator.stop_on_exception() | 上下文管理器,当一个例外出现时请求中止 |
tf.train.Coordinator.wait_for_stop(timeout=None) | 等待Coordinator提示中止进程 |
class tf.train.QueueRunner | 持有一个队列的入列操做列表,用于线程中运行 queue:一个队列 enqueue_ops: 用于线程中运行的入列操做列表 |
tf.train.QueueRunner.create_threads(sess, coord=None, daemon=False, start=False) |
建立运行入列操做的线程,返回一个线程列表 |
tf.train.QueueRunner.from_proto(queue_runner_def) | 返回由queue_runner_def建立的QueueRunner对象 |
tf.train.add_queue_runner(qr, collection=’queue_runners’) | 增长一个QueueRunner到graph的收集器(collection )中 |
tf.train.start_queue_runners(sess=None, coord=None, daemon=True, start=True, collection=’queue_runners’) | 启动全部graph收集到的队列运行器(queue runners) |
▷ class tf.train.Coordinator
#Coordinator的使用,用于多线程的协调 try: ... coord = Coordinator() # Start a number of threads, passing the coordinator to each of them. ...start thread 1...(coord, ...) ...start thread N...(coord, ...) # Wait for all the threads to terminate, give them 10s grace period coord.join(threads, stop_grace_period_secs=10) except RuntimeException: ...one of the threads took more than 10s to stop after request_stop() ...was called. except Exception: ...exception that was passed to coord.request_stop()
▷ tf.train.Coordinator.stop_on_exception()
with coord.stop_on_exception(): # Any exception raised in the body of the with # clause is reported to the coordinator before terminating # the execution of the body. ...body... #等价于 try: ...body... exception Exception as ex: coord.request_stop(ex)
能够阅读TensorFlow的分布式学习框架简介 查看更多tensorflow分布式细节。
操做 | 描述 |
---|---|
class tf.train.Server | 一个进程内的tensorflow服务,用于分布式训练 |
tf.train.Server.init(server_or_cluster_def, job_name=None, task_index=None, protocol=None, config=None, start=True) |
建立一个新的服务,其中job_name, task_index, 和protocol为可选参数, 优先级高于server_or_cluster_def中相关信息 server_or_cluster_def : 为一个tf.train.ServerDef 或 tf.train.ClusterDef 协议(protocol)的buffer, 或者一个tf.train.ClusterSpec对象 |
tf.train.Server.create_local_server(config=None, start=True) | 建立一个新的运行在本地主机的单进程集群 |
tf.train.Server.target | 返回tf.Session所链接的目标服务器 |
tf.train.Server.server_def | 返回该服务的tf.train.ServerDef |
tf.train.Server.start() | 开启服务 |
tf.train.Server.join() | 阻塞直到服务已经关闭 |
# | |
---|---|
class tf.train.Supervisor | 一个训练辅助器,用于checkpoints模型以及计算的summaries。该监视器只是一个小的外壳(wrapper),用于Coordinator, a Saver, 和a SessionManager周围 |
tf.train.Supervisor.__init__(graph=None, ready_op=0, is_chief=True, init_op=0, init_feed_dict=None, local_init_op=0, logdir=None, summary_op=0, saver=0, global_step=0, save_summaries_secs=120, save_model_secs=600, recovery_wait_secs=30, stop_grace_secs=120, checkpoint_basename=’model.ckpt’, session_manager=None, summary_writer=0, init_fn=None) |
建立一个监视器Supervisor |
tf.train.Supervisor.managed_session(master=”, config=None, start_standard_services=True, close_summary_writer=True) | 返回一个管路session的上下文管理器 |
tf.train.Supervisor.prepare_or_wait_for_session(master=”, config=None, wait_for_checkpoint=False, max_wait_secs=7200, start_standard_services=True) | 确保model已经准备好 |
tf.train.Supervisor.start_standard_services(sess) | 为sess启动一个标准的服务 |
tf.train.Supervisor.start_queue_runners(sess, queue_runners=None) | 为QueueRunners启动一个线程,queue_runners为一个QueueRunners列表 |
tf.train.Supervisor.summary_computed(sess, summary, global_step=None) | 指示计算的summary |
tf.train.Supervisor.stop(threads=None, close_summary_writer=True) | 中止服务以及协调器(coordinator),并无关闭session |
tf.train.Supervisor.request_stop(ex=None) | 参考Coordinator.request_stop() |
tf.train.Supervisor.should_stop() | 参考Coordinator.should_stop() |
tf.train.Supervisor.stop_on_exception() | 参考 Coordinator.stop_on_exception() |
tf.train.Supervisor.Loop(timer_interval_secs, target, args=None, kwargs=None) | 开启一个循环器线程用于调用一个函数 每通过timer_interval_secs秒执行,target(*args, **kwargs) |
tf.train.Supervisor.coord | 返回监督器(Supervisor)使用的协调器(Coordinator ) |
# | |
---|---|
class tf.train.SessionManager | 训练的辅助器,用于从checkpoint恢复数据以及建立一个session |
tf.train.SessionManager.__init__(local_init_op=None, ready_op=None, graph=None, recovery_wait_secs=30) | 建立一个SessionManager |
tf.train.SessionManager.prepare_session(master, init_op=None, saver=None, checkpoint_dir=None, wait_for_checkpoint=False, max_wait_secs=7200, config=None, init_feed_dict=None, init_fn=None) | 建立一个session,并确保model能够被使用 |
tf.train.SessionManager.recover_session(master, saver=None, checkpoint_dir=None, wait_for_checkpoint=False, max_wait_secs=7200, config=None) | 建立一个session,若是能够的话,使用恢复方法建立 |
tf.train.SessionManager.wait_for_session(master, config=None, max_wait_secs=inf) | 建立一个session,并等待model准备完成 |
# | |
---|---|
class tf.train.ClusterSpec | 将一个集群表示为一系列“tasks”,并整合至“jobs”中 |
tf.train.ClusterSpec.as_cluster_def() | 返回该cluster中一个tf.train.ClusterDef协议的buffer |
tf.train.ClusterSpec.as_dict() | 返回一个字典,由job名称对应于网络地址 |
tf.train.ClusterSpec.job_tasks(job_name) | 返回一个给定的job对应的task列表 |
tf.train.ClusterSpec.jobs | 返回该cluster的job名称列表 |
tf.train.replica_device_setter(ps_tasks=0, ps_device=’/job:ps’, worker_device=’/job:worker’, merge_devices=True, cluster=None, ps_ops=None) | 返回一个设备函数(device function),以在创建一个副本graph的时候使用,设备函数(device function)用在with tf.device(device_function)中 |
▷ tf.train.Server
server = tf.train.Server(...)
with tf.Session(server.target): # ...
▷ tf.train.Supervisor
相关参数:
ready_op : 一维 字符串 tensor。该tensor是用过监视器在prepare_or_wait_for_session()计算,检查model是否准备好可使用。若是准备好,将返回一个空阵列,若是为None,该model没有被检查。
is_chief : 若是为True,建立一个主监视器用于负责初始化与模型的恢复,若为False,则依赖主监视器。
init_op : 一个操做,用于模型不能恢复时的初始化操做。默认初始化全部操做
local_init_op : 可被全部监视器运行的初始化操做。
logdir : 设置log目录
summary_op : 一个操做(Operation ),返回Summary 和事件logs,须要设置 logdir
saver : 一个Saver对象
save_summaries_secs : 保存summaries的间隔秒数
save_model_secs : 保存model的间隔秒数
checkpoint_basename : checkpoint保存的基本名称
with tf.Graph().as_default(): ...add operations to the graph... # Create a Supervisor that will checkpoint the model in '/tmp/mydir'. sv = Supervisor(logdir='/tmp/mydir') # Get a TensorFlow session managed by the supervisor. with sv.managed_session(FLAGS.master) as sess: # Use the session to train the graph. while not sv.should_stop(): sess.run(<my_train_op>) # 在上下文管理器with sv.managed_session()内,全部在graph的变量都被初始化。 # 或者说,一些服务器checkpoint相应模型并增长summaries至事件log中。 # 若是有例外发生,should_stop()将返回True
# Choose a task as the chief. This could be based on server_def.task_index, # or job_def.name, or job_def.tasks. It's entirely up to the end user. # But there can be only one *chief*. is_chief = (server_def.task_index == 0) server = tf.train.Server(server_def) with tf.Graph().as_default(): ...add operations to the graph... # Create a Supervisor that uses log directory on a shared file system. # Indicate if you are the 'chief' sv = Supervisor(logdir='/shared_directory/...', is_chief=is_chief) # Get a Session in a TensorFlow server on the cluster. with sv.managed_session(server.target) as sess: # Use the session to train the graph. while not sv.should_stop(): sess.run(<my_train_op>)
若是有task崩溃或重启,managed_session() 将检查是否Model被初始化。若是已经初始化,它只须要建立一个session并将其返回至正在训练的正常代码中。若是model须要被初始化,主task将对它进行从新初始化,而其余task将等待模型初始化完成。
注意:该程序方法同样适用于单进程的work,该单进程标注本身为主要的便行
▷ supervisor中master的字符串形式
不管运行在本机或者集群上,均可以使用如下值设定master flag:
▷ supervisor高级用法
#例如: 开启一个线程用于打印loss. 设置每60秒该线程运行一次,咱们使用sv.loop() ... sv = Supervisor(logdir='/tmp/mydir') with sv.managed_session(FLAGS.master) as sess: sv.loop(60, print_loss, (sess)) while not sv.should_stop(): sess.run(my_train_op)
在chief中每100个step,建立summaries # Create a Supervisor with no automatic summaries. sv = Supervisor(logdir='/tmp/mydir', is_chief=is_chief, summary_op=None) # As summary_op was None, managed_session() does not start the # summary thread. with sv.managed_session(FLAGS.master) as sess: for step in xrange(1000000): if sv.should_stop(): break if is_chief and step % 100 == 0: # Create the summary every 100 chief steps. sv.summary_computed(sess, sess.run(my_summary_op)) else: # Train normally sess.run(my_train_op)
▷ tf.train.Supervisor.managed_session
def train(): sv = tf.train.Supervisor(...) with sv.managed_session(<master>) as sess: for step in xrange(..): if sv.should_stop(): break sess.run(<my training op>) ...do other things needed at each training step...
▷ tf.train.SessionManager
with tf.Graph().as_default(): ...add operations to the graph... # Create a SessionManager that will checkpoint the model in '/tmp/mydir'. sm = SessionManager() sess = sm.prepare_session(master, init_op, saver, checkpoint_dir) # Use the session to train the graph. while True: sess.run(<my_train_op>) #其中prepare_session()初始化和恢复一个模型参数。 #另外一个进程将等待model准备完成,代码以下 with tf.Graph().as_default(): ...add operations to the graph... # Create a SessionManager that will wait for the model to become ready. sm = SessionManager() sess = sm.wait_for_session(master) # Use the session to train the graph. while True: sess.run(<my_train_op>) #wait_for_session()等待一个model被其余进程初始化
▷ tf.train.ClusterSpec
一个tf.train.ClusterSpec表示一系列的进程,这些进程都参与分布式tensorflow的计算。每个 tf.train.Server都在一个独有的集群中构建。
建立一个具备两个jobs及其5个tasks的集群们须要定义从job名称列表到网络地址列表之间的映射。
cluster = tf.train.ClusterSpec({"worker": ["worker0.example.com:2222", "worker1.example.com:2222", "worker2.example.com:2222"], "ps": ["ps0.example.com:2222", "ps1.example.com:2222"]})
▷ tf.train.replica_device_setter
# To build a cluster with two ps jobs on hosts ps0 and ps1, and 3 worker # jobs on hosts worker0, worker1 and worker2. cluster_spec = { "ps": ["ps0:2222", "ps1:2222"], "worker": ["worker0:2222", "worker1:2222", "worker2:2222"]} with tf.device(tf.replica_device_setter(cluster=cluster_spec)): # Build your graph v1 = tf.Variable(...) # assigned to /job:ps/task:0 v2 = tf.Variable(...) # assigned to /job:ps/task:1 v3 = tf.Variable(...) # assigned to /job:ps/task:0 # Run compute
咱们能够在一个session中获取summary操做的输出,并将其传输到SummaryWriter以添加至一个事件记录文件中。
操做 | 描述 |
---|---|
tf.scalar_summary(tags, values, collections=None, name=None) | 输出一个标量值的summary协议buffer tag的shape须要与values的相同,用来作summaries的tags,为字符串 |
tf.image_summary(tag, tensor, max_images=3, collections=None, name=None) | 输出一个图像tensor的summary协议buffer |
tf.audio_summary(tag, tensor, sample_rate, max_outputs=3, collections=None, name=None) | 输出一个音频tensor的summary协议buffer |
tf.histogram_summary(tag, values, collections=None, name=None) | 输出一个直方图的summary协议buffer |
tf.nn.zero_fraction(value, name=None) | 返回0在value中的小数比例 |
tf.merge_summary(inputs, collections=None, name=None) | 合并summary |
tf.merge_all_summaries(key=’summaries’) | 合并在默认graph中手机的summaries |
▶▶将记录汇总写入文件中(Adding Summaries to Event Files)
操做 | 描述 |
---|---|
class tf.train.SummaryWriter | 将summary协议buffer写入事件文件中 |
tf.train.SummaryWriter.__init__(logdir, graph=None, max_queue=10, flush_secs=120, graph_def=None) | 建立一个SummaryWriter实例以及新建一个事件文件 |
tf.train.SummaryWriter.add_summary(summary, global_step=None) | 将一个summary添加到事件文件中 |
tf.train.SummaryWriter.add_session_log(session_log, global_step=None) | 添加SessionLog到一个事件文件中 |
tf.train.SummaryWriter.add_event(event) | 添加一个事件到事件文件中 |
tf.train.SummaryWriter.add_graph(graph, global_step=None, graph_def=None) | 添加一个Graph到时间文件中 |
tf.train.SummaryWriter.add_run_metadata(run_metadata, tag, global_step=None) | 为一个单一的session.run()调用添加一个元数据信息 |
tf.train.SummaryWriter.flush() | 刷新时间文件到硬盘中 |
tf.train.SummaryWriter.close() | 将事件问价写入硬盘中并关闭该文件 |
tf.train.summary_iterator(path) | 一个用于从时间文件中读取时间协议buffer的迭代器 |
▷ tf.train.SummaryWriter
建立一个SummaryWriter 和事件文件。若是咱们传递一个Graph进入该构建器中,它将被添加到事件文件当中,这一点与使用add_graph()具备相同功能。
TensorBoard 将从事件文件中提取该graph,并将其显示。因此咱们能直观地看到咱们创建的graph。咱们一般从咱们启动的session中传递graph:
...create a graph...
# Launch the graph in a session. sess = tf.Session() # Create a summary writer, add the 'graph' to the event file. writer = tf.train.SummaryWriter(<some-directory>, sess.graph)
▷ tf.train.summary_iterator
#打印时间文件中的内容 for e in tf.train.summary_iterator(path to events file): print(e) #打印指定的summary值 # This example supposes that the events file contains summaries with a # summary value tag 'loss'. These could have been added by calling # `add_summary()`, passing the output of a scalar summary op created with # with: `tf.scalar_summary(['loss'], loss_tensor)`. for e in tf.train.summary_iterator(path to events file): for v in e.summary.value: if v.tag == 'loss': print(v.simple_value)
操做 | 描述 |
---|---|
tf.train.global_step(sess, global_step_tensor) | 一个用于获取全局step的小辅助器 |
tf.train.write_graph(graph_def, logdir, name, as_text=True) | 将一个graph proto写入一个文件中 |
# | |
:— | |
class tf.train.LooperThread | 可重复地执行代码的线程 |
tf.train.LooperThread.init(coord, timer_interval_secs, target=None, args=None, kwargs=None) | 建立一个LooperThread |
tf.train.LooperThread.is_alive() | 返回是否该线程是活跃的 |
tf.train.LooperThread.join(timeout=None) | 等待线程结束 |
tf.train.LooperThread.loop(coord, timer_interval_secs, target, args=None, kwargs=None) | 启动一个LooperThread,用于周期地调用某个函数 调用函数target(args) |
tf.py_func(func, inp, Tout, stateful=True, name=None) | 将python函数包装成tf中操做节点 |
▷ tf.train.global_step
# Creates a variable to hold the global_step. global_step_tensor = tf.Variable(10, trainable=False, name='global_step') # Creates a session. sess = tf.Session() # Initializes the variable. sess.run(global_step_tensor.initializer) print('global_step: %s' % tf.train.global_step(sess, global_step_tensor)) global_step: 10
▷ tf.train.write_graph
v = tf.Variable(0, name='my_variable') sess = tf.Session() tf.train.write_graph(sess.graph_def, '/tmp/my-model', 'train.pbtxt')
▷ tf.py_func
#tf.py_func(func, inp, Tout, stateful=True, name=None) #func:为一个python函数 #inp:为输入函数的参数,Tensor列表 #Tout: 指定func返回的输出的数据类型,是一个列表 def my_func(x): # x will be a numpy array with the contents of the placeholder below return np.sinh(x) inp = tf.placeholder(tf.float32, [...]) y = py_func(my_func, [inp], [tf.float32])
TensorFlow 提供了一个方便的继承unittest.TestCase类的方法,该类增长有关TensorFlow 测试的方法。以下例子:
import tensorflow as tf class SquareTest(tf.test.TestCase): def testSquare(self): with self.test_session(): x = tf.square([2, 3]) self.assertAllEqual(x.eval(), [4, 9]) if __name__ == '__main__': tf.test.main()
操做 | 描述 |
---|---|
tf.test.main() | 运行全部的单元测试 |
tf.test.assert_equal_graph_def(actual, expected) | 断言 两个GraphDefs 是否几乎同样 |
tf.test.get_temp_dir() | 返回测试期间使用的临时目录 |
tf.test.is_built_with_cuda() | 返回是否Tensorflow支持CUDA(GPU)的build |
可对比compute_gradient 和compute_gradient_error函数的用法
操做 | 描述 |
---|---|
tf.test.compute_gradient(x, x_shape, y, y_shape, x_init_value=None, delta=0.001, init_targets=None) | 计算并返回理论的和数值的Jacobian矩阵 |
tf.test.compute_gradient_error(x, x_shape, y, y_shape, x_init_value=None, delta=0.001, init_targets=None) | 计算梯度的error。在计算所得的与数值估计的Jacobian中 为dy/dx计算最大的error |
注:本教程不是原创 转自http://blog.csdn.net/lenbow/article/details/52218551
感谢做者 的总结 与付出
1 #一个简单的tf.Session例子 2 # 创建一个graph. 3 a = tf.constant(5.0) 4 b = tf.constant(6.0) 5 c = a * b 6 7 # 将graph载入到一个会话session中 8 sess = tf.Session() 9 10 # 计算tensor `c`. 11 print(sess.run(c))#一个会话可能会占用一些资源,好比变量、队列和读取器(reader)。释放这些再也不使用的资源很是重要。 12 #使用close()方法关闭会话,或者使用上下文管理器,释放资源。 13 # 使用`close()`方法. 14 sess = tf.Session() 15 sess.run(...) 16 sess.close() 17 18 # 使用上下文管理器 19 with tf.Session() as sess: 20 sess.run(...)# Launch the graph in a session that allows soft device placement and 21 # logs the placement decisions. 22 sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True, 23 log_device_placement=True))a = tf.constant([10, 20]) 24 b = tf.constant([1.0, 2.0]) 25 # 'fetches' 能够为单个数 26 v = session.run(a) 27 # v is the numpy array [10, 20] 28 # 'fetches' 能够为一个list. 29 v = session.run([a, b]) 30 # v a Python list with 2 numpy arrays: the numpy array [10, 20] and the 31 # 1-D array [1.0, 2.0] 32 # 'fetches' 能够是 lists, tuples, namedtuple, dicts中的任意: 33 MyData = collections.namedtuple('MyData', ['a', 'b']) 34 v = session.run({'k1': MyData(a, b), 'k2': [b, a]}) 35 # v 为一个dict,并有 36 # v['k1'] is a MyData namedtuple with 'a' the numpy array [10, 20] and 37 # 'b' the numpy array [1.0, 2.0] 38 # v['k2'] is a list with the numpy array [1.0, 2.0] and the numpy array 39 # [10, 20].c = tf.constant(..) 40 sess = tf.Session() 41 42 with sess.as_default(): 43 assert tf.get_default_session() is sess 44 print(c.eval())c = tf.constant(...) 45 sess = tf.Session() 46 with sess.as_default(): 47 print(c.eval()) 48 # ... 49 with sess.as_default(): 50 print(c.eval()) 51 #关闭会话 52 sess.close() 53 #使用 with tf.Session()方式能够建立并自动关闭会话sess = tf.InteractiveSession() 54 a = tf.constant(5.0) 55 b = tf.constant(6.0) 56 c = a * b 57 # 咱们直接使用'c.eval()' 而没有经过'sess' 58 print(c.eval()) 59 sess.close()a = tf.constant(5.0) 60 b = tf.constant(6.0) 61 c = a * b 62 with tf.Session(): 63 # We can also use 'c.eval()' here. 64 print(c.eval())optimizer = tf.train.GradientDescentOptimizer(learning_rate)global_step = tf.Variable(0, name='global_step', trainable=False) 65 train_op = optimizer.minimize(loss, global_step=global_step)# Create an optimizer with the desired parameters. 66 opt = GradientDescentOptimizer(learning_rate=0.1) 67 # Add Ops to the graph to minimize a cost by updating a list of variables. 68 # "cost" is a Tensor, and the list of variables contains tf.Variable objects. 69 opt_op = opt.minimize(cost, var_list=<list of variables>) 70 # Execute opt_op to do one step of training: 71 opt_op.run()1、使用函数compute_gradients()计算梯度 72 2、按照本身的愿望处理梯度 73 三、使用函数apply_gradients()应用处理事后的梯度# 建立一个optimizer. 74 opt = GradientDescentOptimizer(learning_rate=0.1) 75 76 # 计算<list of variables>相关的梯度 77 grads_and_vars = opt.compute_gradients(loss, <list of variables>) 78 79 # grads_and_vars为tuples (gradient, variable)组成的列表。 80 #对梯度进行想要的处理,好比cap处理 81 capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars] 82 83 # 令optimizer运用capped的梯度(gradients) 84 opt.apply_gradients(capped_grads_and_vars)m_0 <- 0 (Initialize initial 1st moment vector) 85 v_0 <- 0 (Initialize initial 2nd moment vector) 86 t <- 0 (Initialize timestep)t <- t + 1 87 lr_t <- learning_rate * sqrt(1 - beta2^t) / (1 - beta1^t) 88 89 m_t <- beta1 * m_{t-1} + (1 - beta1) * g 90 v_t <- beta2 * v_{t-1} + (1 - beta2) * g * g 91 variable <- variable - lr_t * m_t / (sqrt(v_t) + epsilon)#该函数返回如下结果 92 decayed_learning_rate = learning_rate * 93 decay_rate ^ (global_step / decay_steps) 94 ##例: 以0.96为基数,每100000 步进行一次学习率的衰退 95 global_step = tf.Variable(0, trainable=False) 96 starter_learning_rate = 0.1 97 learning_rate = tf.train.exponential_decay(starter_learning_rate, global_step, 98 100000, 0.96, staircase=True) 99 # Passing global_step to minimize() will increment it at each step. 100 learning_step = ( 101 tf.train.GradientDescentOptimizer(learning_rate) 102 .minimize(...my loss..., global_step=global_step) 103 )# Example usage when creating a training model: 104 # Create variables. 105 var0 = tf.Variable(...) 106 var1 = tf.Variable(...) 107 # ... use the variables to build a training model... 108 ... 109 # Create an op that applies the optimizer. This is what we usually 110 # would use as a training op. 111 opt_op = opt.minimize(my_loss, [var0, var1]) 112 113 # Create an ExponentialMovingAverage object 114 ema = tf.train.ExponentialMovingAverage(decay=0.9999) 115 116 # Create the shadow variables, and add ops to maintain moving averages 117 # of var0 and var1. 118 maintain_averages_op = ema.apply([var0, var1]) 119 120 # Create an op that will update the moving averages after each training 121 # step. This is what we will use in place of the usual training op. 122 with tf.control_dependencies([opt_op]): 123 training_op = tf.group(maintain_averages_op) 124 125 ...train the model by running training_op... 126 127 #Example of restoring the shadow variable values: 128 # Create a Saver that loads variables from their saved shadow values. 129 shadow_var0_name = ema.average_name(var0) 130 shadow_var1_name = ema.average_name(var1) 131 saver = tf.train.Saver({shadow_var0_name: var0, shadow_var1_name: var1}) 132 saver.restore(...checkpoint filename...) 133 # var0 and var1 now hold the moving average valuesvariables_to_restore = ema.variables_to_restore() 134 saver = tf.train.Saver(variables_to_restore)#Coordinator的使用,用于多线程的协调 135 try: 136 ... 137 coord = Coordinator() 138 # Start a number of threads, passing the coordinator to each of them. 139 ...start thread 1...(coord, ...) 140 ...start thread N...(coord, ...) 141 # Wait for all the threads to terminate, give them 10s grace period 142 coord.join(threads, stop_grace_period_secs=10) 143 except RuntimeException: 144 ...one of the threads took more than 10s to stop after request_stop() 145 ...was called. 146 except Exception: 147 ...exception that was passed to coord.request_stop()with coord.stop_on_exception(): 148 # Any exception raised in the body of the with 149 # clause is reported to the coordinator before terminating 150 # the execution of the body. 151 ...body... 152 #等价于 153 try: 154 ...body... 155 exception Exception as ex: 156 coord.request_stop(ex)server = tf.train.Server(...) 157 with tf.Session(server.target): 158 # ...with tf.Graph().as_default(): 159 ...add operations to the graph... 160 # Create a Supervisor that will checkpoint the model in '/tmp/mydir'. 161 sv = Supervisor(logdir='/tmp/mydir') 162 # Get a TensorFlow session managed by the supervisor. 163 with sv.managed_session(FLAGS.master) as sess: 164 # Use the session to train the graph. 165 while not sv.should_stop(): 166 sess.run(<my_train_op>) 167 # 在上下文管理器with sv.managed_session()内,全部在graph的变量都被初始化。 168 # 或者说,一些服务器checkpoint相应模型并增长summaries至事件log中。 169 # 若是有例外发生,should_stop()将返回True# Choose a task as the chief. This could be based on server_def.task_index, 170 # or job_def.name, or job_def.tasks. It's entirely up to the end user. 171 # But there can be only one *chief*. 172 is_chief = (server_def.task_index == 0) 173 server = tf.train.Server(server_def) 174 175 with tf.Graph().as_default(): 176 ...add operations to the graph... 177 # Create a Supervisor that uses log directory on a shared file system. 178 # Indicate if you are the 'chief' 179 sv = Supervisor(logdir='/shared_directory/...', is_chief=is_chief) 180 # Get a Session in a TensorFlow server on the cluster. 181 with sv.managed_session(server.target) as sess: 182 # Use the session to train the graph. 183 while not sv.should_stop(): 184 sess.run(<my_train_op>)#例如: 开启一个线程用于打印loss. 设置每60秒该线程运行一次,咱们使用sv.loop() 185 ... 186 sv = Supervisor(logdir='/tmp/mydir') 187 with sv.managed_session(FLAGS.master) as sess: 188 sv.loop(60, print_loss, (sess)) 189 while not sv.should_stop(): 190 sess.run(my_train_op)在chief中每100个step,建立summaries 191 # Create a Supervisor with no automatic summaries. 192 sv = Supervisor(logdir='/tmp/mydir', is_chief=is_chief, summary_op=None) 193 # As summary_op was None, managed_session() does not start the 194 # summary thread. 195 with sv.managed_session(FLAGS.master) as sess: 196 for step in xrange(1000000): 197 if sv.should_stop(): 198 break 199 if is_chief and step % 100 == 0: 200 # Create the summary every 100 chief steps. 201 sv.summary_computed(sess, sess.run(my_summary_op)) 202 else: 203 # Train normally 204 sess.run(my_train_op)def train(): 205 sv = tf.train.Supervisor(...) 206 with sv.managed_session(<master>) as sess: 207 for step in xrange(..): 208 if sv.should_stop(): 209 break 210 sess.run(<my training op>) 211 ...do other things needed at each training step...with tf.Graph().as_default(): 212 ...add operations to the graph... 213 # Create a SessionManager that will checkpoint the model in '/tmp/mydir'. 214 sm = SessionManager() 215 sess = sm.prepare_session(master, init_op, saver, checkpoint_dir) 216 # Use the session to train the graph. 217 while True: 218 sess.run(<my_train_op>) 219 #其中prepare_session()初始化和恢复一个模型参数。 220 221 #另外一个进程将等待model准备完成,代码以下 222 with tf.Graph().as_default(): 223 ...add operations to the graph... 224 # Create a SessionManager that will wait for the model to become ready. 225 sm = SessionManager() 226 sess = sm.wait_for_session(master) 227 # Use the session to train the graph. 228 while True: 229 sess.run(<my_train_op>) 230 #wait_for_session()等待一个model被其余进程初始化cluster = tf.train.ClusterSpec({"worker": ["worker0.example.com:2222", 231 "worker1.example.com:2222", 232 "worker2.example.com:2222"], 233 "ps": ["ps0.example.com:2222", 234 "ps1.example.com:2222"]})# To build a cluster with two ps jobs on hosts ps0 and ps1, and 3 worker 235 # jobs on hosts worker0, worker1 and worker2. 236 cluster_spec = { 237 "ps": ["ps0:2222", "ps1:2222"], 238 "worker": ["worker0:2222", "worker1:2222", "worker2:2222"]} 239 with tf.device(tf.replica_device_setter(cluster=cluster_spec)): 240 # Build your graph 241 v1 = tf.Variable(...) # assigned to /job:ps/task:0 242 v2 = tf.Variable(...) # assigned to /job:ps/task:1 243 v3 = tf.Variable(...) # assigned to /job:ps/task:0 244 # Run compute...create a graph... 245 # Launch the graph in a session. 246 sess = tf.Session() 247 # Create a summary writer, add the 'graph' to the event file. 248 writer = tf.train.SummaryWriter(<some-directory>, sess.graph)#打印时间文件中的内容 249 for e in tf.train.summary_iterator(path to events file): 250 print(e) 251 252 #打印指定的summary值 253 # This example supposes that the events file contains summaries with a 254 # summary value tag 'loss'. These could have been added by calling 255 # `add_summary()`, passing the output of a scalar summary op created with 256 # with: `tf.scalar_summary(['loss'], loss_tensor)`. 257 for e in tf.train.summary_iterator(path to events file): 258 for v in e.summary.value: 259 if v.tag == 'loss': 260 print(v.simple_value)# Creates a variable to hold the global_step. 261 global_step_tensor = tf.Variable(10, trainable=False, name='global_step') 262 # Creates a session. 263 sess = tf.Session() 264 # Initializes the variable. 265 sess.run(global_step_tensor.initializer) 266 print('global_step: %s' % tf.train.global_step(sess, global_step_tensor)) 267 268 global_step: 10v = tf.Variable(0, name='my_variable') 269 sess = tf.Session() 270 tf.train.write_graph(sess.graph_def, '/tmp/my-model', 'train.pbtxt')#tf.py_func(func, inp, Tout, stateful=True, name=None) 271 #func:为一个python函数 272 #inp:为输入函数的参数,Tensor列表 273 #Tout: 指定func返回的输出的数据类型,是一个列表 274 def my_func(x): 275 # x will be a numpy array with the contents of the placeholder below 276 return np.sinh(x) 277 inp = tf.placeholder(tf.float32, [...]) 278 y = py_func(my_func, [inp], [tf.float32])import tensorflow as tf 279 280 281 class SquareTest(tf.test.TestCase): 282 283 def testSquare(self): 284 with self.test_session(): 285 x = tf.square([2, 3]) 286 self.assertAllEqual(x.eval(), [4, 9]) 287 288 289 if __name__ == '__main__': 290 tf.test.main()