CNN数值初始化——xavier(下)

作者:冯超
链接:https://zhuanlan.zhihu.com/p/22044472
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

上回说到我们从前向的方向推导,发现了这些0均值的随机变量在计算过程中会产生方差扩散的问题,我们并且从前向的方向给出了解决的办法。既然在刚才的句子中我们反复提到了前向这两个字,那肯定是在别有用心地告诉大家——还有后向呗。

后向的计算公式其实和前向类似,忘记的可以顺便去前面的文章中回顾一下(顺便顺手点个赞啊~),这里我们还是用比较抽象的方式去表示,假设我们还是一个k层的网络,现在我们得到了第k层的梯度\frac{\partial Loss}{\partial x^k},那么对于第k-1层输入的梯度,有

\frac{\partial Loss}{\partial x^{k-1}_j}=\sum_{i=1}^n{\frac{\partial Loss}{\partial x^k_i}*w^k_j}

好了,这个公式的精髓还是在意不在形,也就是说,K-1层一个数值的梯度,相当于上一层的n个参数的乘加。这个n个参数的计算方式和之前方式一样,只是表示了输出端的数据维度,在此先不去赘述了。

然后我们又到了反向传播到非线性函数的地方了,时间一长洗脑可能会失效,让我们再次催眠自己,想象非线性函数像线性函数一样飘过,飘过……

于是我们如果假设每一层的参数也服从某种均值为0,方差为某值的分布,利用这种来自东方的神秘力量,我们又可以写出一个神奇的公式:

Var(\frac{\partial Loss}{\partial x^{k-1}_j})=n^k*Var({\frac{\partial Loss}{\partial x^k_i})*\sigma_w^k}

于是乎,对于这个k层网络,我们又可以推导出一个神奇的公式:

Var(\frac{\partial Loss}{\partial x^{1}_j})=Var({\frac{\partial Loss}{\partial x^k_i})*\prod_{i=1}^{k-1}n^i*\sigma_w^i}

好了,上次我说过的话不会重复再说一遍了。这次我们考虑后向操作是为了什么呢?前面我们前向传播data,我们做到了数值的稳定,现在反向传播如果不能做到同样的数值稳定,那么被diff更新过的data不再服从这种神奇的力量怎么办?要命了。

所以为了服从神奇的力量,我们又可以得到:

为了Var(\frac{\partial Loss}{\partial x^{k-1}_j})=Var({\frac{\partial Loss}{\partial x^k_i}})

\sigma^k_w=\frac{1}{n^k}

咦,好像我们两次推导得到了同样的结果,大功告成了?如果仔细看一下这两个公式,我们就会发现两个n实际上不是同一个n。对于全连接来说,前向操作时,n表示了输入的维度,而后向操作时,n表示了输出的维度。而输出的维度也可以等于下一层的输入维度。所以两个公式实际上可以写作:

\sigma^k_w=\frac{1}{n^k}
\sigma^k_w=\frac{1}{n^{k+1}}

这么看上去前向后向不是很统一啊,但是大功快要告成,怎么也得再糊弄一回了,于是我们把两个公式揉合以下,就成了:

\sigma^k_w=\frac{2}{n^{k+1}+n^k}

下面就是对这个方差的具体使用了。没错,前辈思来想去,决定使用均匀分布进行初始化,我们设定我们要初始化的范围是[-a,a]。熟悉均匀分布和不熟悉均匀分布的各位,都可以看一下上述的范围下,均匀分布的方差为:

Var(uniform)=\frac{(a-(-a))^2}{12}=\frac{a^2}{3}=\sigma^k_w

将上面两个公式合并一下,就可以得到:

a=\sqrt{\frac{6}{n^{k+1}+n^k}}

于是,我们的xavier初始化方法横空出世,那就是把参数初始化成[-\sqrt{\frac{6}{n^{k+1}+n^k}},\sqrt{\frac{6}{n^{k+1}+n^k}}]范围内的均匀分布。


看完了这段晕晕忽忽地演绎,再看看最终的结果,和源代码,有没有一种搞了半天就弄出点这的感觉?

没错,这个初始化的公式不难,但是想这样推导出来还是让前辈们付出了巨大的心血。后人在使用这个初始化方法的时候,理所当然地使用了这些方法,但是很少去理会这些推导背后的真正含义。

虽然前面用了大量戏谑的语言来说明一些假设的不合理性,但是如果没有这些假设,我们也无法得出这样精彩而且实用的结论。其实数学模型的世界经常就是会用到一些抽象这件工具,只有把一些不太好把握的地方抽象掉,才能更容易地抓住事物的本质,找到事物的核心规律。所以在这里还是要由衷的给这个初始化算法的作者点个赞。

向更远方前进

如果熟悉Caffe源码的同学,在看到xavier的源码后,会看到下面还有一个类似结构的初始化方法——MSRAFiller。这个初始化方法来自《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》,不同的是,这篇文章的主要目标是基于ReLU的初始化算法,实际上它的推导过程和我们看过的xavier的方法类似,只是在一些细节处有所不同。如果你理解了xavier的演绎思想,不妨去看看这篇文章的推导过程,相信你会很轻松地理解这一路研究初始化算法的思路。总之,能够出现在应用中的算法都是经过一定实践检验的算法,已经被人证明了它在理论和实践上的可行性,是完全值得去深入了解的。

除了这两篇文章,还有很多大牛写了关于初始化的文章,以它们的角度讲述了它们心中初始化的样子。后面有时间我们还会继续去看这些文章,不过我们要暂时停下脚步了,因为还有在其他方向努力的前辈们要急着登场了,它们又会给我们带来一个全新的角度去理解CNN……


阅读更多
个人分类: CNN
上一篇CNN数值初始化——xavier(上)
下一篇Caffe学习系列(12):训练和测试自己的图片
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