深度学习基础(面经),卷积神经网络基础(面经)

 
本文内容参考魏秀参《解析卷积神经网络》
手写卷积池化代码
池化层的反向传播
cnn的反向传播
 
 
  • 1卷积神经网络基本操作
  • 2卷积神经网络的压缩
  • 3数据扩充
  • 4数据预处理
  • 5网络参数初始化
  • 6激活函数
  • 7目标函数
  • 8网络正则化
  • 9超参数设定和网络训练
  • 10不平衡样本的处理
  • 11模型集成方法
 
 
提高泛化能力的方法: 增广,减小网络,加正则,dropout,bn
共享特征有助于减少神经网络中的参数数量,一定程度上减小了模型的计算复杂度
1.卷积神经网络基本操作
卷积操作的作用
卷积是一种局部操作,通过 一定大小的卷积核作用于局部图像区域获得图像的局部信息。比如边缘滤波等。
事实上,卷积网络中的卷积核参数是通过网络训练学出的,除了可以学到类似的横向,纵向边缘滤波器,还可以学到任意角度的边缘滤波器。不仅如此,检测性状,颜色,纹理等众多基本模式的滤波器都可以包含在一个足够复杂的深层卷积神经网络中。通过组合(池化激活等)这些滤波器以及随着网络的后序操作的进行,基本而一般的模式会逐渐被抽象为具有高层语义的概念表示,并以此对应到具体的样本类别。
 
池化的作用
池化层不包含可学习的参数。只需要指定赤化类型,池化操作核大小,池化步长等超参数。池化有平均池化,最大池化,随机池化(对输入数据中的元素按照一定概率大小随机选择,并不像最大池化那样总是选最大元素,对随机池化而言,元素值大的响应被选中的概率也大。可以说在全局意义上,随机池化与平均池化近似,在局部意义上,则服从最大池化的准则)
作用:其实就是降采样操作,池化层的引入是仿照人的视觉系统对视觉输入对象进行降维(降采样)和抽象。研究者认为池化有三种作用:
  1. 特征不变性:池化操作让模型更关注是否存在某些特征而不是特征的具体位置。可看做是一种很强的闲言,使特征学习包含某种程度的自由度,能容忍一些特征微小的位移
  2. 特征降维:降采样,池化结果中一个元素对应于原输入数据的一个子区域,因此池化相当于在空间范围内做了维度约检,从而使模型可以抽取更广范围的特征。同时减小下一层输入的大小,进而减小计算量和参数个数
  3. 在一定程度上防止过拟合,方便优化
根据相关理论, 特征提取的误差主要来自两个方面:
  1. 邻域大小受限造成的估计值 方差增大
  2. 卷积层参数误差造成估计 均值的偏移
  • 平均池化能减小第一种误差(邻域大小受限造成的估计值方差增大), 更多的保留图像的背景信息
  • 最大池化能减小第二种误差(卷积层参数误差造成估计均值的偏移), 更多的保留纹理信息
  • 随机池化介于两者之间,通过对像素点按照数值大小赋予概率,再按照概率进行采样,在平均意义上,与均值近似,在局部意义上,服从最大池化的准则。
平均池化与最大池化分别适用于什么场景
  • 当map中的信息都应该有所贡献的时候用avgpool,比如图像分割中常用global avgpool来获取全局上下文关系,比如224x224图像分类将最后的7x7map进行avgpool而不是maxpool。因为深层高级语义信息一般来说都能够帮助分类器分类。
  • 反之 为了减少无用信息时候用maxpool,比如浅层网络常见到maxpool,因为刚开始几层对图像而言包含较多的无关信息,另外avgpool与maxpool输出值幅度波动大,可以加一些归一化操作。具体使用场景根据任务来,实际效果炼丹后才知道。
激活函数
引入激活函数的目的是为了增加整个网络的表达能力(即非线性)。否则若干现行操作层的堆叠仍然只能起到线性映射的作用,无法形成复杂的函数。
sigmoid
公式图像,适用范围,缺点
relu
公式图像,解决了什么问题
 
 
2.卷积神经网络的压缩
在追求模型高准确率的同时,尽可能的降低其复杂度,以达到性能与开销(时间计算量)上的平衡。给定一小部分参数子集便能够完整的重构出剩余的参数。这种冗余在训练阶段很必要,因为DL问题是一个极其复杂的非凸优化问题,对于现有的基于梯度下降的优化算法而言,这种参数冗余能保证网络能够收敛到一个比较好的最优值。因而一定程度上,网络越深,参数越多,模型越复杂,最终效果往往也越好。
模型压缩技术主要分为两个部分:前端压缩,后端压缩
  • 前端压缩:是指不改变网络结构的压缩技术,主要包括知识蒸馏,紧凑模型设计,滤波器层面的剪枝等。可很好匹配深度学习库
  • 后端压缩:其目标在于尽可能的减少模型大小,因而会对原始的网络结构造成极大程度上的改造。这种改造往往不可逆。包括低秩近似,未加限制的剪枝,参数量化以及二值网络等。
