Bootstrap

CV面试题

CV

1、什么是归一化,它与标准化的区别是什么?

归一化主要是应用于没有距离计算的地方上,标准化则是使用在不关乎权重的地方上,因为各自丢失了距离信息和权重信息,最后还讲述了下归一化的使用场景,主要是针对数据分布差异比较大–标准化和奇异数据(单个数据对结果有影响的话)–归一化的情况下的使用

一、不同点

  1. 从概念上:归一化是将数值规范到(0,1)或(-1,1)之间。标准化是将数据分布在均值为0,标准差为1的分布上(近似高斯分布)。

  2. 从侧重点上:归一化丢失了数据分布信息,没有保留数据之间的距离,但是保留了权值,换句话说就是得到一种映射关系。标准化保留了数据的分布信息,但是没有保留权重。(数据之间的距离也就是数值与数值的差或者一些其他距离法则,也就是数据之间的关系。权重就是权值,标准化得到的分布而无权重)。

  3. 从缺点上:

    归一化:1.数据之间没有距离信息。2.鲁棒性差,数据容易受到最大值和最小值的影响,也就是容易收到异常点影响,比较适合小数据场景。

    标准化:1.丢失了数据的权重信息。

  4. 从使用场景上:

    归一化:1.适用于小数据/固定数据。2.没有距离度量和数据不符合正态分布的场景。

    标准化:1.分类、聚类算法使用距离度量相似性的场景。2.大样本(样本越大,分布越合理)。3.对超出取值范围的异常点或者最小值、最大值未知的场景(不需要关心异常值,只关心分布)。

  5. 从目的上:

    归一化:消除量纲(指标单位不统一)

    标准化:便于后续的梯度下降和激活函数对数据的处理(因为标准化后数据以0为中心分布,而激活函数如sigmoid等也是以0为中心分布)。

二、相同点

  1. 联系:归一化广义上是包含标准化的
  2. 本质上都是进行特征提取,都是将数据先平移(分子相减)然后在放缩(除以分母),都是缩小范围便于后续处理。
  3. 作用:(重点)1.加快梯度下降,损失函数的收敛–速度上(未进行归一化处理前,梯度方向离最小值方向会有很大差别,处理后可以少走很多弯路)。2.提升模型精度–准确率(往往只有数据好,模型才会更好)。3.防止梯度爆炸—稳定性上。(消除因为数据输入差距(1和2000)过大,而带来的输出差距过大(0.8,999),进而在 反向传播的过程当中,导致梯度过大(因为反向传播的过程当中进行梯度计算,会使用的之前对应层的输入x),从而形成梯度爆炸)

2、如何确定CNN的卷积核通道数和卷积输出层的通道数?

CNN的卷积核通道数 = 卷积输入层的通道数;CNN的卷积输出层通道数 = 卷积核的个数

3、什么是卷积?

对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)的操作就是所谓的『卷积』操作,也是卷积神经网络的名字来源。

4、什么是池化?

池化,简言之,即取区域平均或最大。

5、你有什么调参经验?

(1)relu+bn。这套好基友组合是万精油,可以满足95%的情况,除非有些特殊情况会用identity,比如回归问题,比如resnet的shortcut支路,sigmoid什么的都快从我世界里消失了
(2)dropout 。分类问题用dropout ,只需要最后一层softmax 前用基本就可以了,能够防止过拟合,可能对accuracy提高不大,但是dropout 前面的那层如果是之后要使用的feature的话,性能会大大提升
(3)数据的shuffle 和augmentation 。这个没啥好说的,aug也不是瞎加,比如行人识别一般就不会加上下翻转的,因为不会碰到头朝下的异型种
(4)降学习率。随着网络训练的进行,学习率要逐渐降下来,如果你有tensorboard,你有可能发现,在学习率下降的一瞬间,网络会有个巨大的性能提升,同样的fine-tuning也要根据模型的性能设置合适的学习率,比如一个训练的已经非常好的模型你上来就1e-3的学习率,那之前就白训练了,就是说网络性能越好,学习率要越小

(5)tensorboard。以前不怎么用,用了之后发现太有帮助,帮助你监视网络的状态,来调整网络参数
(6)随时存档模型,要有validation 。这就跟打游戏一样存档,把每个epoch和其对应的validation 结果存下来,可以分析出开始overfitting的时间点,方便下次加载fine-tuning
(7)网络层数,参数量什么的都不是大问题,在性能不丢的情况下,减到最小
(8)batchsize通常影响没那么大,塞满卡就行,除了特殊的算法需要batch大一点
(9)输入减不减mean归一化在有了bn之后已经不那么重要了
上面那些都是大家所知道的常识,也是外行人觉得深度学习一直在做的就是这些很low的东西,其实网络设计上博大精深,这也远超过我的水平范畴,只说一些很简单的

