深度学习调参(tricks and tips)
在深度神经网络中的调参,特别是与图片相关的,主要有8个方面:
- 数据增强;
- 图片预处理;
- 参数初始化;
- 训练过程中的tips;
- 激活函数的选择;
- 多样的正则化;
- some insights found from figures and finally ;
- 集成多深度网络的方法。
数据增强
数据增强有很多方法:水平翻转,随机裁剪,色彩抖动等。此外,可以尝试多种不同处理方式的组合,比如旋转与随机展缩,也可以尝试提高图片的饱和度和像素值(S and V components of the HSV color space)。
Krizhevsky等人在训练AlexNet时采用的PCA算法来改变训练图像的RGB通道的强度。
预处理
我们需要获得的训练样本进行预处理,方法如下:
1.先进行均值归一化,然后再正则化。
X -= np.mean(X, axis=0)
X /= np.std(X, axis=0)
2.PCA Whitening
参数初始化
1.全0初始化,这样做是不太正确的,因为如果网络中的每个神经元计算出相同的输出,那么它们在反向传播过程中也会计算出相同的梯度,并进行完全相同的参数更新。如果神经元的权重初始化为相同,那么它们之间就没有不对称的来源。
2.随机数初始化,希望权值非常接近于零,但不等于零。通过这种方式,你可以将这些神经元随机分配到非常接近于零的小数目,这被视为对称破坏。比如均值为0,标准方差为1的高斯分布进行初始化
3.校准方差,随机初始化神经元的输出分布具有随输入数量增长的方差。结果表明,可以通过将每个神经元的权值向量乘以其扇入(即其输入数量)的平方根来将其输出的方差归一化为1,如下所示:
w = np.random.randn / sqrt(n)
这保证了网络中所有神经元初始输出分布近似相同,从而上提高了收敛速度。
4.目前建议,之前初始化没有考虑激活函数(ReLU)的影响,而在ResNet的论文中推导出以下公式:
w = np.random.randn * sqrt(2.0/n)
训练过程中的tips
- Fliters and pooling size。在训练过程中输入的图片大小更倾向于2^n(比如32,64,224等等)。此外,使用小的 fliter (比如3x3)和较小的不长(比如 1)以及0 padding,不仅能够降低参数的数量,而且能够改善整个深度神经网络的准确率。上面提到的一种特殊情况,即stride为1的33滤波器,可以保持图像/特征图的空间大小。对于池化层,常用的池化大小是22。
- 学习率。训练到一定程度后,当测试集或者验证集的准确率趋于稳定,可以进行调整学习率(比如 learning_rate / 5)。
- 对与训练模型进行微调。由于预先训练的深度模型具有出色的泛化能力,可以直接将这些预先训练的模型用数据集。为了进一步提高数据集上的分类性能,一个非常简单但有效的方法是根据自己的数据微调预先训练好的模型。但是在不同的情况下应该采取不同的微调方式。
激活函数的选择
激活函数是为网络带来非线性,常见的激活函数有Sigmoid、tanh、ReLU、Leaky ReLU、Parametric ReLU等。
- Sigmoid有两个主要的缺点:Sigmoids saturate and kill gradients;输出不是以0为中心
- tanh的非线性将实值压缩到[- 1,1]范围内,而且是以0为中心。
- ReLU:f(x) = max(0,x)。ReLU可以通过简单地对激活矩阵在0处设定阈值来实现,同时ReLUs不受饱和的影响;与sigmoid/tanh函数相比,它大大加快了随机梯度下降的收敛速度;ReLU units can be fragile during training and can “die”。
多样的正则化
正则化的目的是减少过拟合,主要的方法有L2、L1、 Max norm constraints、Dropout。这几种中Dropout是更加有效的,其可以解释为在全神经网络中对一个神经网络进行采样,仅根据输入数据更新采样网络的参数。
最后两个方面见参考文章
参考文章:
[1] https://mp.weixin.qq.com/s/YV5-lYEXwrI-q3oQkBlVyg
[2] https://mp.weixin.qq.com/s/5hs5M3nbJca0PYuOKbNDvA