cv岗位 - 深度学习面试知识总结(不断更新)

github上面有个深度学习500问,大家可以看看那个,我这个作为补充,而且相对说明的更详细一些。

目录

一、优化算法(一阶、二阶)

1. 常用的一阶、二阶优化算法有哪些?区别是什么?

2. 为什么二阶优化算法更快呢?

3. 神经网络为啥不用拟牛顿法而是用梯度下降?(为什么深度学习不用二阶的优化算法?)

二、损失函数

 1. 为什么神经网络中用CE交叉熵代替了MSE

三、 BN层前世今生

前提:理解归一化的作用

1. BN层提出的背景

2. BN层的原理(训练和测试的不同)

3. BN层的作用

4. BN层为什么可以一定程度缓解 过拟合的问题?

5. BN层有哪些可以调整的参数?

6. BN层为什么起作用!

7. Batch Normalization的变种

8. BN位置放在哪里合适?


一、优化算法(一阶、二阶)

1. 常用的一阶、二阶优化算法有哪些?区别是什么?

一阶的有:梯度下降法GD、SGD、ASGD、指数加权平均AdaDelta、RMSProp、Adam

二阶的有:牛顿法、拟牛顿法(二阶收敛更快)https://www.matongxue.com/madocs/205.html牛顿法好材料

基础概念:

  • 梯度(一阶导数)考虑一座在 (x1, x2) 点高度是 f(x1, x2) 的山。那么,某一点的梯度方向是在该点坡度最陡的方向,而梯度的大小告诉我们坡度到底有多陡。
  • Hesse 矩阵(二阶导数,二阶梯度)
  • 牛顿法是一种在实数域和复数域上近似求解方程的方法。方法使用函数f (x)的泰勒级数的前面几项寻找方程f (x) = 0的根。牛顿法最大的特点就在于它的收敛速度很快。主要有两个缺陷,一个是需要计算Hessian矩阵,需要O(np^2) 的复杂度,另外一个便是计算Hessian的逆矩阵需要O(p^3 )的复杂度。
  • 拟牛顿法:本质思想是改善牛顿法每次需要求解复杂的Hessian矩阵的逆矩阵的缺陷,它使用正定矩阵来近似Hessian矩阵的逆,从而简化了运算的复杂度

2. 为什么二阶优化算法更快呢?

更通俗地说的话,比如你想找一条最短的路径走到一个盆地的最底部。梯度下降法每次只从你当前所处位置选一个坡度最大的方向走一步,牛顿法在选择方向时,不仅会考虑坡度是否够大,还会考虑你走了一步之后,坡度是否会变得更大。所以,可以说牛顿法比梯度下降法看得更远一点,能更快地走到最底部。(牛顿法目光更加长远,所以少走弯路;相对而言,梯度下降法只考虑了局部的最优,没有全局思想。)

  根据wiki上的解释,从几何上说,牛顿法就是用一个二次曲面去拟合你当前所处位置的局部曲面,而梯度下降法是用一个平面去拟合当前的局部曲面,通常情况下,二次曲面的拟合会比平面更好,所以牛顿法选择的下降路径会更符合真实的最优下降路径。

可以看到梯度下降是局部最优,只追求当下梯度最大。而牛顿法,则看的更远。

注:红色的牛顿法的迭代路径,绿色的是梯度下降法的迭代路径。

https://blog.csdn.net/owen7500/article/details/51601627                                                                              

3. 神经网络为啥不用拟牛顿法而是用梯度下降?(为什么深度学习不用二阶的优化算法?)

二阶虽然精度高,但是计算量太大,而且精度高对于深度学习这种深层模型反而不一定有好处,因为破坏了泛化性能。

======================================================

首先,深度学习里面使用二阶优化算法的其实也是有的,不多而已,列举几篇

1. Hinton的学生 James Martens,主要的工作就是 Second-order Optimization for Neural Networks如Hessian-free optimization,这里有他的文章和学位论文James Martens: Research

2. Optimization Methods for Large-Scale Machine Learning 和一个新近提出的方法https://papers.nips.cc/paper/6145-a-multi-batch-l-bfgs-method-for-machine-learning.pdf

======================================================

首先分析神经网络的特点:大数据(样本点多),高参数,非凸

牛顿和拟牛顿法适用条件:凸优化情形下,如果迭代点离全局最优很近时,收敛速率快于gd。

反向传播主要是依靠一阶梯度。二阶梯度在理论和实际上都是可以应用网络中的,但相比于一阶梯度,二阶优化问题:
(1)计算量大,训练非常慢。
(2)二阶方法能够更快地求得更高精度的解,这在浅层模型是有益的。而在神经网络这类深层模型中对参数的精度要求不高,甚至不高的精度对模型还有益处,能够提高模型的泛化能力
(3)稳定性。越简单的模型越robust,梯度下降一般还行。

