e.h*_*ton 5 python python-3.x keras
我想在每个实例的模型训练中获得损失值。
history = model.fit(..)
Run Code Online (Sandbox Code Playgroud)
例如,上面的代码返回每个时期的损失值,而不是微型批次或实例。
做这个的最好方式是什么?有什么建议么?
在此官方 keras 文档页面https://keras.io/callbacks/#callback的末尾,正是您要寻找的内容
这是创建自定义回调的代码
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.losses = []
def on_batch_end(self, batch, logs={}):
self.losses.append(logs.get('loss'))
model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
history = LossHistory()
model.fit(x_train, y_train, batch_size=128, epochs=20, verbose=0, callbacks=[history])
print(history.losses)
# outputs
'''
[0.66047596406559383, 0.3547245744908703, ..., 0.25953155204159617, 0.25901699725311789]
'''
Run Code Online (Sandbox Code Playgroud)
如果您想获取每个批次的损失值,您可能需要model.train_on_batch在生成器内使用调用。在不知道您的数据集的情况下很难提供完整的示例,但是您必须将数据集分成批次并逐一提供它们
def make_batches(...):
...
batches = make_batches(...)
batch_losses = [model.train_on_batch(x, y) for x, y in batches]
Run Code Online (Sandbox Code Playgroud)
对于单个实例来说,情况稍微复杂一些。当然,您可以在 1 大小的批次上进行训练,尽管它很可能会破坏您的优化器(通过最大化梯度方差)并显着降低性能。此外,由于损失函数是在 Python 域之外评估的,因此没有直接的方法可以在不修改 C/C++ 和 CUDA 源的情况下劫持计算。即使如此,后端本身也会批量评估损失(受益于高度矢量化的矩阵运算),因此,通过强制它评估每个实例的损失,您将严重降低性能。简而言之,破解后端只会(可能)帮助您减少 GPU 内存传输(与通过 Python 接口对 1 大小批次进行训练相比)。如果您确实想获得每个实例的分数,我建议您批量训练并评估实例(这样您将避免高方差问题并减少昂贵的梯度计算,因为梯度仅在训练期间估计):
def make_batches(batchsize, x, y):
...
batchsize = n
batches = make_batches(n, ...)
batch_instances = [make_batches(1, x, y) for x, y in batches]
losses = [
(model.train_on_batch(x, y), [model.test_on_batch(*inst) for inst in instances])
for batch, instances in zip(batches, batch_instances)
]
Run Code Online (Sandbox Code Playgroud)