人工智能A7论坛 >> Tensorflow和深度学习笔记_论坛版 >> 3.Tensorflow第一步

3.3 Demo代码涉及到的深度学习基本知识

1)one-hot 编码

中文翻译成“独热编码”。 直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。

 

2)激活函数

定义

    一个函数  h : R → ,且几乎处处可导( differentiable almost everywhere)

有什么用?

激活函数的主要作用是提供网络的非线性建模能力。如果没有激活函数,那么该网络仅能够表达线性映射,此时即便有再多的隐藏层,其整个网络跟单层神经网络也是等价的。因此也可以认为,只有加入了激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。 

 

应该具有什么样的性质呢?

 

非线性 当激活函数是非线性的时候,一个两层的神经网络就可以逼近基本上所有的函数了。但是,如果激活函数是恒等激活函数的时候(f(x)=x),就不满足这个性质了,而且如果MLP使用的是恒等激活函数,那么其实整个网络跟单层神经网络是等价的。

 

可微性: 当优化方法是基于梯度的时候,这个性质是必须的。

 

单调性: 当激活函数是单调的时候,单层网络能够保证是凸函数。

 

f(x)x 当激活函数满足这个性质的时候,如果参数的初始化是random的很小的值,那么神经网络的训练将会很高效;如果不满足这个性质,那么就需要很用心的去设置初始值。

 

输出值的范围 当激活函数输出值是 有限 的时候,基于梯度的优化方法会更加 稳定,因为特征的表示受有限权值的影响更显著;   当激活函数的输出是 无限 的时候,模型的训练会更加高效,不过在这种情况小,一般需要更小的learning rate.

 

这些性质,也正是我们使用激活函数的原因!

 

什么是好的激活函数?

单侧抑制,宽兴奋边界,稀疏激活性。

备注:什么是稀疏激活性?-------  Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。

 

其他因素

导数值的最大值不能太小(最好是1),避免梯度弥散和爆炸

Ii 便于求导

 

    最常用的激活函数有 ReLu( rrectifier Linear Unit ,简称rectifier函数或者ReLu) 和 logistic 函数(有的文献中也叫 sigmoid函数,不用过多区分)。但是事实上 激活函数类型非常多

Sigmoid函数(logistic函数)

可以看到,这个函数可以基于自身的值来表示导数,这给神经网络的BP训练过程带来很大的方便。

Tanh函数(双曲正切S形函数)

ReLu函数:

导数很简单。

Softplus函数:

Softplus函数是ReLu的平滑版本,导数刚好是logisticSoftplus函数虽然也有单侧抑制宽兴奋边界的特性,但是没有稀疏激活性。(这句话暗示我们,好的激活函数应该具有这三大特性)

其他:补充两个函数

饱和线性函数 Ramp

 

符号函数  sgn

 

 

 

什么是激活函数的饱和性?

(参考文献:https://arxiv.org/pdf/1603.00391.pdf)

     一个激活函数h(x)被认为是右饱和(right saturate)的,如果 

反之  如果  则称h(x)为左饱和。当一个激活函数,既满足左饱和又满足又饱和时,我们称之为饱和

     sigmoid tanh 两个函数都是饱和函数,而Relu不是饱和函数,只是左饱和函数。

 

    对任意的x,如果存在常数c,当x > c时恒有 h(x) = 0则称其为右硬饱和,当x < c时恒 有h(x)=0则称其为左硬饱和。若既满足左硬饱和,又满足右硬饱和,则称这种激活函数为硬饱和。但如果只有在极限状态下偏导数等于0的函数,称之为软饱和。可以看出,ReLu不光是左饱和,而且是左硬饱和函数

     ReLU在x<0的部分是硬饱和的,所以随着训练推进,部分输入可能会落到硬饱和区,导致权重无法更新,出现“神经元死亡”。

 

怎么选择激活函数?

 

这种问题没有定论。不过经验是除了gate之类的地方,需要把输出限制成0-1之外,尽量不要用sigmoid,可以用tanh或者relu之类的激活函数”。

使用 ReLU,一定要小心设置 learning rate,而且要注意不要让你的网络出现很多 “dead” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLUPReLU 或者 Maxout.

 

3) softmax VS LR

其实softmax对于多分类用的非常广泛,并不局限于神经网络。像LDA中也有用到。

softmax

  SVM只选自己喜欢的男神,Softmax把所有备胎全部拉出来评分,最后还归一化一下

为什么要取指数:

     第一个原因是要模拟max的行为,所以要让大的更大;第二个原因是需要一个可导的函数。

对于一个二分类问题,softmax蜕化成LR 

