我想评估训练后每个样本的模型损失函数。每次调用损失都会导致每个批次只有一个值,因此我会在预测值上手动调用损失函数。
这需要张量评估,因为损失会返回张量。评估此张量很容易,但是尽管操作简单,但调用却要花很长时间。
我已经尝试过来自keras会话的session.run以及keras.backend.eval,它们都有相同的问题。我也尝试过升级keras,但是已经在2.2.4中了
import keras
indim = 28
model = Sequential([Dense(8,input_shape=(indim,),activation='tanh'),Dense(4,activation='tanh'),Dense(1,activation='linear')])
model.compile(optimizer='adam',loss='mae')
def foo():
for i in range(0,500):
input = np.random.rand(32,28)
Y = np.random.rand(32,1)
Ypred = model.predict(input)
loss = model.loss_functions[0](Y,Ypred)
loss = keras.backend.eval(loss)
%prun foo()
我希望上面的示例能在不到一秒钟的时间内完成。第一次需要20秒,第二次需要40秒,探查器返回:
500 27.580 0.055 27.580 0.055 {built-in method _pywrap_tensorflow_internal.ExtendSession}
500 18.866 0.038 18.866 0.038 {built-in method _pywrap_tensorflow_internal.TF_SessionRun_wrapper}
16500 0.124 0.000 0.129 0.000 pywrap_tensorflow_internal.py:39(_swig_setattr_nondynamic)
后续通话花费的时间越来越长(20、40、80秒!)
答案 0 :(得分:0)
解决方案最终是使用K.placeholder。否则,每次调用模型损失函数时,全局图都会增长。
import time
import numpy as np
import keras.backend as K
from keras.layers import Dense
from keras.models import Sequential
indim = 28
model = Sequential([Dense(8, input_shape=(indim,), activation='tanh'), Dense(4, activation='tanh'),
Dense(1, activation='linear')])
model.compile(optimizer='adam', loss='mae')
y_pred = K.placeholder([None, 1])
y_true = K.placeholder([None, 1])
loss_fn = model.loss_functions[0](y_true, y_pred)
for i in range(0, 500):
s = time.time()
input = np.random.rand(32, 28)
Y = np.random.rand(32, 1)
Ypred = model.predict(input)
_ = K.get_session().run(loss_fn, feed_dict={y_true: Y, y_pred: Ypred})
print("Took", time.time() - s)