记录TensorFlow学习中的参考文档

TensorFlow学习参考的文档

记录自己在学习TensorFlow过程中参考过的部分博客和文档,对部分问题也会记录自己的理解。

  1. https://github.com/brightmart/text_classification
    对文本分类常用算法的实现,代码清晰,注释完整,贼酷!

首先要了解TensorFlow的基本概念。tensor可以理解为一种数据,TensorFlow就相当于一个数据的流动过程,所有能用图(graph)来表示的计算任务理论上都能用TensorFlow 来实现。有图就有节点和边的概念,其中节点是一种操作(如加减乘除)被称为operation简称op,一个节点可以连接很多边,而边上传递的数据就是tensor。为了能够实现一个计算流程就需要一个graph来表示这个流程,而为了能够执行这个图就需要一个会话(Session)来启动这个图,这个过程相当于graph是画好的一张图,然后我用一个Session来执行这个图。
由上面的过程就可以知道,想要实现一个计算就需要先画好一张图(graph),然后就是需要一个会话(Session)来启动这个图,然后通过Session的run()方法来计算图中需要计算的的值。最后就是对计算得到的值进行一些评估(这个比较复杂)。

过程就是:建图->启动图->运行取值

  1. TensorFlow学习笔记——节点(constant、placeholder、Variable)

  2. TensorFlow中的get_variable()

  3. Tensorflow中tf.train.exponential_decay函数(指数衰减法)

  4. Tensorflow之神经网络nn模块详解

  5. NCE-loss:Tensorflow 的NCE-Loss的实现和word2vec

def nce_loss(weights, #[num_classes, embed_size]
             biases,  #[num_classes]
             inputs,  #[vocab_size, embed_size]
             labels,  #[vocab_size, num_true]
             num_sampled, num_classes, num_true=1,
             sampled_values=None,
             remove_accidental_hits=False,
             partition_strategy="mod",
             name="nce_loss")

个人理解:对input中的每个词,选择对应的标签构成正样本对,再随机选择num_sampled个标签与该词构成负样本对。对每个单词对,在weights和biases中找到对应标签的w和b,用逻辑回归进行二分类,每个分类问题计算交叉熵

  1. tensorflow中的交叉熵:TensorFlow交叉熵函数(cross_entropy)·理解

可以看这个博客里的代码例子。

对于tf.nn.sigmoid_cross_entropy_with_logits,计算过程如下:

def sigmoid(x):
    return 1.0/(1+np.exp(-x))
# 2个样本三分类问题,且一个样本可以同时拥有多类
y = np.array([[1,0,0],[0,1,1]])
logits = np.array([[12,3,2.2],[3,6.4,1.1]])
# 按计算公式计算
y_pred = sigmoid(logits)
E1 = -y*np.log(y_pred)-(1-y)*np.log(1-y_pred)
print(E1)     # 按计算公式计算的结果
# 按封装方法计算
sess =tf.Session()
y = np.array(y).astype(np.float64) # labels是float64的数据类型,注意这一行!!!
E2 = sess.run(tf.nn.sigmoid_cross_entropy_with_logits(labels=y,logits=logits))
print(E2)     # 按 tf 封装方法计算

输出如下:

[[6.14419348e-06 3.04858735e+00 2.30508332e+00]
 [3.04858735e+00 1.66017841e-03 2.87335325e-01]]
[[6.14419348e-06 3.04858735e+00 2.30508332e+00]
 [3.04858735e+00 1.66017841e-03 2.87335325e-01]]

由代码和结果可以看到函数对每个位置都计算了交叉熵,通常用来做多目标分类下的损失函数。当用sigmoid_cross_entropy_with_logits做损失函数时,对同一个样本的多个交叉熵求和,对多个样本求均值,即

loss = tf.nn.sigmoid_cross_entropy_with_logits(y, logits) #注意两个参数的dtype和shape要一致
loss = tf.reduce_mean(tf.reduce_sum(loss, axis=1))
  1. 深度学习——优化器算法Optimizer详解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

  2. 【Tensorflow】tf.app.run()与命令行参数解析

  3. tf.contrib.layers.optimize_loss