当然也可以将前端压缩的输出作为后端压缩的输入,能够在最大程度上减少模型的复杂度。
低秩近似
CNN的实现通过矩阵相乘完成,通常权重矩阵往往稠密且巨大,从而带来巨大计算和存储开销。为解决这个问题直观想法是,若能将稠密矩阵由若干个小规模矩阵近似重构出来,那么便能够有效降低存储于计算开销。
  • 这类算法大多采用低秩近似来重构权重矩阵。在小数据集上能够达到2-3倍的压缩效果,最终结果甚至可能超过压缩之前的网络。
  • 还可以直接使用矩阵分解来降低矩阵权重参数。如用SVD分解。利用矩阵分解能够将卷积层压缩2-3倍,全连接压缩5-13倍,速度提升2倍,精度损失控制在1%之内。
低秩近似在 小网络模型上取得了不错的效果,但其参数量与网络层数呈线性变化趋势,随着层数增加与模型复杂度提高,其搜索空间急剧增大。
剪枝与稀疏约束
通过剪枝处理,在减小模型复杂度的同时,还能有效防止过拟合,提升模型泛化性。在训练中,需要一定冗余的参数数量来保证模型的可塑性与容量,在完成训练之后,则可以通过剪枝操作来移除这些荣誉参数,使得模型更加成熟。给定一个预训练好的网络模型,常用剪枝算法的流程:
  1. 衡量神经元重要程度(剪枝算法最重要的核心步骤)。根据剪枝粒度不同,神经元定义可以是一个权重连接,也可以是整个滤波器。
  2. 移除掉一部分不重要的神经元。可以根据阈值来判断神经元是否可以被剪除,也可以按照重要程度排序,剪除一定比例的神经元。后者简单
  3. 对网络进行微调。剪枝操作不可避免影响网络精度,为防止对分类性能造成过大破坏,需要对剪枝后的模型进行微调。
  4. 返回第1步,进行下一轮剪枝。
参数量化
量化是指从权重中归纳出若干“代表”,由这些代表来表示某一类权重的具体数值。代表被存储在码本中,而原权重矩阵只需记录各自代表的索引即可,从而极大降低存储开销。即使采用最简单的标量量化算法,也能在保持网络性能不受显著影响的情况下,将模型大小减少8-16倍。不足在于,当压缩率比较大时容易造成分类精度大幅度下降。
二值网络
所有参数取值只能是+1或-1。在普通NN中,一个参数由单精度浮点型表示,参数二值化能将存储开销降低为原来的1/32。二值化需要解决两个基本问题:
  • 如何对权重进行二值化?
    • 直接根据权重正负二值化,x=sign(x)
    • 随机二值化,对每个权重以一定概率去+1,这个更耗时
  • 如何计算二值权重梯度?二值权重梯度为0,无法进行参数更新。用符号函数进行放松。Htanh(x)=max(-1,min(1,x))代替sign(x)。当x在[-1,1],存在梯度值1,否则梯度值0
知识蒸馏
在不改变模型复杂度情况下,增加监督信息的丰富程度肯定会带来性能上的提升。知识蒸馏是迁移学习的一种,目的是将庞大复杂模型学到的知识通过一定 的手段迁移到精简的小模型上,使得小模型能够获得与大模型相近的性能。这两个模型分别扮演老师(大模型)和学生(小模型)角色:让学生自己学的话,收效甚微;若能经过一个老师的指导,便能够事半功倍,学生甚至有可能超越老师。
紧凑的网络结构
设计出很多更加紧凑的网络结构,将这些新结构运用到神经网络设计中来,能够使模型在规模与精度之间达到一个较好的平衡。比如:
  • fire module用在SqueezeNet中
  • MobileNet:Depth-wise conv,深度分离卷积等
 
 
3.数据扩充
数据扩充不仅能够增加样本数量,还能增加样本多样性。一方面避免过拟合,另一方面会带来模型性能的提升。
简单的数据扩充
  • 水平翻转:使数据集扩充一倍
  • 随机抠取(random crops):一般用0.8-0.9倍的正方形在原图的随机位置处抠取图像块,每张图像随机抠取的次数决定了数据集扩充的倍数。使用正方形是因为CNN网络输入是正方形,以正方形抠图避免了矩形抠取后序的图像拉伸操作带来的分辨率失真
  • 尺度变换:将图像分辨率变为原图的0.8,0.9,1.1,1.2,1.3等倍数。将尺度变换后的图像作为扩充的训练样本加入训练
  • 旋转:-30,-15,15,30度等
  • 色彩抖动:对原图或已经变换的图进行操作。在RGB颜色空间对原有RGB色彩分布进行轻微扰动,也可以在HSV颜色空间尝试随机改变图像原有饱和度和透明度,或对色调进行微调
  • 实际中,一般对上面方法叠加组合使用,将数据扩增多倍甚至数十倍
特殊的数据扩充方式
  • Fancy PCA
  • 监督式数据扩充:对基于高层语义进行图像分类任务效果好
 
