web-dev-qa-db-ja.com

Kerasを使用して予測の不確実性を計算する方法は?

NNモデルの確実性/信頼度を計算したい( 私の深いモデルが知らないこと を参照)-NNが「8」を表す画像を私に伝えるとき、それがどれだけ確実かを知りたい。私のモデルは99%が「8」であるか、51%が「8」であると確信していますが、「6」である可能性もあります。一部の数字は非常に曖昧であり、どの画像に対してモデルが「コインを反転」しているのかを知りたいと思います。

私はこれについていくつかの理論的な文章を見つけましたが、これをコードに入れるのに苦労しています。正しく理解できたら、テスト画像を複数回評価して、異なるニューロンを(ドロップアウトを使用して)「殺し」、その後...?

MNISTデータセットに取り組んで、私は次のモデルを実行しています:

from keras.models import Sequential
from keras.layers import Dense, Activation, Conv2D, Flatten, Dropout

model = Sequential()
model.add(Conv2D(128, kernel_size=(7, 7),
                 activation='relu',
                 input_shape=(28, 28, 1,)))
model.add(Dropout(0.20))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Dropout(0.20))
model.add(Flatten())
model.add(Dense(units=64, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(units=10, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',
              optimizer='sgd',
              metrics=['accuracy'])
model.fit(train_data, train_labels,  batch_size=100, epochs=30, validation_data=(test_data, test_labels,))

質問:このモデルでどのように予測すれば、予測についての確実性も得られますか?いくつかの実用的な例をいただければ幸いです(できればKerasですが、他の方法でも可能です)。

[〜#〜] edit [〜#〜]:明確にするために、Yurin Galによって概説された方法を使用して確実性を得る方法を探しています(または他の方法がより良い結果をもたらす理由の説明)。

33
johndodo

dropout不確実性を測定するアプローチを実装する場合は、次を実行する必要があります。

  1. テスト時間にもdropoutを適用する関数を実装します。

    import keras.backend as K
    f = K.function([model.layers[0].input, K.learning_phase()],
                   [model.layers[-1].output])
    
  2. この関数を不確実性予測子として使用します。次の方法で:

    def predict_with_uncertainty(f, x, n_iter=10):
        result = numpy.zeros((n_iter,) + x.shape)
    
        for iter in range(n_iter):
            result[iter] = f(x, 1)
    
        prediction = result.mean(axis=0)
        uncertainty = result.var(axis=0)
        return prediction, uncertainty
    

もちろん、さまざまな関数を使用して不確実性を計算できます。

23
Marcin Możejko

モデルはソフトマックスアクティベーションを使用しているため、何らかの不確実性の尺度を取得する最も簡単な方法は、出力ソフトマックスの確率を調べることです。

probs = model.predict(some input data)[0]

probs配列は、合計が1.0になる[0、1]範囲の数値の10要素ベクトルになるため、確率として解釈できます。たとえば、数字7の確率はちょうどprobs[7]

次に、この情報を使用して後処理を実行できます。通常、予測されるクラスは最も高い確率を持つクラスですが、2番目に高い確率を持つクラスなどを調べることもできます。

4

上位の回答にいくつかの変更を加えました。今では私のために動作します。

これは、モデルの不確実性を推定する方法です。その他の不確実性の原因については、 https://eng.uber.com/neural-networks-uncertainty-estimation/ が役立つと思いました。

f = K.function([model.layers[0].input, K.learning_phase()],
               [model.layers[-1].output])


def predict_with_uncertainty(f, x, n_iter=10):
    result = []

    for i in range(n_iter):
        result.append(f([x, 1]))

    result = np.array(result)

    prediction = result.mean(axis=0)
    uncertainty = result.var(axis=0)
    return prediction, uncertainty
2
Chexn

より簡単な方法は、推論中に実行するドロップアウトレイヤーにもtraining=Trueを設定することです(基本的に、常にトレーニングモードであるかのように動作するようにレイヤーに指示します。したがって、トレーニングと推論の両方に常に存在します)。

import keras

inputs = keras.Input(shape=(10,))
x = keras.layers.Dense(3)(inputs)
outputs = keras.layers.Dropout(0.5)(x, training=True)

model = keras.Model(inputs, outputs)

上記のコードはこちらから issue です。

2
abagshaw