======================================================

【可不看】具体理解高参数:以Newton法和quasi-Newton 法为代表的二阶优化方法最大的问题就是计算复杂度。以BFGS来说,一次迭代更新的复杂度是O(n^2),这在高维的时候是不可行的。L-BFGS使用部分梯度(最近迭代的m个梯度)来近似Hessian,复杂度是O(mn),实际中m的取值可以是5-40. 这大大扩展了BFGS的可用范围。具体实施中,BFGS可以应用到10^3-10^4量级,L-BFGS可以延伸到10^5量级。但这距离深度网络中变量的个数仍有较大差距,如AlexNet有6\times 10^7个参数。

======================================================

https://www.zhihu.com/question/53218358

https://www.zhihu.com/question/46441403/answer/117594441

https://www.zhihu.com/question/53218358

二、损失函数

 1. 为什么神经网络中用CE交叉熵代替了MSE

网上有很多的说法是因为在反向传播求导的过程中,MSE的代价函数的求导,和激活函数有关系的,然后说sigmod有饱和性,然后就用CE了。。。那我就想问了那如果用Relu替代simgod可以用MSE吗?道理就不是这个道理。

神经网络中为什么用交叉熵损失函数,在我的机器学习面试总结里面有为什么逻辑回归用CE。其实是一个道理,决定用什么损失函数,是由概率分布到似然函数再利用最大似然估计的方式,选取损失函数,所以神经网络用CE本来就顺利成章。

三、 BN层前世今生

BN层的出现轰动一时,而后针对说BN层解决了原文中ICS内部方差偏移的问题,后又有学者做了相关实验,进行了否定,不禁令我们这些吃瓜群众,呆呆的摸了摸头。

ICS(Internal Covariate Shift)就是作者认为,网络在不断训练的过程中,中间的参数在不断的进行变化,导致后序层的输入也一直在发生变化,这样就导致了学习率不能设置太大,初始化也要小心。

前提:理解归一化的作用

归一化可以加快收敛:因为大多数的权重的初始化都是以0为均值的,所以提前归一数据可以加快数据收敛

归一化可以降低过拟合:归一化后,网络不再对那些跨度比较大的特征强依赖,所以降低过拟合

归一化有时候可以增加精度:这是因为很多的分类需要样本之间的距离,如knn

1. BN层提出的背景

刚开始的时候,网络需要设置很小的学习率和小心初始化,大大限制的训练的效率,BN层的出现很好的解决了这个问题。

2. BN层的原理(训练和测试的不同)

很简单,训练的时候就是一个mini-batch一个均值,一个方差(通道上),然后进行标准化,之后再有学习参数γ和β。重构原始网络所要学习的特征分布。

测试的时候,用的是整个训练集的均值和方差,做法是利用的是指数加权移动平均的方法。

3. BN层的作用

(1)加速收敛(2)控制过拟合,可以少用或不用Dropout和正则(3)降低网络对初始化权重不敏感(4)允许使用较大的学习率(5)减少梯度消失的概率

4. BN层为什么可以一定程度缓解 过拟合的问题?

其实BN层主要是为了解决训练速度的问题,非要说BN有缓解过拟合的问题的话,只能勉强从下面几点分析:

(1)mini-batch的存在,引入了噪声(2)加入了BN层学习率可以变大(3)BN层归一化,不强依赖于某一特征

5. BN层有哪些可以调整的参数?

pytorch的batchnorm使用时需要小心,training和track_running_stats可以组合出三种behavior,很容易掉坑里(我刚发现我对track_running_stats的理解错了)。

  1. training=True, track_running_stats=True, 这是常用的training时期待的行为,running_mean 和running_var会跟踪不同batch数据的mean和variance,但是仍然是用每个batch的mean和variance做normalization。
  2. training=True, track_running_stats=False, 这时候running_mean 和running_var不跟踪跨batch数据的statistics了,但仍然用每个batch的mean和variance做normalization。
  3. training=False, track_running_stats=True, 这是我们期待的test时候的行为,即使用training阶段估计的running_mean 和running_var.
  4. training=False, track_running_stats=False,同2(!!!).

6. BN层为什么起作用!

关于Normalization的有效性,有以下几个主要观点:

(1) 主流观点,Batch Normalization调整了数据的分布,不考虑激活函数,它让每一层的输出归一化到了均值为0方差为1的分布,这保证了梯度的有效性,目前大部分资料都这样解释,比如BN的原始论文认为的缓解了Internal Covariate Shift(ICS)问题。

