deeplearning-cv-notes
deeplearning-cv-notes copied to clipboard
Batch-normalized 应该放在非线性激活层的前面还是后面?
From: Batch-normalized 应该放在非线性激活层的前面还是后面? - 知乎
1、某个回答:
“应该”放在前面还是后面?这个“应该”其实有两种解释:
- 放在前面还是后面比较好?
- 为什么要放在前面还是后面?
对于第一问,目前在实践上,倾向于把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 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2、某个回答:
和一位答友类似,我见过的很多网络也是都把bn放到激活前面。我做一下解释:
现在我们假设所有的激活都是relu,也就是使得负半区的卷积值被抑制,正半区的卷积值被保留。而bn的作用是使得输入值的均值为0,方差为1,也就是说假如relu之前是bn的话,会有接近一半的输入值被抑制,一半的输入值被保留。
所以bn放到relu之前的好处可以这样理解:bn可以防止某一层的激活值全部都被抑制,从而防止从这一层往前传的梯度全都变成0,也就是防止梯度消失。(当然也可以防止梯度爆炸)
还有一个好处,把bn放到激活前面是有可以把卷积的weight和bn的参数进行合并的,所以它有利于网络在做前向inference时候进行加速。
作者:star all 链接:https://www.zhihu.com/question/283715823/answer/700870267 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。