I need to create a custom callback to get the target values i.e, y_true and y_pred (predicted values). So, I read the post :Create keras callback to save model predictions and targets for each batch during training
And created my callback the same as they created in the answer
from keras.callbacks import Callback
from keras import backend as K
import tensorflow as tf
class CollectOutputAndTarget(Callback):
def __init__(self):
super(CollectOutputAndTarget, self).__init__()
self.targets = [] # collect y_true batches
self.outputs = [] # collect y_pred batches
# the shape of these 2 variables will change according to batch shape
# to handle the "last batch", specify `validate_shape=False`
self.var_y_true = tf.Variable(0., validate_shape=False)
self.var_y_pred = tf.Variable(0., validate_shape=False)
def on_batch_end(self, batch, logs=None):
# evaluate the variables and save them into lists
self.targets.append(K.eval(self.var_y_true))
self.outputs.append(K.eval(self.var_y_pred))
# build a simple model
# have to compile first for model.targets and model.outputs to be prepared
model = Sequential([Dense(5, input_shape=(10,))])
model.compile(loss='mse', optimizer='adam')
# initialize the variables and the `tf.assign` ops
cbk = CollectOutputAndTarget()
fetches = [tf.assign(cbk.var_y_true, model.targets[0], validate_shape=False),
tf.assign(cbk.var_y_pred, model.outputs[0], validate_shape=False)]
model._function_kwargs = {'fetches': fetches} # use `model._function_kwargs` if using `Model` instead of `Sequential`
When I add on_epoch_end
and try to print the value of self.targets
.
I get arrays of 0s.
For on_epoch_end
the code is as below:
def on_epoch_end(self, epoch, logs={}):
print(self.targets)
My model is created using the functional API Model
and has pretrained weights loaded into it, instead of Sequential. And after the compiling the model as model.compile
, I instantiate the callback
and create the fetches
object and add it to train_function
as follows:
cbk = CollectOutputAndTarget()
fetches = [tf.assign(cbk.var_y_true, model.targets[0], validate_shape=False),
tf.assign(cbk.var_y_pred, model.outputs[0], validate_shape=False)]
model._function_kwargs = {'fetches': fetches}
And, then I call model.fit_generator
using my datagenerator. I am getting 0s
in self.targets
, which shouldn't happen, if var_y_true
and var_y_pred
are getting updated with model.targets
and model.outputs
. Also, I don't understand that if we're already assigning the values for cbk.var_y_true
and cbk.var_y_pred
, then why do we need to use model._function_kwargs
?
I tried using model.train_function = None
after setting the fetches
and before calling fit_generator
, but still I get the same result.