optimize_loss用来优化网络参数。

这个相当于连续应用下面几个步骤:

  • compute_gradients: 根据对应的参数,计算每个参数的梯度

  • do sth with gradients: 对每个参数采取一定的操作,例如clip这个梯度,防止梯度爆炸

  • apply_gradients: 对每个参数应用梯度更新

  1. TensorFlow中正则化和标准化:tf.nn.l2_loss和 tf.nn.l2_normalize

正则化是在损失函数中增加对某个变量(张量)的L1或L2正则项,使得在优化损失函数时,会在原来的损失与正则项做权衡,防止过拟合,提高模型的泛化能力。

标准化(normalization)是对变量按照给定规则将数据缩放,使之落入一个小的特定区间。如线性归一化等,能加快模型收敛、提升模型精度

L2 regularizer :使得模型的解偏向于范数较小的 W,通过限制 W 范数的大小实现了对模型空间的限制,从而在一定程度上避免了 overfitting 。不过 ridge regression 并不具有产生稀疏解的能力,得到的系数仍然需要数据中的所有特征才能计算预测结果,从计算量上来说并没有得到改观。

L1 regularizer :它的优良性质是能产生稀疏性,导致 W 中许多项变成零。 稀疏的解除了计算量上的好处之外,更重要的是更具有“可解释性”。

L1会趋向于产生少量的特征,而其他的特征都是0,而L2会选择更多的特征,这些特征都会接近于0。Lasso在特征选择时候非常有用,而Ridge就只是一种规则化而已。在所有特征中只有少数特征起重要作用的情况下,选择Lasso比较合适,因为它能自动选择特征。而如果所有特征中,大部分特征都能起作用,而且起的作用很平均,那么使用Ridge也许更合适。

  1. name_scope:[TensorFlow基础笔记(13) tf.name_scope tf.variable_scope学习]
  2. tf.nn.conv2d:【TensorFlow】理解tf.nn.conv2d方法 ( 附代码详解注释 )

tf.nn.conv2d (input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

参数
input : 输入的要做卷积的图片,要求为一个张量,shape为 [ batch, in_height, in_weight, in_channel ],其中batch为图片的数量,in_height 为图片高度,in_weight 为图片宽度,in_channel 为图片的通道数,灰度图该值为1,彩色图为3

filter: 卷积核,要求也是一个张量,shape为 [ filter_height, filter_weight, in_channel, out_channels ],其中 filter_height 为卷积核高度,filter_weight 为卷积核宽度,in_channel 是图像通道数 ,和 input 的 in_channel 要保持一致,out_channel 是卷积核数量

strides: 卷积时在图像每一维的步长,这是一个一维的向量,[ 1, strides, strides, 1],第一位和最后一位固定必须是1

padding: string类型,值为“SAME” 和 “VALID”,表示的是卷积的形式,是否考虑边界。"SAME"是考虑边界,不足的时候用0去填充周围,"VALID"则不考虑

Return: 返回一个shape为 [batch, out_height, out_weight, out_channels] 的张量,具体执行的操作为,对batch个shape为 [in_height, in_weight] 的输入,使用out_channels个shape为 [filter_height, filter_weight]的卷积核进行卷积

  1. BN层,batch normalization层:

[1] 为什么会出现Batch Normalization层

[2] 深度学习中 Batch Normalization为什么效果好

  • 为什么会出现BN层?

神经网络模型训练时间长的一个原因是,数据分布的不断变化(每批数据分布可能不同、某一层数据分布不同而被累积传递)。在学习过程我们要使每一层适应输入的分布,因此必须降低学习率。这种由于训练导致数据分布发生变化,称之为 internal covariate shift。

为了解决这个问题,Google在论文中提出通过batch normalization,对每一层的输入规范化,使得均值为0,方差为1,即使得数据分布更加稳定,从而保持学习率,加快训练速度。

  • 深层次原因?

实际上,使用BN层work的原因在于防止了梯度弥散/爆炸,即在反向传播过程中系数的累乘可能导致的梯度极大或极小。BN层通过对输入规范化,使得反向传播过程中的梯度更新稳定。

  • 什么时候使用?

当神经网络收敛速度慢或发生梯度爆炸时,可以尝试BN;

一般情况下可以使用BN层加快训练速度;

google在论文中说放在激活层前效果好,也有论文说在激活层后效果好。在CNN中一般放在卷积层后激活层前。

  1. tf.nn.dropout(),官方文档如下:
Signature: tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None)
Docstring: Computes dropout.

