![](/img/trans.png)
[英]How to get the loss for each epoch in custom batch training in 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)
]
在結合了here和here的資源后,我想出了以下代碼。 也許它會幫助你。 這個想法是,您可以從 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.