Tensorflow 为什么输出层在网络的末端是零?
我正在尝试训练一个模型,该模型采用15x15图像,并将每个像素分为两类(1/0) 这是我的损失函数:Tensorflow 为什么输出层在网络的末端是零?,tensorflow,keras,conv-neural-network,loss-function,Tensorflow,Keras,Conv Neural Network,Loss Function,我正在尝试训练一个模型,该模型采用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_pre
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'])
模型左侧为输入,标签为中间列,预测在右侧列始终为零:
培训表现非常糟糕:
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
这听起来像是一个非常不平衡的数据集,真实区域非常小。这可能确实很难训练 您可能希望增加
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)
这样,每个图像都有一个单独的损失值,因此,具有许多正面效果的图像的存在不会影响具有很少正面效果的图像的结果 我试图增加alpha值,但没有多大帮助。还尝试了不同的ADAM学习率,但没有成功。您是否按照建议修复了损失?让我印象深刻的是,无论输入如何,经过培训的网络的输出都会保持不变。您的数据是否在正确的范围内?什么是
y\u train.min()
,y\u train.max()
,预测值.mean()
,等等。获得这些统计数据的最佳方法是什么?要回电话吗?