此文章旨在总结一些大佬在实战中防止过拟合的方法,仅供参考和学习
吴恩达深度学习中关于过拟合的讲解
1.L2正则化
吴恩达说:标准的方法是L2 正则化,它用来修改你的损失函数,从原来的:
J
=
−
1
m
∑
i
=
1
m
(
y
(
i
)
log
(
a
[
L
]
(
i
)
)
+
(
1
−
y
(
i
)
)
log
(
1
−
a
[
L
]
(
i
)
)
)
(1)
J = -\frac{1}{m} \sum\limits_{i = 1}^{m} \large{(}\small y^{(i)}\log\left(a^{[L](i)}\right) + (1-y^{(i)})\log\left(1- a^{[L](i)}\right) \large{)} \tag{1}
J=−m1i=1∑m(y(i)log(a[L](i))+(1−y(i))log(1−a[L](i)))(1)
变化为:
J
正
则
化
后
=
−
1
m
∑
i
=
1
m
(
y
(
i
)
log
(
a
[
L
]
(
i
)
)
+
(
1
−
y
(
i
)
)
log
(
1
−
a
[
L
]
(
i
)
)
)
⏟
交叉熵损失函数
+
1
m
λ
2
∑
l
∑
k
∑
j
W
k
,
j
[
l
]
2
⏟
L2 正则项
(2)
J_{正则化后} = \small \underbrace{-\frac{1}{m} \sum\limits_{i = 1}^{m} \large{(}\small y^{(i)}\log\left(a^{[L](i)}\right) + (1-y^{(i)})\log\left(1- a^{[L](i)}\right) \large{)} }_\text{交叉熵损失函数} + \underbrace{\frac{1}{m} \frac{\lambda}{2} \sum\limits_l\sum\limits_k\sum\limits_j W_{k,j}^{[l]2} }_\text{L2 正则项} \tag{2}
J正则化后=交叉熵损失函数
−m1i=1∑m(y(i)log(a[L](i))+(1−y(i))log(1−a[L](i)))+L2 正则项
m12λl∑k∑j∑Wk,j[l]2(2)
我对于正则项的理解是反过来的,要防止过拟合就要对每一个梯度Wi都要进行惩罚,原来是Wi=Wi - αdWi,可以加上一个λ/m×Wi(λ是一个系数,用来控制正则化程度,除以m是对m个例子求平均)来限制Wi更新的速度。那么现在就应该是Wi=Wi - α×dWi+λ/mWi。
这个值其实是由损失函数求导得到的,那么我们可以对λ/mWi求一个积分,也就λ/2m(Wi)²,那么损失函数里面刚好就是加上一个λ/2m*(Wi)²,这个式子刚好是L2正则项,注意是所有的Wi都要加到损失函数里面去,这样反向传播求导才会有上面的值。
2.随机失活 (dropout)
这里要特别注意随机失活只用于训练集而不能用于测试集,这是很容易犯错的一点!
1.随机失活在两个地方,前向传播和反向传播里面都要有.比如,当你随机失活L层时,前向传播将AL做处理,反向传播将dAL做处理
2.由于随机失活把部分神经元抑制了,这样会导致损失函数的值变小,因此我们处理完AL后要把他除以keep_prob,来防止这一点发生
其他地方看到的技巧
1.一篇公众号关于Kaggle比赛中防止过拟合技巧
原文参见:link
首先应该将训练数据合理地分为训练集和验证集,保证自己有训练集、验证集和测试集。
验证集结果和测试集结果近似相等才是最优的,一般来说,两者相差程度不要超过2%,当然最好的情况是不要超过1%,例如验证集的准确率为90%,那么测试集应该在90±2%。
后面总结了一些原因:
1.验证集划分不合理:通常要求验证集和训练集的数据分布基本相同,可以通过计算欧式距离或者画图来查看分布;
2.测试集和训练集特征相差过大:在训练集和测试集中,一部分特征可能差距过大,例如:以天气距离,训练数据刚好是梅雨季节,测试数据是正常情况,那么就会产生较大的差异。
3.模型参数设计不合理:过低的学习率和较多的参数容易导致过拟合,我们一般在良好的验证集的指导下,能很快找到效果比较好的参数,而且不要忘记正则化。