批量归一化(Batch Normalization,BN)
如果说自适应学习率是让训练适应loss,那归一化就是让loss适应训练。
我们抛掉使用自适应学习率的想法,重新看下面的图。可以看到w1固定时,w2的梯度是比较大的。w2固定时,w1的梯度较小。固定学习率,不是太大导致在w2方向上来回震荡,就是太小导致在w1方向上下降缓慢。
我们想出了一个思路,将这个椭圆(凸的凹凸表面)尽量修成圆的,那这样每个参数的梯度都差不多,就不会出现上述问题了嘛。
要解决椭圆,先思考出现椭圆的原因:
椭圆是loss构成的等高线。
l
o
s
s
由
y
和
y
^
loss由y和\hat y
loss由y和y^得到,y固定,所以只关心
y
^
\hat y
y^。
w是训练得到的参数,我们不管。那原因就出在
x
i
x_i
xi即输入数据(特征)上。如果
x
i
=
1
e
9
x_i=1e9
xi=1e9,那
w
w
w改一点点也会对
y
^
\hat y
y^造成很大的变化。如果
x
i
=
0.000001
x_i=0.000001
xi=0.000001,那么w变很大也改变不了多少
y
^
\hat y
y^。
所以我们可以对不同样本的同一个维度做归一化(比如对[1,2,3],[9,10,11]的[3,11]做归一化),将他们的数值范围统一成相同。方法在机器学习里也有提及过,主要还是结合方差和均值那些。
因为要得到所有数据的标准差、均值这些,而我们往往每次处理一个batch的数据,并且可以在每层之后应用归一化,而不是只对初始输入样本做归一化。所以与feature normalization做区分,叫batch normalization。
在实际应用模型时我们不可能一批一批的获取到数据,但我们也想归一化一下。这里用到了移动平均。
内部协变量偏移看不懂,没看了。。。
卷积神经网络(CNN)
图像其实就是一个像素矩阵,我们都知道有宽高和通道三个维度。
我们这里考虑图像分类任务,我们原本只有下面这写黑白图片及其对应的标签值(mnist),我们想训练一个网络,通过从训练集数据中学习,具备识别用户输入的各种数字图片(测试集)的能力。
本质上是个分类任务,用全连接网络可以学吗?当然可以,我们先将输入样本扁平化成一维向量,前向传播时我们将每个神经元的当前参数与所有训练样本的对应像素值做线性组合,再通过激活函数。前两者操作的顺序和个数可以排列组合,最后通过 softmax 得到
y
^
\hat y
y^,再选择一种损失函数,传入
y
^
\hat y
y^ 和
y
y
y 得到loss,再反向传播计算梯度,再更新参数。这就是一个fc网络的流程。
但我们仔细推敲一下,我们这里让每个神经元为所有像素位置都学习了一个参数,假设图像的宽高是100,第一层线性层有1000个神经元,那么就是100*100*3*1000=3e7(3是RGB 三通道),这种简单情况就需要这么多权重值了,更别提复杂网络了。除此之外,还有过拟合问题(下面会讲)。
针对图像的特性,我们有接下来的逐步改进。并最终将FC转为了CNN。
为了促进理解,提前解释卷积。卷积就是用一个矩阵(卷积核)在一张输入图像上从左到右、从上到下依次扫描(下面这张动图描述的不是很到位,卷积核一般步长没这么大,左边黄色区域不会只扫四次),进行两个矩阵的点积运算,得到相应位置的运算结果并输出为一个新矩阵。
感受野
我们发现图像检测不需要查看整张图像,比如识别一只鸟,只要检测到图中有鸟嘴、翅膀和鸟爪就行。更具体来说,每个神经元不需要保存所有像素位置的参数,那样就是根据整张图片进行识别了(很容易过拟合),我们完全可以让各个神经元只具有识别部分特征(如羽毛、鸟眼、喙)的能力,他们最终线性组合和非线性映射总能有识别出整只鸟的能力。这种方式也能极大地减少参数个数。
在这个任务中,我们可以认为每个神经元是一个检测器,我们让每个神经元只负责学习检测他那块区域的特征,这个区域叫做感受野。不同神经元的感受野可以重叠(防止交界处无神经元检测),感受野宽高可自行调整,可以只负责某些通道(比如RGB中只负责R)。
假定当前所有感受野的宽高为3,如果按照之前的例子,每个神经元负责的参数个数从1e4变为9,少了3个数量级;同时神经元个数从无限制变为等于感受野个数。
在图像任务中,由于不会觉得有些模式只出现在某一个通道里面,所以会看全部的通道。既然会看全部的通道,那么在描述一个感受野的时候,只需要讲它的高跟宽。常见的感受野设定方式就是为 3
∗
*
∗ 3。较大的感受野能够捕捉更大的模式信息,而较小的感受野更关注细节。
虽然感受野有相互重叠,但图像的边缘的像素,被重复检测的次数少于图像内部的,其检测效果肯定不一样。为了统一,又或者为了保持图像输出尺寸不变,可以在外层做零填充。
参数共享
我们让每个神经元学习检测它负责的感受野的特征。但对于羽毛特征,在图像中会多次出现在不同的感受野中。
理所当然的,不同位置的羽毛都是羽毛。这也是图像任务的特征,平移不变性,即我们识别的目标是位置无关的,不可能说左上角的羽毛和右下角的羽毛的特征完全不同。
但是我们现在让神经元只关心一个感受野区域,即左上角的神经元只能学习和检测左上角区域的特征(因为这里还没有过渡到“卷”,只是单纯的位置对位置和线性组合)。除非把这个神经元的参数在每个感受野都放一个。
为了避免在每个感受野放置重复的参数,我们想到,可以让单个神经元具有遍历图像中各个感受野进行学习和检测的能力。神经元是静态的,因此我们提出一个检测器(学习器)类型的动态的主体。那么遍历操作就是把神经元对应的检测器(学习器)从左到右,从上到下,遍历式地在每个感受野上学一下,这就是卷积了,而这个检测器就是卷积核(好像也叫滤波器?),宽高与感受野一致,一个神经元对应一个卷积核。当然,在检测时,也可以用卷积在不同感受野上检测同一特征。
由于单个卷积核从整张图像上学到的参数,能在图像的各个位置检测它对应的神经元对应的感受野的特征,我们认为这个参数是全局共享的(而不是第一个神经元的参数只能给第一个感受野区域用)。这种方式也减少了参数个数。
NOTE:CNN中的神经元好像是个抽象概念,具体使用还是卷积核。
卷积层
全连接层,通过引入感受野减少参数个数,再加上参数共享和卷积操作处理平移不变性,就变成了卷积层。
通过多个卷积层与非线性映射,能识别愈加复杂的特征。
由于参数量减少(每个神经元只保存一个卷积核大小的权重矩阵),而且模型的限制较大(神经元个数受卷积核大小限制,卷积核大小也受图片大小限制等),灵活性较低,但也不易过拟合。这些策略是针对图像任务的特性来设计的。
池化
想到了之前看过的一个视频:b站视频-原来图片是这样压缩的
对一张图片的各个部分分别取一小部分,拼接为一个新的像素明显变少的图像,我们仍能大致看出两张图有一定相似性,即用新生成的图像作为训练样本是有一定可行性的。这就是降采样。
因此我们在CNN中也可以使用这种方式减少网络内传递的参数,减少过拟合。可以对一个感受野只取一个MAX值,或取一个平均值,进一步减少参数个数。这就是池化。
相比较卷积层是对感受野进行映射,池化层像一个算子,不需要学习什么,只需要做一个转换操作,比如取最大值(max pooling)、求平均值(mean pooling)。在CNN中会将卷积层与池化层交替使用。
但是!这种方式本质上还是用降低精度来降低计算资源消耗。对于追求高精度、且算力足够时,可能没有必要使用池化。
经典图像识别网络
传入样本数据->卷积、池化、归一、激活函数等层交替->输出扁平化(转一维向量)->全连接层+softmax->输出结果
什么时候用CNN
只要问题与图像有相似性质就行。图像的特征就比如有位置无关、一些模式只要观察局部特征就行。比如音频、时序数据等场景。可以根据实际情况进行匹配,比如连五子棋、围棋都可以应用CNN。