web-dev-qa-db-fra.com

Utilisation de la perte Tensorflow Huber dans Keras

J'essaie d'utiliser la perte huber dans un modèle de keras (en écrivant DQN), mais j'obtiens un mauvais résultat, je pense que je fais quelque chose de mal. Mon code est ci-dessous.

model = Sequential()
model.add(Dense(output_dim=64, activation='relu', input_dim=state_dim))
model.add(Dense(output_dim=number_of_actions, activation='linear'))
loss = tf.losses.huber_loss(delta=1.0)
model.compile(loss=loss, opt='sgd')
return model
11
hakaishinbeerus

Je suis venu ici avec exactement la même question. La réponse acceptée utilise logcosh qui peut avoir des propriétés similaires, mais ce n'est pas exactement Huber Loss. Voici comment j'ai implémenté Huber Loss pour Keras (notez que j'utilise Keras de Tensorflow 1.5).

import numpy as np
import tensorflow as tf

'''
 ' Huber loss.
 ' https://jaromiru.com/2017/05/27/on-using-huber-loss-in-deep-q-learning/
 ' https://en.wikipedia.org/wiki/Huber_loss
'''
def huber_loss(y_true, y_pred, clip_delta=1.0):
  error = y_true - y_pred
  cond  = tf.keras.backend.abs(error) < clip_delta

  squared_loss = 0.5 * tf.keras.backend.square(error)
  linear_loss  = clip_delta * (tf.keras.backend.abs(error) - 0.5 * clip_delta)

  return tf.where(cond, squared_loss, linear_loss)

'''
 ' Same as above but returns the mean loss.
'''
def huber_loss_mean(y_true, y_pred, clip_delta=1.0):
  return tf.keras.backend.mean(huber_loss(y_true, y_pred, clip_delta))

Selon que vous souhaitez réduire la perte ou la moyenne de la perte, utilisez la fonction correspondante ci-dessus.

8
avejidah

Vous pouvez envelopper le Tensorflow tf.losses.huber_loss dans une fonction de perte Keras personnalisée, puis transmettez-la à votre modèle.

La raison de l'encapsuleur est que Keras ne passera que y_true, y_pred à la fonction de perte, et vous souhaiterez probablement également utiliser certains des nombreux paramètres pour tf.losses.huber_loss. Vous aurez donc besoin d'une sorte de fermeture comme:

def get_huber_loss_fn(**huber_loss_kwargs):

    def custom_huber_loss(y_true, y_pred):
        return tf.losses.huber_loss(y_true, y_pred, **huber_loss_kwargs)

    return custom_huber_loss

# Later...
model.compile(
    loss=get_huber_loss_fn(delta=0.1)
    ...
)
15
Chris Marciniak

Je regardais les pertes de keras. Apparemment, le bûcheron a les mêmes propriétés que la perte de huber. Plus de détails sur leur similitude peuvent être vus ici .

4
hakaishinbeerus

Que diriez-vous:

    loss=tf.keras.losses.Huber(delta=100.0)
2
Val