为啥 TensorFlow 返回 [[nan nan]] 而不是 CSV 文件中的概率?

Posted

技术标签:

【中文标题】为啥 TensorFlow 返回 [[nan nan]] 而不是 CSV 文件中的概率?【英文标题】:Why does TensorFlow return [[nan nan]] instead of probabilities from a CSV file?为什么 TensorFlow 返回 [[nan nan]] 而不是 CSV 文件中的概率? 【发布时间】:2016-02-28 14:56:27 【问题描述】:

这是我正在使用的代码。我正在尝试将 1、0 或希望的概率作为真实测试集的结果。当我只是拆分训练集并在训练集上运行它时,我得到了大约 93% 的准确率,但是当我训练程序并在实际测试集上运行它时(没有 1 和 0 填充的第 1 列) 它只返回 nan 的。

import tensorflow as tf
import numpy as np
from numpy import genfromtxt
import sklearn

# Convert to one hot
def convertOneHot(data):
    y=np.array([int(i[0]) for i in data])
    y_onehot=[0]*len(y)
    for i,j in enumerate(y):
        y_onehot[i]=[0]*(y.max() + 1)
        y_onehot[i][j]=1
    return (y,y_onehot)


data = genfromtxt('cs-training.csv',delimiter=',')  # Training data
test_data = genfromtxt('cs-test-actual.csv',delimiter=',')  # Actual test data

#This part is to get rid of the nan's at the start of the actual test data
g = 0
for i in test_data:
    i[0] = 1
    test_data[g] = i
    g += 1

x_train=np.array([ i[1::] for i in data])
y_train,y_train_onehot = convertOneHot(data)

x_test=np.array([ i[1::] for i in test_data])
y_test,y_test_onehot = convertOneHot(test_data)
A=data.shape[1]-1 # Number of features, Note first is y
B=len(y_train_onehot[0])
tf_in = tf.placeholder("float", [None, A]) # Features
tf_weight = tf.Variable(tf.zeros([A,B]))
tf_bias = tf.Variable(tf.zeros([B]))
tf_softmax = tf.nn.softmax(tf.matmul(tf_in,tf_weight) + tf_bias)

# Training via backpropagation
tf_softmax_correct = tf.placeholder("float", [None,B])
tf_cross_entropy = -tf.reduce_sum(tf_softmax_correct*tf.log(tf_softmax))

# Train using tf.train.GradientDescentOptimizer
tf_train_step = tf.train.GradientDescentOptimizer(0.01).minimize(tf_cross_entropy)

# Add accuracy checking nodes
tf_correct_prediction = tf.equal(tf.argmax(tf_softmax,1), tf.argmax(tf_softmax_correct,1))
tf_accuracy = tf.reduce_mean(tf.cast(tf_correct_prediction, "float"))

saver = tf.train.Saver([tf_weight,tf_bias])

# Initialize and run
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

print("...")
# Run the training
for i in range(1):
    sess.run(tf_train_step, feed_dict=tf_in: x_train, tf_softmax_correct: y_train_onehot)
    #print y_train_onehot
    saver.save(sess, 'trained_csv_model')

    ans = sess.run(tf_softmax, feed_dict=tf_in: x_test)
    print ans

#Print accuracy
    #result = sess.run(tf_accuracy, feed_dict=tf_in: x_test, tf_softmax_correct: y_test_onehot)
#print result

当我打印 ans 时,我得到以下信息。

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

我不知道我在这里做错了什么。我想要的只是让ans 产生一个 1、0 或特别是一个概率数组,其中数组中的每个单元的长度为 2。

我不希望有很多人能够为我回答这个问题,但请至少尝试一下。我被困在这里等待天才时刻的到来,现在两天还没有出现,所以我想我会问。谢谢!

test_data 看起来像这样-

