本站消息

站长简介/公众号


站长简介:逗比程序员,理工宅男,前每日优鲜python全栈开发工程师,利用周末时间开发出本站,欢迎关注我的微信公众号:幽默盒子,一个专注于搞笑,分享快乐的公众号

  价值13000svip视频教程,python大神匠心打造,零基础python开发工程师视频教程全套,基础+进阶+项目实战,包含课件和源码

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2020-10(74)

2020-11(25)

深度学习(一):深度学习基础知识

发布于2019-08-20 10:45     阅读(594)     评论(0)     点赞(15)     收藏(3)



随着数据(越来越多的数据集,数据收集和存储越来越容易),软件(tensorflow等),硬件(GPU等)的发展,深度学习受到越来越多的人的青睐。

深度学习有多个不同的算法,这些算法大都由神经网络构成,神经网络又是由一个一个神经元构成。神经网络详细介绍可以参考这篇文章:神经网络浅讲:从神经元到深度学习。下面我们对深度学习的一些基础知识点进行一下介绍。

前向传播:

图1描述的是感知机的前向传播。感知机的具体讲解可以参考机器学习系列第一篇文章:机器学习(一):机器学习基础知识及感知机(perceptron)

图1. 感知机的前向传播

在图中,从最左边看,第一列是输入的数据(input),我们一共有m个特征(feature),x_{1},x_{2}...x_{m}。第二列是每个特征的权重(weight),w_{i}x_{i}的权重,其中w_{0}是1的权重,它一般称为偏置(bias)。第三列是对所有的权重与特征相乘的结果求和。第四列是将求和的结果放入一个非线性函数g,进行运算。第五列即可以得到最终的输出(output)\hat{y}。整个过程用公式可以表示成图\hat{y}=g(w_0+\sum_{i=1}^{m}{x_i w_i})。如果用线性代数中的向量形式表示则可以表示成第二个公式。其中大写的X是一个向量,它表示x_{1},x_{2}...x_{m},大写的W也是一个向量,它表示w_{1},w_{2}...w_{m}

激活函数

上图中非线性函数(non-linear function)g又叫激活函数(activation function)或激励函数。常用的激活函数有以下几种,见图2:

sigmoid的输出范围为[0,1],曲线类似于字母s,这也是它名字的由来。它的一阶导数的输出范围为[0,0.25]。

tanh的输出范围[-1,1],它的一阶导数的输出范围是[0,1].

relu函数是如果x比0小,则输出为0,x比0大,则输出原值。它是一个分段函数, 在x小于0时,它的一阶导数是0,大于0时,一阶导数是1。

对于这几个函数的优缺点及什么时候选择哪个函数大家可以去google或者baidu。或者参考常用激活函数(激励函数)理解与总结。激活函数的求导过程参考激活函数求导过程

图2. 常用激活函数

引入这些激活函数的目的就是引入非线性。 因为在现实生活中的大部分的数据都是非线性的,如果让我们用一条线(即线性)去进行数据的划分,那么无论神经网络多么强大,无论有多少层,无论有多少神经元,我们都很难进行一些数据的划分(得到较好的结果)。如果我们引入非线性函数,那么我们就能产生很复杂的函数,在特征空间中得到很复杂的决策边界,这是为什么神经网络为什么这么强大的原因,见图3。

图3. 为什么要引入激活函数

针对感知机的前向传播计算,我们举个例子说明一下,如图4。 模型为\hat{y}=g(1+ 3x_{1} - 2x_{2})g是sigmoid函数。 如果来了一个数据(-1,2),代入模型,计算过程及结果如图左下所示。

在这个例子中,我们的数据只有2维,所以可以用一个2维坐标将图画出来,但是实际中我们碰到的输入数据可能是十几维几百维,就不方便用图来直观地展示了。

图4. 感知机例子

上面是只有一个输出节点的感知机,我们也可以构建有多个输出的感知机。

图5. 多输出感知机

 

我们还可以将第一层感知机的输出作为下一层感知机的输入,形成一个三层的网络,见图6,这是一个含有一个隐藏层的神经网络。最左边为输入层,最右边为输出层,中间的层叫隐藏层,因为输入和输出层的数据我们都可以显示的看到,所以中间的叫做隐藏层,这样的隐藏层可以有多层,每一层的神经元个数也可以不一样。

由于每一层都是多个感知机,都是去拟合一个函数,当把多层复合起来,则会形成一个链式结构, 类似f_x=f_1(f_2(f_3(x)))))。如下图含有一层隐藏层的输出可以表示为:\hat{y_1}=g(w_{02}}+\sum_{j=1}^{d}{(g(w_{01} + \sum_{i=1}^{}m}{x_iw_{1i}}}})) w_{j2}})

图6 一个隐藏层的神经网络

如果网络中每一个节点(神经元neuron)都和其他相邻层的节点相连,则叫做全连接(full connect)神经网络,用图7中的符号表示

