在 Keras 的批量训练期间显示每个 epoch 的进度条

Posted

技术标签:

【中文标题】在 Keras 的批量训练期间显示每个 epoch 的进度条【英文标题】:Show progress bar for each epoch during batchwise training in Keras 【发布时间】:2016-12-31 16:04:15 【问题描述】:

当我将整个数据集加载到内存中并使用以下代码在 Keras 中训练网络时:

model.fit(X, y, nb_epoch=40, batch_size=32, validation_split=0.2, verbose=1)

这会在每个 epoch 生成一个进度条,其中包含 ETA、准确性、损失等指标

当我批量训练网络时,我使用的是以下代码

for e in range(40):
        for X, y in data.next_batch():
            model.fit(X, y, nb_epoch=1, batch_size=data.batch_size, verbose=1)

这将为每个批次而不是每个时期生成一个进度条。在批量训练期间是否可以为每个时期生成一个进度条?

【问题讨论】:

这是一个答案***.com/a/38579937/5082406 【参考方案1】:
model.fit(X, y, nb_epoch=40, batch_size=32, validation_split=0.2, verbose=1)

在上面更改为verbose=2,正如documentation中提到的那样:

verbose:0 表示不记录到标准输出,1 表示进度条记录,2 表示每个 epoch 一个日志行

它会将你的输出显示为:

Epoch 1/100
0s - loss: 0.2506 - acc: 0.5750 - val_loss: 0.2501 - val_acc: 0.3750
Epoch 2/100
0s - loss: 0.2487 - acc: 0.6250 - val_loss: 0.2498 - val_acc: 0.6250
Epoch 3/100
0s - loss: 0.2495 - acc: 0.5750 - val_loss: 0.2496 - val_acc: 0.6250
.....
.....

如果您想显示一个完成 epoch 的进度条,请保留 verbose=0(它会关闭对 stdout 的日志记录)并按以下方式实现:

from time import sleep
import sys

epochs = 10

for e in range(epochs):
    sys.stdout.write('\r')

    for X, y in data.next_batch():
        model.fit(X, y, nb_epoch=1, batch_size=data.batch_size, verbose=0)

    # print loss and accuracy

    # the exact output you're looking for:
    sys.stdout.write("[%-60s] %d%%" % ('='*(60*(e+1)/10), (100*(e+1)/10)))
    sys.stdout.flush()
    sys.stdout.write(", epoch %d"% (e+1))
    sys.stdout.flush()

输出如下:

[============================================================] 100%, epoch 10

如果你想在每 n 个批次后显示损失,你可以使用:

out_batch = NBatchLogger(display=1000)
model.fit([X_train_aux,X_train_main],Y_train,batch_size=128,callbacks=[out_batch])

不过,我以前从未尝试过。上面的例子取自这个 keras github 问题:Show Loss Every N Batches #2850

您也可以在此处关注NBatchLogger 的演示:

class NBatchLogger(Callback):
    def __init__(self, display):
        self.seen = 0
        self.display = display

    def on_batch_end(self, batch, logs=):
        self.seen += logs.get('size', 0)
        if self.seen % self.display == 0:
            metrics_log = ''
            for k in self.params['metrics']:
                if k in logs:
                    val = logs[k]
                    if abs(val) > 1e-3:
                        metrics_log += ' - %s: %.4f' % (k, val)
                    else:
                        metrics_log += ' - %s: %.4e' % (k, val)
            print('/ ... '.format(self.seen,
                                        self.params['samples'],
                                        metrics_log))

您也可以使用progbar 来获取进度,但它会批量打印进度

from keras.utils import generic_utils

progbar = generic_utils.Progbar(X_train.shape[0])

for X_batch, Y_batch in datagen.flow(X_train, Y_train):
    loss, acc = model_test.train([X_batch]*2, Y_batch, accuracy=True)
    progbar.add(X_batch.shape[0], values=[("train loss", loss), ("acc", acc)])

【讨论】:

【参考方案2】:

tqdm(版本 >= 4.41.0)还刚刚添加了对 keras 的内置支持,因此您可以这样做:

from tqdm.keras import TqdmCallback
...
model.fit(..., verbose=0, callbacks=[TqdmCallback(verbose=2)])

这会关闭 keras' 进度 (verbose=0),并改用 tqdm。对于回调,verbose=2 表示时期和批次的单独进度条。 1 表示完成后清除批处理栏。 0 表示仅显示 epoch(从不显示批处理条)。

【讨论】:

+1! model.fit(..., verbose=0, callbacks=[TqdmCallback(verbose=0)]) 在训练大量 epoch(数十个或数百个)时提供最佳输出。 这应该是默认值(verbose=0)!【参考方案3】:

您可以设置 verbose=0 并设置回调,以在每次拟合结束时更新进度,

clf.fit(X, y, nb_epoch=1, batch_size=data.batch_size, verbose=0, callbacks=[some_callback])

https://keras.io/callbacks/#example-model-checkpoints

或设置回调https://keras.io/callbacks/#remotemonitor

【讨论】:

以上是关于在 Keras 的批量训练期间显示每个 epoch 的进度条的主要内容,如果未能解决你的问题,请参考以下文章

数据增强期间的 Keras CONV 训练似乎显示了错误的批量大小和训练示例数量

在 Keras 中拟合模型时,批量大小和 epoch 数应该有多大?

如何找到训练 keras 模型的 epoch 数?

Keras 交叉验证精度在每个 epoch 后稳定在 (1/output_classes)

预测取决于 Keras 中的批量大小

使用Tensorflow后端的Keras LSTM RNN中令人费解的训练损失与纪元...行为的任何原因