Настройка функции fit() в keras приводит к функции evaluate(), возвращающей пустой список

#class #tensorflow #keras #loss-function #custom-training

#класс #тензорный поток #keras #потеря-функция #пользовательское обучение

Вопрос:

Я обучаю VAE, используя учебное пособие Keras:https://keras.io/examples/generative/vae /. Это включает в себя создание класса VAE и указание пользовательской процедуры обучения, которая подробнее описана здесь:https://keras.io/guides/customizing_what_happens_in_fit /. После создания кодировщика и декодера, как указано в руководстве, и обучения модели я создаю модель VAE с помощью следующего:

 vae = VAE(encoder, decoder) 
vae.compile(optimizer=keras.optimizers.Adam())

vae.fit(x=x_train, y=None, 
        epochs=epochs, 
        batch_size=batch_size, 
        verbose=False,
        validation_data=(x_test, None))
  

Я хочу оценить модель на отдельных наборах данных после обучения (поскольку у меня есть несколько наборов данных для оценки, я не использую его в качестве validation_data). Однако, когда я пытаюсь запустить vae.evaluate(data) , она возвращает пустой список [] .

Примечание: я могу легко получить показатели обучения и проверки через vae.history.history , но проблема заключается в том, когда я пытаюсь оценить после обучения. Но когда я пытаюсь вернуть показатели vae.metrics , она также возвращает пустой список. Как мне заставить model.evaluate работать с пользовательской процедурой обучения, которая возвращает dict показателей потерь? Нужно ли мне определять что-то пользовательское для evaluate?

Вот как определяется класс VAE. Более подробную информацию можно найти в руководстве выше.

 class VAE(keras.Model):
    def __init__(self, encoder, decoder, **kwargs):
        super(VAE, self).__init__(**kwargs)
        self.encoder = encoder
        self.decoder = decoder

    def train_step(self, data):
        if isinstance(data, tuple):
            data = data[0]
        with tf.GradientTape() as tape:
            z_mean, z_log_var, z = encoder(data)
            reconstruction = decoder(z)
            reconstruction_loss = tf.reduce_mean(
                keras.losses.binary_crossentropy(data, reconstruction)
            )
            reconstruction_loss *= 28 * 28
            kl_loss = 1   z_log_var - tf.square(z_mean) - tf.exp(z_log_var)
            kl_loss = tf.reduce_mean(kl_loss)
            kl_loss *= -0.5
            total_loss = reconstruction_loss   kl_loss
        grads = tape.gradient(total_loss, self.trainable_weights)
        self.optimizer.apply_gradients(zip(grads, self.trainable_weights))
        return {
            "loss": total_loss,
            "reconstruction_loss": reconstruction_loss,
            "kl_loss": kl_loss,
        }
  

Комментарии:

1. согласно статье fchollet, которую вы предоставили, вам нужно будет реализовать / переопределить метод test_step . Я пробовал это, но все еще получаю пустой список!

2. evaluate возвращает числа сейчас, как только будут реализованы средства отслеживания потерь и metrics метод переопределен.