4.数据预处理
机器学习中,对特征进行归一化
实践中,对每个特征减去平均值来中心化数据非常重要,这种归一化处理方式被称为“中心式归一化”。CNN中预处理通常是计算训练集图像像素均值,之后再处理训练集、验证集和测试集图像时要减去该均值。减去均值的原理是:默认自然图像是一种平稳分布(每个维度的统计都服从相同的分布),此时在每个样本上减去平均值可以移除共同部分,凸显个体差异。注意均值只能通过训练集计算得到,然后再训练集验证集测试集中使用。否则违背ML基本原理:模型训练过程中只能从训练数据中获取信息。
 
5.网络参数初始化
  • 全零初始化:网络无能力对此做出改变,从而无法进行模型训练
  • 随机初始化:将参数随机设定为接近0的一个很小的随机数(有正有负)。实际中,随机参数服从高斯分布或均匀分布都是较好的初始化方式。
    • 设网络输入神经元个数n_in, 输出神经元个数n_out,服从高斯分布的参数随机初始化为: w=0.001*randn(n_in,n_out),其中高斯分布均值0,方差为1的标准高斯分布,0.001是为了将参数期望保持在接近0的小范围。但是这样会有一个问题,即网络输出数据分布的方差会随着输入神经元个数改变。
      • Xavier参数初始化  w=(0.001 * randn(n_in,n_out)) / sqrt(n),其中n=n_in或者n=(n_in+n_out)/2。该方法并未考虑非线性映射函数对输入的影响
WL = np.random.randn(WL.shape[0],WL.shape[1])* np.sqrt(1/n)
  • He等人将对此改进-将非线性映射造成的影响考虑进初始化中,将Xavier方法中方差规范化的分母应该是  sqrt(n/2),而不是  sqrt(n)
  • 以上是服从高斯分布,均匀分布也是一种很好的初始化分布,当参数初始化服从均匀分布,由于分布性质不同,均匀分布需要制定其取值区间,则Xavier和He初始化方法分别修改为
    • Xavier
      • low = -sqrt(3/n) ;  high = sqrt(3/n);
      • random_param = a+(b-a).*rand(n_in,n_out);
      • w = 0.001*rand_param
    • He
      • low = -sqrt(6/n) ;   high = sqrt(6/n) ;
      • rand_param = a +(b-a) * rand(n_in, n_out) ;
      • w = 0.001 * rand_param
  • 其他初始化方法:比如利用预训练模型初始化,预训练模型已经在原先任务上收敛到理想的局部最优解,加上预训练模型容易获得,因此将其作为新任务的参数初始化无疑是一个优质首选
 
6.激活函数
常用的激活函数,sigmoid, tanh(x), ReLU, Leaky ReLU, 参数化ReLU, 随机化ReLU和指数化线性单元(ELU)
sigmoid
  • 经过sigmoid函数作用后,输出响应值被压缩到[0,1]之间,0对应抑制状态,1对应兴奋状态,但是存在两个问题:
    • sigmoid两端梯度接近于0,这会导致在误差反向传播过程中导数处于该区域的误差很难甚至无法传递至前层,进而导致整个网络无法正常训练。
    • 而且其在值域的均值非0,而全部是正数,不符合对神经网络内数值的期望应为0的假象
tanh(x)
以0为中心,但是仍然会出现梯度饱和现象

 

ReLU
函数在大于等于0范围内为1,否则为0.
  • 对x大于等于0的部分完全消除了sigmoid函数的梯度饱和效应
  • 计算复杂度也简单
  • 同时ReLU有助于随机梯度下降方法收敛
但是缺点:对小于0的卷积结果响应,他们一旦变为负值将无法再影响网络响应
 
Leaky ReLU
为缓解ReLU中小于0部分的死区现象,将x<0部分调整为f(x) = a*x,其中a为0.01或者0.001数量级较小正数。a为超参数,需要人为设定,但是在实际中并不稳定
 
参数化ReLU
为解决Leaky ReLU中超参数a不容易设定的问题:直接将a也作为一个网络中可学习的变量融入模型的整体训练过程。
  • 自动学习a的值,分类精度上优于原始ReLU
  • 自由度较大的通道独享参数的参数化ReLU更优
 
随机化ReLU与ELU
 
