2016-08-23 83 views
1

我在玩TensorFlow,使用'MNIST for beginners'示例(initial code here)。我做了一些轻微的adaptions:试图适应TensorFlow的MNIST示例给出NAN预测

mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True) 

sess = tf.InteractiveSession() 

# Create the model 
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) 

# Define loss and optimizer 
y_ = tf.placeholder(tf.float32, [None, 10]) 
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1])) 
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) 

fake_images = mnist.train.images.tolist() 

# Train 
tf.initialize_all_variables().run() 
for i in range(10): 
    batch_xs, batch_ys = fake_images, mnist.train.labels 
    train_step.run({x: batch_xs, y_: batch_ys}) 

# Test trained model 
print(y.eval({x: mnist.test.images})) 

具体来说,我只跑训练步骤10次(我不关心的准确性,更多的速度)。我也一次在所有的数据上运行它(为了简单起见)。最后,我输出TF正在做出的预测,而不是准确率。这里的(一些)上面的代码的输出:

[ 1.08577311e-02 7.29394853e-01 5.02395593e-02 ..., 2.74689011e-02 
    4.43389975e-02 2.32385024e-02] 
..., 
[ 2.95746652e-03 1.30554764e-02 1.39354384e-02 ..., 9.16484520e-02 
    9.70732421e-02 2.57733971e-01] 
[ 5.94450533e-02 1.36338845e-01 5.22132218e-02 ..., 6.91468120e-02 
    1.95634082e-01 4.83607128e-02] 
[ 4.46179360e-02 6.66685810e-04 3.84704918e-02 ..., 6.51754031e-04 
    2.46591796e-03 3.10819712e-03]] 

这似乎是概率TF被分配给每一个的可能性(0-9)。一切都与世界一致。

我的主要目标是适应另一个用途,但首先我想确保我可以给它其他数据。这是我已经试过:

fake_images = np.random.rand(55000, 784).astype('float32').tolist() 

其中,按照我的理解,应该产生随机垃圾的阵列,其结构与从MNIST数据。但做出以上更改,这里是我得到的:

[[ nan nan nan ..., nan nan nan] 
[ nan nan nan ..., nan nan nan] 
[ nan nan nan ..., nan nan nan] 
..., 
[ nan nan nan ..., nan nan nan] 
[ nan nan nan ..., nan nan nan] 
[ nan nan nan ..., nan nan nan]] 

这显然没那么有用。查看每个选项(mnist.train.imagesnp.random.rand选项),它看起来像是listlist s的float s。

为什么TensorFlow不接受这个数组?这是否只是抱怨,因为它认识到无法从一堆随机数据中学习?我不期望,但我以前错了。

+0

'np.random.rand'产生范围为[[0,1]'的数字。你从'mnist.train.images'得到的数字范围是多少?一些中间值很可能溢出或下溢。我会尝试打印出中间值,比如说'tf.matmul(x,W)'的结果,看看这是不是问题。 – keveman

+0

'0.5'因为学习速度也很大,所以试试'0.01'或更少 – fabrizioM

+0

@keveman'mnist.train.images [0]'是一个大部分为0的数组,大部分都在0-1范围内。在尝试将“matmul”分解为中间计算时,我将训练步数改为2 ...并突然发挥作用,给出预期的〜10%的准确度。我已经将它隔离到修正它的那个变化上,这似乎确认了上/下溢。想想可能在哪里,或者我可以如何解决它? – Undo

回答

0

真实的MNIST数据包含非常稀疏的数据。大部分值为零。您的合成数据均匀分布(请参见numpy)。 W和b训练假设稀疏输入。您可能训练的模型能够强烈过度拟合,并且具有连接到特定输入像素的非常大的W权重,以实现良好的输出概率(大型后softmax值需要大的pre-softmax激活)。当您输入合成数据时,突然间,所有输入量值都比以前大得多,导致无处不在的非常大的激活,可能导致溢出。

+0

这有助于提高准确性,但在我的测试中,它并未解决'nan'问题。 – Undo

+0

查看修订后的答案。 – ahaque

+0

有意义,虽然这发生在一个新鲜训练的模型上(用随机数据训练) – Undo

1

什么是你搞砸的是log(softmax)在数值上不稳定。

The softmax cross entropy with logits loss数值稳定。

所以,你可以做

activations = tf.matmul(x, W) + b 
loss = tf.nn.softmax_cross_entropy_with_logits(activations, y) 

# only to get predictions, for accuracy or you know, actual forward use of the model 
predictions = tf.nn.softmax(activations) 

我偷懒找对数SOFTMAX数值稳定性机器学习栈交流的文章,但你能很快我敢肯定,找到他们。