神经网络实践心得
- 1.关于神经网络层数
- 2.关于隐藏层神经元个数
- 3.关于优化器optimizer
- 4.关于Mini-batch SGD
- 5.关于hard-mining
- 6.关于loss函数
- 7.数据归一化与BN
- 参考文献
1.关于神经网络层数
隐藏层先选择1层,即使用3层神经网络进行训练。
然后增加1层看看训练集、测试集等的效果,如果几乎没有提升,那就只在3层基础上优化吧。
毕竟增加一层,时间效率、成本都需要考虑、
2.关于隐藏层神经元个数
链接中给出了3条指导性的原则,那不妨就先采用2/3*输入输出层神经元之和作为隐藏层神经元个数。
- The number of hidden neurons should be between the size of the input
layer and the size of the output layer. - The number of hidden neurons should be 2/3 the size of the input layer, plus the size of the output layer.
- The number of hidden neurons should be less than twice the size of the input layer.
然后再使用贝叶斯优化等AUTOML方法优化,来获得最佳的隐藏层神经元个数。
下面给出了采用了贝叶斯优化,取值范围(1/3 ,4/3)输入输出神经元个数之和的计算结果,其实也不同神经元个数都差不了多少吧。
number of hidden layer neurons:9 test_precision:0.9969
number of hidden layer neurons:21 test_precision:0.9974
number of hidden layer neurons:15 test_precision:0.9971
number of hidden layer neurons:22 test_precision:0.9972
number of hidden layer neurons:8 test_precision:0.9968
number of hidden layer neurons:21 test_precision:0.9974
number of hidden layer neurons:14 test_precision:0.9971
number of hidden layer neurons:10 test_precision:0.9973
number of hidden layer neurons:17 test_precision:0.9971
number of hidden layer neurons:19 test_precision:0.9971
3.关于优化器optimizer
我比较习惯用RMSprop、Adam和SGD,其实影响最大的还是学习率。
最近研究了下torch.optim.lr_scheduler,其包含了众多的学习率lr调整策略,如LambdaLR,MultiplicativeLR等,但是我在实际训练过程中发现,加上这些学习率策略,有时甚至会适得其反。
我这里采用了一种策略:early_stopping+StepLR。
即通过检查某个metric,如val_loss,当训练过程中它出现一定次数不再增加(满足early_stopping条件)时,让学习率*factor;
设定满足early_stopping的次数,达到时自动退出训练。
这样我认为是比较高效的。
4.关于Mini-batch SGD
对于训练数据量比较大,当前使用的计算资源又不太好(如只有cpu),Mini-batch SGD确实运行起来 的,而且由于其选择数据的随机性,最终的效果也并不差。
5.关于hard-mining
在训练中单独将训练结果不正确的样本抽出来,再以加入一定倍数个数的训练正确的样本,将这个新的数据集重新开始训练。
遗憾的是,发现对最终结果并未有太大提升。
看来初始训练结果错误的样本,很有可能是噪声点。
6.关于loss函数
当前训练数据集是个四分类任务,简单对比了下torch.nn.SMOOTHL1LOSS、SmoothL1Loss以及BCEWithLogitsLoss,最后发现BCEWithLogitsLoss还是相对优秀的。
7.数据归一化与BN
发现模型中使用了BN之后,数据预处理有没有加StandardScaler,没有啥影响~
from sklearn.preprocessing import MinMaxScaler,StandardScaler