Résolvez le problème selon lequel lors de l'utilisation de l'API de fonction de perte fournie par keras, le gradient ne peut pas être rétropropagé et la fonction de perte ne diminue pas.

Lors de l'utilisation de l'API de fonction de perte fournie par keras, le gradient ne peut pas être rétropropagé et la fonction de perte ne diminue pas.

question:

Lors de l'utilisation de l'API de fonction de perte fournie par keras, le dégradé ne peut pas être rétropropagé

Code:

from tensorflow.keras.losses import categorical_crossentropy

def train_generator(x, y, z, eps, dcgan, siamese_model, loss=None):

    with tf.GradientTape(persistent=True) as t:
        fake_x = dcgan.generator([z, y])
        loss_G = -tf.reduce_mean(dcgan.discriminator(fake_x)) 
        preds = aux_model(fake_x)
        aux_mean = categorical_crossentropy(y, preds)
        aux_loss = tf.reduce_mean(aux_mean)
        total_loss  = aux_loss + loss_G
        gradient_g = t.gradient(total_loss, dcgan.generator.trainable_variables)

    dcgan.optimizer_G.apply_gradients(zip(gradient_g, dcgan.generator.trainable_variables))

Devinez la raison :

L'interface Keras prétraite parfois d'abord les données, puis appelle le backend de Tensorflow. Cela entraînera la déconnexion de la chaîne de gradient de fonction et la descente de gradient ne pourra pas être effectuée via la dérivation de chaîne.

Découvrez comment le code source de Keras définit categorical_crossentropy :

root@Ie1c58c4ee0020126c:~# find / -iname keras
/usr/local/lib/python3.7/dist-packages/keras
/usr/local/lib/python3.7/dist-packages/tensorflow_core/contrib/keras
/usr/local/lib/python3.7/dist-packages/tensorflow_core/contrib/keras/api/keras
/usr/local/lib/python3.7/dist-packages/tensorflow_core/python/keras
/usr/local/lib/python3.7/dist-packages/tensorflow_core/python/keras/api/_v1/keras
/usr/local/lib/python3.7/dist-packages/tensorflow_core/python/keras/api/_v2/keras
/usr/local/lib/python3.7/dist-packages/tensorflow_core/python/keras/api/keras

vim /usr/local/lib/python3.7/dist-packages/tensorflow_core/python/keras/losses.py

pertes.py

def categorical_crossentropy(y_true,
                             y_pred,
                             from_logits=False,
                             label_smoothing=0):
  """Computes the categorical crossentropy loss.

  Args:
    y_true: tensor of true targets.
    y_pred: tensor of predicted targets.
    from_logits: Whether `y_pred` is expected to be a logits tensor. By default,
      we assume that `y_pred` encodes a probability distribution.
    label_smoothing: Float in [0, 1]. If > `0` then smooth the labels.

  Returns:
    Categorical crossentropy loss value.
  """
  y_pred = ops.convert_to_tensor(y_pred)
  y_true = math_ops.cast(y_true, y_pred.dtype)
  label_smoothing = ops.convert_to_tensor(label_smoothing, dtype=K.floatx())
  def _smooth_labels():
    num_classes = math_ops.cast(array_ops.shape(y_true)[1], y_pred.dtype)
    return y_true * (1.0 - label_smoothing) + (label_smoothing / num_classes)

  y_true = smart_cond.smart_cond(label_smoothing,
                                 _smooth_labels, lambda: y_true)
  return K.categorical_crossentropy(y_true, y_pred, from_logits=from_logits)

On peut voir qu'un prétraitement a été effectué sur les données dans l'interface keras, puis l'interface categorical_crossentropy du backend tensorflow (K) a été appelée, ce qui a provoqué la rupture de la chaîne de gradient et le gradient n'a pas pu être mis à jour via la dérivation de chaîne et la rétropropagation.

Solution:

Implémentez vous-même la fonction de perte ou recherchez le code source dans le fichier loss.py de keras et appelez directement l'interface fournie par le backend tensorflow en tant que fonction de perte.

J'ai finalement changé le code en :

from tensorflow.keras import backend as K

def train_generator(x, y, z, eps, dcgan, siamese_model, loss=None):

    with tf.GradientTape(persistent=True) as t:
        fake_x = dcgan.generator([z, y])
        loss_G = -tf.reduce_mean(dcgan.discriminator(fake_x)) 
        preds = aux_model(fake_x)
        aux_mean = K.categorical_crossentropy(y, preds)
        aux_loss = tf.reduce_mean(aux_mean)
        total_loss  = aux_loss + loss_G
        gradient_g = t.gradient(total_loss, dcgan.generator.trainable_variables)

    dcgan.optimizer_G.apply_gradients(zip(gradient_g, dcgan.generator.trainable_variables))

Le problème est parfaitement résolu. Si vous rencontrez le même problème, vous pouvez vous y référer.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43669978/article/details/127235996
conseillé
Classement