证明过程参考 http://ufldl.stanford.edu/wiki/index.php/Softmax%E5%9B%9E%E5%BD%92 

 

4Why cross entropy loss?

   交叉熵

 

是我们预测的概率分布, y' 是实际的分布(我们输入的one-hot vector)。比较粗糙的理解是,交叉熵是用来衡量我们的预测用于描述真相的低效性。

具体原理是什么?为什么交叉熵最小时得到的模型是最佳的模型?我们通过附录10.110.2已经讲清楚了。请参考。

 

5Epoches

为什么需要多个epoch  直接告诉我最佳答案不行吗?

    时间成本和训练效果的一个balance。用户自己指定epoch,并为最终效果负责。。    

一个epoch发生了什么,下一个epoch会怎样。为什么通常下一个epoch比当前epoch效果更好

    因为在前一轮epoch训练得到的模型基础上  还是拿以前的训练样本重新过一遍网络

 

6)最优化方法有哪些

SGDAdagradAdadeltaAdamAdamaxNadamMomentumRMSprop

SGD

    随机梯度下降。现在的SGD一般都指mini-batch gradient descent

Adagrad

      自适应地为各个参数分配不同学习率的算法

Adadelta

      Adagrad的扩展

Momentum

      momentum即动量,它模拟的是物体运动时的惯性

RMSprop

  一个神奇的方法, Geoff Hinton coursera课程里讲到但是并没有公开发表过论文的一种方法。自适应学习率。可以算作Adadelta的一个特例

Adam

      Adaptive Moment Estimation。本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。

Adamax

      AdamaxAdam的一种变体

Nadam

      Nadam类似于带有Nesterov动量项的Adam

各种方法的收敛速度和路径的比较(用浏览器看动图)

 

sgd收敛速度会慢一些,但是最终收敛后的结果,一般都比较好。

更多了解,参考:http://sebastianruder.com/optimizing-gradient-descent/

 

Tensorflow中的实现:tf.train.Optimizer

Optimizer基类提供了基于损失计算梯度并将梯度应用于变量的方法。不需要产生Optimizer 类的实例,直接产生它的子类的实例就行。

tf.train.GradientDescentOptimizer

tf.train.AdadeltaOptimizer

tf.train.AdagradOptimizer

tf.train.AdagradDAOptimizer

tf.train.MomentumOptimizer

tf.train.AdamOptimizer

tf.train.FtrlOptimizer

tf.train.ProximalGradientDescentOptimizer

tf.train.ProximalAdagradOptimizer

tf.train.RMSPropOptimizer

参考:https://www.tensorflow.org/api_guides/python/train#Optimizers

 

 

7)batch的大小对学习效果有何影响

Batch_Size 这个参数是干嘛的:

Batch_size 的选择,决定的是下降的方向。

如果Batch_Size 等于 Full Batch 

全数据集  Full Batch Learning )的形式,有 个好处:

其一,由全数据集确定的方向能够更好地代表样本总体,从而更准确地朝向极值所在的方向。

其二,由于不同权重的梯度值差别巨大,因此选取一个全局的学习率很困难。

 

如果Batch_Size = 1 

这就是在线学习(Online Learning)。线性神经元在均方误差代价函数的错误面是一个抛物面,横截面是椭圆。对于多层神经元、非线性网络,在局部依然近似是抛物面。使用在线学习,每次修正方向以各自样本的梯度方向修正,横冲直撞各自为政,难以达到收敛。

 

怎样选择一个适中的 Batch_Size 值?

     批梯度下降法(Mini-batches Learning)。因为如果数据集足够充分,那么用一半(甚至少得多)的数据训练算出来的梯度与用全部数据训练出来的梯度是几乎一样的。

 

增大 Batch_Size 有何好处?

① 内存利用率提高了,大矩阵乘法的并行化效率提高。

② 跑完一次 epoch(全数据集)所需的迭代次数减少,对于相同数据量的处理速度进一步加快。

③ 在一定范围内,一般来说 Batch_Size 越大,其确定的下降方向越准,引起训练震荡越小。

 

盲目增大 Batch_Size 有何坏处?

④ 内存利用率提高了,但是内存容量可能撑不住了。

⑤ 跑完一次 epoch(全数据集)所需的迭代次数减少,要想达到相同的精度,其所花费的时间大大增加了,从而对参数的修正也就显得更加缓慢。

⑥ Batch_Size 增大到一定程度,其确定的下降方向已经基本不再变化。

 

    好了 说了这么多  然而并没有什么卵用。我们常说 深度学习是一门实验科学,需要大量动手实验、多调调参,练出手感,捷径无它。

 

参考:https://www.zhihu.com/question/32673260