0

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.

Community
  • 1
  • 1
aspiring1
  • 344
  • 1
  • 13
  • 32
  • Have you found the main reason for this error? – Yasmin Aug 12 '19 at 22:52
  • @Yasmin: yes, I've found the solution, actually I was getting the values for the class ids, seems like yolo has y_true values as class_ids, instead of the box_coordinates. – aspiring1 Aug 20 '19 at 07:16

0 Answers0