以下内容有任何不理解可以翻看我之前的博客哦:吴恩达deeplearning.ai专栏
学习曲线是一种图形表示方法,用于展示模型在训练过程中的学习表现,即模型的训练集和验证集上的性能如何随着训练时间的增加而变化。可以帮助我们了解模型的学习进度。
文章目录
- 学习曲线
- 线性回归方程为例
- 一个理想的学习曲线
- 高偏差时的学习曲线
- 高方差时的学习曲线
- 决定下一步做什么
- 大型神经网络带来对于偏方差的新解决方法
- 解决神经网络过大问题
- 代码实现
学习曲线
线性回归方程为例
我们以以下方程为例:
f
w
,
b
(
x
)
=
w
1
x
+
w
2
x
2
+
b
f_{w,b}(x)=w_1x+w_2x^2+b
fw,b(x)=w1x+w2x2+b
一个理想的学习曲线
然后我们可以绘制其学习曲线,横坐标为训练集的大小(也可以理解为epoch的次数),纵坐标为training set以及validation set的价值函数值,你拟合出来的图像很有可能是这样子的:
可以看出,随着training set的增大,
J
t
r
a
i
n
J_{train}
Jtrain逐渐上升,而
J
c
v
J_{cv}
Jcv逐渐减小,这其实是容易理解的。当数据的量很少时,我们的拟合曲线很容易通过所有的点,此时training set上的损失值就比较小甚至为0,但是此时模型的泛化程度就肯定很低了,因此在cv set上的损失就会很大。而随着数据量的增加,拟合曲线就很难通过所有的点了,因此此时的
J
t
r
a
i
n
J_{train}
Jtrain
必然就会上升,而因为模型接受的数据多了,
J
c
v
J_{cv}
Jcv便渐渐减小,直到数据量足够多时二者就都趋于稳定并且比较接近。
高偏差时的学习曲线
如果在你的算法的拟合下,最后的结果是高偏差的,那么它的学习曲线会具有一定的特点:
J
c
v
J_cv
Jcv和
J
t
r
a
i
n
J_train
Jtrain二者的关系是不太变化的,但是于之前不同的是你的代价函数值会明显高于你的预期值(如图所示),而且随着数据量的增加,最后的代价函数值仍然处于一个稳定的范围,并不会随着数据量的增加而使得模型的效果变好。因此,如果你的模型出现了高偏差的情况,不要着急着去增加数据量,此时更好的选择应该是优化你的算法。
高方差时的学习曲线
如果在定义你的代价函数的时候,
λ
\lambda
λ设置得过小,那么此时容易出现过拟合的现象,此时容易出现的情况就是低偏差高方差,难以泛化:
在这种情形之下,一开始的
J
t
r
a
i
n
J_{train}
Jtrain会极小(过拟合),甚至比人类表现的代价还要小。而模型的泛化能力极弱,最终会导致
J
c
v
J_{cv}
Jcv很大,但这种情况有个好处,就是随着数据量的增大,最后
J
c
v
J_{cv}
Jcv会降低到合适的水平,接近于人类水平,虽然
J
t
r
a
i
n
J_{train}
Jtrain上升但是也不会超过人类水平很多。
总之,在训练神经模型的时候,绘制其学习曲线能够很好地帮助你直到下一步该如何调整模型,但是缺点就是你如果实验多个模型,对算力是个很大的考验,可能会非常昂贵。但即使你无法真实地绘制出这个曲线,你也可以利用这种思想在脑海中形成一个虚拟图像,帮助你提高模型效果。
决定下一步做什么
在了解了以上这些概念之后,我们在模型遇到困难时应该了解了一些努力的方向了。现在我们还是用以前的例子,看看如何综合利用之前的方法:
你已经完成了一个关于房价预测的线性回归模型,代价函数如上图,但是预测的时候出现了一些错误的预测,你下一步该做什么呢?
以下是一些常见的选择:
——获得更多的训练数据
——尝试使用更少的特征
——尝试获得更多的特征
——添加多项式特征
——尝试增大
λ
\lambda
λ
——尝试减小
λ
\lambda
λ
事实上,以上的六个方法都有可能减少偏差和方差,这取决于你具体的应用场景,我们来依次分析。
对于第一个方法:如果你的算法具有高方差,比如算法对于过小的数据集过度拟合,那么确实可以通过添加更多训练数据对模型提供很大的帮助,但是如果是高偏差,那么这个方法帮助就很小了。
对于第二个方法:如果你的算法具有很多的特征,那么这将赋予算法很高的灵活性,从而无法适应更加复杂的模型。如果你怀疑你的算法具有很多意义不明的特征或者冗余的特征,可以尝试采用这种方法。从而可以降低过拟合的发生(用于解决高方差的发生)。
对于第三个方法:这个就比较明显了,可以用于解决高偏差的问题。
对于第四个方法:如果你是线性函数,三线可以很好地拟合训练集,那么添加额外的多项式特征可以帮助你在训练集做得更好,用于解决高偏差问题。
对于第五个方法:以前的博客详细介绍过,用于解决高偏差问题。
对于第六个方法:同理,解决高方差问题。
总结如下:
大型神经网络带来对于偏方差的新解决方法
在上面我们提到了解决偏差与方差的一般方法,但是大型神经网络与大数据为解决此类问题提供了新的思路。
在神经网络出现之前,机器学习工程师经常需要考虑的问题就是偏差方差权衡,因为模型简单,就会导致高偏差,而模型复杂,就会导致高方差,两者是矛盾的,因此常常需要在二者之中找到一个平衡点:
但是,神经网络和大数据的出现改变了这种情况。
事实证明,在小中规模的数据集上训练大型神经网络是低偏差机器,即只要你的神经网络足够大,那么就一定可以很好地拟合数据,因此我们可以根据需要来增加或减小偏差方差(水多加面面多加水法):
即你先训练了一个神经网络,如果在训练集表现不佳,那么就构建更大的神经网络,如果在cv表现不佳,那么就加更多的数据,直到达到你需要的平衡。这种方法的缺点就是对算力的要求很高,因此随着近些年硬件的发展,神经网络才能获得足够的算力从而长足发展。
解决神经网络过大问题
如果你感觉你的神经网络过大了,担心会不会导致过度拟合,怎么办勒。
事实证明,精心选择的大型正则化网络往往与较小的神经网络一样好甚至更好。因此如果模型大了,那就好好正则化吧,这样也能够达到你想要的效果。另一种说法是,只要你好好正则化,大型的神经网络几乎不会比小模型差。当然大型神经网络要求的算力必然很高,会拖慢运算速度。
代码实现
之前我们创建神经网络的代码是这样的:
layer_1 = Dense(units=25, activation='relu')
layer_2 = Dense(units=15, activation='relu')
layer_1 = Dense(units=1, activation='sigmoid')
model = Sequential([layer_1, layer_2, layer_3])
如果要添加正则化项:
layer_1 = Dense(units=25, activation='relu', kernel_regularizer=L2(0.01))
layer_2 = Dense(units=15, activation='relu', kernel_regularizer=L2(0.01))
layer_1 = Dense(units=1, activation='sigmoid', kernel_regularizer=L2(0.01))
model = Sequential([layer_1, layer_2, layer_3])
为了给读者你造成不必要的麻烦,博主的所有视频都没开仅粉丝可见,如果想要阅读我的其他博客,可以点个小小的关注哦。