TensorFlow机器学习(原书第2版)
上QQ阅读APP看书,第一时间看更新

3.4 正则化

不要被3.3节中多项式的美妙的灵活性所迷惑。高阶多项式不过是低阶多项式的扩展,但这并不意味着你应该总是倾向于更灵活的模型。

在现实世界中,数据很少按照平滑的多项式曲线来分布。假设你在绘制一段时间内的房价。数据可能会包含一些波动。回归的目标是通过简单的数学方程表达复杂性。如果你的模型太灵活,模型对输入的解释会过于复杂。

以图3.12中所示的数据为例。你试图通过一个8次多项式来拟合看起来符合075-02分布的数据。这个过程不幸失败了,因为算法要努力更新多项式的9个系数。

图3.12 当模型过于复杂时,最佳拟合曲线看起来笨拙复杂或者不直观。我们需要正则化提高拟合效果,以使得模型在测试数据上表现良好

正则化是一种以你希望的形式构建参数的技术,通常用于解决过拟合问题(见图3.13)。在这种情况下,你期望学习到的系数除了第二项之外全都是0,因此得到曲线075-02。回归算法可能会产生得分很高但看起来复杂奇怪的曲线。

图3.13 正则化的概览。建模的过程以数据X为输入,尝试以最小化模型预测与ground truth的差距或者代价函数来学习模型参数W。简单起见,用顶部灰色象限展示的2维模型参数空间表示权重选择。正则化保证了训练算法不会在不理想(灰色)的区域内选择权重,而是在白色圈的理想区域内选择

为了影响学习算法以产生以一个较小的系数向量(我们称之为w),你需要在代价中增加惩罚项。为了控制你加入的惩罚项的权重,将惩罚乘以一个恒定非负数λ,如下所示:

如果λ设置为0,正则化就不起作用。设置的λ值越大,具有较大范数的参数受到的惩罚就越重。范数的选择视情况而定,但参数通常按L1或L2范数测量。简单地说,正则化降低了一些容易紊乱的模型的灵活性。

为了找出最合适的正则化参数λ,你需要将数据集分成不交叉的两部分。约70%的随机选择的输入/输出对用于训练集,剩下的30%用于测试。使用清单3.4中提供的函数分割数据集。

清单3.4 分割数据为训练集和测试集

练习3.3

一个名为SK-learn的Python库支持很多有用的数据预处理算法。可以调用SK-learn的函数实现同清单3.4一样的功能。你能从此库的文档中找到这个函数吗?(提示:参见http://mng.bz/7Grm。)

答案

函数被称为sklearn.model_selection.train_test_split

通过这个方便的工具,可以测试哪个值在你的数据上表现最好。按照清单3.5新建一个Python文件。

清单3.5 估算正则化参数

如果你画出清单3.5中每个正则化参数对应的输出,你可以看到随着λ的增加曲线的变化。当λ为0时,算法倾向于使用高阶项来拟合数据。当你开始使用高L2范数惩罚参数时,代价降低了,这表明你在从过拟合中恢复过来,如图3.14所示。

图3.14 随着你在一定程度上增加正则化参数,代价降低。结果表明最初的模型过拟合了数据,而正则化帮助优化了结构

支持正则化的TensorFlow库

TensorFlow是一个全面支持机器学习的库,尽管本节聚焦在如何自行实现正则化,TensorFlow为实现L2正则化提供了自己的函数。你可以使用函数tf.nn.l2_loss(weights)在代价函数中对每个权重增加正则化损失,以得到同等的效果。