(2) 可以使用更大的学习率,文[2]指出BN有效是因为用上BN层之后可以使用更大的学习率,从而跳出不好的局部极值,增强泛化能力,在它们的研究中做了大量的实验来验证。

(3) 损失平面平滑。文[3]的研究提出,BN有效的根本原因不在于调整了分布,因为即使是在BN层后模拟ICS,也仍然可以取得好的结果。它们指出,BN有效的根本原因是平滑了损失平面。很明显加入BN后loss的震荡变小了。之前我们说过,Z-score标准化对于包括孤立点的分布可以进行更平滑的调整。

魏秀参认为:

说到底,BN的提出还是为了克服深度神经网络难以训练的弊病。其实BN背后的insight非常简单,只是在文章中被Google复杂化了。
“ICS”大家都知道在统计机器学习中的一个经典假设是“源空间(source domain)和目标空间(target domain)的数据分布(distribution)是一致的”。如果不一致,那么就出现了新的机器学习问题,如,transfer learning/domain adaptation等。covariate shift就是分布不一致假设之下的一个分支问题它是指源空间和目标空间的条件概率是一致的,但是其边缘概率不同,即:对所有x\in \mathcal{X},P_s(Y|X=x)=P_t(Y|X=x),但是P_s(X)\ne P_t(X). 大家细想便会发现,的确,对于神经网络的各层输出,由于它们经过了层内操作作用,其分布显然与各层对应的输入信号分布不同,而且差异会随着网络深度增大而增大,可是它们所能“指示”的样本标记(label)仍然是不变的,这便符合了covariate shift的定义。由于是对层间信号的分析,也即是“internal”的来由。
那么好,为什么前面我说Google将其复杂化了。其实如果严格按照解决covariate shift的路子来做的话,大概就是上“importance weight”(ref)之类的机器学习方法。可是这里Google仅仅说“通过mini-batch来规范化某些层/所有层的输入,从而可以固定每层输入信号的均值与方差”就可以解决问题。如果covariate shift可以用这么简单的方法解决,那前人对其的研究也真真是白做了。此外,试想,均值方差一致的分布就是同样的分布吗?当然不是。显然,ICS只是这个问题的“包装纸”嘛,仅仅是一种high-level demonstration。
那BN到底是什么原理呢?说到底还是为了防止“梯度弥散”。关于梯度弥散,大家都知道一个简单的栗子:0.9^{30}\approx 0.04。在BN中,是通过将activation规范为均值和方差一致的手段使得原本会减小的activation的scale变大。可以说是一种更有效的local response normalization方法(见4.2.1节)。

7. Batch Normalization的变种

Normalization思想非常简单,为深层网络的训练做出了很大贡献。因为有依赖于样本数目的缺陷,所以也被研究人员盯上进行改进。说的比较多的就是Layer Normalization与Instance Normalization,Group Normalization了。

前面说了Batch Normalization各个通道之间是独立进行计算,如果抛弃对batch的依赖,也就是每一个样本都单独进行normalization,同时各个通道都要用到,就得到了Layer Normalization

跟Batch Normalization仅针对单个神经元不同,Layer Normalization考虑了神经网络中一层的神经元。如果输出的blob大小为(N,C,H,W),那么在每一层Layer Normalization就是基于C*H*W个数值进行求平均以及方差的操作

Layer Normalization把每一层的特征通道一起用于归一化,如果每一个特征层单独进行归一化呢?也就是限制在某一个特征通道内,那就是instance normalization了

如果输出的blob大小为(N,C,H,W),那么在每一层Instance Normalization就是基于H*W个数值进行求平均以及方差的操作。对于风格化类的图像应用,Instance Normalization通常能取得更好的结果,它的使用本来就是风格迁移应用中提出。

Group Normalization是Layer Normalization和Instance Normalization 的中间体, Group Normalization将channel方向分group,然后对每个Group内做归一化,算其均值与方差

如果输出的blob大小为(N,C,H,W),将通道C分为G个组,那么Group Normalization就是基于G*H*W个数值进行求平均以及方差的操作。我只想说,你们真会玩,要榨干所有可能性。

在Batch Normalization之外,有人提出了通用版本Generalized Batch Normalization,有人提出了硬件更加友好的L1-Norm Batch Normalization等,不再一一讲述。

另一方面,以上的Batch Normalization,Layer Normalization,Instance Normalization都是将规范化应用于输入数据x,Weight normalization则是对权重进行规范化,感兴趣的可以自行了解,使用比较少,也不在我们的讨论范围。

