Keras是否有内置方法可以在训练单个epoch时输出(并随后绘制)损失的变化?
通常使用keras.callbacks.History()函数可以输出每个epoch的损失。然而,在我的情况下,训练集相当大,因此我只传递一个epoch给神经网络。由于我想绘制训练(和开发)损失在训练过程中的变化,有没有办法做到这一点?
我目前的解决方案是将训练集分成不同的批次,然后在每个批次上依次训练一个epoch,并每次保存模型。但也许有内置的方法可以做到这一点?
我使用的是TensorFlow后端。
回答:
你可以使用回调函数来实现这个目的。
使用Keras MNIST CNN示例(这里不复制整个代码),进行以下更改/添加:
from keras.callbacks import Callbackclass TestCallback(Callback): def __init__(self, test_data): self.test_data = test_data def on_batch_end(self, batch, logs={}): x, y = self.test_data loss, acc = self.model.evaluate(x, y, verbose=0) print('\nTesting loss: {}, acc: {}\n'.format(loss, acc))model.fit(x_train, y_train, batch_size=batch_size, epochs=1, verbose=1, validation_data=(x_test, y_test), callbacks=[TestCallback((x_test, y_test))] )
为了在每个批次结束时评估测试/验证集,我们得到以下结果:
Train on 60000 samples, validate on 10000 samplesEpoch 1/1Testing loss: 0.0672039743446745, acc: 0.9781 128/60000 [..............................] - ETA: 7484s - loss: 0.1450 - acc: 0.9531/var/venv/DSTL/lib/python3.4/site-packages/keras/callbacks.py:120: UserWarning: Method on_batch_end() is slow compared to the batch update (15.416976). Check your callbacks. % delta_t_median)Testing loss: 0.06644540682602673, acc: 0.9781 256/60000 [..............................] - ETA: 7476s - loss: 0.1187 - acc: 0.9570/var/venv/DSTL/lib/python3.4/site-packages/keras/callbacks.py:120: UserWarning: Method on_batch_end() is slow compared to the batch update (15.450395). Check your callbacks. % delta_t_median)Testing loss: 0.06575664376271889, acc: 0.9782
然而,正如你可能会发现的那样,这会显著减慢代码的运行速度(并相应地产生一些相关的警告)。作为一种折衷方案,如果你只想在每个批次结束时获取训练性能,你可以使用一个略有不同的回调函数:
class TestCallback2(Callback): def __init__(self, test_data): self.test_data = test_data def on_batch_end(self, batch, logs={}): print() # 只是一个空的打印命令
现在的结果(在model.fit()
中替换为callbacks=[TestCallback2((x_test, y_test))
)运行速度更快,但只在每个批次结束时提供训练指标:
Train on 60000 samples, validate on 10000 samplesEpoch 1/1 128/60000 [..............................] - ETA: 346s - loss: 0.8503 - acc: 0.7188 256/60000 [..............................] - ETA: 355s - loss: 0.8496 - acc: 0.7109 384/60000 [..............................] - ETA: 339s - loss: 0.7718 - acc: 0.7396 [...]
更新
以上所有方法都可能很好,但生成的损失和准确度并未存储在任何地方,因此无法绘制图表;因此,这里提供了另一个回调函数解决方案,实际上存储了训练集上的指标:
from keras.callbacks import Callbackclass Histories(Callback): def on_train_begin(self,logs={}): self.losses = [] self.accuracies = [] def on_batch_end(self, batch, logs={}): self.losses.append(logs.get('loss')) self.accuracies.append(logs.get('acc'))histories = Histories()model.fit(x_train, y_train, batch_size=batch_size, epochs=1, verbose=1, validation_data=(x_test, y_test), callbacks=[histories] )
这使得训练过程中每个批次结束时的指标分别存储在histories.losses
和histories.accuracies
中 – 这里是每个的前5个条目:
histories.losses[:5]# [2.3115866, 2.3008101, 2.2479887, 2.1895032, 2.1491694]histories.accuracies[:5]# [0.0703125, 0.1484375, 0.1875, 0.296875, 0.359375]