1. ホーム
  2. python

[解決済み] TensorFlowでクロスエントロピーの損失を選択するには?

2023-01-28 08:32:51

質問

ロジスティック回帰や多項ロジスティック回帰のような分類問題を を最適化する問題です。 クロスエントロピー 損失を最適化する。 通常、クロスエントロピーの層は ソフトマックス 層に従う。 確率分布を生成する。

テンソルフローでは、少なくとも クロスエントロピーの損失関数があります。 :

  • tf.losses.softmax_cross_entropy
  • tf.losses.sparse_softmax_cross_entropy
  • tf.losses.sigmoid_cross_entropy
  • tf.contrib.losses.softmax_cross_entropy
  • tf.contrib.losses.sigmoid_cross_entropy
  • tf.nn.softmax_cross_entropy_with_logits
  • tf.nn.sigmoid_cross_entropy_with_logits
  • ...

どれが二値分類にのみ有効で、どれが多値問題に向いているのでしょうか?どのような場合に sigmoid の代わりに softmax ? どのように sparse 関数は他の関数とどのように違うのでしょうか、そしてなぜ softmax ?

関連する(より数学的な)議論。 KerasとTensorFlowのクロスエントロピーの損失はどれも違うのか? .

どのように解決するのか?

予備知識

  • 機能的な意味では シグモイドはソフトマックス関数の一部であり の部分的なケースであり、クラスの数が2に等しいときです。両者とも同じ操作を行います:logits(下記参照)を確率に変換します。

    単純な2値分類では、この2つの間に大きな違いはありません。 しかし、多項分類の場合、シグモイドは非排他的なラベル(例えば、「levels」)を扱うことができます。 非排他的なラベル(例えば マルチラベル を扱うことができますが,ソフトマックス は排他的なクラスを扱います(下記参照)。

  • A ロジット (スコアとも呼ばれる)は クラスに関連付けられたスケールされていない生の値 であり、確率を計算する前のものです。ニューラルネットワークのアーキテクチャの観点から、これはロジットが密な(完全に接続された)層の出力であることを意味します。

    Tensorflowのネーミングは少し変です。 以下のすべての関数は、確率ではなくlogitを受け取ります。 で、自分自身で変換を適用します(これは単純により効率的です)。

シグモイド関数ファミリー

先に述べたように sigmoid の損失関数は二値分類のためのものである。 しかし、tensorflowの関数はより一般的であり、クラスが独立である場合、複数ラベルの分類を行うことができる。 クラスが独立している場合、マルチラベル分類を行うことができる。 つまり tf.nn.sigmoid_cross_entropy_with_logitsN の2つの分類を一度に解決します。

ラベルは一発符号化されているか、ソフトクラス確率を含むことができる必要があります。

tf.losses.sigmoid_cross_entropy は、さらに バッチ内ウェイト , すなわち、ある例を他の例より重要視することができます。 tf.nn.weighted_cross_entropy_with_logits を設定することができます。 クラスの重み (分類はバイナリであることを思い出してください)、つまり、正の誤差を負の誤差より大きくすることができます。 正の誤差を負の誤差より大きくすることです。これは、学習データがアンバランスな場合に有効です。

ソフトマックス関数ファミリー

これらの損失関数は、多項式相互排他的分類のために使用されるべきです。 のうち1つを選択します。 N クラスから1つを選ぶような場合です。また、以下のような場合にも適用できます。 N = 2 .

ラベルはワンショットでエンコードされていなければなりませんし、ソフトクラスの確率を含むことができます。 ある特定の例が50%の確率でクラスAに属し、50%の確率でクラスBに属することができる。 に50%の確率で属することができます。厳密に言えば、それは両方のクラスに属することを意味しないことに注意してください。 を意味するものではありませんが、確率をこのように解釈することができます。

のように sigmoid のファミリーになります。 tf.losses.softmax_cross_entropy では を設定することで バッチ内重み付け を設定することができる。つまり、いくつかの例を他の例よりも重要視することができる。 私の知る限り、tensorflow 1.3の時点では、ビルトインで クラス重み付け .

[UPD] tensorflow 1.5では v2 バージョン が紹介されました。 と、オリジナルの softmax_cross_entropy_with_logits の損失は非推奨となりました。両者の唯一の違いは、新しいバージョンでは、バックプロパゲーションがロジットとラベルの両方に対して起こることです ( ここで議論されている なぜこれが有用なのか)。

疎関数族

通常の softmax と同様に,これらの損失関数は 多項相互排他的分類,すなわち N クラスから1つを選ぶということです。 違いはラベルのエンコーディングにあります: クラスは整数(クラスインデックス)で指定されます。 であり,1ホットのベクトルではありません.明らかに、これはソフトクラスを許しません。 何千、何百万ものクラスがある場合、メモリを節約することができます。 しかし、以下の点に注意してください。 logits 引数はまだ各クラスごとにロジットを含まなければならないことに注意してください。 したがって、少なくとも [batch_size, classes] メモリを消費します。

上のように tf.losses バージョンでは weights 引数があり で、バッチ内重みを設定することができます。

サンプルソフトマックス関数族

これらの関数は、膨大な数のクラスを扱うための別の選択肢を提供します。 正確な確率分布を計算し比較する代わりに、ランダムなサンプルから を計算します。

引数 weightsbiases は、選択されたサンプルのロジットを計算するために使用される別の完全連結レイヤーを指定します。 は、選択されたサンプルのロジットを計算するために使用されます。

上記のように labels は一発符号化されておらず、以下のような形をしています。 [batch_size, num_true] .

サンプリングされた関数は、トレーニングにのみ適しています。テスト時には を使うことが推奨されます。 softmax 損失(スパースまたはワンショット)を使用して、実際の分布を得ることをお勧めします。

もう一つの代替損失は tf.nn.nce_loss で、これは ノイズコントラスト推定 (興味のある方は、こちらの をご覧ください。 ). NCE は極限で softmax に近似することを保証しているので、私はこの関数を softmax ファミリーに含めました。