Liam0205 / liam0205.github.io

Deployment of my weblog.
https://liam0205.github.io
35 stars 5 forks source link

谈谈激活函数以零为中心的问题 | 始终 #232

Open Liam0205 opened 5 years ago

Liam0205 commented 5 years ago

https://liam.page/2018/04/17/zero-centered-active-function/

今天在讨论神经网络中的激活函数时,陆同学提出 Sigmoid 函数的输出不是以零为中心的(non-zero-centered),这会导致神经网络收敛较慢。关于这一点,过去我只是将其记下,却并未理解背后的原因。此篇谈谈背后的原因。

XinyuLyu commented 5 years ago

牛逼

yozyan commented 5 years ago

还是这个说的明白,牛逼

820fans commented 5 years ago

醍醐灌顶!

yifan97 commented 5 years ago

请问 $\partial L/\partial w_i$ 的式子里面,$\partial f/\partial w_i$ 是否应该是一个 chain rule 呢?

$$ \partial f/\partial w_i = \partial f/\partial z \partial z/\partial w_i = \sigma(z)(1-\sigma(z))x_i$$

——如果假设f是sigmoid的话。

Liam0205 commented 5 years ago

@yifan97 你讲的对,这里是我疏忽了。不过不影响结论。已修正文中问题。

yifan97 commented 5 years ago

@Liam0205 @yifan97 你讲的对,这里是我疏忽了。不过不影响结论。已修正文中问题。

谢谢回复!

tcoln commented 5 years ago

有个疑问,sigmoid输出恒为正的话,w0和w1如何同时往负方向走呢?就是图中Z字路线向左下部分

Liam0205 commented 5 years ago

@yifan97 客气了,是我要感谢你才是。

Liam0205 commented 5 years ago

@tcoln \frac{\partial L}{\partial f}\frac{\partial f}{\partial z} 可以是负数啊,它与 x_i 的乘积决定梯度下降的方向。

ShenYounger commented 5 years ago

@Liam0205 @tcoln \frac{\partial L}{\partial f}\frac{\partial f}{\partial z} 可以是负数啊,它与 x_i 的乘积决定梯度下降的方向。

黄指导是否可以修改下评论的格式,很多公式无法展现很好显示啊,需要某种插件么?

Nobody0321 commented 5 years ago

文章里说了最终的导数正负由\frac{\partial L}{\partial f}决定,我的理解是最终是由loss function决定,那么在loss确定的时候\frac{\partial L}{\partial f}的正负也确定了对吗。这样的话整体的梯度方向不是也确定了吗,为什么会走之字形?,应该只会朝正方向和负方向其中一个方向更新才对吧

Liam0205 commented 5 years ago

@Nobody0321 之字形的意思是,这次迭代往正方向走,下一次往负方向走。

Liam0205 commented 5 years ago

@ShenYounger 没太好的办法。评论本质上是 GitHub 上的 issue,目前不支持 MathJax 渲染。

dddeeplearn commented 4 years ago

请问L对w的导数应该是L对f的导数和f对z的导数以及z对w导数的乘积,f对w的导数是恒正的,L对f的导数应该是有正有负吧,那么L对w的导数应该也是有正有负呀,所以w0增大的同时w1应该也可以减小吧,这两个应该是不互相影响的吧?

z1y1 commented 4 years ago

@dddeeplearn 请问L对w的导数应该是L对f的导数和f对z的导数以及z对w导数的乘积,f对w的导数是恒正的,L对f的导数应该是有正有负吧,那么L对w的导数应该也是有正有负呀,所以w0增大的同时w1应该也可以减小吧,这两个应该是不互相影响的吧?

