簡體   English   中英

獲取每個訓練實例的損失值 - Keras

[英]Get loss values for each training instance - Keras

我想獲得每個實例的損失值作為模型訓練。

history = model.fit(..)

例如上面的代碼返回每個時期的損失值,而不是小批量或實例。

這樣做的最佳方法是什么? 有什么建議嗎?

在此官方 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]
'''

如果您想獲得每個批次的損失值,您可能需要在生成器中使用 call 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)
]

在結合了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)

如果你想要這樣的東西,請告訴我。

一種解決方案是計算訓練期望值和訓練輸入預測值之間的損失函數。 在 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM