次のように最後のレイヤーに_Softmax Activation
_を設定すると、私はunetで画像セマンティックセグメンテーションジョブを実行しています。
_...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
conv10 = (Activation('softmax'))(conv9)
model = Model(inputs, conv10)
return model
...
_
次に、loss = tf.keras.losses.CategoricalCrossentropy(from_logits=False)
を使用します。トレーニングは、1つのトレーニング画像でも収束しません。
しかし、次のように最後のレイヤーに_Softmax Activation
_を設定しない場合:
_...
conv9 = Conv2D(n_classes, (3,3), padding = 'same')(conv9)
model = Model(inputs, conv9)
return model
...
_
次に、loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
を使用します。トレーニングは、1つのトレーニング画像に対してconvergeになります。
私のGroundtruthデータセットは次のように生成されます:
_X = []
Y = []
im = cv2.imread(impath)
X.append(im)
seg_labels = np.zeros((height, width, n_classes))
for spath in segpaths:
mask = cv2.imread(spath, 0)
seg_labels[:, :, c] += mask
Y.append(seg_labels.reshape(width*height, n_classes))
_
どうして?私の使い方に何か問題がありますか?
これは私のgitの実験コードです。 https://github.com/honeytidy/unet チェックアウトして実行できます(CPUで実行できます)。 CategoricalCrossentropyのアクティベーションレイヤーとfrom_logitsを変更して、私が言ったことを確認できます。
「softmax」アクティベーションをクロスエントロピー損失層にプッシュすると、損失計算が大幅に簡略化され、数値的に安定します。
あなたの例では、数値の問題が、トレーニングプロセスをfrom_logits=False
オプション。
クロスエントロピー損失( "情報ゲイン"損失の特別なケース)の導出は、 この投稿 にあります。この導出は、softmaxとクロスエントロピー損失を組み合わせたときに回避される数値的な問題を示しています。
問題はソフトマックス起動機能にあると思います。 doc を見ると、デフォルトで最後の軸にsotmaxが適用されていることがわかりました。 model.summary()
を見て、それが必要なものかどうかを確認できますか?
softmax
が正しく機能するには、次のことを確認する必要があります。
Kerasのデフォルトのチャネル設定として_'channels_last'
_を使用しています。
(None, height, width, channels)
_のようになります。n_classes
_を配置しているため、これはあなたのケースのようです。ただし、_Conv2D
_を使用していて、出力Y
は_(1, height, width, n_classes)
_であり、使用している奇妙な形ではないため、これも奇妙です。Y
には0と1しかありません(通常、画像で発生する0と255ではありません)。
Y.max() == 1
およびY.min() == 0
を確認しますY = Y / 255.
_が必要になる場合があります正しいクラスは1つだけです(データには、値= 1のパス/チャネルが複数ありません)。
(Y.sum(axis=-1) == 1).all()
_がTrue
であることを確認します