7.目标函数
分类任务的目标函数
  • 交叉熵损失函数
  • 合页损失函数:对错误越大的样本施加越严重的惩罚。合页损失对噪声的抵抗能力较差,若某样本本身标记错误或该样本本身是离群点,则由于错分导致该样本分类误差变得很大,这样会影响整个超平面的学习,从而降低模型泛化能力。一般交叉熵损失结果略优于合页损失结果
  • 当样本被正确分类且函数间隔大于1时,合页损失才是0,否则损失是1-y(wx+b)。这也就是说合页损失函数不仅要正确分类,而且确信度足够高时损失才是0.也就是说合页损失函数对学习有更高的要求。
  • 坡道损失函数:非凸损失可以很好解决这个问题(分类中坡道,回归中Tukey's biweight),他们针对噪声数据和离群点具备良好的抗噪特性,因此是鲁棒损失函数。其共同特点是在分类(回归)误差较大的区域进行截断,使得较大误差不再大程度影响整个误差函数。公式如上图,s指定了截断的位置,坡道损失也就是在s处截断的合页损失,也称为截断合页损失。上图表示两种损失函数的对比。在断点处不可导,但不影响使用。s由分类类别数c决定,一般s=-1/(c-1)
为了进一步提高学习到的特征的判别性,研究者基于交叉熵损失函数设计了新型损失函数,比如大间隔交叉熵,中心损失函数。这些损失函数考虑了增加类间距离,减小类内差异等不同要素,进一步提升了网络学习特征的判别能力。
  • 大间隔交叉熵损失函数:增大类间距离
  • 中心损失函数:考虑类间距离的同时将一些注意力放在减小类内差异上,其中Cyi为第yi类所有深度特征的均值,直观上,所有属于yi类的样本与之中心不要距离过远,否则将增大惩罚。也可以和考虑类间距离的损失函数配合使用。
回归任务目标函数
  • L1损失函数
  • L2损失函数:效果和L1损失函数差不多,但是速度比L1损失函数快
  • Tukey's biweight损失函数:非凸损失函数,可克服在回归任务中的离群点或样本噪声对整体回归模型的干扰和影响,是回归任务中一种鲁棒的损失函数。
其他任务目标函数
很多问题不能直接用分类和回归来衡量,比如年龄判断的30岁左右。这种可以用标记分布来描述,这种分布明显区别于分类问题的离散标记,也区别与回归问题的连续标记。与回归问题区别在于,回归问题虽然标记连续,缺不符合一个合法的概率分布。假设 为网络模型对于输入样本xi的最终输出结果,利用标记分布技术解决问题之前,先需要将h转化为一个合法分布。以softmax为例可将h转化为: ,其中 代表标记向量的第k维。针对预测的标记向量 ,通常可用KL散度来度量其余真实标记向量y的误差,KL散度也称KL损失。下面两种写法等价,通过KL散度可以衡量样本标记分布于真实标记分布之间的差异,并利用该差异指导模型训练。
 
8.网络正则化
正则化是机器学习中通过显式的控制模型复杂度来避免模型过拟合、确保泛化性能的一种有效方式。在此介绍5种常用的CNN网络正则化方法。
  • L2正则化(权重衰减,岭回归):深度模型常用L2和L1正则对操作层(卷积层,分类层等)进行正则化,约束模型复杂度。假设待正则的网络层参数为w,L2正则项形式为: ,λ控制正则项大小,较大λ将较大程度约束模型复杂度。一般将正则项加入目标函数,通过整体目标函数的误差反向传播,从而达到正则项影响和指导网络训练的目的。
  • L1正则化,L1正则化除了同L2正则化一样能约束参数量级外,L1正则化还能起到使参数更稀疏的作用。稀疏化的结果使优化后的参数w一部分为0,另一部分为非0值。非0值那部分参数可起到选择重要参数或特征维度的作用,同时可起到去除噪声的效果。此外L2和L1正则可以联合使用
  • 最大范数约束:通过向参数量级的范数设置上限对网络进行正则化的手段,比如 。类似于梯度裁剪
  • 随机失活(dropout):配备全连接层CNN都在使用的方法,其在 约束网络复杂度同时,还是一种 针对深度模型的高效集成学习方法
    • dropout的提出一定程度上缓解了神经元之间复杂的协同适应(由于神经元之间互连,对某个神经元其反向传播来的梯度信息的同时也受到其他神经元的影响,也就是牵一发动全身),降低了神经元间以来,避免了过拟合发生。
    • 原理:对某层每个神经元,在训练阶段均以概率p随机将该神经元权重置0,测试阶段所有神经元均呈激活状态;但训练时其权重需乘(1-p)以保证训练和测试阶段各自权重拥有相同的期望。
    • 平均集成:失活的神经元无法参与到网络训练,因此每次训练时相当于面对一个全新网络。以包含2层,每层有3个神经元的NN为例,若每层随机失活一个神经元,该网络共可产生9中子网络,测试阶段相当于9个子网络的平均集成。对于提升网络泛华性效果显著。
    • 缺点:会明显增加训练时间,因为引入dropout之后相当于每次只是训练的原先网络的一个子网络,为了达到同样的精度需要的训练次数会增多。使用dropout大概是没有使用dropout的2~3倍。
dropout代码
keep_prob = 0.8  # 设置神经元保留概率
d3 = np.random.rand(a3.shape[0], a3.shape[1]) < keep_prob
a3 = np.multiply(a3, d3)
a3 /= keep_prob
  • 验证集的使用:一般在每轮训练结束后对验证集进行前向运算,绘制学习曲线,以此检验模型泛化能力。
    • 验证集准确率一直低于训练集准确率,但无明显下降趋势,---》 欠拟合(偏差大)。增加网络层数,调整网络结构、调整激活函数增加非线性,减少正则化等方式增大网络复杂度。
    • 验证集曲线不仅低于训练集,且随着训练轮数增长有明显下降趋势--》 过拟合(方差大)。增大模型正则化削弱网络模型复杂度,使用早停(early stopping)策略,扩充数据等方法。去验证集准确率最高的那一轮训练结果作为最终网络,用于测试集数据的预测。
 
9.超参数设定和网络训练
介绍一些网络设计过程中超参数设定技巧和训练技巧,如学习率设定,批规范化操作和网络优化策略的选择等。
  • 网络超参数的设定:输入图像像素,卷积层个数,卷积核相关参数等
    • 输入图像像素大小:对不同图像为了得到同规格的输出,同时便于gpu设备并行,会同一将图像压缩到2^n大小。若不考虑设备限制,更高分辨率作为输入一般均有助于网络性能的提升,特别是注意力模型的深度网络提升更为显著,但是会增加计算消耗,增大训练时间延长。一般CNN有全连接层为分类层,若直接改变原始网络模型的输入图像分辨率,会导致原始模型卷积层输出无法输入全连接层的状况(后来一般都用全卷积),此时需重新改变全连接层输入滤波器大小或重新制定其他相关参数。
    • 卷积层参数的设定:主要包括卷积核大小,卷积步长和卷积核个数。
      • 卷积核大小:小卷积比大卷积优势:1增强网络容量和模型复杂度,2.减少卷积参数个数。因此一般使用3x3,5x5的小卷积
      • 步长建议为1.
      • 卷积操作可搭配填充padding操作,其有两层功效:1.可充分利用和处理输入图像的边缘信息,2.搭配合适的卷积层参数可保持输出与输入同等大小,而避免随着网络深度增加,输入大小的急剧减少。当p=(f-1)/2大小时,可维持输出与原输入大小相同。
      • 为了硬件字节级存储管理的方便,卷积核个数通常设置为2的次幂,如64,128,256,512等。这样设定有利于硬件计算过程中划分数据矩阵和参数矩阵,尤其在利用显卡计算时更为明显
    • 池化层参数设定:核大小一般设置为较小值,如2x2,3x3等。常用核大小2x2,步长2.此设定下,输出结果大小仅为输入数据长宽大小的四分之一,也就是75%响应被丢弃,这起到下采样作用。
  • 训练技巧
    • 训练数据随机打乱:从不相似的事件中学习总是比从相似实践中学习更具有信息量。训练CNN时,尽管训练数据固定,但由于采用了minibatch训练机制,因此可在模型每轮训练进行前将训练数据集随机打乱,确保模型不同轮数相同批次“看到”的数据是不同的。这样处理不仅会提高模型收敛速率,同时,相对固定次序训练的模型,此操作会略微提升模型在测试集上的预测结果。
    • 学习率设定:学习率具体可以参考下图
      • 1.模型训练初始学习率不宜过大,0.01或者0.001为宜,若发现刚开始训练几个批次损失急剧增大,说明学习率太大,应该减小学习率从头学
      • 2.训练过程中,学习率应该随轮数增加而减缓。衰减策略有很多,比如:
        • 轮数衰减:每5轮减一半
        • 指数衰减:学习率按训练轮数增长指数插值递减,
        • 分数递减:若原始学习率为lr0,学习率按照下式递减, ,其中k为超参数用来控制学习率减缓幅度,t为训练轮数
      • 模型损失在刚开始几个批次直接爆炸(黄色),则学习率过大,应大幅减少学习率从头训练网络
      • 模型一开始损失下降明显,但是后劲不足(绿色),此时应使用小学习率从头训练,或在后几轮改小学习率仅重新训练后几轮即可
      • 若模型损失下降缓慢(蓝色),应稍微加大学习率,然后继续观察曲线,直到模型呈现红色曲线的理想学习率下的训练曲线为止。
      • 注意微调(fine-tune)时学习率的设定
  • 批规范化操作(batch normalization,BN):使得网络每层输入数据分布稳定,不仅加快了模型收敛速度,更重要是在一定程度上 缓解了深层网络的梯度消失,从而使训练深层网络模型更加稳定容易,也有一定正则效果。BN不仅适合于深层网络,也适合于浅层网络。算法流程:在模型每次随机梯度下降训练时,通过mini-batch来对相应的网络响应做规范化操作,使得结果(输出信号各个维度)的均值为0,方差为1. 算法共分为四步,前两步分别计算批处理的数据均值和方差,第三步则根据计算的均值方差对该批数据进行规范化。 最后尺度变化和偏移操作是为了让因训练所需而刻意加入的BN能够有可能还原最初的输入), 从而保证整个网络的容量
    • BN为什么效果好:对NN的各层输出,由于经过了层内操作作用,其分布显然与各层对应的输入信号分布不同,而且差异会随着深度增大越来越大,不过label不变,因此就是内部协变量偏移。实验发现,可通过BN来规范化某些层或所有层的输入,从而可以固定每层输入信号的均值与方差。这样即使网络模型较深层的响应或梯度很小,也可通过BN的规范化作用将其尺度变大,以此解决深层网络训练可能带来的梯度消失问题。比如一组随机数很小,然后经过规范化后,原本微小差异被拉大,这样缓解了梯度消失现象。
    • 作用:BN一般作用在非线性映射函数前。若网络训练收敛速率慢或梯度爆炸等无法训练也可尝试用BN解决。同时BN可以加快模型训练速度,甚至提高模型精度。
    • BN在训练时和测试时差别:BN就是为了让网络在每一层都保持相近的分布。
      • 训练时:对每批数据进行归一化,也就是用每一批数据的均值和方差。对于BN,当模型训练完之后,所有参数都确定了,包括均值方差,gamma,beta
      • 测试时:比如对某样本进行预测,没有batch概念,因此均值和方差是全量训练数据的均值和方差,这可以通过移动平均法得到。
    • BN计算均值的时候计算多少次:假设[b,c,h,w],计算b*h*w次,因为是相当于对每个channel计算
    • BN共有多少个参数:2*c个参数
    • BN训练时为啥不用全量均值和方差:用全量均值和方差容易过拟合,对于BN,就是对每一批数据归一化到相同的分布,而每一批的数据均值和方差肯定是有差别的,而不是用固定值,这个差别能够增加模型鲁棒性,同时也一定程度上减少过拟合。正因如此,一般BN要求数据完全打乱,并用一个较大batch,否则,一个batch无法较好的代表训练集的分布,会影响模型的训练。若batch较小,可以使用GN(group normalization)
    • BN和dropout共同使用出现的问题:存在神经方差不一致行为。 Understanding the Disharmony between Dropout and Batch Normalization by Variance Shift。解决方法有两种:1.在BN后使用dropout,2.使用高斯dropout
