关于python:Tensorflow预测总是相同的结果

Tensorflow predicts always the same result

我正在尝试使用我自己的数据运行 TensorFlow 示例,但不知何故分类器总是为每个测试示例选择相同的类。输入数据总是先打乱。我有大约 4000 张图像作为训练集,500 张图像作为测试集。

我得到的结果如下:

1
2
3
4
5
6
7
Result: [[ 1.  0.]] Actually: [ 1.  0.]
Result: [[ 1.  0.]] Actually: [ 0.  1.]
Result: [[ 1.  0.]] Actually: [ 1.  0.]
Result: [[ 1.  0.]] Actually: [ 1.  0.]
Result: [[ 1.  0.]] Actually: [ 0.  1.]
Result: [[ 1.  0.]] Actually: [ 0.  1.]
...

右侧保留所有 500 张图像 [1. 0.]。分类是二元的,所以我只有两个标签。

这是我的源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import tensorflow as tf
import input_data as id

test_images, test_labels = id.read_images_from_csv(
   "/home/johnny/Desktop/tensorflow-examples/46-model.csv")

train_images = test_images[:4000]
train_labels = test_labels[:4000]
test_images = test_images[4000:]
test_labels = test_labels[4000:]

print len(train_images)
print len(test_images)

pixels = 200 * 200
labels = 2

sess = tf.InteractiveSession()

# Create the model
x = tf.placeholder(tf.float32, [None, pixels])
W = tf.Variable(tf.zeros([pixels, labels]))
b = tf.Variable(tf.zeros([labels]))
y_prime = tf.matmul(x, W) + b
y = tf.nn.softmax(y_prime)

# Define loss and optimizer
y_ = tf.placeholder(tf.float32, [None, labels])
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(y_prime, y_)
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

# Train
tf.initialize_all_variables().run()
for i in range(10):
    res = train_step.run({x: train_images, y_: train_labels})
# Test trained model
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x: test_images, y_: test_labels}))

for i in range(0, len(test_images)):
    res = sess.run(y, {x: [test_images[i]]})
    print("Result:" + str(res) +" Actually:" + str(test_labels[i]))

我漏掉了一点吗?


您的代码中存在三个潜在问题:

  • 权重 W 被初始化为零。来自 stats.stackexchange.com 的这个问题很好地讨论了为什么这会导致训练结果不佳(例如陷入局部最小值)。相反,您应该随机初始化它们,例如如下:

    1
    2
    W = tf.Variable(tf.truncated_normal([pixels, labels],
                                        stddev=1./math.sqrt(pixels)))
  • cross_entropy 应在最小化之前聚合为单个标量值,例如使用 tf.reduce_mean():

    1
    2
    cross_entropy = tf.reduce_mean(
        tf.nn.softmax_cross_entropy_with_logits(y_prime, y_))
  • 如果您在小批量(甚至单个示例)上训练而不是一次在整个数据集上训练,您可能会获得更快的收敛:

    1
    2
    3
    4
    for i in range(10):
            for j in range(4000):
                res = train_step.run({x: train_images[j:j+1],
                                      y_: train_labels[j:j+1]})

  • 您可能遇到的另一个问题是类别不平衡。如果您的一个类大大超过另一个类,则您的函数可能会收敛到该值。尝试平衡训练样本中的类以及使用较小的批次。例如,如果您的标签是二进制的,那么请确保您的训练样本中有等量的零和一个标签。