Make Your Neural Network More Powerful

写这篇文章主要是对最近看的一些论文和资料做一个总结。同时,我觉得下面写的这些tricks或结论对于工业界来说很有价值。虽然目前大家都知道神经网络性能非常强大,但却很少知道神经网络为什么能够work地这么好,以及有哪些技巧可以在实践中使神经网络工作地更好。最近这段时间,我了解了一些关于解释神经网络性能的工作(虽然没有看到特别满意的工作,但这些工作给出的一些实验性的技巧和结论挺有意思的)。

下面主要分两部分来写:神经网络能够work的一些结论以及训练神经网络的一些tricks

神经网络能够work的一些结论

1、使用正奇次函数()比如ReLU或者max-pooling作为激活函数的神经网络,它的局部最优解更加靠近全局最优解(在一些条件下它的局部最优解即全局最优解),而且不容易收敛到鞍点解(相比使用非正奇次函数,比如sigmoid作为激活函数的神经网络)。

2、复杂网络(模型参数数量比训练数据大)会使全局最优解退化(degenerate),即会有很多flat minima解的产生,通过SGD可以以很大概率找到这些flat minima

3、复杂网络虽然在loss上会看到过拟合的现象,但是在错误率上却不会出现过拟合(有一些特定条件需要满足),关于这个现象的一个解释是,神经网络往往能够求得margin最大的分类超曲面,所以即使在loss上会过拟合,但是error rate可以保持不变。见下图:

训练神经网络的一些tricks

1、SGDwith momentum,下面提到SGD假设都加了一阶动量)性能一般都很好,一般情况下都能收敛到一个比较好的局部最优解,相比于Adam等二阶动量算法,SGD适用范围更广。

2、开始训练时可以用收敛速度较快的二阶动量优化算法,比如Adam,到后期再转用一阶动量优化算法SGD。有实验证明二阶动量优化算法虽然收敛速度快,但很容易陷入较差的局部最优解,而一阶动量优化算法虽然收敛速度没二阶动量优化算法快,但不容易收敛到较差的局部最优解。

3、学习速率根据batch size大小来调,如果实验中设置了较大的batch size,可以一开始把初始学习速率设大一点,vise versa。这个trick很容易理解,因为batch size越大说明梯度干扰越小,因此可以通过把学习速率设大一点,来弥补梯度干扰小的问题。

4、周期性改变学习速率的大小,比如设置一个restart 周期,一个周期结束后重新设置学习速率,可以通过引入cosin函数来实现。

5、用不同的策略选择初始参数值,不同初始参数值最后会收敛到不同的参数解。但这个技巧目前好像没有特别通用的策略来设置初始参数值。其实上面的第4个技巧也可以理解为一种设置不同参数初始值的策略(每个周期可以看做一次完整的训练过程,然后把前一次得到的参数解作为初始参数值再训练)。

6、如果只关心模型的性能,可以“无脑”地用最复杂的网络来训练,原因参考“神经网络能够work的一些结论”里的第2和第3个结论。

上面讲的一些结论和tricks肯定是不完整的,如果想深入了解和理解这些结论以及tricks可以阅读相关参考文献,也欢迎大家补充自己知道的一些结论和tricks :-)

主要参考文献:

Visualizing the Loss Landscape of Neural Nets

Theory of Deep Learning III: explaining the non-overfitting puzzle

Universal Function Approximation by Deep Neural Nets with Bounded Width and ReLU Activations

Mathematics of Deep Learning

Understanding Deep Neural Networks with Rectified Linear Units

http://ruder.io/deep-learning-optimization-2017/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>