BN:(batchnorm)是在batch上,对NHW做归一化,对小batchsize效果不好
LN:layernorm在通道方向上,对CHW做归一化,主要对RNN作用明显
IN:instancenorm在图像像素上,对HW做归一化,用在风格迁移上
GN:(groupnorm)将channel分组,然后再做归一化
switchableNorm将BN,LN,IN结合,赋予权重,让网络自己去学习归一化层应该使用什么方法。
BN算法过程
  • 沿着通道计算每个batch的均值u
  • 沿着通道计算每个batch的方差σ^2
  • 对x做归一化
  • 加入缩放和平移变量γ和β,归一化后的值,y=γx+β。 加入缩放平移变量的原因是:不一定每次都是标准正太分布,也许需要偏移或者拉伸。保证每一次数据经过归一化后还保留原有学习来的特征,同时又能完成归一化操作,加速训练。这两个参数是用来学习的参数
  • 缺点:对batchsize的大小比较敏感,由于每次计算均值和方差是在一个batch上,所以如果batchsize太小,则计算的均值、方差不足以代表整个数据分布。
BN代码
BN代码
import numpy as np
def Batchnorm(x, gamma, beta, bn_param):
    # x_shape:[B, C, H, W]
    running_mean = bn_param['running_mean']
    running_var = bn_param['running_var']
    results = 0.
    eps = 1e-5
    x_mean = np.mean(x, axis=(0, 2, 3), keepdims=True)
    x_var = np.var(x, axis=(0, 2, 3), keepdims=True0)
    x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
    results = gamma * x_normalized + beta
    # 因为在测试时是单个图片测试,这里保留训练时的均值和方差,用在后面测试时用
    running_mean = momentum * running_mean + (1 - momentum) * x_mean
    running_var = momentum * running_var + (1 - momentum) * x_var
    bn_param['running_mean'] = running_mean
    bn_param['running_var'] = running_var
    return results, bn_param