这么多的Normalization怎么使用呢?有一些基本的建议吧,不一定是正确答案。

(1) 正常的处理图片的CNN模型都应该使用Batch Normalization。只要保证batch size较大(不低于32),并且打乱了输入样本的顺序。如果batch太小,则优先用Group Normalization替代。

(2)对于RNN等时序模型,有时候同一个batch内部的训练实例长度不一(不同长度的句子),则不同的时态下需要保存不同的统计量,无法正确使用BN层,只能使用Layer Normalization。

(3) 对于图像生成以及风格迁移类应用,使用Instance Normalization更加合适。

 

算了,让大佬先上吧。

[1] Ioffe S, Szegedy C. Batch normalization: Accelerating deep network training by reducing internal covariate shift[J]. arXiv preprint arXiv:1502.03167, 2015.

[2] Bjorck N, Gomes C P, Selman B, et al. Understanding batch normalization[C]//Advances in Neural Information Processing Systems. 2018: 7705-7716.

[3] Santurkar S, Tsipras D, Ilyas A, et al. How does batch normalization help optimization?[C]//Advances in Neural Information Processing Systems. 2018: 2488-2498.

BN层技术的出现确实让网络学习起来更加简单了,降低了调参的工作量,不过它本身的作用机制还在被广泛研究中。几乎就像是深度学习中没有open问题的一个缩影,BN到底为何,还无定论,如果你有兴趣和时间,不妨也去踩一坑。

https://www.zhihu.com/question/38102762/answer/85238569

8. BN位置放在哪里合适?

在BN的原始论文中,BN是放在非线性激活层前面的(arXiv:1502.03167v3,第5页)

We add the BN transform immediately before the nonlinearity

(注意:before的黑体是我加的,为了突出重点)

 

但是,François Chollet爆料说BN论文的作者之一Christian把BN放在ReLU后面(你的问题里引用的文字也提到了这一段)。

I can guarantee that recent code written by Christian applies relu before BN.

 

另外,Jeremy Howard直接主张把BN放在非线性激活后面

You want the batchnorm after the non-linearity, and before the dropout.

 

“应该”放在前面还是后面?这个“应该”其实有两种解释:

  1. 放在前面还是后面比较好?
  2. 为什么要放在前面还是后面?

对于第一问,目前在实践上,倾向于把BN放在ReLU后面。也有评测表明BN放ReLU后面效果更好。

 

对于第二问,实际上,我们目前对BN的机制仍然不是特别清楚,这里只能尝试做些(玄学)解释,不一定正确。

 

BN,也就是Batch-Normalization,这名字就能让我们想到普通的normalization(归一化),也就是将输入传给神经网络之前对输入做的normalization。这个normalization是对输入操作的,是在输入层之前进行的。那么,从这个角度上来说,Batch-Normalization可以视作对传给隐藏层的输入的normalization。想象一下,如果我们把网络中的某一个隐藏层前面的网络层全部砍掉,那么这个隐藏层就变成了输入层,传给它的输入需要normalization,就在这一层之间,这个位置,就是原本的BN层的位置。从这方面来说,BN层放非线性激活之后,是很自然的。

 

然后,我们再来考虑一些具体的激活函数。我们看到,无论是tanh

 

还是sigmoid

函数图像的两端,相对于x的变化,y的变化都很小(这其实很正常,毕竟tanh就是拉伸过的sigmoid)。也就是说,容易出现梯度衰减的问题。那么,如果在tanh或sigmoid之前,进行一些normalization处理,就可以缓解梯度衰减的问题。我想这可能也是最初的BN论文选择把BN层放在非线性激活之前的原因。

但是ReLU的画风和它们完全不一样啊。

实际上,最初的BN论文虽然也在使用ReLU的Inception上进行了试验,但首先研究的是sigmoid激活。因此,试验ReLU的,我猜想作者可能就顺便延续了之前把BN放前面的配置,而没有单独针对ReLU进行处理。

总结一下,BN层的作用机制也许是通过平滑隐藏层输入的分布,帮助随机梯度下降的进行,缓解随机梯度下降权重更新对后续层的负面影响。因此,实际上,无论是放非线性激活之前,还是之后,也许都能发挥这个作用。只不过,取决于具体激活函数的不同,效果也许有一点差别(比如,对sigmoid和tanh而言,放非线性激活之前,也许顺便还能缓解sigmoid/tanh的梯度衰减问题,而对ReLU而言,这个平滑作用经ReLU“扭曲”之后也许有所衰弱)。

https://www.zhihu.com/question/283715823/answer/438882036

 

 

 

 

  • 6
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值