intro
本文主要是笔者学习神经网络时一些思考的感悟,由于本人对人工智能方向了解甚浅,所以记录的理解会有不正确的地方,欢迎批评指正!
深度学习与传统机器学习算法的一个显著区别:对于传统的机器学习算法,可以感受到其中还是有很多人为的因素在。比如对于SVM我们需要人为的去调整软间隔的参数来避免过拟合,对于一些决策树算法,我们调整人为的剪枝策略。并且在一个机器学习项目里边,我们经常需要花费时间去思考和实验与有关特征工程的问题,毕竟这与我们实验结果直接相关。但是对于一些深度学习算法模型,对于特征工程的处理就变得自动化起来,比如对于一个神经网络,其对应的特征参数数量可以非常之大,它一定程度能够学习什么样的特征是重要的,怎么组合和处理是最合适的,我们有时候并不需要考虑太多特征工程的问题。但是参数与神经网络的复杂性也决定了它的黑盒的特性,也就是可解释性差,并且资源开销很高。
可以说,数据特征决定了模型的上限,我们选取什么样的算法只是怎么去逼近这个上限。
关于全连接神经网络
What:神经网络在做什么事?可以理解为计算得分函数。比如我们有一堆动物图片,通过训练,我们能够让这个模型告诉我们个label的得分,从而区别出这个图片是属于牛,还是属于兔子等等。就像下图,W就代表的是权重参数矩阵(我更愿意理解为抽象的处理矩阵)。当然很多时候我们会用softmax去放大区别然后归一化为概率值(对于分类任务)。
How:我们要怎么去训练这个神经网络变或者怎么去训练这么多参数呢?其实如果我们只有一个W,这个问题就会有点像个线性回归模型的感觉,但是神经网络实际上有很多层,也就是我们有很多个W,做很多次变换和操作,这些处理我们也叫做隐层,通过多次的操作来更好的拟合我们的输入。我们在更新这些W的时候其实也和线性回归的更新方法很像,就是对损失函数的梯度下降!但是由于我们有很多层,我们计算梯度的时候就要像剥洋葱一样从外到内一层一层计算(其实就是求偏导的链式法则),在神经网络里就是从后向前,很多教程说的反向传播就是这个意思。剩下的操作就和正常梯度下降是差不多的,只不过我们需要处理的参数变多了。
Why:为什么神经网络长成这个样子?在我的理解中,神经网络的结构其实映射到数据结构层面本质上是矩阵的各种操作,只不过如果我们把这些操作用一根一根线表示一下,连接一下数据就会变成神经网络的模样了,也就是说神经网络并不是像他长得那样是一个图的数据结构,而是矩阵操作的一种抽象。
优化:对于神经网络的优化有很多方法。比如在每一层时候使用激活函数,就是每层之后做一个非线性处理。常见的激活函数有sigmod,relu。现在大部分适用relu函数,因为sigmoid函数在后面可能会出现梯度消失的情况,而且在计算机上计算其梯度的时候也非常耗时。但是relu函数就不会有这种情况
正则化处理也是重要方法。正则化惩罚就是在损失函数末尾加上正则化惩罚项来防止W的参数过于剧烈的波动,比如加上W的平方项(W越平稳这个值就会越小)。
DROPOUT:就是在训练的时候每次迭代随机杀死一些神经元。来减少模型的复杂程度。
关于卷积神经网络
学习的时候顺便了解了一下卷积神经网络,因为笔者也不是做计算机视觉方向的,所以认知较浅,请见谅。
在我的理解中,卷积神经网络其实和神经网络的区别就是对神经网络中的处理做了一种针对性的定义和约束。我们的W并不是完全抽象而没有意义的了,而是归结为了卷积或者池化的操作。卷积是一种很常用的图像处理方式,用一个卷积核去在原图蠕动,越符合特征的部分得到的值就会越大。当然在这个过程中我们的中间层会越来越胖,因为用于处理的卷积核并不止一个。
为什么说CNN是局部连接与权值共享的?在上面说到。我们给W赋予了卷积的意义,或者我们用卷积这个操作去充当W。卷积核在计算的时候是不变的,映射到矩阵上就是很多w参数值是共享的!而且试想一下,每次卷积的时候实际上我们只会覆盖一小片区域,所以映射到神经网络上会发现,每个神经元就不会和所有神经元都有连线,毕竟左上角的像素点和右下角的像素点不可能同时被一个卷积核完全覆盖。这样卷积神经网络就能大幅度减少计算量,增加了可理解性。
池化层可以理解为对特征图的进一步特征抽样,并且可以很大程度上减少中间层的大小,为什么要池化?因为发现在卷积的时候一个像素点周围的卷积值都非常近似。
Padding操作就是扩充了我们的数据矩阵,因为卷积操作会导致边缘信息的获取丢失,并且有时候我们的数据也不是完全尺寸一致的。Stride也就是步幅就是卷积核蠕动的距离,距离越大,处理的越粗糙,花费的时间越少。距离越少,过拟合风险越大,拟合效果越好,时间成越高。