对每个元素按照keep_prob概率选择,若选中,则返回原来的值乘上`1/keep_prob`,否则为0,例子如下:

a = tf.Variable([1,2,3,4,5], dtype=tf.float32,name='1')
b = tf.nn.dropout(a,keep_prob=0.5)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(b))

output:[0. 4. 6. 8. 0.]
  1. tf.layers.dense(),官方文档如下:
Signature: tf.layers.dense(inputs, units, activation=None, use_bias=True, kernel_initializer=None, bias_initializer=<tensorflow.python.ops.init_ops.Zeros object at 0x0000027931A2B710>,...)
Docstring:
Functional interface for the densely-connected layer.(全连接层)

实现操作为: `outputs = activation(inputs.dot(kernel) + bias)`
Where `activation` is the activation function passed as the `activation`
argument (if not `None`), `kernel` is a weights matrix created by the layer,
and `bias` is a bias vector created by the layer
(only if `use_bias` is `True`)

增加模型的非线性表达能力,增加模型复杂度,提高模型的学习能力;

通常在CNN的尾部进行重新拟合,减少特征信息的损失。

一篇关于卷积层和全连接的博客,举了很形象的例子:深入理解卷积层,全连接层的作用意义

  1. tf.contrib.rnn.BasicLSTMCell:tensorflow学习之BasicLSTMCell详解
__init__(
    num_units, #LSTM单元中的神经元数量,即输出神经元数量,h维度
    forget_bias=1.0, #偏置增加了忘记门。从训练的检查点(checkpoint)恢复时,必须手动设置为0.0
    state_is_tuple=True, #如果为True,则接受和返回的状态是c_state和m_state的2-tuple;如果为                               False,则他们沿着列轴连接。后一种即将被弃用。
    activation=None, #激活函数,默认为tanh
    reuse=None,
    name=None,
    dtype=None )
  1. DropoutWrapper:tensorflow教程:tf.contrib.rnn.DropoutWrapper

从官方文档中看到,它有input_keep_prob和output_keep_prob,也就是说裹上这个DropoutWrapper之后,如果我希望是input传入这个cell时dropout掉一部分input信息的话,就设置input_keep_prob,那么传入到cell的就是部分input;如果我希望这个cell的output只部分作为下一层cell的input的话,就定义output_keep_prob。

备注:Dropout只能是层与层之间(输入层与LSTM1层、LSTM1层与LSTM2层)的Dropout;同一个层里面,T时刻与T+1时刻是不会Dropout的。

  1. tf.nn.dynamic_rnn:tf.nn.dynamic_rnn的详解 TensorFlow笔记:dynamic_rnn

inputs :是一个tensor,如果time_major== False(默认),则张量的形状必须是:[batch_size,max_time,embed_size]

返回的是一个元组 (outputs, state)

outputs:RNN的最后一层的输出,是一个tensor。如果为time_major== False,则shape为[batch_size,max_time,cell.output_size]。

state: RNN最后时间步的state,如果cell.state_size是一个整数(一般是单层的RNNCell),则state的shape:[batch_size,cell.state_size]。如果它是一个元组(一般这里是 多层的RNNCell),那么它将是一个具有相应形状的元组。注意:如果若RNNCell是 LSTMCells,则state将为每层cell的LSTMStateTuple的元组Tuple(LSTMStateTuple,LSTMStateTuple,LSTMStateTuple)。

注意这里的加粗字体,最后一层指的是输出包括每个时间步的RNN最后一层的结果 h h ,如句子中最大长度max_time为10,则对每个句子应该循环10次(10个时间步),对应地,每个句子有10个输出。而state是最后时间步所有层的记忆单元 c c 和隐层输出 h h ,维度由RNN的层数决定。

猜你喜欢

转载自blog.csdn.net/qq_36153312/article/details/87896720