(10)卷积核的分解。从最初的5×5分解为两个3×3,到后来的3×3分解为1×3和3×1,再到resnet的1×1,3×3,1×1,再xception的3×3 channel-wise conv+1×1,网络的计算量越来越小,层数越来越多,性能越来越好,这些都是设计网络时可以借鉴的
(11)不同尺寸的feature maps的concat,只用一层的feature map一把梭可能不如concat好,pspnet就是这种思想,这个思想很常用
(12)resnet的shortcut确实会很有用,重点在于shortcut支路一定要是identity
(13)针对于metric learning,对feature加个classification 的约束通常可以提高性能加快收敛

9、为什么不同的机器学习领域都可以使用CNN,CNN解决了这些领域的哪些共性问题?他是如何解决的?

CNN的关键是卷积运算,卷积核与卷积输入层进行局部连接可以获取整个输入的局部特征信息或者说是每个输入特征的组合特征。所以CNN的本质是完成了特征提取或者说是对原始特征的特征组合工作,从而增加模型的表达能力。不同领域的机器学习都是通过数据的特征进行建模,从而解决该领域的问题。故CNN解决了不同领域的特征提取问题,所用的方法是基于局部连接/权值共享/池化操作/多层次结构。

12、为什么引入非线性激励函数?

深度学习的前提是神经网络的隐层加上了非线性激活函数,提升了模型的非线性表达能力,使得神经网络可以逼近任意复杂的函数。假如有一个100层的全连接神经网络,其隐层的激活函数都是线性的,则从输入层到输出层实际上可以用一层全连接来等价替换,这样就无法实现真正的深度学习。举个简单的例子,线性函数 f(x)=2x+3 对 x 经过三次相同的线性变换等价于对 x 只进行一次线性变换:f(f(f(x)))=2(2(2x+3)+3)+3=8x+21。

13、请问人工神经网络中为什么ReLu要好过于tanh和sigmoid function?

第一,采用sigmoid等函数,算激活函数时(指数运算),计算量大,反向传播求误差梯度时,求导涉及除法和指数运算,计算量相对大,而采用Relu激活函数,整个过程的计算量节省很多。

第二,对于深层网络,sigmoid函数反向传播时,很容易就会出现梯度消失的情况(在sigmoid接近饱和区时,变换太缓慢,导数趋于0,这种情况会造成信息丢失),这种现象称为饱和,从而无法完成深层网络的训练。而ReLU就不会有饱和倾向,不会有特别小的梯度出现。

第三,Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。当然现在也有一些对relu的改进,比如prelu,random relu等,在不同的数据集上会有一些训练速度上或者准确率上的改进。

16、什么样的数据集不适合用深度学习?

1、数据集太小,数据样本不足时,深度学习相对其它机器学习算法,没有明显优势。

2、数据集没有局部相关特性,目前深度学习表现比较好的领域主要是图像/语音/自然语言处理等领域,这些领域的一个共性是局部相关性。图像中像素组成物体,语音信号中音位组合成单词,文本数据中单词组合成句子,这些特征元素的组合一旦被打乱,表示的含义同时也被改变。对于没有这样的局部相关性的数据集,不适于使用深度学习算法进行处理。举个例子:预测一个人的健康状况,相关的参数会有年龄、职业、收入、家庭状况等各种元素,将这些元素打乱,并不会影响相关的结果。

18、如何缓解梯度消失和梯度膨胀(微调、梯度截断、改良激活函数等)

梯度膨胀:根据链式法则,如果每一层神经元对上一层的输出的偏导乘上权重结果都大于1的话,在经过足够多层传播之后,误差对输入层的偏导会趋于无穷大
可以通过激活函数来解决,或用Batch Normalization解决这个问题。

具体而言,梯度消失爆炸的解决方案主要包括以下几个部分:

  • 预训练加微调
  • 梯度剪切、权重正则(针对梯度爆炸)
  • 使用不同的激活函数
  • 使用batchnorm
  • 使用残差结构
  • 使用LSTM网络