[[  1.00000000e+00   8.85519080e-01   4.30000000e+01 ...,   0.00000000e+00
0.00000000e+00   0.00000000e+00]
 [  1.00000000e+00   4.63295269e-01   5.70000000e+01 ...,   4.00000000e+00
0.00000000e+00   2.00000000e+00]
 [  1.00000000e+00   4.32750360e-02   5.90000000e+01 ...,   1.00000000e+00
0.00000000e+00   2.00000000e+00]
 ..., 
 [  1.00000000e+00   8.15963730e-02   7.00000000e+01 ...,   0.00000000e+00
0.00000000e+00              nan]
 [  1.00000000e+00   3.35456547e-01   5.60000000e+01 ...,   2.00000000e+00
1.00000000e+00   3.00000000e+00]
 [  1.00000000e+00   4.41841663e-01   2.90000000e+01 ...,   0.00000000e+00
0.00000000e+00   0.00000000e+00]]

数据中第一个单位等于 1 的唯一原因是因为我去掉了填充该位置的 nan 以避免错误。请注意,第一列之后的所有内容都是特征。第一列是我试图预测的。

编辑:

我将代码更改为以下-

import tensorflow as tf
import numpy as np
from numpy import genfromtxt
import sklearn
from sklearn.cross_validation import train_test_split
from tensorflow import Print

# Convert to one hot
def convertOneHot(data):
    y=np.array([int(i[0]) for i in data])
    y_onehot=[0]*len(y)
    for i,j in enumerate(y):
        y_onehot[i]=[0]*(y.max() + 1)
        y_onehot[i][j]=1
    return (y,y_onehot)


#buildDataFromIris()


data = genfromtxt('cs-training.csv',delimiter=',')  # Training data
test_data = genfromtxt('cs-test-actual.csv',delimiter=',')  # Test data

#for i in test_data[0]:
#    print i
#print test_data

#print test_data
g = 0
for i in test_data:
    i[0] = 1.
    test_data[g] = i
    g += 1

#print 1, test_data

x_train=np.array([ i[1::] for i in data])
y_train,y_train_onehot = convertOneHot(data)
#print len(x_train), len(y_train), len(y_train_onehot)

x_test=np.array([ i[1::] for i in test_data])
y_test,y_test_onehot = convertOneHot(test_data)
#for u in y_test_onehot[0]:
#    print u
#print y_test_onehot
#print len(x_test), len(y_test), len(y_test_onehot)
#print x_test[0]

#print '1'

#  A number of features, 4 in this example
#  B = 3 species of Iris (setosa, virginica and versicolor)
A=data.shape[1]-1 # Number of features, Note first is y
#print A
B=len(y_train_onehot[0])
#print B
#print y_train_onehot
tf_in = tf.placeholder("float", [None, A]) # Features
tf_weight = tf.Variable(tf.zeros([A,B]))
tf_bias = tf.Variable(tf.zeros([B]))
tf_softmax = tf.nn.softmax(tf.matmul(tf_in,tf_weight) + tf_bias)

tf_bias = tf.Print(tf_bias, [tf_bias], "Bias: ")
tf_weight = tf.Print(tf_weight, [tf_weight], "Weight: ")
tf_in = tf.Print(tf_in, [tf_in], "TF_in: ")
matmul_result = tf.matmul(tf_in, tf_weight)
matmul_result = tf.Print(matmul_result, [matmul_result], "Matmul: ")
tf_softmax = tf.nn.softmax(matmul_result + tf_bias)
print tf_bias
print tf_weight
print tf_in
print matmul_result

# Training via backpropagation
tf_softmax_correct = tf.placeholder("float", [None,B])
tf_cross_entropy = -tf.reduce_sum(tf_softmax_correct*tf.log(tf_softmax))

print tf_softmax_correct

# Train using tf.train.GradientDescentOptimizer
tf_train_step = tf.train.GradientDescentOptimizer(0.01).minimize(tf_cross_entropy)

# Add accuracy checking nodes
tf_correct_prediction = tf.equal(tf.argmax(tf_softmax,1), tf.argmax(tf_softmax_correct,1))
tf_accuracy = tf.reduce_mean(tf.cast(tf_correct_prediction, "float"))

print tf_correct_prediction
print tf_accuracy

#saver = tf.train.Saver([tf_weight,tf_bias])

# Initialize and run
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

print("...")
prediction = []
# Run the training
#probabilities = []
#print y_train_onehot
#print '-----------------------------------------'
for i in range(1):
    sess.run(tf_train_step, feed_dict=tf_in: x_train, tf_softmax_correct: y_train_onehot)
    #print y_train_onehot
    #saver.save(sess, 'trained_csv_model')

    ans = sess.run(tf_softmax, feed_dict=tf_in: x_test)
    print ans

