Tensorflow 收敛但预测结果差

前几天我发布了一个类似的问题在这里,但自那以后我已经修复了一些发现的错误,然而预测结果差的问题依然存在。

我有两个网络——一个有3个卷积层,另一个在3个卷积层之后接着3个反卷积层。两者都接受200×200的输入图像。输出也是相同的200×200分辨率,但它有两个分类(要么是0要么是1——这是一个分割网络),所以网络预测的维度是200x200x2(加上批次大小)。我们来讨论一下带有反卷积层的网络。

奇怪的是…在10次训练运行中,可能只有3次会收敛。其余7次会发散到准确率为0.0。

卷积和反卷积层由ReLu激活。优化器的行为有些奇怪。当我在每次训练迭代后打印预测值时,值的幅度开始很大——考虑到它们都通过了ReLu,这是正确的——但在每次迭代后,值会变小,直到它们大致在0到2之间。我随后将它们通过一个Sigmoid函数(sigmoid_cross_entropy_wight_logits)——因此将大的负值压缩到0,将大的正值压缩到1。当我进行预测时,我通过再次将输出通过Sigmoid函数来重新激活输出。

所以在第一次迭代后,预测值是合理的…

Accuracy = 0.508033[[[[ 1.  0.]   [ 0.  1.]   [ 0.  0.]   ...,    [ 1.  0.]   [ 1.  1.]   [ 1.  0.]]  [[ 0.  1.]   [ 1.  1.]   [ 0.  0.]   ...,    [ 1.  1.]   [ 1.  1.]   [ 0.  1.]]

但在几次迭代后,假设这次它确实收敛了,预测值看起来像…(因为优化器使输出变小,它们都在Sigmoid函数的奇怪中间地带)

  [[ 0.51028508  0.63202268]   [ 0.24386917  0.52015287]   [ 0.62086064  0.6953823 ]   ...,    [ 0.2593964   0.13163178]   [ 0.24617286  0.5210492 ]   [ 0.24692698  0.5876413 ]]]]Accuracy = 0.999913

我是否使用了错误的优化器函数?

这是整个代码…跳到def conv_net查看网络创建…在该函数之后是成本函数、优化器和准确率的定义。你会注意到当我测量准确率和进行预测时,我通过tf.nn.sigmoid(pred)重新激活输出——这是因为成本函数sigmoid_cross_entropy_with_logits将激活和损失结合在同一个函数中。换句话说,pred(网络)输出一个线性值。

...

correct_pred变量(测量准确率的变量)是一个简单的减法运算符,用于预测和真实值之间的差异,然后与零进行比较(如果两者相等,那么差异应该为零)。

此外,我已经绘制了网络,它看起来对我来说非常不对劲。这是一张图片,我不得不裁剪以便查看。

image1

image2

编辑:我发现我的图看起来很糟糕的原因(感谢Olivier),我还尝试更改我的损失函数,但没有结果——它仍然以同样的方式发散

...

编辑 现在完整的代码看起来像这样(仍然在发散)

...

回答:

反卷积的概念是输出与输入相同大小的内容。

在这一行:

conv6 = tf.nn.bias_add(conv6, biases['bdc3'])

你有这个形状为[batch_size, 200, 200, 2]的输出,所以你不需要添加你的全连接层。只需返回conv6(不带最终的ReLU)。


如果你在预测和真实标签y中使用两个类别,你需要使用tf.nn.softmax_cross_entropy_with_logits(),而不是Sigmoid交叉熵。

确保y始终具有如下值:y[i, j] = [0., 1.]y[i, j] = [1., 0.]

pred = conv_net(x, weights, biases, keep_prob)  # 新预测 conv6pred = tf.reshape(pred, [-1, n_classes])# 定义损失和优化器cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))

如果你想让你的TensorBoard图看起来好看(至少是可读的),请确保使用tf.name_scope()


编辑:

你的准确率也是错误的。你测量softmax(pred)y是否相等,但softmax(pred)永远不会等于0.1.,所以你的准确率将是0.

你应该这样做:

with tf.name_scope("acc") as scope:    correct_pred = tf.equal(tf.argmax(temp_pred, 1), tf.argmax(temp_y, 1))    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

编辑2:

真正的错误是在convert_to_2_channel中的一个拼写错误,在循环中

for j in xrange(3):

它应该是200而不是3。

教训:在调试时,逐步打印所有内容,使用非常简单的例子,你会发现那个有问题的函数返回了错误的输出。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注