22、神经网络中激活函数的真正意义?一个激活函数需要具有哪些必要的属性?还有哪些属性是好的属性但不必要的?

  1. 非线性:即导数不是常数。这个条件是多层神经网络的基础,保证多层网络不退化成单层线性网络。这也是激活函数的意义所在。
  2. 几乎处处可微:可微性保证了在优化中梯度的可计算性。传统的激活函数如sigmoid等满足处处可微。对于分段线性函数比如ReLU,只满足几乎处处可微(即仅在有限个点处不可微)。对于SGD算法来说,由于几乎不可能收敛到梯度接近零的位置,有限的不可微点对于优化结果不会有很大影响[1]。
  3. 计算简单:非线性函数有很多。极端的说,一个多层神经网络也可以作为一个非线性函数,类似于Network In Network中把它当做卷积操作的做法。但激活函数在神经网络前向的计算次数与神经元的个数成正比,因此简单的非线性函数自然更适合用作激活函数。这也是ReLU之流比其它使用Exp等操作的激活函数更受欢迎的其中一个原因。
  4. 非饱和性(saturation):饱和指的是在某些区间梯度接近于零(即梯度消失),使得参数无法继续更新的问题。最经典的例子是Sigmoid,它的导数在x为比较大的正值和比较小的负值时都会接近于0。更极端的例子是阶跃函数,由于它在几乎所有位置的梯度都为0,因此处处饱和,无法作为激活函数。ReLU在x>0时导数恒为1,因此对于再大的正值也不会饱和。但同时对于x<0,其梯度恒为0,这时候它也会出现饱和的现象(在这种情况下通常称为dying ReLU)。Leaky ReLU[3]和PReLU的提出正是为了解决这一问题。
  5. 单调性(monotonic):即导数符号不变。这个性质大部分激活函数都有,除了诸如sin、cos等。个人理解,单调性使得在激活函数处的梯度方向不会经常改变,从而让训练更容易收敛。
  6. 输出范围有限:有限的输出范围使得网络对于一些比较大的输入也会比较稳定,这也是为什么早期的激活函数都以此类函数为主,如Sigmoid、TanH。但这导致了前面提到的梯度消失问题,而且强行让每一层的输出限制到固定范围会限制其表达能力。因此现在这类函数仅用于某些需要特定输出范围的场合,比如概率输出(此时loss函数中的log操作能够抵消其梯度消失的影响)、LSTM里的gate函数。
  7. 接近恒等变换(identity):即约等于x。这样的好处是使得输出的幅值不会随着深度的增加而发生显著的增加,从而使网络更为稳定,同时梯度也能够更容易地回传。这个与非线性是有点矛盾的,因此激活函数基本只是部分满足这个条件,比如TanH只在原点附近有线性区(在原点为0且在原点的导数为1),而ReLU只在x>0时为线性。这个性质也让初始化参数范围的推导更为简单。额外提一句,这种恒等变换的性质也被其他一些网络结构设计所借鉴,比如CNN中的ResNet和RNN中的LSTM。
  8. 参数少:大部分激活函数都是没有参数的。像PReLU带单个参数会略微增加网络的大小。还有一个例外是Maxout,尽管本身没有参数,但在同样输出通道数下k路Maxout需要的输入通道数是其它函数的k倍,这意味着神经元数目也需要变为k倍;但如果不考虑维持输出通道数的情况下,该激活函数又能将参数个数减少为原来的k倍。
  9. 归一化(normalization):这个是最近才出来的概念,对应的激活函数是SELU,主要思想是使样本分布自动归一化到零均值、单位方差的分布,从而稳定训练。在这之前,这种归一化的思想也被用于网络结构的设计,比如Batch Normalization。

24、简单说说CNN常用的几个模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CIdlsWci-1690098277712)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1690097375392.png)]

26、什么是梯度爆炸?

误差梯度是神经网络训练过程中计算的方向和数量,用于以正确的方向和合适的量更新网络权重。
在深层网络或循环神经网络中,误差梯度可在更新中累积,变成非常大的梯度,然后导致网络权重的大幅更新,并因此使网络变得不稳定。在极端情况下,权重的值变得非常大,以至于溢出,导致 NaN 值。
网络层之间的梯度(值大于 1.0)重复相乘导致的指数级增长会产生梯度爆炸。

27、梯度爆炸会引发什么问题?

在深度多层感知机网络中,梯度爆炸会引起网络不稳定,最好的结果是无法从训练数据中学习,而最坏的结果是出现无法再更新的 NaN 权重值。
梯度爆炸导致学习过程不稳定。.
在循环神经网络中,梯度爆炸会导致网络不稳定,无法利用训练数据学习,最好的结果是网络无法学习长的输入序列数据。

28、如何确定是否出现梯度爆炸?

