TensorFlow を使用してバイナリ クロス エントロピー損失値を求める

Hafiz Muhammad Zohaib 2023年6月21日
TensorFlow を使用してバイナリ クロス エントロピー損失値を求める

この短い記事では、バイナリ クロス エントロピーを計算する 2つの方法 (つまり、TensorFlow フレームワークの組み込み関数と生の Python での式のカスタム実装) について説明します。 さらに、どちらの方法でも同じ結果が得られることが証明されています。

クロスエントロピー損失を計算する前に、まずバイナリクロスエントロピー損失とそれが推定される理由を理解する必要があります。 次に、生の Python を使用して、TensorFlow フレームワークに従ってその式を実装します。

TensorFlow を使用してバイナリ クロス エントロピー損失値を求める

loss 関数は、機械学習でモデルのパフォーマンスを測定するために使用されます。 損失 が高い場合、モデルのパフォーマンスは低下しています。

反対に、低い場合、モデルは適切に機能し、グラウンド トゥルースに近い結果を生成します。

クロス エントロピーは、損失 (対数損失とも呼ばれます) の尺度でもあります。 一般に、バイナリ分類問題での損失を計算するために使用されます。

Binary Cross Entropy は、修正された予測確率の対数の負の平均です。

次の式を使用してバイナリ クロス エントロピーを計算します。

$$
\text { 対数損失 }=\frac{1}{N} \sum_{i=1}^{N}-\left(y_{i} * \log \left(p_{i}\right)+\left (1-y_{i}\right) * \log \left(1-p_{i}\right)\right)
$$

上記の式を Python で実装してみましょう。

import numpy as np


def BinaryCrossEntropy(y_true, y_pred):
    y_pred = np.clip(y_pred, 1e-7, 1 - 1e-7)
    term_0 = y_true * np.log(y_pred + 1e-7)
    term_1 = (1 - y_true) * np.log(1 - y_pred + 1e-7)
    return -np.mean(term_0 + term_1, axis=0)


print(
    BinaryCrossEntropy(
        np.array([1, 0, 1]).reshape(-1, 1), np.array([0, 0, 1]).reshape(-1, 1)
    )
)

上記のコードを 1 行ずつ理解していきましょう。 y_truey_pred の 2つの引数を取る関数 BinaryCrossEntropy を定義しました。

これらの引数は、バイナリ分類の 1D 配列です。 y_true は実際の値で、y_pred は ML モデルの予測値です。

np.clip(array, min_val, max_val) 呼び出しは、入力配列をクリップするだけです。 たとえば、[0,0,1][1e^-7, 1e^-7, 0.9999999] にクリップされます。

np.mean() は、入力配列をバッチ サイズ N で割って、入力配列の 平均 を見つけます。

クリッピングに 1*e^-7 のような最小値を使用するのはなぜですか?

上記の式には、いくつかの対数項が含まれています。 log(0) (つまり、ゼロの自然対数) は未定義 (無限大) を生成するためです。

無限大を N (つまり、予測値/真の値のバッチサイズ) で割ると、エラーが発生します。 したがって、クリッピングには最小値 1*e^-7 を使用しました。

上記のコードは、次の出力を提供します。

[5.14164949]

ここで、TensorFlow を使用してバイナリ クロス エントロピー損失値を見つけます。 以下のコードを見てみましょう。

import tensorflow as tf
import numpy as np

y_true = np.array([1.0, 1.0, 1.0]).reshape(-1, 1)
y_pred = np.array([1.0, 1.0, 0.0]).reshape(-1, 1)

bce = tf.keras.losses.BinaryCrossentropy(
    from_logits=False, reduction=tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE
)
loss = bce(y_true, y_pred)

print(loss.numpy())

組み込み関数 tf.keras.losses.BinaryCrossentropy( from_logits=False , reduction=tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE) は、真のラベルと予測されたラベルの間の交差エントロピー損失を計算します。

上記のコードでは、bce( y_true, y_pred) は 2つの引数を取ります。

  1. y_true (真のラベル): これは 0 または 1 です。
  2. y_pred (予測値): これはモデルの予測です。つまり、logit を表す単一の浮動小数点値です (つまり、from_logits の場合の [-inf, inf] の値)。 =True) または確率 (つまり、from_logits=False の場合は [0., 1.] の値)。

Binary Cross-Entropy の詳細については こちら を参照してください。

上記のコードは、次のバイナリ クロス エントロピー値を示します。

5.1416497230529785

これは、TensorFlow を使用したバイナリ クロス エントロピー損失値と数式からのバイナリ クロス エントロピー損失値が等しいという結果から明らかです。