Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Kerasで自作損失関数を使う

More than 1 year has passed since last update.

Kerasで自作の損失関数を使いたい!!

kerasで自作の損失関数を使う方法をまとめます!

そもそも損失関数とは?

損失関数は予測した値と、正解の値との誤差がどれほどあるかを計算するものです。
kerasでは平均二乗誤差を使っているものをよく見ます。
二乗誤差の式は

L = (t-x)^2

kerasで導入されている損失関数は公式ドキュメントを見てください。

自作関数を作って追加

Huber損失

Huber損失は二乗誤差に比べて異常値に対して強い損失関数です。
式はこちら

L = \left\{
\begin{array}{ll}
\frac{1}{2}(t-x)^2 & ,|t-x| < \delta \\
\delta(|t-x|-\frac{1}{2}\delta) & ,overview
\end{array}
\right.

このときδは閾値を示してます。
二乗誤差は以下のようなグラフになります。
image.png
誤差が小さいほど損失が小さくなります。
逆に誤差が大きいほど損失が大きくなります。
Huber関数は次のようなグラフになります。
image.png
これは指定した閾値以下ならば2次関数を使ってそれ以外なら線形関数を使うものです。
2乗誤差に比べ大きな誤差(異常値)が出たとき損失を小さく算出するので、異常値が出た場合に強いです。

Huber_loss.py
import numpy as np
import tensorflow as tf

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)

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))

#使い方はモデルのコンパイル時に次のように指定してください。
model.compile(loss=huber_loss_mean)

許容損失

許容損失はある程度の誤差を許容するものです。
式はこちら

L = \left\{
\begin{array}{ll}
0 & ,|t-x| < \delta \\
(t-x)^2 & ,overview
\end{array}
\right.

グラフはこちら
image.png
コードはこちら

allowable_loss.py
import numpy as np
import tensorflow as tf
def allowable_loss(y_true, y_pred,clip_delta=1.0):
  error = y_true - y_pred
  cond  = K.abs(error) < clip_delta

  squared_loss = K.square(error)

  return tf.where(cond, 0, squared_loss)
def allowable_loss_mean(y_true, y_pred, clip_delta=0.01):
    if not K.is_tensor(y_pred):
      y_pred = K.constant(y_pred)
    y_true = K.cast(y_true, y_pred.dtype)
    return K.mean(K.square(y_pred - y_true), axis=-1)

以上です。

参考にさせていただいた記事・ブログ

python – KerasでTensorflow Huber lossを使う - コードログ様
機械学習で抑えておくべき損失関数(回帰編) ― HELLO CYBERNETICS様

harachan
エンジニアです。 アルバイトでwebサービスの開発保守をサーバーサイド・フロントサイド両方やってました。 Vue/python/php/c/html+css/js
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away