3

完全な畳み込みニューラル ネットワークを使用して画像のセグメンテーションを行っています (論文へのリンク): https://people.eecs.berkeley.edu/~jonlong/long_shelhamer_fcn.pdf

これは、ピクセルの分類と見なすことができます (最終的に、各ピクセルはラベルを取得します)。

私は tf.nn.sparse_softmax_cross_entropy_with_logits 損失関数を使用しています。

loss = tf.reduce_mean((tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits,
                                                                      labels=tf.squeeze(annotation, squeeze_dims=[3]),
                                                                      name="entropy"))) 

すべてがうまくいっています。しかし、1 つのクラスが大部分のピクセル (95% 以上) で発生することがわかりました。これをクラス 0 と呼びます。別の 3 つのクラス、1、2、および 3 があるとします。

クラスに重みを付ける最も簡単な方法は何ですか? 基本的に、通常の重み 1 を持つべき他の 3 つのクラスと比較して、クラス 0 の重みを非常に低くしたいと考えています (0.1 など)。

この関数が存在することは知っています: https://www.tensorflow.org/api_docs/python/tf/losses/sparse_softmax_cross_entropy

まったく違うことをしているように見えますが、重みがラベルと同じランクになる方法がわかりません。つまり、私の場合、重みは Tensor([0.1, 1, 1, 1]) のような形 (4,) でランク 1、ラベルは形 (batch_size, width, height) でランク 3 のようにする必要があります。何か不足していますか?

PyTorch で同等のものは次のようになります。

torch.nn.CrossEntropyLoss(weight=None, size_average=True, ignore_index=-100)

ここで、重みはトーチ テンソル [0.1, 1, 1, 1] です。

ありがとう!

4

1 に答える 1

1

あなたの推測は正しいです。weightsパラメーターtf.losses.softmax_cross_entropyとは、バッチtf.losses.sparse_softmax_cross_entropy全体の重みを意味します。つまり、いくつかの入力を他のものよりも重要にします。クラス間で損失を重み付けするすぐに使える方法はありません。

回避策としてできることは、現在のラベルに従って特別に重みを選択し、それらをバッチの重みとして使用することです。これは、重みベクトルがバッチごとに異なることを意味しますが、まれなクラスをより重要なものにしようとします。この質問のサンプル コードを参照してください。

注: バッチには必ずしも均一なクラス分布が含まれているとは限らないため、このトリックはバッチ サイズが小さい場合はうまく機能せず、バッチ サイズが大きいほどうまく機能します。バッチ サイズが 1 の場合は、まったく役に立ちません。そのため、バッチをできるだけ大きくします。

于 2017-11-11T15:03:16.900 に答える