Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batch-normalized 应该放在非线性激活层的前面还是后面? #19

Open
jayboxyz opened this issue Nov 30, 2019 · 1 comment
Open
Labels
深度学习 深度学习知识

Comments

@jayboxyz
Copy link
Owner

No description provided.

@jayboxyz jayboxyz added the 深度学习 深度学习知识 label Nov 30, 2019
@jayboxyz
Copy link
Owner Author

jayboxyz commented Nov 30, 2019

From: Batch-normalized 应该放在非线性激活层的前面还是后面? - 知乎

1、某个回答:

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

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

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

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

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

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

image

还是sigmoid

image

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

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

image

实际上,最初的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
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
深度学习 深度学习知识
Projects
None yet
Development

No branches or pull requests

1 participant