web-dev-qa-db-ja.com

Keras:重み付きバイナリクロスエントロピー

Kerasで重み付きバイナリクロスエントロピーを実装しようとしましたが、コードが正しいかどうかわかりません。トレーニングの出力は少しわかりにくいようです。数エポック後に、精度は〜0.15になります。それはあまりにも少ないと思います(ランダムな推測であっても)。

一般に、出力には約11%のゼロがあり、89%のゼロがあるため、重みはw_zero = 0.89およびw_one = 0.11です。

私のコード:

def create_weighted_binary_crossentropy(zero_weight, one_weight):

    def weighted_binary_crossentropy(y_true, y_pred):

        # Original binary crossentropy (see losses.py):
        # K.mean(K.binary_crossentropy(y_true, y_pred), axis=-1)

        # Calculate the binary crossentropy
        b_ce = K.binary_crossentropy(y_true, y_pred)

        # Apply the weights
        weight_vector = y_true * one_weight + (1. - y_true) * zero_weight
        weighted_b_ce = weight_vector * b_ce

        # Return the mean error
        return K.mean(weighted_b_ce)

    return weighted_binary_crossentropy

誰かが間違っているのを見ているかもしれませんか?

ありがとうございました

15
Kevin Meier

通常、マイノリティクラスのクラスウェイトは高くなります。 one_weight=0.89, zero_weight=0.11を使用する方が良いでしょう(ただし、コメントで提案されているように、class_weight={0: 0.11, 1: 0.89}を使用できます)。

クラスの不均衡の下で、モデルは1よりも多くのゼロを見ています。また、そうすることでトレーニング損失を最小限に抑えることができるため、1よりも多くのゼロを予測することも学習します。これが、比率0.11に近い精度を示している理由でもあります。モデル予測の平均を取る場合、ゼロに非常に近いはずです。

クラスの重みを使用する目的は、損失関数を変更して、トレーニングの損失を「簡単な解決策」(つまり、ゼロを予測すること)で最小化できないようにすることです。

最適な重みは必ずしも0.89と0.11ではないことに注意してください。場合によっては、対数や平方根(またはone_weight > zero_weightを満たす重み)を使用して機能させる必要があります。

6
Yu-Yang

sklearnモジュール を使用して、次のように各クラスの重みを自動的に計算できます。

_# Import
import numpy as np
from sklearn.utils import class_weight

# Example model
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(1, activation='sigmoid'))

# Use binary crossentropy loss
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# Calculate the weights for each class so that we can balance the data
weights = class_weight.compute_class_weight('balanced',
                                            np.unique(y_train),
                                            y_train)

# Add the class weights to the training                                         
model.fit(x_train, y_train, epochs=10, batch_size=32, class_weight=weights)
_

class_weight.compute_class_weight()の出力は、_[2.57569845 0.68250928]_のようなnumpy配列であることに注意してください。

9
tsveti_iko

Model.fitでクラスの重みを使用するのは正しくないと思います。 {0:0.11、1:0.89}、0はインデックスであり、0クラスではありません。 Kerasドキュメント: https://keras.io/models/sequential/ class_weight:クラスインデックス(整数)を重み(浮動)値にマッピングするオプションの辞書、損失関数の重み付けに使用(トレーニング中のみ) )。これは、不十分な表現のクラスのサンプルに「もっと注意を払う」ようにモデルに伝えるのに役立ちます。

1
Cheng Yang