图7. 全连接层神经网络

我们可以建立很多这样的层(layer),形成深度神经网络,图8。

图8. 深度神经网络

 

损失函数

当我们建立好一个神经网络,输入数据,就能得到一个输出。但是这个输出不一定是正确的。图9中f(x)是模型预测的输出,y是真实的输出。

损失函数(loss function)是指预测的输出和实际的数据之间的差别。

实际生活中x可能有很多个样本时,比如我们根据一个学生两门作业的成绩来预测他是否能顺利通过这门课,X的每一行表示一个学生的成绩。如第一行是第一个学生的两门作业成绩(4,5),第二行是第二个学生的两门作业成绩(2,1)等等。在计算损失函数的时候是计算所有学生的loss的平均值,而不是一个学生的loss值。

当loss很小时,说明预测的结果和实际的结果相差很小,模型效果不错;当loss很大时,说明预测的结果和实际的结果相差很大,模型的效果不好。

图9. 损失函数

 

损失函数有很多种,主要分为针对分类问题的损失函数和回归问题的损失函数,另外一些不同的机器学习算法也都有自己对应的损失函数。损失函数的具体介绍请见:常用损失函数回归损失函数

梯度下降

有了损失函数之后,为了达到好的效果,我们希望loss能最小。而损失函数是W的函数,W表示所有的weights,w_{1},w_{2}...w_{m}。假如我们有两个weights,w_{0},w_{1}, 则可以画出一个三维loss图像,其中x,y轴表示w_{0},w_{1},z轴表示loss。如图10所示。

当我们随机初始化weights的时候,w_{0},w_{1}会有一个初始值,假设位于图中最上面的“×”处。这时,计算损失函数对权重的梯度\frac{\partial J(W))}{\partial W}, 它的方向应该是向上的,我们取梯度的负数,使它的方向向下,以一定的学习速率(learning rate)前进一小步,到达第二个“×”处,然后再计算第二点的梯度,继续下降,直至到达最低点。这个过程叫做梯度下降。详细步骤见图11,其中\eta是指学习速率。

那梯度是什么?为什么要用梯度?梯度的函数是:gradf(w_{0},w_{1}, \cdots,w_n )=(\frac{\partial f}{\partial w_0},\cdots,\frac{\partial f}{\partial w_j},\frac{\partial f}{\partial w_n})。 它是由多元变量对各个方向的偏导数形成,是一个向量,有大小有方向。梯度的方向是函数值增加最快的方向。梯度的详细解释可以参考梯度与梯度下降法梯度的方向为什么是函数值增加最快的方向

在层次比较深的神经网络中可能会出现梯度消失(gradient vanishing)或者梯度爆炸(gradient exploding) 问题。

图10. loss图像及梯度下降

 

 

图11 梯度下降

 

反向传播

当我们算出梯度后\frac{\partial J(W))}{\partial W},就可以通过W\leftarrow W-\eta \frac{\partial J(W)}{W}对权重进行更新,使函数对数据的拟合越来越好,从而使得loss越来越小。由于前向传播函数是一个嵌套函数,而梯度的本质是求导数,所以可以采用链式法则求导。

如图12中,计算J(W)后,先求J(W)\hat{y}的导数,再求\hat{y}z_{1}的导数,最后求z_{1}w_{1}的导数,即可得到\frac{\partial J(W))}{\partial w_1} ,然后通过w_1\leftarrow w_1-\eta \frac{\partial J(W)}{w_1}更新w_{1}。采用同样的方法可以对所有的参数进行更新。这个从后往前更新的过程叫做反向传播。

 

反向传播详细介绍可以阅读一文弄懂神经网络中的反向传播法——BackPropagation

图12.反向传播

 

利用这种方法找到的loss 是一个局部最小值,而不是一个全局最小值。

因为随机梯度下降是一个greedy优化算, 用greedy的方法只能得到一个局部最优解。

随机梯度下降有一些扩展方法,他们不是用greedy方法,而是用adaptive方法,他们会在周围都看一看,但是这些方法计算量很大,而随机梯度下降是一个计算量相对而言较小的方法。同时,在实际中,局部最优往往够用了。

优化函数

优化函数是指怎么让权重weights进行更新的函数,梯度下降是一种常用的方法。但是梯度更新有一个缺点是每次更新需要计算所有数据集的输出,再求总损失,然后再计算梯度更新一次,计算和更新比较慢,尤其是数据集比较大的时候。

随机梯度下降(stochastic gradient descent)是每次只计算一个数据的输出和损失,然后计算梯度,更新一次权重。所以更新的速度比较快,但是由于每次只用一个样本,它并不能代表所有数据集的特点,所以并不是每次迭代都向着整体最优的方向,损失函数的变化方向很多。此外,虽然它最后能够到达最优值附近,但是不会停下来,而是在最优值附近摆动。

