Почему выходной слой просто равен нулю в конце сети? - PullRequest
0 голосов
/ 26 сентября 2019

Я пытаюсь обучить модель, которая берет изображение 15x15 и классифицировать каждый пиксель на два класса (1/0).

Это моя функция потерь:

smooth = 1
def tversky(y_true, y_pred):
    y_true_pos = K.flatten(y_true)
    y_pred_pos = K.flatten(y_pred)
    true_pos = K.sum(y_true_pos * y_pred_pos)
    false_neg = K.sum(y_true_pos * (1-y_pred_pos))
    false_pos = K.sum((1-y_true_pos)*y_pred_pos)
    alpha = 0.5
    return (true_pos + smooth)/(true_pos + alpha*false_neg + (1-alpha)*false_pos + smooth)

def tversky_loss2(y_true, y_pred):
    return 1 - tversky(y_true,y_pred)

Этоэто модель:

input_image = layers.Input(shape=(size, size, 1))

b2 = layers.Conv2D(128, (3,3), padding='same',  activation='relu')(input_image)
b2 = layers.Conv2D(128, (3,3), padding='same',  activation='relu')(b2)
b2 = layers.Conv2D(128, (3,3), padding='same',  activation='relu')(b2)

output = layers.Conv2D(1, (1,1), activation='sigmoid', padding='same')(b2)

model = models.Model(input_image, output)
model.compile(optimizer='adam', loss=tversky_loss2, metrics=['accuracy'])

Левая модель - это ввод, а метка - средний столбец, а в правом столбце прогноз всегда равен нулю:

enter image description here

Тренировка очень плохая:

Epoch 1/10
100/100 [==============================] - 4s 38ms/step - loss: 0.9269 - acc: 0.1825
Epoch 2/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9277 - acc: 0.0238
Epoch 3/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9276 - acc: 0.0239
Epoch 4/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9270 - acc: 0.0241
Epoch 5/10
100/100 [==============================] - 3s 30ms/step - loss: 0.9274 - acc: 0.0240
Epoch 6/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9269 - acc: 0.0242
Epoch 7/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9270 - acc: 0.0241
Epoch 8/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9271 - acc: 0.0241
Epoch 9/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9276 - acc: 0.0239
Epoch 10/10
100/100 [==============================] - 3s 29ms/step - loss: 0.9266 - acc: 0.0242

1 Ответ

1 голос
/ 26 сентября 2019

Это звучит как очень несбалансированный набор данных с очень маленькими истинными областями.Это может быть трудно на самом деле тренироваться.

Вы можете увеличить alpha, чтобы оштрафовать больше ложных срабатываний, чем ложных срабатываний.В любом случае, если альфа не достаточно велика, это нормально, что вначале ваша модель сначала обращается ко всем отрицательным, потому что это определенно отличный способ уменьшить потери.

Теперь, есть принципиальная ошибка относительно того, как работает Keras.в этой потере.Вы должны держать «образцы» отдельно.В противном случае вы рассчитываете потери, как если бы все изображения были одним изображением.(Таким образом, вполне вероятно, что изображения с большим количеством позитивов дают результат, который можно восстановить, а изображения с небольшим количеством позитивов - нет, и это будет хорошим решением)

Исправьте потерю как:


def tversky(y_true, y_pred):
    y_true_pos = K.batch_flatten(y_true) #keep the batch dimension
    y_pred_pos = K.batch_flatten(y_pred)

    true_pos = K.sum(y_true_pos * y_pred_pos, axis=-1) #don't sum over the batch dimension   
    false_neg = K.sum(y_true_pos * (1-y_pred_pos), axis=-1)
    false_pos = K.sum((1-y_true_pos)*y_pred_pos, axis=-1)
    alpha = 0.5
    return (true_pos + smooth)/(true_pos + alpha*false_neg + (1-alpha)*false_pos + smooth)

Таким образом, у вас есть индивидуальное значение потерь для каждого изображения, поэтому выход изображений с большим количеством позитивов не влияет на результаты изображений с небольшим количеством позитивов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...