在每个示例上使用 tensorflow 获得相同的预测

Posted

技术标签:

【中文标题】在每个示例上使用 tensorflow 获得相同的预测【英文标题】:Getting same prediction with tensorflow on every example 【发布时间】:2017-12-03 06:26:03 【问题描述】:

我有以下代码,我在 MNIST 数据集上训练神经网络。然后,通过训练有素的网络,我试图预测 test_inputs 中的值。

import pandas as pd
import numpy as np
import tensorflow as tf
from math import trunc
from subprocess import check_output

def make_one_hot(m):
    result = pd.DataFrame((np.asarray(m)[:,None] == np.arange(10)).astype(int))
    return result

train_data = pd.read_csv("../input/train.csv", delimiter=',')
train_labels = make_one_hot(train_data.ix[:, 0])
train_inputs = train_data.ix[:, 1:]
test_inputs = pd.read_csv("../input/test.csv", delimiter=',')    

x = tf.placeholder(tf.float32, [None, 784])

W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x, W) + b)
y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(tf.clip_by_value(y,1e-10,1.0)), reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(cross_entropy)


sess = tf.InteractiveSession()
tf.global_variables_initializer().run()
for _ in range(1000):
  batch_xs = train_inputs.sample(n=100)
  batch_ys = train_labels.sample(n=100)
  sess.run(train_step, feed_dict=x: batch_xs, y_: batch_ys)

y = tf.nn.softmax(tf.matmul(x,W) + b)
result = sess.run(y, feed_dict=x: test_inputs)

f = open("results.csv","w+")
f.write("ImageId,Label\n")
for i in range(0, len(result)):
  x = 0
  for j in range(0, 10):
      if(result.item(i, j) == 1):
          x = j
  f.write(",\n".format(i+1, x))

但是,无论输入如何,网络总是将所有示例的数字预测为相同的数字。

数字本身会发生变化,有时是1,有时是67,但所有示例在同一次运行中得到相同的数字。

知道它可能有什么问题吗?

编辑

我修复了最后一行的缩进(这是错误的),但所有测试示例的结果仍然具有相同的标签。

【问题讨论】:

您是否尝试使用步骤打印训练/开发损失?另外,你为什么不使用softmax_cross_entropy_with_logits “您是否尝试使用步骤打印训练/开发损失?”不,我没有。我怎样才能做到这一点? "另外,你为什么不使用 softmax_cross_entropy_with_logits" 在哪里使用这个? 另外,我认为采用batch_xs = train_inputs.sample()batch_ys = train_labels.sample() 可能会导致不相关的输入和标签,这不会导致良好的学习...试试batch_ys = train_labels.loc[batch_xs.index] 但我认为主要问题是@jack6e 指出的 @PietroTortella 谢谢这实际上是主要问题 【参考方案1】:

为响应 OP 编辑​​而编辑

我仍然认为您打算在 f.write 迭代中使用 x。现在,除了 i 迭代和 j 迭代的值之外,您没有将任何内容打印到文件中,但实际上没有任何结果。

您是否正在尝试执行以下操作:

for i in range(0, len(result)):
    x = 0
    for j in range(0, 10):
        if(result.item(i, j) == 1):
            x = j
            f.write(",\n".format(i+1, x))

或许:

for i in range(0, len(result)):

    for j in range(0, 10):
        x = result.item(i, j)
        f.write(",\n".format(i+1, x))

原始回复

您需要修复缩进:

for j in range(0, 10):
    if(result.item(i, j) == 1):
        x = j
    f.write(",\n".format(i+1, j))

这样f.write 命令就属于for j 循环。现在您正在编写最后一个j 值,在循环运行后range(0,10) 中始终为9,这意味着每个i image_id 都会获得标签9。 另外,你在用x做什么?您首先根据条件设置x = 0,然后设置x = j,但从未实际使用它。

【讨论】:

是的,我太愚蠢了。我修复了缩进,但结果是一样的。 谢谢。我错误地编辑了问题。现在我改变了它。目的是在第二个 for 循环结束时打印 x。但是,我对所有示例都得到相同答案的问题仍然存在。我认为这与机器学习有关,而不是对齐。【参考方案2】:

变量的初始化将不允许网络训练。将偏差和权重都初始化为零将导致无法进行训练,因为梯度始终为零。

使用均值不为零的截断法线(0.1 左右为佳)。 https://www.tensorflow.org/api_docs/python/tf/truncated_normal

和偏见一样。这将有助于网络训练,因为现在梯度不会为零。

【讨论】:

好的,我用truncated_normal代替zeros,但结果还是一样。

以上是关于在每个示例上使用 tensorflow 获得相同的预测的主要内容,如果未能解决你的问题,请参考以下文章

如何在保持相同形状和尺寸的同时获得 tensorflow 数据集中的最大值?

Tensorflow:tf.random_normal使用初始种子获得不同的结果

如何使用TensorFlow Hub和代码示例

使用 Tensorflow 进行图像增强,因此所有类都具有完全相同数量的图像

TensorFlow 保存和加载不一致

如何使用tensorflow为每个类获取具有相同数量图像的验证集?