【发布时间】:2018-01-05 17:05:16
【问题描述】:
我想获得损失值作为每个实例的模型训练。
history = model.fit(..)
例如上面的代码返回每个时期的损失值,而不是小批量或实例。
最好的方法是什么?有什么建议吗?
【问题讨论】:
标签: python python-3.x keras
我想获得损失值作为每个实例的模型训练。
history = model.fit(..)
例如上面的代码返回每个时期的损失值,而不是小批量或实例。
最好的方法是什么?有什么建议吗?
【问题讨论】:
标签: python python-3.x keras
在这个官方 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)
]
【讨论】:
一种解决方案是计算列车期望值与列车输入预测值之间的损失函数。在 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
【讨论】:
结合here 和here 的资源后,我想出了以下代码。也许它会帮助你。这个想法是,您可以覆盖 keras 中的 Callbacks 类,然后使用 on_batch_end 方法检查 keras 将自动提供给该方法的 logs 的损失值。
这是一个内置特定功能的神经网络的工作代码。也许你可以从这里开始 -
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)
如果你想要这样的东西,请告诉我。
【讨论】:
on_batch_end 仅在每个 mini batch 结束时的回波损耗。我想要做的是在每个训练实例之后变得更深并获得损失。有什么建议吗?