10
votes

Sortie de plusieurs pertes ajoutées par add_loss dans Keras

J'ai étudié l'exemple Keras pour la couche de perte personnalisée démontrée par un Variational Autoencoder (VAE) . Ils n'ont qu'une seule couche de perte dans l'exemple alors que l'objectif de la VAE se compose de deux parties différentes: Reconstruction et KL-Divergence. Cependant, j'aimerais tracer / visualiser comment ces deux parties évoluent pendant l'entraînement et diviser la perte personnalisée unique en deux couches de perte:

Exemple de modèle Keras:

entrez la description de l'image ici

Mon modele:

entrez la description de l'image ici

Malheureusement, Keras ne génère qu'une seule valeur de perte dans le pour mon exemple multi-pertes, comme on peut le voir dans mon exemple Jupyter Notebook où j'ai implémenté les deux approches. Est-ce que quelqu'un sait comment obtenir les valeurs par perte qui ont été ajoutées par add_loss ? Et de plus, comment Keras calcule-t-il la valeur de perte unique, compte tenu de plusieurs appels add_loss (Mean / Sum / ...?)?


0 commentaires

3 Réponses :


1
votes

Il s'avère que la réponse n'est pas simple et de plus, Keras ne prend pas en charge cette fonctionnalité prête à l'emploi. Cependant, j'ai implémenté une solution où chaque couche de perte génère la perte et une fonction de rappel personnalisée l'enregistre après chaque époque. La solution pour mon exemple à plusieurs têtes peut être trouvée ici: https://gist.github.com/tik0/7c03ad11580ae0d69c326ac70b88f395


0 commentaires

6
votes

Ceci n'est en effet pas pris en charge, et actuellement discuté à différents endroits sur le Web. La solution peut être obtenue en ajoutant à nouveau vos pertes sous forme de métrique distincte après l'étape de compilation (également discutée ici )

Il en résulte quelque chose comme ceci (spécifiquement pour une VAE):

Epoch 1/1
252/252 [==============================] - 23s 92ms/step - loss: 0.4336 - kl_loss: 0.0823 - mse_loss: 0.3513 - val_loss: 0.2624 - val_kl_loss: 0.0436 - val_mse_loss: 0.2188

Pour moi, cela donne une sortie comme celle-ci:

reconstruction_loss = mse(K.flatten(inputs), K.flatten(outputs))
kl_loss = beta*K.mean(- 0.5 * 1/latent_dim * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1))

model.add_loss(reconstruction_loss)
model.add_loss(kl_loss)
model.compile(optimizer='adam')

model.metrics_tensors.append(kl_loss)
model.metrics_names.append("kl_loss")

model.metrics_tensors.append(reconstruction_loss)
model.metrics_names.append("mse_loss")


0 commentaires

6
votes

J'utilise la version 2.2.4-tf de Keras et la solution ci-dessus n'a pas fonctionné pour moi. Voici la solution que j'ai trouvée (pour continuer l' exemple de dumkar ):

reconstruction_loss = mse(K.flatten(inputs), K.flatten(outputs))
kl_loss = beta*K.mean(- 0.5 * 1/latent_dim * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1))

model.add_loss(reconstruction_loss)
model.add_loss(kl_loss)

model.add_metric(kl_loss, name='kl_loss', aggregation='mean')
model.add_metric(reconstruction_loss, name='mse_loss', aggregation='mean')

model.compile(optimizer='adam')

J'espère que cela vous aidera.


4 commentaires

Merci pour l'extension! C'est en fait la seule solution réalisable dans tf-keras (aka tensorflow 2.0).


J'ai implémenté, juste à titre de référence, votre solution proposée pour l'exemple VAE Keras standard ici: gist.github.com/tik0/6aa42cabb9cf9e21567c3deb309107b7


@ValentinVIGNAL Merci pour la réponse. pouvez-vous s'il vous plaît me dire (curieux et voulez savoir) comment vous avez compris / pensé de passer l'argument aggregation = 'mean' à add_metric. Je ne vois aucun exemple qui utilise autre que la fonction, nom des arguments. Il y a des ** kwargs mais je ne sais pas à quoi ils font référence.


En utilisant une version plus récente de TF (2.2.0), vous devez déplacer l'appel model.compile après les appels model.add_metric , sinon vous obtenez une TypeError: unhashable type: 'DictWrapper' (j'ai proposé ceci comme modification à ce post).