激活函数
https://blog.youkuaiyun.com/kangyi411/article/details/78969642
梯度爆炸、梯度消失
根据链式法则,如果每一层神经元对上一层的输出的偏导乘上权重结果都小于1的话,那么即使这个结果是0.99,在经过足够多层传播之后,误差对输入层的偏导会趋于0。这种情况会导致靠近输入层的隐含层神经元调整极小。
同样的,如果每一层神经元对上一层的输出的偏导乘上权重结果都大于1的话,在经过足够多层传播之后,误差对输入层的偏导会趋于无穷大。这种情况又会导致靠近输入层的隐含层神经元调整变动极大。
解决办法:
- relu (系列,还有 leaky relu 等)激活函数,正数部分的梯度都是 1,负数部分都是 0,不存在累加效应
- BN 层(batch normalization):通过对每一层的输出规范为均值和方差一致的方法,消除了 w 带来的放大缩小的影响,进而解决梯度消失和爆炸的问题
- 权重正则化:如在Keras深度学习库中,可以在每层上使用L1或L2正则器设置kernel_regularizer参数来完成权重的正则化操作。
- 残差结构(resnet)
过拟合的解决
原因
- 训练数据不足 or 样本里的噪音数据干扰过大
- epoch 迭代轮次过多
- 参数太多、模型复杂度高 (网络层过多,神经元个数过多,树身过深,叶子结点过多等)
解决
- 训练集越多,过拟合的概率越小,数据增强等进行增加训练数据
- 减少特征数量
- 调低模型复杂度:减少层数、减少树深等
- 机器学习中,增加正则约束,深度学习中,增加 Dropout 层
- 减少训练轮次,early stop,
- 更加细致的数据清理(脏数据、空值数据等)
- 采用更大的 batch size 和更大的 learning_rate,但是 batch size 不要过大,在 512 以内
- optimizer 中加入正则
网络技巧
- 数据预处理,进行 max - min 归一化
- 训练数据进行 shuffle 打乱顺序
- 在数据集很大的情况下,先用 1/10 的数据跑,推算模型性能和训练时间
- 输出层使用正确的激活函数。如:在最后一层只使用 relu 激活函数的话,神经网络便只会训练得到正值。而且网络最后一层之前不要加 relu 等激活(sigmoid 或者 softmax 之前不要激活)因为 softmax 本身就是激活函数了
- DropOut 值一般设为0.5,一般只需要最后一层 softmax 或者 sigmoid 前用就可以了)
- learning rate:从 0.1 开始,然后逐步 * 0.1 进行
- batch_size:128 左右开始,某些任务 batch_size 设成1有奇效。
- embedding size:一般是 128 附近
- 优化器:sgd 收敛速度会慢一些,但是最终收敛后的结果,一般都比较好。如果使用 sgd 的话,可以选择从1.0或者 0.1 的学习率开始,隔一段时间,在验证集上检查一下,如果cost没有下降,就对学习率减半,adam,adadelta 等可以自动对学习率进行衰减,可以解决一堆奇奇怪怪的问题
- 看train/eval的loss曲线,正常的情况应该是train loss呈log状一直下降最后趋于稳定,eval loss开始时一直下降到某一个epoch之后开始趋于稳定或开始上升,这时候可以用early stopping保存eval loss最低的那个模型