LN:LN针对深度网络某一层的所有神经元的输入进行normalize操作。LN中同层神经元输入拥有相同的均值和方差,不同的输入样本有不同的均值和方差。LN用于RNN效果比较明显,但是在CNN上,不如BN。

def Layernorm(x, gamma, beta):
    # x_shape:[B, C, H, W]
    results = 0.
    eps = 1e-5
    x_mean = np.mean(x, axis=(1, 2, 3), keepdims=True)
    x_var = np.var(x, axis=(1, 2, 3), keepdims=True0)
    x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
    results = gamma * x_normalized + beta
    return results

IN,instance normalization:在图像风格化中,生成结果主要依赖于某个图像实例,所以对整个batch归一化不适合图像风格化中,因而对HW做归一化。可以加速模型收敛,并且保持每个图像实例之间的独立。

def Instancenorm(x, gamma, beta):
   # x_shape:[B, C, H, W]
    results = 0.
    eps = 1e-5
    x_mean = np.mean(x, axis=(2, 3), keepdims=True)
    x_var = np.var(x, axis=(2, 3), keepdims=True0)
    x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
    results = gamma * x_normalized + beta
    return results

GN,Group normalization:主要针对bn对小batchsize效果差,GN将channel方向分group,然后每个group内做归一化,算(C//G)HW的均值,这样与batchsize无关,不受其约束

def GroupNorm(x, gamma, beta, G=16):
    # x_shape:[B, C, H, W]
    results = 0.
    eps = 1e-5
    x = np.reshape(x, (x.shape[0], G, x.shape[1]/16, x.shape[2], x.shape[3]))
    x_mean = np.mean(x, axis=(2, 3, 4), keepdims=True)
    x_var = np.var(x, axis=(2, 3, 4), keepdims=True0)
    x_normalized = (x - x_mean) / np.sqrt(x_var + eps)
    results = gamma * x_normalized + beta
    return results
  • 梯度消失的解决方法:
    • 将sigmoid换为relu等
    • 使用BN
    • 梯度裁剪
    • 更好的初始化方式(He 初始化)
    • 正则(梯度爆炸)
    • 变网络结构(比如将vgg变为resnet,加入残差结构)
    • 循环网络可以考虑用lstm
  • 网络模型优化算法选择:假设待学习参数为w,学习率(或步长)为n,一阶梯度值为g,t表示第t轮训练。
    • 随机梯度下降法SGD:每次批处理训练时计算网络误差并作误差的反向传播,后根据一阶梯度信息对参数进行更新,更新策略可表示为: 一阶梯度信息g完全依赖于当前批数据在网络目标函数上的误差,可将学习率n理解为当前批的梯度对网络整体参数更新的影响程度。收敛效果稳定,但是收敛速度慢
    • 基于动量的随机梯度下降法momentum:用于改善SGD更新时可能产生的震荡现象,通过积累前几轮的动量信息辅助参数更新,更新表达式为: ,其中u为动量因子,控制动量信息对整体梯度更新的影响程度,一般设置为0.9. 除了可以抑制震荡,还可以在网络训练中后期趋于收敛,网络参数在局部最小值附近来回震荡时跳出局部限制,找到最好的网络参数。动量因子u可以动态设置,0.5为初值,之后随着轮数增长逐渐变为0.9或者0.99
    • Nesterov型动量随机下降法:在动量梯度下降法更新梯度时加入对当前梯度的矫正。其对凸函数在收敛性证明上有更强的理论保证,实际中也有更好的表现。
    • 无论以上三种方法哪种都是为了使梯度更新更加灵活,对非凸且复杂函数空间学习更重要。但其也有自身局限,一般小学习率更加合适网络后期的优化,但这些方法学习率n却一直不变,并未将学习率的自适应性考虑进去。
    • Adagrad法:针对学习率自适应问题,Adagrad法根据训练轮数不同,对学习率进行动态调整 ,e是很小的数防止分母为0.。不过其需要人为指定一个全局学习率uglobal,同时网络训练到一定轮数后,分母上的梯度累加过大会使得学习率为0而导致训练过早结束。
    • Adadelta法:引入衰减因子p消除Adagrad法对全局学习率的依赖
    • RMSProp法:可以认为是Adadelta法的一个特例,依然使用全局学习率替换掉Adadelta法中的St
    • Adam:本质上是带有动量项的RMSProp,他利用梯度的一阶矩估计和二阶矩估计动态调整参数的学习率。主要优点在于经过偏置矫正后,每次迭代学习率都有一个范围,这样使得参数更新比较平稳。Adam仍然需要指定基本学习率n
  • 优化算法(吴恩达):
    • momentum,动量梯度下降算法,速度比随机梯度下降快很多。在每次训练时, 对其梯度做指数加权平均处理,然后用得到的梯度值更新权重w和常数项b。原始的梯度下降方法如上图蓝色折线所示。在梯度下降过程中,梯度下降的震荡较大,尤其对于w,b之间的数值范围差别较大的情况。此时每一点处的梯度只与当前的方向有关,产生类似折现的效果,前进缓慢。而 如果对梯度进行指数加权平均,这样使当前梯度不仅与当前方向有关,还与之前的方向有关,这样处理让梯度前进方向更加平滑,减少震荡,能够更快的到达最小值处。从动量的角度看,以权重w为例,Vdw可以看成速度v,dW可以看成加速度a。指数加权平均实际上是计算当前的速度,当前速度由之前的速度和现在的加速度共同影响。β<1,又能限制速度Vdw过大。也就是说当前的速度是渐变的,而不是瞬变的,是动量的过程。 这保证了梯度下降的平稳性和准确性,减少震荡,较快的达到最小值
    • 初始时令Vdw=0,Vdb=0, 一般设置β=0.9. 即指数加权平均前10天的
    • RMSProp:每次训练过程中,其权重w和常数项b的更新表达式为(下面):以下图为例分析RMSProp的原理,令水平方向为w的方向,垂直方向为b的方向。从图中可以看出,梯度下降(蓝色折线)在垂直方向(b)上震荡较大,在水平方向上(w)震荡较小,表示在b方向上梯度较大,即db较大,而在w方向上梯度较小,即dw较小。因此下面表达式中Sb较大,而Sw较小。在更新w和b的表达式中, 。也就使得w变化的多一点,b变化的少一点。即加快了w方向的速度,减小了b方向的速度,减小震荡,实现快速梯度下降算法,其梯度也就是绿色线所示。总的来说, 就是如果哪个方向震荡大,就减小该方向的更新速度,从而减小震荡。通常为了避免分母为0,可以在分母增加一个极小的常数e,其中e=10^(-8)或者较小值。
    • AdamAdaptive Moment Estimation,自适应矩估计):结合了动量梯度下降算法和RMSProp算法,其算法流程为:
    • Adam算法包含了几个超参数: 。其中β1通常设置为0.9,β2通常设置为0.999,e设置为10^(-8),一般只需要对β1和β2调整。实际应用中,Adam算法结合了动量梯度下降和RMSProp算法的优点,使得神经网络训练速度大大提高。
  • 微调神经网络finetune:由于网络在原数据上已经收敛,因此设置较小的学习率在目标数据上微调,10^(-4)以下
    • 在新数据上微调时泛化特征更新可能或程度小,高层语义特征更新可能程度大,因此对不同深度层使用不同学习率:网络深层学习率稍大于浅层学习率
    • 若目标数据极少,同时与原始数据有较大差异情况:一种有效方式是借助部分原始数据与目标数据协同训练。因为与训练模型的浅层网络特征更具有泛化性,故可在浅层特征空间选择目标数据的近邻作为原始数据的子集。之后将微调阶段改造为多目标学习任务:一者将目标任务基于原始数据子集,二者将目标任务基于全部目标数据。实验证明这样可大幅提高这种情况下的微调结果
 
