大型模型的最佳批量大小和时期



我知道有很多相关的问题,但我希望有人能为我试图构建的模型提供一些具体的建议。

这是一个图像分类模型。目前,我正试图将40种不同的动物分类(40种不同类型的动物)。在每个类别中有120到220个图像。我的训练集是4708张图片,我的验证集是2512张图片。

我运行了一个序列模型(下面的代码),其中我使用了64和30个时期的批量大小。代码运行了很长时间。在30个时期之后,在验证集上的准确度约为67,在训练集上的准确性约为70。验证集的损失约为1.2,训练集的损失为1(我在下面包含了最后12个历元结果)。在大约25个时代之后,它似乎正在逐渐减少。

我的问题是关于批量大小和时代。使用更大或更小的批处理大小(大于64)有价值吗?我应该使用更多的时期吗。我读到,通常情况下,50到100个划时代是常见的做法,但如果我的结果在25个划时代后逐渐减少,那么增加更多的划时代有价值吗。

型号

history = model.fit_generator(
train_data_gen,
steps_per_epoch= 4708 // batch_size,
epochs=30,
validation_data=val_data_gen,
validation_steps= 2512 // batch_size
)

结果

Epoch 18/30
73/73 [==============================] - 416s 6s/step - loss: 1.0982 - accuracy: 0.6843 - val_loss: 1.3010 - val_accuracy: 0.6418
Epoch 19/30
73/73 [==============================] - 414s 6s/step - loss: 1.1215 - accuracy: 0.6712 - val_loss: 1.2761 - val_accuracy: 0.6454
Epoch 20/30
73/73 [==============================] - 414s 6s/step - loss: 1.0848 - accuracy: 0.6809 - val_loss: 1.2918 - val_accuracy: 0.6442
Epoch 21/30
73/73 [==============================] - 413s 6s/step - loss: 1.0276 - accuracy: 0.7013 - val_loss: 1.2581 - val_accuracy: 0.6430
Epoch 22/30
73/73 [==============================] - 415s 6s/step - loss: 1.0985 - accuracy: 0.6854 - val_loss: 1.2626 - val_accuracy: 0.6575
Epoch 23/30
73/73 [==============================] - 413s 6s/step - loss: 1.0621 - accuracy: 0.6949 - val_loss: 1.3168 - val_accuracy: 0.6346
Epoch 24/30
73/73 [==============================] - 415s 6s/step - loss: 1.0718 - accuracy: 0.6869 - val_loss: 1.1658 - val_accuracy: 0.6755
Epoch 25/30
73/73 [==============================] - 419s 6s/step - loss: 1.0368 - accuracy: 0.6957 - val_loss: 1.1962 - val_accuracy: 0.6739
Epoch 26/30
73/73 [==============================] - 419s 6s/step - loss: 1.0231 - accuracy: 0.7067 - val_loss: 1.3491 - val_accuracy: 0.6426
Epoch 27/30
73/73 [==============================] - 434s 6s/step - loss: 1.0520 - accuracy: 0.6919 - val_loss: 1.2039 - val_accuracy: 0.6683
Epoch 28/30
73/73 [==============================] - 417s 6s/step - loss: 0.9810 - accuracy: 0.7151 - val_loss: 1.2047 - val_accuracy: 0.6711
Epoch 29/30
73/73 [==============================] - 436s 6s/step - loss: 0.9915 - accuracy: 0.7140 - val_loss: 1.1737 - val_accuracy: 0.6711
Epoch 30/30
73/73 [==============================] - 424s 6s/step - loss: 1.0006 - accuracy: 0.7087 - val_loss: 1.2213 - val_accuracy: 0.6619

只有当模型不再"学习"时,才应该中断训练过程,这意味着验证数据的损失和准确性不会得到改善。要做到这一点,您可以放置任意多个时期,并使用tf.keras.callbacks.EarlyStopping(文档)。当满足特定条件时,例如当val_loss在10个时期内没有减少时,这将中断训练过程。

es = EarlyStopping(monitor='val_loss', patience=10)
fit_generator(... callbacks=[es])

这将确保在模型仍在学习时,学习过程不会中断,并且模型不会过度拟合。

32的批量大小是标准的,但这对另一个网站来说是一个更相关的问题,因为它是关于统计数据的(这是一个非常激烈的争论)。

是的,如果您可以选择尽可能大的批量。

大批量几乎总是导致更快的收敛,更短的训练时间。如果你有一个内存很好的GPU,那就尽可能地高。

至于历元,很难决定,因为我认为你的模型在28-29个历元中仍在改进,所以你可能需要训练更多的历元才能得到更好的模型,但为了寻找val_accurcy,你的val_acc似乎也在改进,这表明模型需要更多的训练。

您可以使用ModelCheckpoint在每个时期之后存储模型,以获得模型的最佳版本。https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/ModelCheckpoint

你可以使用keras

选择批量大小有三个原因。

  1. 速度。如果你使用的是GPU,那么大批量的处理速度通常几乎和小批量一样快。这意味着个别病例要快得多,这意味着每个时期也更快
  2. 规范化。较小的批次添加正则化,类似于增加辍学率、增加学习率或添加权重衰减。较大的批次将减少规则化
  3. 内存限制。这是一个硬性限制。在某个时刻,你的GPU将无法容纳内存中的所有数据,你也无法再增加批量大小

这表明,在内存耗尽之前,批量大小越大越好。除非您遇到过拟合问题,否则较大且仍在工作的批量将(1)加快训练速度,(2)允许较大的学习率,这也会加快训练过程。

第二点是因为正则化。如果你增加批量大小,减少的正则化会返回一些"正则化预算",用于增加学习率,这将增加正则化。


顺便说一句,正则化只是一种思考训练过程有多嘈杂或流畅的方式。

低正则化意味着训练非常平滑,这意味着训练很容易收敛,但训练也很容易过拟合。

高正则化意味着训练更嘈杂或更困难,但验证结果更好,因为嘈杂的训练过程减少了过拟合和由此产生的泛化误差。

如果您熟悉偏差-方差权衡,则添加正则化是添加一点偏差以减少方差的一种方式。以下是关于这个主题的许多好文章之一:正则化:偏差-方差权衡的路径。


关于正则化、训练计划和超参数调整这一更广泛的主题,我强烈推荐Leslie N.Smith关于这一主题的两篇论文。

  • 超收敛:使用大学习率的神经网络的快速训练
  • 神经网络超参数的一种有纪律的方法:第1部分——学习率、批量大小、动量和权重衰减

关于超级收敛的第一篇论文还将解决您关于使用多少历元的一些问题。


在那之后,没有关于使用多少历元的正确答案,只有指导。我所做的是:

  • 在制作模型时,尽可能快地保持训练计划。更快的训练意味着可以尝试更多的想法,更精细地调整你的超参数
  • 当你准备好出于某种原因对结果进行微调(提交给Kaggle,将模型部署到生产中)时,你可以增加时期并进行一些最终的超参数调整,直到验证结果停止改善"足够",其中"足够"是你的耐心和对更好结果的需求的结合

最新更新