基础知识篇
卷积神经网络
深度学习
- 感知器模型使得人工神经网络可以解决一些常见的分类回归任务,但是没办法很好的解决简单的异或(XOR)问题
- 反向传播算法:随着网络的加深,BP算法容易出现梯度消失和梯度爆炸的问题 / 容易陷入局部最优
- 卷积神经网络中每一种层都表示为一种运算方法
感知器
- 这里求和函数类似于隐藏层里的一个神经元,阶越函数相当于输出层
- 深度学习就是包含多隐藏层的多层感知器
- 神经元 -> 感知器 -> 神经网络 -> 深度学习 (多层感知器->神经网络 / 多隐藏层 -> 深度学习)
深度学习中的核心知识
- 前向运算(必须知道网络结构并且知道网络中的参数) & 反向传播(通过BP来获取参数具体的值)
- Layer2层的一个节点是通过上一层与其相连的节点经过线性运算从而得到的。这里的线性运算具体是什么运算,需要根据Layer2的定义决定。如果Layer是一个卷积层那么就是卷积运算,如果Layer是一个池化层那么就是池化运算等等
反向传播(Backpropagation, BP)
- 反向传播也就是把参数w和b利用梯度下降的算法来进行更新。从最末端依次往回对参数计算偏导数,根据这个偏导数作为梯度,利用梯度下降法来依次更新每一层的参数。
- 图节选自这里
卷积神经网络相关知识
- 卷积神经网就是以卷积结构为主,搭建起来的深度网络。其主要解决图片类的任务。图片( n ∗ h ∗ w ∗ c n*h*w*c n∗h∗w∗c n是batchsize的大小。w,h是图片的长和宽 c是通道数)作为网络的输入。输入的数据结构是这样网络就知道输入的是一张图片了。
- 将图片作为网络的输入,自动提取特征(也就是参数的优化),并且这些提取出来的特征对图片的变形(如平移,比例缩放,倾斜)等具有高度不变形
- 也就是想对参数进行足够的优化之后,当前网络对于输入图像的形状是不敏感的,是鲁棒的
- 特征提取往往在输出结果前一层完成,一般也就是FC层
- dropout 层一般在FC层前面用的比较多
- 为什么卷积核都是一些奇数:比如 3 ∗ 3 3*3 3∗3的卷积核是存在一个中心点的,而 2 ∗ 2 2*2 2∗2就不存在,利用这个中心点我们可以保护图像的位置信息。即卷积之后图像上的点和原始图像上的点是一一对应的。
- 奇数卷积核的时候也可以保证padding时候的对称性
- 一个卷积核对应了一种特征,也就对应了一个feature map
- numout:输出的channel的数量决定了我们需要卷积核的个数
- 一幅图像在进行卷积运算的时候,所有的局部区域所对应的卷积核的参数是相通的。这个性质我们把它叫做:这些区域是权值共享的。输入图像和输出层的图像之间是局部连接的
- 全连接指:输出层的每一个节点和输入层的每一个节点都连接
- 使用权值共享之后,卷积核参数数量将大大降低。参数量少意味着我们的模型更加不容易过拟合
卷积核中参数量和计算量
- 计算量决定平台的功耗,运算效率
步长 stride
- 这是一种下采样过程,与pooling层的下采样相对比
- 输出Feature Map大小的变化:
- stride的变化并不影响参数量的变化。在改变stride的时候,输出特征图的大小会发生变化,所以计算量会带来变化。
- Pad也是不改变参数量但是会增加计算量
池化层
- 常见的池化策略:最大池化/平均池化/随即池化
- 池化层是无参数的
激活函数
- 指数运算是非常耗时的。其输出是以y轴的0.5为中心,我们这里可以将其平移0.5,这样就可以输出以0为中心了
- 一般不在卷积网络中间层使用sigmoid函数,而是在最后的输出层使用
- 双曲正切函数在循环神经网络中用的比较多
- 其作用就是将小于0的值置为0
- 使用ReLU要非常注意设置学习率,通过调整学习率来保证网络一直处于一个激活的状态
BatchNorm层
- 对于原始的输入数据,如果我们不加规范化的话,其分布是不可控的,每一层的数据分布都是有差异的。这样的话在训练的过程中每一层以及不同层之间数据的分布是在不停变化的,非常不利于网络的收敛。
下文参考这里 - 机器学习领域有个很重要的假设:IID独立同分布假设,就是假设训练数据和测试数据是满足相同分布的,这是通过训练数据获得的模型能够在测试集获得好的效果的一个基本保障。BatchNorm就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同分布的。
- 对于深度学习这种包含很多隐层的网络结构,在训练过程中,因为各层参数老在变,所以每个隐层都会面临covariate shift的问题,也就是在训练过程中,隐层的输入分布老是变来变去。
- BN的基本思想其实相当直观:因为深层神经网络在做非线性变换前的激活输入值(就是那个x=WU+B,U是输入)随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于Sigmoid函数来说,意味着激活输入值WU+B是大的负值或正值),所以这导致后向传播时低层神经网络的梯度消失,这是训练深层神经网络收敛越来越慢的本质原因,而BN就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正太分布而不是正态分布,其实就是把越来越偏的分布强制拉回比较标准的分布,这样使得激活输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,意思是这样让梯度变大,避免梯度消失问题产生,而且梯度变大意味着学习收敛速度快,能大大加快训练速度。
- 但是很明显,稍微了解神经网络的读者一般会提出一个疑问:如果都通过BN,那么不就跟把非线性函数替换成线性函数效果相同了?这意味着什么?我们知道,如果是多层的线性函数变换其实这个深层是没有意义的,因为多层线性网络跟一层线性网络是等价的。这意味着网络的表达能力下降了,这也意味着深度的意义就没有了。所以BN为了保证非线性的获得,对变换后的满足均值为0方差为1的x又进行了scale加上shift操作(y=scale * x + shift),每个神经元增加了两个参数scale和shift参数,这两个参数是通过训练学习到的,意思是通过scale和shift把这个值从标准正态分布左移或者由移一点并长胖一点或者变瘦一点,每个实例挪动的程度不一样,这样等价于非线性函数的值从正中心周围的线性区往非线性区动了动。核心思想应该是想找到一个线性和非线性的较好平衡点,既能享受非线性的较强表达能力的好处,又避免太靠非线性区两头使得网络收敛速度太慢。
全连接层
- 其参数量非常大,所以通常配合dropout层(随机杀死一些节点)使用
- 如果输入数据的尺度发生了变化,在FC层参数量也会发生变化。所以全连接层是尺度敏感的
Dropout层
- Dropout说的简单一点就是:我们在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作,这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征
- (1)在训练模型阶段
Bernoulli函数是为了生成概率r向量,也就是随机生成一个0、1的向量。代码层面实现让某个神经元以概率p停止工作,其实就是让它的激活函数值以概率p变为0。比如我们某一层网络神经元的个数为1000个,其激活函数输出值为y1、y2、y3、…、y1000,我们dropout比率选择0.4,那么这一层神经元经过dropout后,1000个神经元中会有大约400个的值被置为0。 - (2)在测试模型阶段
预测模型的时候,每一个神经单元的权重参数要乘以概率p。
损失层
- 损失包括了:经验风险最小和结构风险最小
- 经验风险最小;对于数据分布拟合的程度 结构风险最小:模型的复杂程度越低,模型的结构风险就越小(一般用范数约束,也就是正则项)
- 不是像之前一样通过一个表达式来表示损失,而是通过一个网络层来表示损失