10.不平衡样本的处理
不平衡的训练样本会导致训练模型侧重样本数目较多的类别,而轻视样本数目较少的类别,这样模型在测试数据上的泛华能力就会受到影响。在分类、回归、语义分割、图像深度估计等任务重经常出现。主要从数据层面和算法层面介绍不平衡样本问题的处理方法。
  • 数据层面:借助数据采样使整体训练集样本趋于平衡。
    • 数据重采样:对数据少的类上采样或扩充、样本多的类下采样。 下采样不是扔掉一部分数据,而是在每个batch控制样本类较多的数量。只使用上采样可能造成过拟合。一般上采样与下采样结合使用
    • 类别平衡采样:把样本按类别分组,每个类别生成一个样本列表。训练过程线随机选择1个或几个类别,然后从各个类别所对应的样本中随机选择样本。这样可以保证每个类别参与训练的机会均等。可以使用类别重组法(海康威视研究院提出)
  • 算法层面:对样本数目少的类别欠学习的现象,很自然的解决办法是增加小样本错分的“惩罚代价”并将惩罚代价直接体现在目标函数中,这就是代价敏感方法。这样通过优化目标函数就可以调整模型在小样本上的“注意力”。算法层面处理不平衡样本问题的方法也多从代价敏感角度出发。
    • 代价敏感方法:
      • 基于代价敏感矩阵的代价敏感
      • 基于代价敏感向量的代价敏感
    • 代价敏感法中的权重指定方式
      • 按照样本比例指定
      • 根据混淆矩阵指定
 
 