批量梯度下降(min-batch gradient descent)是指每次选择n个样本的数据计算loss,然后计算梯度,更新一次权重。它可以利用矩阵操作来进行更有效的梯度计算,提高更新速度。同时比随机梯度更稳定,收敛结果更接近梯度下降的效果。

批量梯度下降有一个选择n大小的问题。如果训练集数据较少,如少于2000个样本,则使用整体数据进行梯度下降即可,n=m.

batch size最好设成2的整数次幂,如32, 64,128,256等。确保每个mini batch都能放进内存。

三种梯度下降的方法对比图如下:其中蓝色是梯度下降,紫色是随机梯度下降,绿色是批量梯度下降。

3种梯度下降方法对比

学习率

在梯度下降的公式W\leftarrow W-\eta \frac{\partial J(W)}{W}中,\eta指学习率,即每次weight以多大的步幅更新,也就是每一步走多远。

当学习率很小时,模型的收敛速度会很慢,而且容易陷入局部最优,走不出去了。

当学习率很大时,模型一步跨越的距离较大,可能错过了最优值,而且会比较震荡不收敛。

当以合适的学习率迭代时,模型能比较平滑地收敛,避免局部最优。

图13. 以很小的学习率学习
图14.以很大的学习率学习
图15.以比较合适的学习率学习

 

怎样才能设置一个合适的学习率呢。

一种方法是多尝试,尝试不同的学习率,看看哪个是比较合适的。

另一种方法就是使用自适应的学习率。

自适应学习率是指学习率不再固定不变,它会随着一些因素而改变大小。常用的自适应学习率有以下几种,见图16。这些学习率的详细知识可以参考:各种优化算法Adaptive Learning Rate (适应性学习率)

图16. 自适应学习率

 

 

欠拟合和过拟合

欠拟合(underfitting)是指模型没有很好地学习到训练数据的特点,在训练集上的准确率不高。

过拟合(overfitting)是指模型在训练集上表现很好,但是模型太过复杂,参数太多,泛化性不好,在没有见过的测试集上效果不好。如图17所示。

图17.欠拟合和过拟合

正则化(regularization)是为了防止过拟合,增强对没有见过的数据的泛化能力的方法。

一种正则化的方法是dropout,如图18所示。

每次随机将一定比例的神经元的值置为0,即dropout掉,每轮dropout掉的神经元可能不一样。 这样的话就可以让网络不是那么强烈依赖网络的每一个路径,而是一个不同路径的集合(不同模型的集合),这样面对没有见过的test 数据的时候表现会更好。

 

图18. dropout

 

另一种正则化的方法叫做early stopping,如图19.

随着训练次数的增加,训练集的loss在逐步降低,测试集的loss也在逐步降低,当降低到一定值的时候,测试集的loss逐步开始上升,而训练集由于参数不断更新仍然会不断减少loss。我们认为再训练就可能导致过拟合了,所以可以选择这个点停止训练。当然也不是说只要loss不下降就停止,有可能这一次不下降,后面又下降了,所以一般记录目前为止最低的loss,当连续k次,如10次epoch没有再下降,则认为可以停止迭代了。

图19. early stopping

正则化

过拟合欠拟合

参数初始化

Batch Normalization

 

参考:

1.深度学习: http://introtodeeplearning.com/

2.神经网络:https://www.cnblogs.com/subconscious/p/5058741.html

3.常用激励函数:https://blog.csdn.net/tyhj_sf/article/details/79932893

4.常用回归损失函数:https://www.jiqizhixin.com/articles/2018-06-21-3

5.常用损失函数:https://blog.csdn.net/shenxiaoming77/article/details/51614601

6.自适应学习率:https://www.jianshu.com/p/c363f24ee0cc

7.反向传播:https://www.cnblogs.com/charlotte77/p/5629865.html

8. 梯度:https://blog.csdn.net/walilk/article/details/50978864

9.梯度的方向:https://zhuanlan.zhihu.com/p/38525412

10. 损失函数:https://zhuanlan.zhihu.com/p/44216830

11. https://blog.csdn.net/marsjhao/article/details/72630147

12. 常用求导公式:https://blog.csdn.net/MyArrow/article/details/51187712

13.激活函数求导过程:https://www.cnblogs.com/hutao722/p/9732223.html

14. 梯度消失与梯度爆炸:https://zhuanlan.zhihu.com/p/25631496

15. 梯度爆炸:https://zhuanlan.zhihu.com/p/32154263

16. 优化算法:https://www.cnblogs.com/guoyaohua/p/8542554.html

17.欠拟合和过拟合的原因及方法:https://blog.ailemon.me/2019/02/26/solution-to-loss-doesnt-drop-in-nn-train/






所属网站分类: 技术文章 > 博客

作者:83748wuw

链接:https://www.pythonheidong.com/blog/article/49006/b07cdb8907ba90ea0363/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

15 0
收藏该文
已收藏

评论内容:(最多支持255个字符)