我们常说的正则化防止过拟合是怎么一回事

从上周开始,突然想起了正则化这么个东西,一直都听到加个范数就可以防止过拟合,正则化为什么这么神奇呢?
断断续续地看了一周的相关书籍,博客,决定先来个短暂的总结,以后有了更深入的理解再来补充。

什么是过拟合

先来一张图:
拟合情况
过拟合指的是模型学习时过于复杂,以至于出现这一模型对已知的数据预测得很好,但是对未知数据预测得很差的现象。换言之,就是模型在训练集上表现的很好(均方差优化到1e-10了),可是在预测集上表现相当糟糕。从上面的图我们可以看到,右侧的图明显是过拟合了,模型在训练集上的优化目标可以优化到很优秀,可是对于接下来要预测的数据来说,并没有什么用。
接下来,我们以 logistic regression 模型作为basis,看下正则化项是怎么通过看似简单的范数来影响我们的模型得到防止过拟合的。

第一范数正则化项

定义:

第一范数定义 L1ni=1|wi| ,简而言之,就是每个参数的绝对值只和。

模型变化:

原来的 LR 模型优化目标是最小化损失函数,即:
L(w)=1NN1(f(xi,w)yi)2
现在我们给它加上一个一范数正则化项,有:
L(w)=1NN1(f(xi,w)yi)2+λ||w||1

基于 Occam’s razor 的解释

为什么加上这么一个项就可以了呢,我们先来引入奥卡姆剃刀原理:在所有可能选择的模型中,能够很好地解释已知数据并且十分简单的模型才是最好的模型,也就是应该选择的模型。从拉格朗日乘子法的计算过程我们可以把后面加的那个一范数正则化项当做一个限制,现在,让我们通过一张图来看下这项是怎么调整我们的模型来降低过拟合的:
这里写图片描述
图片来自 PRML 的第三章。
上图中的模型是线性回归,有两个特征,要优化的参数分别是w1和w2,左图的正则化是l2,右图是l1。蓝色线就是原始目标函数优化过程中遇到的等高线,一圈代表一个目标函数值,受限条件就是红色边界(就是正则化那部分),二者第一次相交处,就是我们要找的最优化参数。
可以看到 L1 范数的限制区域比较尖,优化目标和限制区域相交的时候更大概率在尖尖的部分,可以这么想,你把一个圆往一个正方形移动,肯定更大概率先撞到正方形的角。
相交点落在坐标轴上表明什么:有0的权值产生!
好了,突然一下子就明朗了, L1 范数会使我们的模型在优化目标函数的过程中偏向模型稀疏(某些特征对应的权重为0),这完全符合剃须刀原理,都一样的优化结果,模型越简单越好。

第二范数正则项

定义:

第一范数定义 L1ni=1(wi)2 ,简而言之,就是个参数的绝对值只和。

模型变化

现在我们给它加上一个一范数正则化项,有:
L(w)=1NN1(f(xi,w)yi)2+λ||w||2

condition number

从 zouxy 的博客里面了解到这个keyword,Wiki 了一下:In the field of numerical analysis, the condition number of a function with respect to an argument measures how much the output value of the function can change for a small change in the input argument. This is used to measure how sensitive a function is to changes or errors in the input, and how much error in the output results from an error in the input.condition number 用来衡量一个模型对输入的敏感程度,当输入变化稍微变化一点点的时候,如果输出变化很大,说明我们的模型对输入的数据很敏感,这并不是一个好的现象,在做 Titanic 的时候,年龄更小的存活率更加高(小孩子可以优先逃生),如果我们的模型对数据比较敏感,10岁和11岁预测出来的存活概率相差特别大,这显然是我们不愿意看到的。因此,我们在优化的过程中希望我们训练出来的模型很稳定,不会因为输入数据的稍微一点点变化而导致预测结果的天翻地覆。

再遇贝叶斯

在上一节中,我们提到模型的稳定性问题,我们希望模型足够稳定,所以我们在优化的过程中加入这么个先验,
这里写图片描述
我们相当于是给模型参数w 添加了一个协方差为 1α 的零均值高斯分布先验。 对于 α=0 ,也就是不添加正则化约束,则相当于参数的高斯先验分布有着无穷大的协方差,那么这个先验约束则会非常弱,模型为了拟合所有的训练数据,w可以变得任意大不稳定。 α 越大表明先验的高斯协方差越小,w 的波动范围越小,模型越趋于稳定, 相对的variance也越小。

总结

