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
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.
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)
...
)
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 .
Que diriez-vous:
loss=tf.keras.losses.Huber(delta=100.0)