大致一看感觉讲得挺清楚的,但是细细思考后发现没那么简单,博主的理解不知道有没有参考书籍或者文章,(如果有的话希望可以给我们参考一下),这边提一下我感觉有问题的地方。 在你写的“更新方向”中,你说“参数 $w_i$ 的更新方向实际上由 $x_i\cdot \frac{\partial L}{\partial f}\frac{\partial f}{\partial z}$ 决定”,这个我感觉没问题,但是为什么说“$\frac{\partial L}{\partial f}\frac{\partial f}{\partial z}$ 对于所有的 $w_i$ 来说是常数,符号由$x_i$决定”,如果w_i一定,改变x_i可以改变这一层的值,那激活函数f对该值的倒是会变化,损失函数对激活函数f的导数也会随该值的变化变化,所以$\frac{\partial L}{\partial f}\frac{\partial f}{\partial z}$ 对于所有的 $w_i$ 来说是并不是常数,然后说“符号由$x_i$决定”,x_i是上一层的输出值,更新w_i的时候x_i已经确定了,它是无法确定w_i的更新方向的,更新w_i只会改变当前层的输出(举个例子在DNN中,就看最后的输出层,更新当前的W参数为了能够在一定的输入下,改变输出使得损失函数减小)。 而为什么tanh的收敛速度会比sigmoid快呢,我的理解是当前层更新w时,给定输入和损失函数,对于某一分量,sigmoid只能往正方向更新,而tanh不仅可以往正方向也可以往负方向。

这是我的理解,如有错误烦请指出。

WatsonZhouAnda commented 4 years ago

@Liam0205 @Nobody0321 之字形的意思是,这次迭代往正方向走,下一次往负方向走。

楼主你好,有一点没太明白望不吝赐教。为什么这次迭代往正方形走,下一次就往负方向呢? 我理解的是,如果上一层输出是由sigmoid决定,即当前层的输入x都是正数,且当前层的输出同样是由sigmoid决定,即f函数为sigmoid函数。那么当前层的w的导数,就都为正数。应该没有负数的可能吧?所以无论多少次迭代,w都往正的方向更新?不知道理解的哪里有问题。

tsaizehua commented 4 years ago

@Liam0205 @Nobody0321 之字形的意思是,这次迭代往正方向走,下一次往负方向走。

楼主你好,有一点没太明白望不吝赐教。为什么这次迭代往正方形走,下一次就往负方向呢? 我理解的是,如果上一层输出是由sigmoid决定,即当前层的输入x都是正数,且当前层的输出同样是由sigmoid决定,即f函数为sigmoid函数。那么当前层的w的导数,就都为正数。应该没有负数的可能吧?所以无论多少次迭代,w都往正的方向更新?不知道理解的哪里有问题。

还是把“当前层的输入x都是正数”理解成“当前层的输入x符号都相同”吧,也就是 w 权重更新要么全都被减值,要么全都被加值。 至于“w 都往正的方向更新?”,文中推导到最后是想说明 x 符号都一样且都是正值,但别忘了还有"∂L/∂f"、"∂f/∂z"这两项呢,这两项可能是或正或负值吧。 这是我的理解,不知道是否合理严谨,当做参考吧~

1041787154 commented 4 years ago

如果损失函数L和激活函数f确定了,那整个权重w的更新方向也就确定了吧(或一直往右,或者一直往左)?为啥会有Z字形的走位呢?

hzp0821 commented 4 years ago

所以到底跟sigmod输出大于0有什么关系,我感觉只跟sigmod导数大于0有关呢?

linzf23 commented 4 years ago

为什么我看不了公式呢?

1041787154 commented 4 years ago

回答:首先看下这个前向传播图片: 权重更新方式是发生在反向更新阶段,过程:,对于神经元A来说,wi更新的方向和后几项都有关系,先看超参数,他是人为规定的,默认值,所以学习率可以不考虑;再看最后两位乘积项,这个对于神经元A来说,它是神经元A的误差表示,在某一次反向传播也是不变的,也不考虑,所以w值得更新方向只与x值有关,这个x值是上一层神经元的输入值,即经过了sigmod函数激活过,所以肯定是正值,那么可以得出结论:在某一次反向传播时,对于神经元A来说,w1、w2..改变的方向是统一的,或正或负。如果你的最优值是需要w1增加,w2减少,那么只能走z字形才能实现。