又一次近距离接触到贝叶斯的强大,可以这么说,正则化项对英语模型的先验概率,可以假设复杂不稳定的模型有较小的先验概率,简单稳定的模型有较大的先验概率。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
非常感谢您的提问,这是一个非常复杂的问题,需要涵盖多个领域的知识。为了回答这个问题,我需要逐步解释每个领域的知识和概念,因此这里只提供一些思路和大致的代码框架,具体实现还需要您自己完成。 首先,我们需要导入必要的库: ```python import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.preprocessing import MinMaxScaler from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout from tensorflow.keras.callbacks import EarlyStopping from tensorflow.keras.regularizers import l2 ``` 然后读取数据集并进行标准化: ```python data = pd.read_csv('your_dataset.csv') # 将数据集划分为训练集和测试集 train_size = int(len(data) * 0.8) train_data, test_data = data[:train_size], data[train_size:] # 对数据进行标准化 scaler = MinMaxScaler() train_data = scaler.fit_transform(train_data) test_data = scaler.transform(test_data) ``` 接下来,我们需要将数据集转换为序列数据,并将它们分成输入和输出: ```python def create_sequences(dataset, seq_length): X, y = [], [] for i in range(len(dataset) - seq_length - 1): X.append(dataset[i:(i + seq_length), :]) y.append(dataset[(i + seq_length), 0]) return np.array(X), np.array(y) # 设置序列长度 seq_length = 100 # 创建训练集和测试集的序列数据 X_train, y_train = create_sequences(train_data, seq_length) X_test, y_test = create_sequences(test_data, seq_length) ``` 接下来,我们可以定义 LSTM 模型: ```python model = Sequential([ LSTM(64, input_shape=(seq_length, 4), return_sequences=True, bias_regularizer=l2(0.01)), Dropout(0.2), LSTM(32, bias_regularizer=l2(0.01)), Dropout(0.2), Dense(1) ]) ``` 在模型中,我们使用了两个 LSTM 层和一个密集层。为了防止过拟合,我们在每个 LSTM 层后添加了一个 Dropout 层。我们还添加了偏差正则化器(bias_regularizer)来防止模型的偏差过大。 接下来,我们可以编译模型并定义早停回调: ```python model.compile(loss='mean_squared_error', optimizer='adam') early_stop = EarlyStopping(monitor='val_loss', patience=10, verbose=1, mode='min') ``` 然后,我们可以使用 fit 方法来拟合模型: ```python history = model.fit(X_train, y_train, epochs=100, batch_size=64, validation_split=0.1, callbacks=[early_stop], shuffle=False) ``` 在训练模型时,我们使用了早停回调来在验证集上监控损失,并在连续 10 个 epoch 中没有进展时停止训练。 最后,我们可以使用模型来进行预测: ```python train_predict = model.predict(X_train) test_predict = model.predict(X_test) # 反标准化预测结果 train_predict = scaler.inverse_transform(train_predict) y_train = scaler.inverse_transform([y_train]) test_predict = scaler.inverse_transform(test_predict) y_test = scaler.inverse_transform([y_test]) ``` 最后,我们可以使用多个评价指标来评估模型性能: ```python from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score # 计算均方误差、平均绝对误差和 R2 得分 train_rmse = np.sqrt(mean_squared_error(y_train[0], train_predict[:, 0])) test_rmse = np.sqrt(mean_squared_error(y_test[0], test_predict[:, 0])) train_mae = mean_absolute_error(y_train[0], train_predict[:, 0]) test_mae = mean_absolute_error(y_test[0], test_predict[:, 0]) train_r2 = r2_score(y_train[0], train_predict[:, 0]) test_r2 = r2_score(y_test[0], test_predict[:, 0]) ``` 最后,我们可以绘制数据趋势图和预测图: ```python # 绘制数据趋势图 plt.plot(data['feature1']) plt.plot(range(len(train_data), len(train_data) + len(test_predict)), test_predict, color='green', label='predicted') plt.axvline(x=len(train_data), color='k', linestyle='--') plt.legend() # 绘制训练集和测试集的预测图 plt.plot(y_train[0]) plt.plot(train_predict[:, 0], color='green') plt.plot(range(len(y_train[0]), len(y_train[0]) + len(y_test[0])), y_test[0], color='blue') plt.plot(range(len(y_train[0]), len(y_train[0]) + len(test_predict)), test_predict[:, 0], color='green') plt.legend() ``` 这就是一个简单的基于 LSTM 和 seq2seq 的预测模型。希望这个代码框架能够对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值