声明
1)该文章整理自网上的大牛和机器学习专家无私奉献的资料,具体引用的资料请看参考文献。
2)本文仅供学术交流,非商用。所以每一部分具体的参考资料并没有详细对应。如果某部分不小心侵犯了大家的利益,还望海涵,并联系博主删除。
3)博主才疏学浅,文中如有不当之处,请各位指出,共同进步,谢谢。
4)此属于第一版本,若有错误,还需继续修正与增删。还望大家多多指点。大家都共享一点点,一起为祖国科研的推进添砖加瓦。
文章目录
0、前言
深度神经网络训练过程中存在一些问题。
- 首先,你将面临一个棘手的梯度消失问题(或相关的爆炸梯度问题),它会影响深层神经网络,并使较低层很难训练。
- 其次,有了如此庞大的网络,训练将非常缓慢。
- 最后,一个具有数百万个参数的模型将严重地冒着过拟合训练集的风险。
今天,我将介绍一些实践方法,以通过正则化避免过拟合问题。
1、提前停止(earlystopping)
提前终止可能是最简单的正则化方式,适用于模型的表达能力很强的时候。这种情况下,一般训练误差会随着训练次数的增多逐渐下降,而测试误差则会先下降而后再次上升。为了避免过拟合训练集,一个很好的解决方案是 提前停止,当它在验证集上的性能开始下降时就中断训练。
举一个例子,下面分别展示了训练1500次与2500次时的训练误差与测试误差:
其中训练1500次,测试集上的正确率是82%,而训练2500次,测试集上的正确率是80%。可以看出随着训练次数的增加,训练误差会一直下降,而训练2500次的测试误差要高于训练1500次的测试误差,所以我们在1500次的时候停止会更好。
2、L1 和 L2 正则化(Regularization)
详细的可以看一下博客——深度学习100问之深入理解Regularization(正则化)
正则化对模型的不同参数增加了惩罚,从而降低了模型的自由度。因此,该模型不太可能适应训练数据的噪声,提高了模型的泛化能力。
L2 参数范数惩罚通常称为权重衰减。这种正则化策略通过在目标函数中添加一个正则化项,使权重更接近原点。
在其他学术界,L2 正则化也称为岭回归或 Tikhonov 正则化。
L1 正则化策略通过向目标函数添加 L1 正则化项来使权重更接近原点。这也称为 Lasso 正则化。
# Add Regulization
# https://stackoverflow.com/questions/36706379/how-to-exactly-add-l1-regularisation-to-tensorflow-error-function
total_loss = meansq # or other loss calcuation
l1_regularizer = tf.contrib.layers.l1_regularizer(
scale=0.005, scope=None
)
weights = tf.trainable_variables() # all vars of your graph
regularization_penalty = tf.contrib.layers.apply_regularization(
l1_regularizer, weights)
# this loss needs to be minimized
regularized_loss = total_loss + regularization_penalty
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(regularized_loss)
3、随机失活(Dropout)
直观理解如下:
也就是说把部分的神经元 注销!!!
最流行的深度神经网络正则化技术可以说是 Dropout 。这是一个相当简单的算法:在每个训练步骤中,每个神经元都有一个暂时“Dropout”的概率 p ,这意味着在这个训练步骤中它将被完全忽略,但它可能在下一步中处于活动状态。超参数 p 称为丢失率,通常设置为 50% 。
# Set up the pooling layer with dropout using tf.nn.max_pool
with tf.name_scope("pool3"):
pool3 = tf.nn.max_pool(
conv2, ksize=[
1, 2, 2, 1], strides=[
1, 2, 2, 1], padding="VALID")
pool3_flat = tf.reshape(pool3, shape=[-1, pool3_fmaps * 14 * 14])
pool3_flat_drop = tf.layers.dropout(
pool3_flat, pool3_dropout_rate, training=training)
dropout的缺点在于,需要将训练集分为不同子集输入每一次的迭代,这就需要较大的训练集,所以在训练集较小的情况下,dropout的效果可能并不好。
大家都知道增大数据集是最好的正则化方式,所以在增大数据集的情况下,使用dropout需要使用的计算代价可能会比它带来正则化效果更高,这需要我们在实际使用场景中做取舍。
4、数据增强(Data Augmentation)
最后一种正则化技术,数据增强,更大数量的训练集是提升机器学习模型泛化能力最好的方法。做一个不可能的假设,如果你的训练集包含了所有的你需要测试的数据,那么该模型的泛化能力将是100%(开个玩笑)。在实际项目中,获取训练数据的成本会很高,这时候就需要我们自己来“创造”数据。
从现有的训练实例中生成新的训练实例,人为地增加训练集的大小,可以采用小幅旋转,平移,放大,缩小甚至给图片加上波动等方法。这将减少过拟合。诀窍是生成真实的训练实例。
常用的数据增强方法有:
- 旋转 | 反射变换(Rotation/reflection): 随机旋转图像一定角度; 改变图像内容的朝向;
- 翻转变换(flip): 沿着水平或者垂直方向翻转图像;
- 缩放变换(zoom): 按照一定的比例放大或者缩小图像;
- 平移变换(shift): 在图像平面上对图像以一定方式进行平移;
- 可以采用随机或人为定义的方式指定平移范围和平移步长, 沿水平或竖直方向进行平移. 改变图像内容的位置;
- 尺度变换(scale): 对图像按照指定的尺度因子, 进行放大或缩小; 或者参照SIFT特征提取思想, 利用指定的尺度因子对图像滤波构造尺度空间. 改变图像内容的大小或模糊程度;
- 对比度变换(contrast): 在图像的HSV颜色空间,改变饱和度S和V亮度分量,保持色调H不变. 对每个像素的S和V分量进行指数运算(指数因子在0.25到4之间), 增加光照变化;
- 噪声扰动(noise): 对图像的每个像素RGB进行随机扰动, 常用的噪声模式是椒盐噪声和高斯噪声;
- 颜色变化:在图像通道上添加随机扰动。
- 输入图像随机选择一块区域涂黑,参考《Random Erasing Data Augmentation》。
例如,如果模型用于对数字图片进行分类,可以通过各种数量轻微移动,旋转和调整训练集中每张图片的大小,并将生成的图片添加到训练集中。
# Image Augmentation
for img_id in imges:
image = np.array(cv2.imread(train_dir + img_id))
label = train_df[train_df['id'] == img_id]['has_cactus'].values[0]
X_tr.append(image)
Y_tr.append(label)
X_tr.append(np.flip(image))
Y_tr.append(label)
X_tr.append(np.flipud(image))
Y_tr.append(label)
X_tr.append(np.fliplr(image))
Y_tr.append(label)
X_tr = np.asarray(X_tr).astype('float32') / 225
Y_tr = np.asarray(Y_tr)
如果想要更多的资源,欢迎关注 @我是管小亮,文字强迫症MAX~
回复【福利】即可获取我为你准备的大礼,包括C++,编程四大件,NLP,深度学习等等的资料。
想看更多文(段)章(子),欢迎关注微信公众号「程序员管小亮」~