对于深度学习的理解
机器学习的任务可以看作是数据统计中对于给定数据的拟合。也就是给定一些样本点,用合适的曲线揭示这些样本点跟随自变量变化的关系。
现在我们将将目光由二维的点扩充向由向量、矩阵等等组成的点对。此时,这种点对之间的关系非常复杂,很难再去用一个简单说的数学函数去表示。因此,就用神经网络去表示这种关系,而多层神经网络的本质就是一个多层复合的函数。
即深度学习就是弄出来一个超级大的函数,这个函数含有海量的权值参数、偏置参数,再通过一系列复合的复杂运算,得到结果。
借用博文深度学习 – Deep learning | DL中对于深度学习的解释,比较好理解:
我们将深度学习要处理的信息看做是水流。而处理数据的深度学习网络是一个由管道和阀门组成的巨大水管网络。网络的入口是若干管道开口,网络的出口也是若干管道开口。这个水管网络有许多层,每一层由许多个可以控制水流流向与流量的调节阀。根据不同任务的需要,水管网络的层数、每层的调节阀数量可以有不同的变化组合。对复杂任务来说,调节阀的总数可以成千上万甚至更多。水管网络中,每一层的每个调节阀都通过水管与下一层的所有调节阀连接起来,组成一个从前到后,逐层完全连通的水流系统。
假设这个水流系统是一个用来识别汉字的系统,我们如何让这个水管系统学习到这种能力呢?
比如,当计算机看到一张写有“田”字的图片,就简单将组成这张图片的所有数字(在计算机里,图片的每个颜色点都是用“0”和“1”组成的数字来表示的)全都变成信息的水流,从入口灌进水管网络。
我们预先在水管网络的每个出口都插一块字牌,对应于每一个我们想让计算机认识的汉字。这时,因为输入的是“田”这个汉字,等水流流过整个水管网络,计算机就会跑到管道出口位置去看一看,是不是标记由“田”字的管道出口流出来的水流最多。如果是这样,就说明这个管道网络符合要求。如果不是这样,就调节水管网络里的每一个流量调节阀,让“田”字出口“流出”的水最多。
这下,计算机要忙一阵了,要调节那么多阀门!好在计算机的速度快,暴力的计算加上算法的优化,总是可以很快给出一个解决方案,调好所有阀门,让出口处的流量符合要求。
下一步,学习“申”字时,我们就用类似的方法,把每一张写有“申”字的图片变成一大堆数字组成的水流,灌进水管网络,看一看,是不是写有“申”字的那个管道出口流水最多,如果不是,我们还得再调整所有的阀门。这一次,要既保证刚才学过的“田”字不受影响,也要保证新的“申”字可以被正确处理。
如此反复进行,知道所有汉字对应的水流都可以按照期望的方式流过整个水管网络。这时,我们就说,这个水管网络是一个训练好的深度学习模型了。当大量汉字被这个管道网络处理,所有阀门都调节到位后,整套水管网络就可以用来识别汉字了。这时,我们可以把调节好的所有阀门都“焊死”,静候新的水流到来。
与训练时做的事情类似,未知的图片会被计算机转变成数据的水流,灌入训练好的水管网络。这时,计算机只要观察一下,哪个出水口流出来的水流最多,这张图片写的就是哪个字。
将神经网络与上面的水流做对比。在这个由许多阀门组成的水流系统中,入口就是神经网络的输入层,出口就是输出层。每个阀门代表的就是网络的参数,每一组阀门代表了网络的每一层。让这个水流系统具有辨识手写数字的能力就是我们训练模型的过程。
深度学习就是用一个超级大的函数,这个函数含有海量的权值参数、偏置参数,再结合尽可能多的训练数据以及计算机的大规模运算能力去调节内部参数,尽可能逼近问题目标的半理论、半经验的建模方式。
梯度下降
对于机器学习中其中一个主要的步骤是构造损失函数,当构建好损失函数后需要对损失函数进行优化,使得损失值最小。(损失指的是深度神经网络经过前向传播之后,得到的预测值与先前给出真实值之间存在的差距,损失函数指的是关于参数的函数)。
我们整个训练的目标就是设计合理的损失函数,并通过合理的优化方式使损失值不断下降,越趋于0越好,最后趋于收敛。
为什么要用梯度下?
- 策略1:随机寻找(不太实用),相当于暴力搜索。
最直接粗暴的方法就是,我们尽量多地去试参数,然后从里面选那个让损失函数最小的参数组,最为最后的W。当参数量比较少时,暴搜可能可以,但是当参数量很大时,所需要的计算量是难以估计的。 - 策略2:随机局部搜索。
在现有的参数W基础上,随机搜索一下周边的参数,查看有没有比现在更好的W,然后用新的W替换现有的W,不断迭代。 - 策略3:梯度下降。
梯度下降相当于是贪心的思路,即每一步都选取当前的最优解,不断逼近。既然无法直接获得该点,那么我们就想要一步一步逼近该点。形象的理解是下山时,找到最陡的方向,逐一小步,然后再找到当前位置最陡的下山方向,再迈一小步…即可到达山谷最底部。
显然,梯度下降的方式最快,所需要的计算量最小。
反向传播
首先得搞清楚反向传播是什么,为什么要用反向传播。看了好多博客资料,很多都是直接将链式法则以及求偏导,搞清楚what,why是很重要的。
下面是重点,是看了好多资料后,对于反向传播自己的理解。
在训练模型时,我们需要不断更新参数,以便让模型的损失不断下降,在上面一节刚说过要采用梯度下降的方式,也就是我们需要求出损失函数对于每一个参数的梯度,以此来更新参数。有不同的更新参数的方式,但都要用到这个梯度。
然而,当网络的模型比较深时,即有好多层时,求Loss对于前面一两层的梯度还比较好求(求梯度高数里的链式法则求偏导,具体的怎么推导百度一下,这里只讲理解),但是Loss如果想对好多层前面的参数求梯度,此时表达式可能是极其复杂的,需要很大的计算量。此时,我们就想有没有什么方法可以比较简单得求出Loss对于好多层前面的参数,而避免如此巨大的计算量呢?
此时,反向传播就登场了。我们通过前向传播计算时,比如是y = wx + b,在计算得到y时,同时把y对于w参数的梯度也求出来,这个分散到每一步还是非常容易算的。当网络模型比较深时,我们在每一步前向传播计算值的过程中,同时也将每一步的梯度也求出来,当前向传播计算到最后时,前面,每一步的梯度也就被计算了出来。如果要求Loss对于好多层之前的某个参数的梯度,只需要将Loss与这个参数中间的所包含的小梯度值从后往前依次累乘,此时就避免了Loss对这个参数的表达式求偏导的过程,避免了很大的计算量,很容易得就将这个Loss与相距甚远的参数的梯度求出来了。这个参数也就相当于打仗的一个小兵,也就可以拿着这个梯度去更新自己,以便为整个模型的优化目标贡献出自己的力量。
参考资料
[1] https://blog.csdn.net/crxk_/article/details/97137789
[2] https://easyai.tech/ai-definition/deep-learning/
[3] https://blog.csdn.net/honghu110/article/details/55211228