打印出来后,我看到其中一个对象是布尔值。我不知道这是否是问题,但请查看以下内容,看看是否有任何方法可以提供帮助。

Tensor("Print_16:0", shape=TensorShape([Dimension(2)]), dtype=float32)
Tensor("Print_17:0", shape=TensorShape([Dimension(10), Dimension(2)]), dtype=float32)
Tensor("Print_18:0", shape=TensorShape([Dimension(None), Dimension(10)]), dtype=float32)
Tensor("Print_19:0", shape=TensorShape([Dimension(None), Dimension(2)]), dtype=float32)
Tensor("Placeholder_9:0", shape=TensorShape([Dimension(None), Dimension(2)]), dtype=float32)
Tensor("Equal_4:0", shape=TensorShape([Dimension(None)]), dtype=bool)
Tensor("Mean_4:0", shape=TensorShape([]), dtype=float32)
...
[[ nan  nan]
 [ nan  nan]
 [ nan  nan]
 ..., 
 [ nan  nan]
 [ nan  nan]
 [ nan  nan]]

【问题讨论】:

【参考方案1】:

我不知道直接答案,但我知道如何调试它:tf.Print。它是一个在执行 tensorflow 时打印值的操作,并返回张量以供进一步计算,因此您可以将它们内嵌在模型中。

尝试加入其中的一些。而不是这一行:

tf_softmax = tf.nn.softmax(tf.matmul(tf_in,tf_weight) + tf_bias)

试试:

tf_bias = tf.Print(tf_bias, [tf_bias], "Bias: ")
tf_weight = tf.Print(tf_weight, [tf_weight], "Weight: ")
tf_in = tf.Print(tf_in, [tf_in], "TF_in: ")
matmul_result = tf.matmul(tf_in, tf_weight)
matmul_result = tf.Print(matmul_result, [matmul_result], "Matmul: ")
tf_softmax = tf.nn.softmax(matmul_result + tf_bias)

看看 Tensorflow 认为中间值是什么。如果 NaN 在管道中较早出现,它应该让您更好地了解问题所在。祝你好运!如果您从中获得了一些数据,请随时跟进,我们会看看我们是否可以为您提供更多信息。

更新添加:这是一个精简的调试版本,我去掉了输入函数,只生成了一些随机数据:

import tensorflow as tf
import numpy as np

def dense_to_one_hot(labels_dense, num_classes=10):
  """Convert class labels from scalars to one-hot vectors."""
  num_labels = labels_dense.shape[0]
  index_offset = np.arange(num_labels) * num_classes
  labels_one_hot = np.zeros((num_labels, num_classes))
  labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1
  return labels_one_hot

x_train=np.random.normal(0, 1, [50,10])
y_train=np.random.randint(0, 10, [50])
y_train_onehot = dense_to_one_hot(y_train, 10)

x_test=np.random.normal(0, 1, [50,10])
y_test=np.random.randint(0, 10, [50])
y_test_onehot = dense_to_one_hot(y_test, 10)

#  A number of features, 4 in this example
#  B = 3 species of Iris (setosa, virginica and versicolor)

A=10
B=10
tf_in = tf.placeholder("float", [None, A]) # Features
tf_weight = tf.Variable(tf.zeros([A,B]))
tf_bias = tf.Variable(tf.zeros([B]))
tf_softmax = tf.nn.softmax(tf.matmul(tf_in,tf_weight) + tf_bias)

tf_bias = tf.Print(tf_bias, [tf_bias], "Bias: ")
tf_weight = tf.Print(tf_weight, [tf_weight], "Weight: ")
tf_in = tf.Print(tf_in, [tf_in], "TF_in: ")
matmul_result = tf.matmul(tf_in, tf_weight)
matmul_result = tf.Print(matmul_result, [matmul_result], "Matmul: ")
tf_softmax = tf.nn.softmax(matmul_result + tf_bias)

# Training via backpropagation
tf_softmax_correct = tf.placeholder("float", [None,B])
tf_cross_entropy = -tf.reduce_sum(tf_softmax_correct*tf.log(tf_softmax))

# Train using tf.train.GradientDescentOptimizer
tf_train_step = tf.train.GradientDescentOptimizer(0.01).minimize(tf_cross_entropy)

