为什么输出层在网络末端只是零?

问题描述 投票:0回答:1

[我正在尝试训练一个拍摄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
tensorflow keras conv-neural-network
1个回答
1
投票

这听起来像是一个非常不平衡的数据集,只有很小的真实区域。确实,这可能很难训练。

您可能想增加alpha来比假阳性更多地惩罚假阴性。无论如何,除非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)

这样,您对每个图像都有一个单独的损耗值,因此具有许多正值的图像的退出不会影响具有少量正值的图像的结果。

© www.soinside.com 2019 - 2024. All rights reserved.