Использование потери Tensorflow Huber в Keras
Я пытаюсь использовать huber loss в keras-модели (написав DQN), но я получаю плохой результат, я думаю, что я что-то не так. Мой код ниже.
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
Ответы
Ответ 1
Я пришел сюда с тем же вопросом. В принятом ответе используется logcosh
который может иметь схожие свойства, но это не совсем Huber Loss. Вот как я реализовал Huber Loss для Keras (обратите внимание, что я использую Keras от 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))
В зависимости от того, хотите ли вы уменьшить потерю или среднее значение потери, используйте соответствующую функцию выше.
Ответ 2
Вы можете обернуть Tensorflow tf.losses.huber_loss
в пользовательскую функцию потери Keras и затем передать ее своей модели.
Причина обертки в том, что Keras будет передавать только y_true, y_pred
в функцию потерь, и вы, вероятно, захотите также использовать некоторые из многих параметров для tf.losses.huber_loss
. Итак, вам понадобится какое-то закрытие вроде:
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)
...
)
Ответ 3
Я искал потери кераса. По-видимому, logcosh обладает теми же свойствами, что и потеря хубера. Более подробную информацию об их сходстве можно увидеть здесь.
Ответ 4
Как насчет:
loss=tf.keras.losses.Huber(delta=100.0)