防止过拟合最简单的方式是降低模型复杂度,比如减少模型的学习参数(learnable parameters)。极客时间:TensorFlow 2项目进阶实战减少神经网络的层数,减少每一层网络的节点数都能达到目的。在深度学习中,学习参数的数量往往代表了模型“容量”(capacity)。容量越大,记忆能力越强,更容易学习到训练集的特征和标签的映射关系,类似于字典。如果这种映射关系缺乏泛化能力,在测试集上不可能有好的表现。

训练的目的不是为了让模型完全拟合训练数据,而是为了训练出具有泛化能力的模型。

反过来,如果模型较小,记忆能力较弱,学习映射关系比较困难。为了最小化损失(loss),模型需要压缩学习到的东西,因而具备更好的预测能力。但是,如果模型过小,没有足够的神经元记住有用的信息,训练会非常困难。因此需要取得权衡。

如何选择合适的网络层数和神经元数量呢?没有公式,只能不断尝试。

为了确定合适的模型大小,建议一开始采用一个参数少的模型,然后逐渐增大,直到验证集的损失(loss)基本不再变化。我们用之前的 IMDB 影评分类模型来试一试。

先搭一个基线模型,再创建大、小2个模型比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def build_and_train(hidden_dim, regularizer=None, dropout=0):
   model = keras.Sequential([
       keras.layers.Dense(hidden_dim, activation='relu',
                          input_shape=(N,),
                          kernel_regularizer=regularizer),
       keras.layers.Dropout(dropout),
       keras.layers.Dense(hidden_dim, activation='relu',
                          kernel_regularizer=regularizer),
       keras.layers.Dropout(dropout),
       keras.layers.Dense(1, activation='sigmoid')
   ])

   model.compile(optimizer='adam', loss='binary_crossentropy',
                 metrics=['accuracy', 'binary_crossentropy'])
   history = model.fit(train_x, train_y, epochs=10, batch_size=512,
                       validation_data=(test_x, test_y), verbose=0)

   return history


baseline_history = build_and_train(16)
smaller_history = build_and_train(4)
larger_history = build_and_train(512)

我们画图看一看这三个模型在训练集和验证集上的表现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def plot_history(histories, key='binary_crossentropy'):
   plt.figure(figsize=(10, 6))

   for name, history in histories:
       val = plt.plot(history.epoch, history.history['val_'+key],
                      '--', label=name + ' 验证集')
       plt.plot(history.epoch, history.history[key],
                color=val[0].get_color(), label=name + ' 训练集')

   plt.xlabel('Epochs')
   plt.ylabel('Loss - ' + key)
   plt.legend()

   plt.xlim([0, max(history.epoch)])

plot_history([('基线', baseline_history),
             ('较小', smaller_history),
             ('较大', larger_history)])


更多文章请关注《万象专栏》