web-dev-qa-db-ja.com

セマンティックセグメンテーションケラスのクロスエントロピー損失

これはばかげた質問だと確信していますが、他の場所では見つけられないので、ここで質問します。

7つのラベルを持つケラスでcnn(unet)を使用してセマンティックイメージセグメンテーションを行っています。したがって、各画像の私のラベルは、theanoバックエンドを使用した(7、n_rows、n_cols)です。したがって、各ピクセルの7つのレイヤー全体で、ワンホットエンコードされます。この場合、カテゴリカルクロスエントロピーを使用するための正しい誤差関数はありますか?それは私にはそのように思えますが、ネットワークはバイナリのクロスエントロピー損失でよりよく学習するようです。なぜそうなるのか、そして原則的な目的は何かについて誰かが光を当てることはできますか?

15
TSW

バイナリクロスエントロピー損失は、最後のレイヤーのsigmodアクティベーションで使用する必要があり、反対の予測に深刻なペナルティを課します。出力がワンホットコードであり、予測の合計が1であることは考慮されていません。ただし、予測の誤りがモデルに深刻なペナルティを課しているため、モデルは適切に分類することをやや学習しています。

ここで、ワンホットコードの事前適用を強制するには、カテゴリカルクロスエントロピーでsoftmaxアクティベーションを使用します。これを使用する必要があります。

現在、問題はsoftmaxを使用しています。Kerasは各ピクセルでsoftmaxをサポートしていないためです。

それを実行する最も簡単な方法は、Permuteレイヤーを使用して(n_rows、n_cols、7)に次元を並べ替え、次にReshapeレイヤーを使用して(n_rows * n_cols、7)に再形成することです。次に、softmaxアクティベーションレイヤーを追加して、クロスエントロピー損失を使用できます。データもそれに応じて再形成する必要があります。

そうするもう1つの方法は、depth-softmaxを実装することです。

def depth_softmax(matrix):
    sigmoid = lambda x: 1 / (1 + K.exp(-x))
    sigmoided_matrix = sigmoid(matrix)
    softmax_matrix = sigmoided_matrix / K.sum(sigmoided_matrix, axis=0)
    return softmax_matrix

ラムダレイヤーとして使用します。

model.add(Deconvolution2D(7, 1, 1, border_mode='same', output_shape=(7,n_rows,n_cols)))
model.add(Permute(2,3,1))
model.add(BatchNormalization())
model.add(Lambda(depth_softmax))

tfimage_dim_orderingが使用されている場合は、Permuteレイヤーを使用できます。

詳細については、 ここ を確認してください。

15
indraforyou

私は@indraforyouの解決策をテストし、提案された方法にはいくつかの間違いがあると思います。コメントセクションでは適切なコードセグメントが許可されていないので、これが私が修正バージョンだと思うものです:

def depth_softmax(matrix):

    from keras import backend as K

    exp_matrix = K.exp(matrix)
    softmax_matrix = exp_matrix / K.expand_dims(K.sum(exp_matrix, axis=-1), axis=-1)
    return softmax_matrix

このメソッドは、マトリックスの順序が(高さ、幅、チャネル)であることを期待します。

0
AljoSt