- 使不同量纲的特征处于同一数值量级,减少方差大的特征的影响,使模型更准确。
- 加快学习算法的收敛速度。
参考资料: 归一化 (Normalization)、标准化 (Standardization)和中心化/零均值化 (Zero-centered),《百面机器学习》
- 线性归一化(min-max标准化)
x’ = (x-min(x)) / (max(x)-min(x)),其中max是样本数据的最大值,min是样本数据的最小值 适用于数值比较集中的情况,可使用经验值常量来来代替max,min - 标准差归一化(z-score 0均值标准化) x’=(x-μ) / σ,其中μ为所有样本的均值,σ为所有样本的标准差 经过处理后符合标准正态分布,即均值为0,标准差为1
- 非线性归一化
使用非线性函数log、指数、正切等,如y = 1-e^(-x),在x∈[0, 6]变化较明显, 用在数据分化比较大的场景
空洞卷积(Atrous Convolution)也叫做膨胀卷积、扩张卷积,最初的提出是为了解决图像分割在用下采样(池化、卷积)增加感受野时带来的特征图缩小,后再上采样回去时造成的精度上的损失。空洞卷积通过引入了一个扩张率的超参数,该参数定义了卷积核处理数据时各值的间距。
可以在增加感受野的同时保持特征图的尺寸不变,从而代替下采样和上采样,通过调整扩张率得到不同的感受野不大小:
a. 是普通的卷积过程(dilation rate = 1),卷积后的感受野为3
b. 是dilation rate = 2的空洞卷积,卷积后的感受野为5
c. 是dilation rate = 3的空洞卷积,卷积后的感受野为8
可以这么说,普通卷积是空洞卷积的一种特殊情况
参考资料: 吃透空洞卷积(Dilated Convolutions)、『计算机视觉』空洞卷积
在构建模型的过程中,通常会划分训练集、测试集。
当模型在训练集上精度很高,在测试集上精度很差时,模型过拟合;当模型在训练集和测试集上精度都很差时,模型欠拟合。
预防过拟合策略:
- 增加训练数据:获取更多数据,也可以使用图像增强、增样等;
- 使用合适的模型:适当减少网络的层数、降低网络参数量;
- Dropout:随机抑制网络中一部分神经元,使的每次训练都有一批神经元不参与模型训练;
- L1、L2正则化:训练时限制权值的大小,增加惩罚机制,使得网络更稀疏;
- 数据清洗:去除问题数据、错误标签和噪声数据;
- 限制网络训练时间:在训练时将训练集和验证集损失分别输出,当训练集损失持续下降,而验证集损失不再下降时,网络就开始出现过拟合现象,此时就可以停止训练了;
- 在网络中使用BN层(Batch Normalization)也可以一定程度上防止过拟合。
参考资料:N,LN,IN,GN都是什么?不同归一化方法的比较、深度学习中的五种归一化(BN、LN、IN、GN和SN)方法简介、层归一化,循环批归一化(2016)和批归一化RNN(2015)有什么区别?
主要有三大类:
a. 基本梯度下降法,包括 GD,BGD,SGD;
b. 动量优化法,包括 Momentum,NAG 等;
c. 自适应学习率优化法,包括 Adam,AdaGrad,RMSProp 等。
参考资料: 从SGD到NadaMax,十种优化算法原理及实现
- 感受野指的是卷积神经网络每一层输出的特征图上每个像素点映射回输入图像上的区域的大小,神经元感受野的范围越大表示其接触到的原始图像范围就越大,也就意味着它能学习更为全局,语义层次更高的特征信息,相反,范围越小则表示其所包含的特征越趋向局部和细节。因此感受野的范围可以用来大致判断每一层的抽象层次,并且我们可以很明显地知道网络越深,神经元的感受野越大。
- 卷积层的感受野大小与其之前层的卷积核尺寸和步长有关,与padding无关。 计算CNN的感受野
神经网络的深度决定了网络的表达能力,早期的backbone设计都是直接堆叠卷积层,它的深度指的是神经网络的层数;后来的backbone设计采用了更高效的module(或block)堆叠的方式,每个module是由多个卷积层组成,这时深度指的是module的个数。
神经网络的宽度决定了网络在某一层学习到的信息量,指的是卷积神经网络中最大的通道数,由卷积核数量最多的层决定。通常的结构设计中卷积核的数量随着层数越来越多的,直到最后一层feature map达到最大,这是因为越到深层,feature map的分辨率越小,所包含的信息越高级,所以需要更多的卷积核来进行学习。通道越多效果越好,但带来的计算量也会大大增加,所以具体设定也是一个调参的过程,并且各层通道数会按照8×的倍数来确定,这样有利于GPU的并行计算。
在卷积神经网络中,由于输入图像通过卷积神经网络(CNN)提取特征后,输出的尺寸往往会变小,而有时我们需要将图像恢复到原来的尺寸以便进行进一步的计算(如图像的语义分割),这个使图像由小分辨率映射到大分辨率的操作,叫做上采样,它的实现一般有三种方式:
a. 插值,一般使用的是双线性插值,因为效果最好,虽然计算上比其他插值方式复杂,但是相对于卷积计算可以说不值一提,其他插值方式还有最近邻插值、三线性插值等;
b. 转置卷积又或是说反卷积,通过对输入feature map间隔填充0,再进行标准的卷积计算,可以使得输出feature map的尺寸比输入更大;
c. Max Unpooling,在对称的max pooling位置记录最大值的索引位置,然后在unpooling阶段时将对应的值放置到原先最大值位置,其余位置补0;
参考资料:深度卷积网络中如何进行上采样?、三种上采样方法 | Three up sampling methods、上采样(upsampling)
下采样层有两个作用,一是减少计算量,防止过拟合;二是增大感受野,使得后面的卷积核能够学到更加全局的信息。
下采样的方式主要有两种:
a. 采用stride为2的池化层,如Max-pooling和Average-pooling,目前通常使用Max-pooling,因为他计算简单而且能够更好的保留纹理特征;
b. 采用stride为2的卷积层,下采样的过程是一个信息损失的过程,而池化层是不可学习的,用stride为2的可学习卷积层来代替pooling可以得到更好的效果,当然同时也增加了一定的计算量。
参考资料:CNN详解(卷积层及下采样层)
参数量指的是网络中可学习变量的数量,包括卷积核的权重weights,批归一化(BN)的缩放系数γ,偏移系数β,有些没有BN的层可能有偏置bias,这些都是可学习的参数,即在模型训练开始前被赋予初值,在训练过程根据链式法则不断迭代更新,整个模型的参数量主要是由卷积核的权重weights的数量决定,参数量越大,则该结构对平台运行的内存要求越高。
参数量的计算方式:
- Kh × Kw × Cin × Cout (Conv卷积网络)
- Cin × Cout (FC全连接网络)
神经网络的前向推理过程基本上都是乘累加计算,所以它的计算量也是指的前向推理过程中乘加运算的次数,通常用FLOPs来表示,即floating point operations(浮点运算数)。计算量越大,在同一平台上模型运行延时越长,尤其是在移动端/嵌入式这种资源受限的平台上想要达到实时性的要求就必须要求模型的计算量尽可能地低,但这个不是严格成正比关系,也跟具体算子的计算密集程度(即计算时间与IO时间占比)和该算子底层优化的程度有关。
FLOPs的计算方式:
- Kh × Kw × Cin × Cout × H × W = params × H × W (Conv卷积网络)
- Cin x Cout (FC全连接网络)
- 计算量 = 输出的feature map * 当前层filter 即(H × W × Cout) × (K × K × Cin)
参考资料:CNN 模型所需的计算力flops是什么?怎么计算?、pytorch: 计算网络模型的计算量(FLOPs)和参数量(Params)、神经网络的计算量和参数量估计总结
深度可分离卷积将传统的卷积分两步进行,分别是depthwise和pointwise。首先按照通道进行计算按位相乘的计算,深度可分离卷积中的卷积核都是单通道的,输出不能改变feature map的通道数,此时通道数不变;然后依然得到将第一步的结果,使用1*1的卷积核进行传统的卷积运算,此时通道数可以进行改变。
计算量的前后对比:
Kh × Kw × Cin × Cout × H × W
变成了 Kh × Kw × Cin × H × W + 1 × 1 × Cin × Cout × H × W
Addition和Concatenate分支操作统称为shortcut,Addition是在ResNet中提出,两个相同维度的feature map相同位置点的值直接相加,得到新的相同维度feature map,这个操作可以融合之前的特征,增加信息的表达,Concatenate操作是在Inception中首次使用,被DenseNet发扬光大,和addition不同的是,它只要求两个feature map的HW相同,通道数可以不同,然后两个feature map在通道上直接拼接,得到一个更大的feature map,它保留了一些原始的特征,增加了特征的数量,使得有效的信息流继续向后传递。
参考资料:The difference and connection between contact and add operation (feature fusion)
激活函数(又叫激励函数,后面就全部统称为激活函数)是模型整个结构中的非线性扭曲力,神经网络的每层都会有一个激活函数。
常用的激活函数:Sigmoid函数、tanh函数、Relu函数、Leaky ReLU函数(PReLU)、ELU (Exponential Linear Units) 函数、MaxOut函数
参考资料:常用激活函数的比较、深度学习领域最常用的10个激活函数,一文详解数学原理及优缺点、26种神经网络激活函数可视化、深度学习笔记——常用的激活(激励)函数
- 降维,减少计算量;在ResNet模块中,先通过1×1卷积对通道数进行降通道,再送入3×3的卷积中,能够有效的减少神经网络的参数量和计算量;
- 升维;用最少的参数拓宽网络通道,通常在轻量级的网络中会用到,经过深度可分离卷积后,使用1×1卷积核增加通道的数量,例如mobilenet、shufflenet等;
- 实现跨通道的交互和信息整合;增强通道层面上特征融合的信息,在feature map尺度不变的情况下,实现通道升维、降维操作其实就是通道间信息的线性组合变化,也就是通道的信息交互整合的过程;
- 1×1卷积核可以在保持feature map尺度(不损失分辨率)不变的情况下,大幅增加非线性特性(利用后接的非线性激活函数)。
参考资料:卷积神经网络中用1*1 卷积有什么作用或者好处呢?、深度学习——1×1卷积核理解
- 当处理大量数据时,比如SSD或者faster-rcnn等目标检测算法,每个样本都有大量候选框参与训练,这时使用随机梯度下降法能够加快梯度的计算;
- 每次只随机选取一个样本来更新模型参数,因此每次的学习是非常快速的,并且可以进行在线更新。
不能,因为初始化权重是0,每次传入的不同数据得到的结果是相同的。网络无法更新
权重初始化的目的是在深度神经网络中前向传递时,阻止网络层的激活函数输出爆炸(无穷大)或者消失(0)。如果网络层的输出爆炸或者消失,损失函数的梯度也会变得很大或者很小,无法有效后向传递,使得神经网络需要更长的时间才能收敛甚至无法收敛。
初始化方法有: Xavier初始化、Kaiming初始化、随机初始化
参考资料:神经网络中的权重初始化一览:从基础到Kaiming、深度学习中神经网络的几种权重初始化方法、神经网络参数初始化方法
空洞卷积、池化操作、较大卷积核尺寸的卷积操作
- 数据增强(镜像对称、随机裁剪、旋转图像、剪切图像、局部弯曲图像、色彩转换)
- early stopping(比较训练损失和验证损失曲线,验证损失最小即为最优迭代次数)
- L2正则化(权重参数的平方和)
- L1正则化(权重参数的绝对值之和)
- dropout 正则化(设置keep_pro参数随机让当前层神经元失活)
原因:激活函数的选择。
梯度消失:令bias=0,则神经网络的输出结果等于各层权重参数的积再与输入数据集相乘,若参数值较小时,则权重参数呈指数级减小。
梯度爆炸:令bias=0,则神经网络的输出结果等于各层权重参数的积再与输入数据集相乘,若参数值较大时,则权重参数呈指数级增长。
参考资料:出现梯度消失与梯度爆炸的原因以及解决方案、详解机器学习中的梯度消失、爆炸原因及其解决方法
传统的计算机视觉方法需首先基于经验手动设计特征,然后使用分类器分类,这两个过程都是分开的。而深度学习里的卷积网络可实现对局部区域信息的提取,获得更高级的特征,当神经网络层数越多时,提取的特征会更抽象,将更有助于分类,同时神经网路将提取特征和分类融合在一个结构中。
- 在前向传播和反向传播过程中,ReLU相比于Sigmoid等激活函数计算量小;
- 在反向传播过程中,Sigmoid函数存在饱和区,若激活值进入饱和区,则其梯度更新值非常小,导致出现梯度消失的现象。而ReLU没有饱和区,可避免此问题;
- ReLU可令部分神经元输出为0,造成网络的稀疏性,减少前后层参数对当前层参数的影响,提升了模型的泛化性能。
- 卷积层是局部连接,所以提取的是局部信息;全连接层是全局连接,所以提取的是全局信息;
- 当卷积层的局部连接是全局连接时,全连接层是卷积层的特例;
所谓的正则化,就是在原来 Loss Function 的基础上,加了一些正则化项,或者叫做模型复杂度惩罚项,正则化机器学习中一种常用的技术,其主要目的是控制模型复杂度,减小过拟合。
两者的区别:
L1:它的优良性质是能产生稀疏性,导致 W 中许多项变成零。 稀疏的解除了计算量上的好处之外,更重要的是更具有“可解释性”。
L2:使得模型的解偏向于范数较小的 W,通过限制 W 范数的大小实现了对模型空间的限制,从而在一定程度上避免了过拟合。不过岭回归并不具有产生稀疏解的能力,得到的系数仍然需要数据中的所有特征才能计算预测结果,从计算量上来说并没有得到改观。
L1范数更容易产生稀疏的权重,L2范数更容易产生分散的权重
参考资料:l1正则与l2正则的特点是什么,各有什么优势?、深入理解L1、L2正则化
平方损失(预测问题)、交叉熵(分类问题)、hinge损失(SVM支持向量机)、CART回归树的残差损失
总结 | 深度学习损失函数大全
防止参数过分依赖训练数据,减少神经元之间复杂的共适应关系,增加参数对数据集的泛化能力。
一般来说,在合理的范围之内,越大的 batch size 使下降方向越准确,震荡越小;batch size 如果过大,则可能会出现内存爆表和局部最优的情况。小的 bath size 引入的随机性更大,难以达到收敛,极少数情况下可能会效果变好。
参考资料:深度学习中的batch的大小对学习效果有何影响?,深度学习中Batch size对训练效果的影响
- TensorFlow与PyTorch编程方式不同
PyTorch:命令式编程;TensorFlow:符号式编程 - 图的创建及调试不同
pytorch 图结构的创建是动态的,即图是运行时创建;更易调试pytorch代码,调试pytorch代码就像调试python代码一样,可以利用pdp在任何地方设置断点 - 灵活性、设备管理不同
参考资料:pytorch 和 tensorflow的区别和选择;TensorFlow与PyTorch编程方式不同
tensorflow 图结构的创建是静态的,即图首先被"编译",然后在运行;不易调试要么从会话请求检查变量,要么学习使用tfdbg调试器
参考资料:Pytorch 分布式训练;深度学习框架分布式训练总结
- 欠采样 - 随机删除观测数量足够多的类,使得两个类别间的相对比例是显著的。虽然这种方法使用起来非常简单,但很有可能被我们删除了的数据包含着预测类的重要信息。
- 过采样 - 对于不平衡的类别,我们使用拷贝现有样本的方法随机增加观测数量。理想情况下这种方法给了我们足够的样本数,但过采样可能导致过拟合训练数据。
- 合成采样( SMOTE )-该技术要求我们用合成方法得到不平衡类别的观测,该技术与现有的使用最近邻分类方法很类似。问题在于当一个类别的观测数量极度稀少时该怎么做。比如说,我们想用图片分类问题确定一个稀有物种,但我们可能只有一幅这个稀有物种的图片。
- 在loss方面,采用focal loss等loss进行控制不平衡样本。
反馈神经网络正常工作需要的条件就是每一个点提供一个方向,即导数;0值不可微,本质上来说是因为这个地方可画多条切线,但我们需要的只是一条;由于这出现的0值的概率极低,任意选择一个子梯度就OK了,在0处的次微分集合是【0,1】;即选择其中一个就OK了;一般默认是0;
池化层没有可以训练的参数,因此在卷积神经网络的训练中,池化层只需要将误差传递到上一层,并不需要做梯度的计算。要追求一个原则,那就是梯度之和不变。
- average pooling: 前向传播是取某特征区域的平均值进行输出,这个区域的每一个神经元都是有参与前向传播了的,因此,在反向传播时,框架需要将梯度平均分配给每一个神经元再进行反向传播;
- max pooling: 前向传播是取某特征区域的最大值进行输出,这个区域仅有最大值神经元参与了前向传播,因此,在反向传播时,框架仅需要将该区域的梯度直接分配到最大值神经元即可,其他神经元的梯度被分配为0且是被舍弃不参与反向传播的,但如何确认最大值神经元,这个还得框架在进行前向传播时记录下最大值神经元的Max ID位置。
- 作用:对输入的特征图进行压缩,一方面使特征图变小,简化网络计算复杂度;一方面进行特征压缩,提取主要特征。
- 通常来讲,max-pooling的效果更好,虽然max-pooling和average-pooling都对数据做了下采样,但是max-pooling感觉更像是做了特征选择,选出了分类辨识度更好的特征,提供了非线性。 pooling的主要作用一方面是去掉冗余信息,一方面要保留feature map的特征信息,在分类问题中,我们需要知道的是这张图像有什么object,而不大关心这个object位置在哪,在这种情况下显然max pooling比average pooling更合适。在网络比较深的地方,特征已经稀疏了,从一块区域里选出最大的,比起这片区域的平均值来,更能把稀疏的特征传递下去。
- average-pooling更强调对整体特征信息进行一层下采样,在减少参数维度的贡献上更大一点,更多的体现在信息的完整传递这个维度上,在一个很大很有代表性的模型中,比如说DenseNet中的模块之间的连接大多采用average-pooling,在减少维度的同时,更有利信息传递到下一个模块进行特征提取。
- average-pooling在全局平均池化操作中应用也比较广,在ResNet和Inception结构中最后一层都使用了平均池化。有的时候在模型接近分类器的末端使用全局平均池化还可以代替Flatten操作,使输入数据变成一维向量。
参考资料:计算机视觉面试常见问题
反向传播算法的motivation是期望通过在神经网络的训练过程中自适应的调整各神经元间的连接权值,以寻求最佳的输入输出间的映射函数,使得目标函数或损失函数达到最小,完成分类、回归等任务。
手推反向传播公式:BP(反向传播算法)公式推导及例题解析
CNN的卷积运算并非数学定义的卷积,CNN中的运算是不需要翻转卷积核的。
参考答案:卷积神经网络发展历程;CNN模型演变;一文详解卷积神经网络的演变历程!
优势:
- 拟合复杂的函数:随着神经网络层数的加深,网络的非线性程度愈来愈高,从而可拟合更加复杂的函数;
- 结构灵活:神经网络的结构可根据具体的任务进行相应的调整,选择适合的网络结构;
参考资料:深度学习 优缺点
- 单样本几何变换:翻转,旋转,裁剪,缩放
- 单样本像素内容变换:噪声,模糊,颜色扰动
- 多样本插值 Mixup:图像和标签都进行线性插值
参考资料:计算机视觉中的数据增强
warm up, 在刚刚开始训练时以很小的学习率进行训练,使得网络熟悉数据,随着训练的进行学习率慢慢变大,到了一定程度,以设置的初始学习率进行训练,接着过了一些inter后,学习率再慢慢变小;学习率变化:上升——平稳——下降。
- 有助于减缓模型在初始阶段对mini-batch的提前过拟合现象,保持分布的平稳;
- 有助于保持模型深层的稳定性。
参考资料:深度学习 warmup 策略;神经网络中 warmup 策略为什么有效;有什么理论解释么?
2个3*3的卷积核串联和5*5的卷积核有相同的感知野,前者拥有更少的参数。多个3*3的卷积核比一个较大尺寸的卷积核有更多层的非线性函数,增加了非线性表达,使判决函数更具有判决性。
若卷积神将网络的上一层有N个卷积核,则对应的通道数也为N。设群数目为M,在进行卷积操作的时候,将通道分成M份,每个group对应N/M个通道,然后每个group卷积完成后输出叠在一起,作为当前层的输出通道。
并不能说明这个模型无效,导致模型不收敛的原因可能有数据分类的标注不准确,样本的信息量太大导致模型不足以fit整个样本空间。学习率设置的太大容易产生震荡,太小会导致不收敛。可能复杂的分类任务用了简单的模型。数据没有进行归一化的操作。
Sigmoid的导数只有在0的附近时有较好的激活性,而在正负饱和区域的梯度趋向于0,从而产生梯度弥散的现象,而relu在大于0的部分梯度为常数,所以不会有梯度弥散现象。Relu的导数计算的更快。Relu在负半区的导数为0,所以神经元激活值为负时,梯度为0,此神经元不参与训练,具有稀疏性。
神经网络在训练的时候随着网络层数的加深,激活函数的输入值的整体分布逐渐往激活函数的取值区间上下限靠近,从而导致在反向传播时低层的神经网络的梯度消失。而BatchNormalization的作用是通过规范化的手段,将越来越偏的分布拉回到标准化的分布,使得激活函数的输入值落在激活函数对输入比较敏感的区域,从而使梯度变大,加快学习收敛速度,避免梯度消失的问题。
GAN用一个生成模型和一个判别模型,判别模型用于判断给定的图片是不是真实的图片,生成模型自己生成一张图片和想要的图片很像,开始时两个模型都没有训练,然后两个模型一起进行对抗训练,生成模型产生图片去欺骗判别模型,判别模型去判别真假,最终两个模型在训练过程中,能力越来越强最终达到稳态。
减少处理高维输入数据的计算负担,结构化的选取输入的子集,从而降低数据的维度。让系统更加容易的找到输入的数据中与当前输出信息相关的有用信息,从而提高输出的质量。帮助类似于decoder这样的模型框架更好的学到多种内容模态之间的相互关系。
从数据上提升性能:收集更多的数据,对数据做缩放和变换,特征组合和重新定义问题。 从算法调优上提升性能:用可靠的模型诊断工具对模型进行诊断,权重的初始化,用小的随机数初始化权重。对学习率进行调节,尝试选择合适的激活函数,调整网络的拓扑结构,调节batch和epoch的大小,添加正则化的方法,尝试使用其它的优化方法,使用early stopping。
DNN的输入是向量形式,并未考虑到平面的结构信息,在图像和NLP领域这一结构信息尤为重要,例如识别图像中的数字,同一数字与所在位置无关(换句话说任一位置的权重都应相同),CNN的输入可以是tensor,例如二维矩阵,通过filter获得局部特征,较好的保留了平面结构信息。
参考答案:DNN的梯度更新方式
首先,caffe原先的gpu实现group convolution很糟糕,用for循环每次算一个卷积,速度极慢。第二,cudnn7.0及之后直接支持group convolution,但本人实测,速度比github上几个直接写cuda kernel计算的dw convolution速度慢。例如对于n=128, c=512, h=32, w=32, group=512的卷积跑100次,cudnn 7.0里的group convolution需要4秒多,而DepthwiseConvolution大概只需要1秒。
分析了一下dw convolution与普通convolution的理论计算复杂度,举例如下:
卷积1:普通卷积,输入为64*64*256,输出为64*64*256,卷积核大小为3*3。参数为3*3*256*256=590K,计算量为64*64*256*3*3*256=2.42G,计算过程的工作集内存总量(输入输出数据+参数)为64*64*256*2 + 3*3*256*256 = 2.69M。
卷积2:dw卷积,输入为64*64*256,输出为64*64*256,卷积核大小为3*3。参数为3*3*256=2.3K个,计算量为64*64*256*3*3=9.44M,计算过程的工作集内存总量为64*64*256*2 + 3*3*256=2.10M。
卷积3:普通卷积,输入为64*64*16,输出为64*64*16,卷积核大小为3*3。参数为3*3*16*16=2.3K个,计算量为64*64*16*3*3*16=9.44M,计算过程的工作集内存总量为64*64*16*2 + 3*3*16*16=133K。
可以看到卷积2肯定比卷积1快,因为计算量下降到1/256了,但卷积2实际上无法达到卷积1的256倍速度(我记得我测得结果大概是快10倍左右),因为工作集内存大小并没有显著降低。卷积2也无法达到卷积3的速度,因为虽然FLOPS相同,但工作集内存大小相差了很多倍,因此单位数据的计算密度小很多,很难充分利用GPU上的计算单元。