训练过程中出现梯度爆炸会伴随一些细微的信号,如:
模型无法从训练数据中获得更新(如低损失)。
模型不稳定,导致更新过程中的损失出现显著变化。
训练过程中,模型损失变成 NaN。
如果你发现这些问题,那么你需要仔细查看是否出现梯度爆炸问题。

以下是一些稍微明显一点的信号,有助于确认是否出现梯度爆炸问题。
训练过程中模型梯度快速变大。
训练过程中模型权重变成 NaN 值。
训练过程中,每个节点和层的误差梯度值持续超过 1.0。

29、如何修复梯度爆炸问题?

  1. 重新设计网络模型
    在深度神经网络中,梯度爆炸可以通过重新设计层数更少的网络来解决。
    使用更小的批尺寸对网络训练也有好处。
    在循环神经网络中,训练过程中在更少的先前时间步上进行更新(沿时间的截断反向传播,truncated Backpropagation through time)可以缓解梯度爆炸问题。
  2. 使用 ReLU 激活函数
    在深度多层感知机神经网络中,梯度爆炸的发生可能是因为激活函数,如之前很流行的 Sigmoid 和 Tanh 函数。
    使用 ReLU 激活函数可以减少梯度爆炸。采用 ReLU 激活函数是最适合隐藏层的新实践。
  3. 使用长短期记忆网络
    在循环神经网络中,梯度爆炸的发生可能是因为某种网络的训练本身就存在不稳定性,如随时间的反向传播本质上将循环网络转换成深度多层感知机神经网络。
    使用长短期记忆(LSTM)单元和相关的门类型神经元结构可以减少梯度爆炸问题。
    采用 LSTM 单元是适合循环神经网络的序列预测的最新最好实践。
  4. 使用梯度截断(Gradient Clipping)
    梯度截断,就是要解决 梯度消失/梯度爆炸 的问题,也就是设定阈值,当预更新的梯度小于阈值时,那么将预更新的梯度设置为阈值。在 pytorch 中通过 clip_grad_norm 方法来实现。
  5. 使用权重正则化(Weight Regularization)
    如果梯度爆炸仍然存在,可以尝试另一种方法,即检查网络权重的大小,并惩罚产生较大权重值的损失函数。该过程被称为权重正则化,通常使用的是 L1 惩罚项(权重绝对值)或 L2 惩罚项(权重平方)。
    对循环权重使用 L1 或 L2 惩罚项有助于缓解梯度爆炸。

37、在神经网络中,有哪些办法防止过拟合?

  1. Dropout
  2. 加L1/L2正则化
  3. BatchNormalization
  4. 网络bagging
  5. 提取终止训练
  6. 数据增强

38、CNN关键的层有哪些?

① 输入层,对数据去均值,做data augmentation等工作
② 卷积层,局部关联抽取feature
③ 激励层,非线性变化(也就是常说的激活函数)
④ 池化层,下采样
⑤ 全连接层,增加模型非线性
⑥ BN层,缓解梯度弥散

40、如何解决深度学习中模型训练效果不佳的情况?

如果模型的训练效果不好,可先考察以下几个方面是否有可以优化的地方。

(1)选择合适的损失函数(choosing proper loss )
神经网络的损失函数是非凸的,有多个局部最低点,目标是找到一个可用的最低点。非凸函数是凹凸不平的,但是不同的损失函数凹凸起伏的程度不同,例如下述的平方损失和交叉熵损失,后者起伏更大,且后者更容易找到一个可用的最低点,从而达到优化的目的。

  • Square Error(平方损失)
  • Cross Entropy(交叉熵损失)

(2)选择合适的Mini-batch size
采用合适的Mini-batch进行学习,使用Mini-batch的方法进行学习,一方面可以减少计算量,一方面有助于跳出局部最优点。因此要使用Mini-batch。更进一步,batch的选择非常重要,batch取太大会陷入局部最小值,batch取太小会抖动厉害,因此要选择一个合适的batch size。

(3)选择合适的激活函数(New activation function)
使用激活函数把卷积层输出结果做非线性映射,但是要选择合适的激活函数。

  • Sigmoid函数是一个平滑函数,且具有连续性和可微性,它的最大优点就是非线性。但该函数的两端很缓,会带来猪队友的问题,易发生学不动的情况,产生梯度弥散。
  • ReLU函数是如今设计神经网络时使用最广泛的激活函数,该函数为非线性映射,且简单,可缓解梯度弥散。

(4)选择合适的自适应学习率(apdative learning rate)

  • 学习率过大,会抖动厉害,导致没有优化提升
  • 学习率太小,下降太慢,训练会很慢