所以,如何避免这种情况呢。方法之一就是改变激活函数,不需要激活函数值全正或者全负。所以你说,这里的sigmod函数输出均>0,和更新梯度有关系吗? w i

wangjia 1041787154@qq.com

在 2020年5月4日,下午4:46,hzp0821 notifications@github.com 写道:

所以到底跟sigmod输出大于0有什么关系,我感觉只跟sigmod导数大于0有关呢?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Liam0205/liam0205.github.io/issues/232#issuecomment-623337528, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADT4CMIOYXLZ7RAS3AEEUWDRPZ6G5ANCNFSM4GPSIVNA.

Liam0205 commented 4 years ago

@1041787154

回答:首先看下这个前向传播图片: 权重更新方式是发生在反向更新阶段,过程:,对于神经元A来说,wi更新的方向和后几项都有关系,先看超参数,他是人为规定的,默认值,所以学习率可以不考虑;再看最后两位乘积项,这个对于神经元A来说,它是神经元A的误差表示,在某一次反向传播也是不变的,也不考虑,所以w值得更新方向只与x值有关,这个x值是上一层神经元的输入值,即经过了sigmod函数激活过,所以肯定是正值,那么可以得出结论:在某一次反向传播时,对于神经元A来说,w1、w2..改变的方向是统一的,或正或负。如果你的最优值是需要w1增加,w2减少,那么只能走z字形才能实现。

所以,如何避免这种情况呢。方法之一就是改变激活函数,不需要激活函数值全正或者全负。所以你说,这里的sigmod函数输出均>0,和更新梯度有关系吗? w i

wangjia 1041787154@qq.com

在 2020年5月4日,下午4:46,hzp0821 notifications@github.com 写道:

所以到底跟sigmod输出大于0有什么关系,我感觉只跟sigmod导数大于0有关呢?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Liam0205/liam0205.github.io/issues/232#issuecomment-623337528, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADT4CMIOYXLZ7RAS3AEEUWDRPZ6G5ANCNFSM4GPSIVNA.

你这个是看懂了的。

brooke007 commented 3 years ago

ORZ 太清楚了 谢谢大佬

yyxx1997 commented 3 years ago

说的清清楚楚、明明白白!

Jerry-Hanson commented 3 years ago

懂了,谢谢大佬, orz

T-ze-yu commented 2 years ago

全网最明白的了,牛逼!感谢感谢,这个困恼了我好久了,醍醐灌顶啊!

Liam0205 commented 2 years ago

@T-ze-yu 当不得这个夸哈~

Nobody0321 commented 2 years ago

时隔两年重新拜读,有了新的理解,文中所说的之字形线路只是一个比喻,不用太过于纠结; 我认为之字形指代的就是不能同时一增一减更新参数时候,采用的先同时增大所有参数,然后同时减少所有参数的次优解决方案。 通过不同参数的梯度不同控制每次更新幅度,最后达到该增大的参数增大,该减少的参数减少的目的。

Liam0205 commented 2 years ago

时隔两年重新拜读,有了新的理解,文中所说的之字形线路只是一个比喻,不用太过于纠结; 我认为之字形指代的就是不能同时一增一减更新参数时候,采用的先同时增大所有参数,然后同时减少所有参数的次优解决方案。 通过不同参数的梯度不同控制每次更新幅度,最后达到该增大的参数增大,该减少的参数减少的目的。

没错。

dongtaishanybc commented 2 years ago

还是不理解,因为这里如果上一层采用sigmoid函数作为激活函数,即下一层的输入xi恒为正数,同时L对于f的偏导为sigmoid(x)*(1-sigmoid(x))也是正数,示例中f对于z的偏导是常数1 ,这样一来,L对于wi的偏导数只能为正数,所以梯度更新的话,只能恒为正数,,,

