Machine Learning 简明教程

Machine Learning - Overfitting

过拟合是指模型学习训练数据中的噪声,而不是底层模式。这会导致模型在训练数据上表现良好,但在新数据上表现不佳。从本质上讲,模型变得过于专注于训练数据,无法推广到新数据。

在使用复杂模型(例如深度神经网络)时,过拟合是一个常见的问题。这些模型有许多参数,并且能够非常紧密地拟合训练数据。然而,这通常是以牺牲推广性能为代价的。

Causes of Overfitting

有几个因素会导致过拟合 −

  1. Complex models − 如前所述,复杂的模型比简单的模型更容易过拟合。这是因为复杂的模型有更多参数,能够更贴近拟合训练数据。

  2. Limited training data − 当训练数据不够时,模型难以学习潜在模式,而可能转而去学习数据中的噪声。

  3. Unrepresentative training data − 如果训练数据并不能代表模型试图解决的问题,则该模型可能学习到不相关的模式,而这些模式不能很好地推广至新的数据。

  4. Lack of regularization − 正则化是一种通过在代价函数中添加惩罚项来防止过拟合的技术。如果不存在该惩罚项,则该模型更有可能过拟合。

Techniques to Prevent Overfitting

有多种技术可用于防止机器学习中的过拟合−

  1. Cross-validation − 交叉验证是一种用于评估模型在新的、不可见数据上的性能的技术。它涉及将数据分成几个子集,并轮流使用每个子集作为验证集,同时在剩余数据上进行训练。这有助于确保该模型能很好地推广至新的数据。

  2. Early stopping − 早期停止是一种通过在训练过程完全收敛前停止训练来防止模型过拟合的技术。这可通过在训练过程中监视验证误差,并在误差停止改善时进行停止来实现。

  3. Regularization − 正则化是一种通过在代价函数中添加惩罚项来防止过拟合的技术。该惩罚项促使模型具有较小的权重,并有助于防止其拟合训练数据中的噪声。

  4. Dropout − Dropout 是一种用于深度神经网络中以防止过拟合的技术。它涉及在训练过程中随机丢弃一些神经元,迫使剩余的神经元学习更鲁棒的特征。

Example

以下是使用 Keras 在 Python 中实现早期停止和 L2 正则化的办法 −

from keras.models import Sequential
from keras.layers import Dense
from keras.callbacks import EarlyStopping
from keras import regularizers

# define the model architecture
model = Sequential()
model.add(Dense(64, input_dim=X_train.shape[1], activation='relu', kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(32, activation='relu', kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(1, activation='sigmoid'))

# compile the model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# set up early stopping callback
early_stopping = EarlyStopping(monitor='val_loss', patience=5)

# train the model with early stopping and L2 regularization
history = model.fit(X_train, y_train, validation_split=0.2, epochs=100, batch_size=64, callbacks=[early_stopping])

在此代码中,我们使用了 Keras 中的 Sequential 模型来定义模型架构,我们使用 kernel_regularizer 参数将 L2 正则化添加到前两层。我们还使用 Keras 中的 EarlyStopping 类设置了一个早期停止回调,它会监视验证损失,并在验证损失在 5 个 epoch 内停止改善后停止训练。

在训练期间,我们传入 X_train 和 y_train 数据,以及 0.2 的验证拆分来监视验证损失。我们还设置批量大小为 64,最高训练 100 个 epoch。

Output

当你执行此代码时,它会生成类似于下面所示的输出 −

Train on 323 samples, validate on 81 samples
Epoch 1/100
323/323 [==============================] - 0s 792us/sample - loss: -8.9033 - accuracy: 0.0000e+00 - val_loss: -15.1467 - val_accuracy: 0.0000e+00
Epoch 2/100
323/323 [==============================] - 0s 46us/sample - loss: -20.4505 - accuracy: 0.0000e+00 - val_loss: -25.7619 - val_accuracy: 0.0000e+00
Epoch 3/100
323/323 [==============================] - 0s 43us/sample - loss: -31.9206 - accuracy: 0.0000e+00 - val_loss: -36.8155 - val_accuracy: 0.0000e+00
Epoch 4/100
323/323 [==============================] - 0s 46us/sample - loss: -44.2281 - accuracy: 0.0000e+00 - val_loss: -49.0378 - val_accuracy: 0.0000e+00
Epoch 5/100
323/323 [==============================] - 0s 52us/sample - loss: -58.3326 - accuracy: 0.0000e+00 - val_loss: -62.9369 - val_accuracy: 0.0000e+00
Epoch 6/100
323/323 [==============================] - 0s 40us/sample - loss: -74.2131 - accuracy: 0.0000e+00 - val_loss: -78.7068 - val_accuracy: 0.0000e+00
-----continue

通过使用早期停止和 L2 正则化,我们可以帮助防止过拟合,并提高我们模型的泛化性能。