获取每个培训实例的损失值 - Keras

时间:2018-01-05 17:05:17

标签: keras

我希望将损失值作为每个实例的模型训练。

history = model.fit(..)

例如上面的代码返回每个纪元而非迷你批次或实例的损失值。

这样做的最佳方式是什么?有什么建议吗?

4 个答案:

答案 0 :(得分:3)

在此官方keras文档页面https://keras.io/callbacks/#callback的末尾确实有您想要的东西

这是创建自定义回调的代码

navigator.permissions.query()

答案 1 :(得分:2)

如果您想获得每个批次的损失值,您可能希望在生成器中使用调用model.train_on_batch。在不知道您的数据集的情况下很难提供完整的示例,但您必须将数据集分成几批并逐个提供它们

def make_batches(...):
    ...

batches = make_batches(...)
batch_losses = [model.train_on_batch(x, y) for x, y in batches]

单个实例有点复杂。当然,您可以在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)
]

答案 2 :(得分:0)

在合并herehere的资源后,我想出了以下代码。也许它会帮助你。我们的想法是您可以从keras覆盖Callbacks类,然后使用on_batch_end方法检查keras将自动提供给该方法的logs的损失值。

这是一个NN的工作代码,内置了该特定功能。也许你可以从这里开始 -

import numpy as np
import pandas as pd
import seaborn as sns
import os
import matplotlib.pyplot as plt
import time
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.callbacks import Callback

# fix random seed for reproducibility
seed = 155
np.random.seed(seed)

# load pima indians dataset

# download directly from website
dataset = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data", 
                      header=None).values
X_train, X_test, Y_train, Y_test = train_test_split(dataset[:,0:8], dataset[:,8], test_size=0.25, random_state=87)
class NBatchLogger(Callback):
    def __init__(self,display=100):
        '''
        display: Number of batches to wait before outputting loss
        '''
        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:
            print('\n{0}/{1} - Batch Loss: {2}'.format(self.seen,self.params['samples'],
                                                logs.get('loss')))


out_batch = NBatchLogger(display=1000)
np.random.seed(seed)
my_first_nn = Sequential() # create model
my_first_nn.add(Dense(5, input_dim=8, activation='relu')) # hidden layer
my_first_nn.add(Dense(1, activation='sigmoid')) # output layer
my_first_nn.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

my_first_nn_fitted = my_first_nn.fit(X_train, Y_train, epochs=1000, verbose=0, batch_size=128,
                                     callbacks=[out_batch], initial_epoch=0)

如果您想要这样的话,请告诉我。

答案 3 :(得分:0)

一种解决方案是计算列车期望值和列车输入值之间的损失函数。在loss = mean_squared_error和三维输出的情况下(即图像宽度x高度x通道):

model.fit(train_in,train_out,...)

pred = model.predict(train_in)
loss = np.add.reduce(np.square(test_out-pred),axis=(1,2,3)) # this computes the total squared error for each sample
loss = loss / ( pred.shape[1]*pred.shape[2]*pred.shape[3]) # this computes the mean over the sample entry 

np.savetxt("loss.txt",loss) # This line saves the data to file