Liam0205 commented 2 years ago

@dongtaishanybc 还是不理解,因为这里如果上一层采用sigmoid函数作为激活函数,即下一层的输入xi恒为正数,同时L对于f的偏导为sigmoid(x)*(1-sigmoid(x))也是正数,示例中f对于z的偏导是常数1 ,这样一来,L对于wi的偏导数只能为正数,所以梯度更新的话,只能恒为正数,,,

偏 f 比偏 z 和偏 L 比偏 f 具体是什么不重要。因为当我们讨论同一个 cell 的不同 w_i 时,它们的值是确定的。一定要纠结的话……

dongtaishanybc commented 2 years ago

我忘记考虑loss函数了,,,尴尬,loss函数对于输出的偏导是可+可-,这样一来对于每一次更新迭代就是要么全正,要么全负

Liam0205 commented 2 years ago

@dongtaishanybc 对了。

Q-H-Zhang commented 2 years ago

@dongtaishanybc 我忘记考虑loss函数了,,,尴尬,loss函数对于输出的偏导是可+可-,这样一来对于每一次更新迭代就是要么全正,要么全负

没错,所以如果非要深挖的话,在激活函数是sigmoid的前提下,其实是 “偏L/偏f” 决定了梯度更新的方向。

Liam0205 commented 2 years ago

@Q-H-Zhang partial L / partial fx_i 的乘积才是 w_i 的更新方向。

文中高亮了差异二字。

Liam0205 commented 2 years ago

稍微加了一些描述。这样看起来应该更容易懂。

Q-H-Zhang commented 2 years ago

@Liam0205 @Q-H-Zhang partial L / partial fx_i 的乘积才是 w_i 的更新方向。

文中高亮了差异二字。

我明白您的意思,“偏L / 偏 f 和 x_i的乘积是w_i的更新方向”这个结论适用于所有的激活函数。我说的那句话是在激活函数为sigmoid的前提下,即输入的x_i始终>0,也就是x_i不影响w_i的更新方向,只由偏L / 偏 f 决定

dongtaishanybc commented 2 years ago

这样一来,relu作为激活函数应该也会遇到类似的问题。剔除loss函数带来的+-,单纯从激活函数来看,f(w0*x0+w1x1+b),对于激活函数的求导是≥0,输入x0和x1也是≥0.也会出现迭代时同正或同负的现象。因此,用prelu之类的让输出存在负数进行替换可以加速模型的收敛。

MrCoderOrange commented 2 years ago

棒!

YesYourHighness commented 1 year ago

国内写好文的真的太少了

Liam0205 commented 1 year ago

@YesYourHighness 感谢认可

Orion-Zheng commented 1 year ago

谢谢楼主。按这个原理的话,如果在Sigmoid层数后加入BatchNorm的话(把输出的均值和方差进行调整),是不是就可以避免发生这种问题了呢?

Liam0205 commented 1 year ago

@Orion-Zheng 我理解 Batch Norm 不解决这个问题吧……

Ru1yi commented 1 year ago

写得太好了,通俗易懂。

real-brilliant commented 4 months ago

你的推导过程中,默认z是一个scalar而非vector,所以对同一层所有神经元来说,f/z的偏导可以视为统一常数,梯度符号仅与x决定。 但实际上z是一个vector,即便在同一层,element-wise的符号也可能彼此不同,所以并不存在zigzag的问题

Liam0205 commented 4 months ago

你再想想……

Liam Huang From my iPhone

在 2024年5月9日,16:01,777 @.***> 写道:

 你的推导过程中,默认z是一个scalar而非vector,所以对同一层所有神经元来说,f/z的偏导可以视为统一常数,梯度符号仅与x决定。 但实际上z是一个vector,即便在同一层,element-wise的符号也可能彼此不同,所以并不存在zigzag的问题

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.

real-brilliant commented 4 months ago

image