我想在TensorFlow中使用{0.0,1.0}中的值学习图像分割。我有两个图像ground_truth
和prediction
,每个图像的形状均为(120,160)
。 ground_truth
图像像素仅包含0.0或1.0的值。
预测图像是解码器的输出,它的最后两层是tf.layers.conv2d_transpose
和tf.layers.conv2d
,如下所示:
transforms (?,120,160,30) -> (?,120,160,15)
outputs = tf.layers.conv2d_transpose(outputs, filters=15, kernel_size=1, strides=1, padding='same')
# ReLU
outputs = activation(outputs)
# transforms (?,120,160,15) -> (?,120,160,1)
outputs = tf.layers.conv2d(outputs, filters=1, kernel_size=1, strides=1, padding='same')
最后一层没有激活功能,因此它的输出是无界的。我使用以下损失函数:
logits = tf.reshape(predicted, [-1, predicted.get_shape()[1] * predicted.get_shape()[2]])
labels = tf.reshape(ground_truth, [-1, ground_truth.get_shape()[1] * ground_truth.get_shape()[2]])
loss = 0.5 * tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=labels,logits=logits))
此设置可以很好地收敛。但是,我已经意识到,验证时我最后一个NN层的输出似乎在[-inf,inf]中。如果我看到输出,我可以看到分割的对象没有被分割,因为几乎所有像素都被“激活”了。最后一个conv2d层的单个输出的值分布如下所示:
是否必须对输出进行后处理(裁剪负值或通过S型激活等运行输出)?我该怎么做才能将输出值强制为{0,1}?
答案 0 :(得分:3)
解决了。问题是=INDIRECT(ADDRESS(ROW(),COLUMN(),1,0,"January"),0)
通过S形运行logit,因为在丢失时间仅在训练期间调用损失操作,所以在验证时当然不使用它。因此,解决方案是:
确保在验证/测试时通过tf.nn.sigmoid_cross_entropy_with_logits
运行网络输出,如下所示:
tf.nn.sigmoid