# Add accuracy checking nodes
tf_correct_prediction = tf.equal(tf.argmax(tf_softmax,1), tf.argmax(tf_softmax_correct,1))
tf_accuracy = tf.reduce_mean(tf.cast(tf_correct_prediction, "float"))

print tf_correct_prediction
print tf_accuracy

init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

for i in range(1):
    print "Running the training step"
    sess.run(tf_train_step, feed_dict=tf_in: x_train, tf_softmax_correct: y_train_onehot)
    #print y_train_onehot
    #saver.save(sess, 'trained_csv_model')

    print "Running the eval step"
    ans = sess.run(tf_softmax, feed_dict=tf_in: x_test)
    print ans

您应该会看到以“Bias:”等开头的行。

【讨论】:

首先,我要感谢您尝试帮助我解决这个问题。我正在尝试调试代码并找出数字更改为 NaN 的位置,但我仍然找不到它。我试过你的 tf.Print ,它没有产生任何输出;只是相同的 NaN 数组。 请检查我对 OP 中的代码所做的最新编辑。那里有一个布尔值,我不知道这是否是代码出错的地方。如果是,也许您可​​以提出解决方法。 您没有按照我建议的顺序放置照片。您需要将它们交错:在定义 tf_bias 之后,立即重新分配 tf_bias = tf.Print(tf_bias, [tf_bias], "Bias: ")。打印运算符仅在数据流过它时执行。具体来说,您需要在 matmul 之前进行这些重新分配,因为那是数据要去的地方... 您在编辑 2 中显示的输出来自 'print ',而不是来自 tf.Print 操作。你能显示 tf.Print 的输出吗?在 python 中打印 tf 张量只会得到像 Tensor("Print_16:0", shape=TensorShape([Dimension(2)]), dtype=float32) 这样的输出,但这并不能告诉你张量中有什么。 tf.Print 将在执行时向您显示 runtime 值,您应该能够在此处发现 NaN。 tf.Print 不会产生任何输出。我尝试添加sess.run(tf_in),即使在我定义sess = tf.Session() 之后我也会收到错误消息。我还尝试了print sess.run(tf_in),它也提供了一个错误。我尝试了简单的tf.Print(<foo>),但仍然没有输出。【参考方案2】:

tf_cross_entropy = -tf.reduce_sum(tf_softmax_correct*tf.log(tf_softmax))

这是我正在测试的项目中遇到的问题。具体来说,它最终是 0*log(0) 产生 nan。

如果您将其替换为:

tf_cross_entropy = -tf.reduce_sum(tf_softmax_correct*tf.log(tf_softmax + 1e-50)) 它应该避免这个问题。

我也使用了 reduce_mean 而不是 reduce_sum。如果您将批量大小加倍并使用 reduce_sum,它将使成本(以及梯度的大小)加倍。除此之外,当使用 tf.print (打印到控制台 tensorfow 开始时)时,它使得它在改变批量大小时更具可比性。

具体来说这是我现在调试时使用的:

cross_entropy = -tf.reduce_sum(y*tf.log(model + 1e-50)) ## avoid nan due to 0*log(0) cross_entropy = tf.Print(cross_entropy, [cross_entropy], "cost") #print to the console tensorflow was started from

【讨论】:

啊,现在我明白为什么 tf.Print 对我没有用了。我一直在使用 IPython Notebook。谢谢你的回答。我会支持它,但问题已经解决了。如果你和我一样认为这样可以解决问题,那么我会点击勾选。 对于这些极端情况,tf.softmax_cross_entropy_with_logits 损失函数似乎更加稳健:***.com/questions/34240703/…

以上是关于为啥 TensorFlow 返回 [[nan nan]] 而不是 CSV 文件中的概率?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 tensorflow 模型输出在 x 个时期后变为 NaN?

为啥 NaN^0 == 1

当我使用 RELU 激活时,为啥我的 TensorFlow 网络权重和成本为 NaN?

Tensorflow 强化学习 RNN 在使用 GradientTape 优化后返回 NaN

在 TensorFlow 中使用 SSIM 损失返回 NaN 值

为啥 Assert.AreEqual(1.0, double.NaN, 1.0) 通过?