11.模型集成方法
  • 数据层面的集成方法
    • 测试阶段数据扩充:图像多尺度,随机抽取等。比如随机抽取,对某张测试图像可得到n张随机抽取图像,测试阶段只需要用训练好的网络对n张图片分别预测,将结果置信度平均作为该图片的结果。
    • 简易集成法:对于样本较多的类采用降采样,每次采样数依照样本数目最少的类别而定,这样每类取到的样本数可保持均等。采样结束后,针对每次采样得到的子数据集训练模型,如此训练采样反复多次。最后对测试数据的预测依据训练得到的若干个模型的结果取平均或投票获得。这样,在模型集成的同时,还能够缓解数据不平衡带来的问题。
  • 模型层面的集成方法
    • 单模型集成
      • 多层特征融合:深度CNN具有层次性的特点,不同层特征包含的语义特征可以互补。一般多层特征融合操作时可直接将不同层网络特征级联。对于特征融合应该选择哪些网络层,实践经验:最好使用靠近目标函数的几层卷积特征,因为越深层特征包含的高层语义性越强,分辨能力越强。低层特征较普适,用于特征融合可能起不到作用甚至会起到相反作用。
      • 网络快照集成法:NN存在许多局部最优解,经典的minibatchSGD只能让网络模型收敛到其中一个局部最优解。快照法利用这些局部最优解对单个网络模型集成。通过循环调整网络学习率可使网络依次收敛到不同的局部最优解处。
    • 多模型集成:
      • 多模型生成策略:
        • 同一模型不同初始化:特别对小样本学习场景,先对同一模型不同初始化,之后将得到的网络模型进行结果集成会缓解其随机性,提升最终结果的预测任务。
        • 同一模型不同训练轮数:可降低随机误差,也避免了训练轮数过多带来的过拟合风险。
        • 不同目标函数:交叉熵损失,合页损失,大间隔交叉熵损失,中心损失等作为目标函数训练模型。预测时可对不同模型置信度级别进行平均或者投票。也可以做特征级别模型集成:将不同网络得到的深度特征抽出级联后作为最终特征,最后离线训练浅层分类器完成预测任务。
        • 不同网络结构:vgg,resnet等不同模型集成
      • 多模型集成方法:
        • 直接平均法
        • 加权平均法
        • 投票法
        • 堆叠法stacking:以一阶学习过程的输出作为输入开展二阶学习的过程,也成为元学习(meta learning)。学习器可以使任何学习算法模型,svm,rf,nn等。但堆叠法有过拟合风险。
 
 
 
 
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值