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:
Mon modele:
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 / ...?)?
3 Réponses :
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
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")
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.
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).