(5)使用动量(Momentum)
在梯度的基础上使用动量,有助于冲出局部最低点。

如果以上五部分都选对了,效果还不好,那就是产生过拟合了,可使如下方法来防止过拟合,分别是

  • 1.早停法(earyly stoping)。早停法将数据分成训练集和验证集,训练集用来计算梯度、更新权重和阈值,验证集用来估计误差,若训练集误差降低但验证集误差升高,则停止训练,同时返回具有最小验证集误差的连接权和阈值。
  • 2.权重衰减(Weight Decay)。到训练的后期,通过衰减因子使权重的梯度下降地越来越缓。
  • 3.Dropout。Dropout是正则化的一种处理,以一定的概率关闭神经元的通路,阻止信息的传递。由于每次关闭的神经元不同,从而得到不同的网路模型,最终对这些模型进行融合。
  • 4.调整网络结构(Network Structure)。

51、什么是fine-tuning?

在实践中,由于数据集不够大,很少有人从头开始训练网络。常见的做法是使用预训练的网络(例如在ImageNet上训练的分类1000类的网络)来重新fine-tuning(也叫微调),或者当做特征提取器。

以下是常见的两类迁移学习场景:

1 卷积网络当做特征提取器。使用在ImageNet上预训练的网络,去掉最后的全连接层,剩余部分当做特征提取器(例如AlexNet在最后分类器前,是4096维的特征向量)。这样提取的特征叫做CNN codes。得到这样的特征后,可以使用线性分类器(Liner SVM、Softmax等)来分类图像。

2 Fine-tuning卷积网络。替换掉网络的输入层(数据),使用新的数据继续训练。Fine-tune时可以选择fine-tune全部层或部分层。通常,前面的层提取的是图像的通用特征(generic features)(例如边缘检测,色彩检测),这些特征对许多任务都有用。后面的层提取的是与特定类别有关的特征,因此fine-tune时常常只需要Fine-tuning后面的层。

56、CNN的特点以及优势

CNN使用范围是具有局部空间相关性的数据,比如图像,自然语言,语音

局部连接:可以提取局部特征。
权值共享:减少参数数量,因此降低训练难度(空间、时间消耗都少了)。可以完全共享,也可以局部共享(比如对人脸,眼睛鼻子嘴由于位置和样式相对固定,可以用和脸部不一样的卷积核)

降维:通过池化或卷积stride实现。
多层次结构:将低层次的局部特征组合成为较高层次的特征。不同层级的特征可以对应不同任务。

57、深度学习中有什么加快收敛/降低训练难度的方法?

瓶颈结构
残差
学习率、步长、动量
优化方法
预训练

60、神经网络中会用到批量梯度下降(BGD)吗?为什么用随机梯度下降(SGD)?

1)一般不用BGD

2)a. BGD每次需要用到全量数据,计算量太大
b. 引入随机因素,即便陷入局部极小,梯度也可能不为0,这样就有机会跳出局部极小继续搜索(可以作为跳出局部极小的一种方式,但也可能跳出全局最小。还有解决局部极小的方式:多组参数初始化、使用模拟退火技术)

61、当神经网络的调参效果不好时,从哪些角度思考?(不要首先归结于overfiting)

1)是否找到合适的损失函数?(不同问题适合不同的损失函数)(理解不同损失函数的适用场景)

2)batch size是否合适?batch size太大 -> loss很快平稳,batch size太小 -> loss会震荡(理解mini-batch)

3)是否选择了合适的激活函数?(各个激活函数的来源和差异)

4)学习率,学习率小收敛慢,学习率大loss震荡(怎么选取合适的学习率)

5)是否选择了合适的优化算法?(比如adam)(理解不同优化算法的适用场景)

6)是否过拟合?(深度学习拟合能力强,容易过拟合)(理解过拟合的各个解决方案)
a. Early Stopping
b. Regularization(正则化)
c. Weight Decay(收缩权重)
d. Dropout(随机失活)
e. 调整网络结构

loss很快平稳,batch size太小 -> loss会震荡(理解mini-batch)

3)是否选择了合适的激活函数?(各个激活函数的来源和差异)

4)学习率,学习率小收敛慢,学习率大loss震荡(怎么选取合适的学习率)

5)是否选择了合适的优化算法?(比如adam)(理解不同优化算法的适用场景)

6)是否过拟合?(深度学习拟合能力强,容易过拟合)(理解过拟合的各个解决方案)
a. Early Stopping
b. Regularization(正则化)
c. Weight Decay(收缩权重)
d. Dropout(随机失活)
e. 调整网络结构

;