我尝试构建回归模型以通过TensorFlow训练我的数据集。当它是W1 * x ^ 2 + W2 * x + b时,它显示为nan;当它是W2 * x + b时,它可以输出数字。为什么不能找到W1 = 0?我的模型建筑逻辑有什么问题吗?
import tensorflow as tf
import csv
import re
import datetime
import numpy
import matplotlib.pyplot as plt
# Parameters
learning_rate = 0.01
training_epochs = 2000
# Training Data
data_X = [ 0., 2., 5., 6., 7., 8., 9., 12., 13., 14.]
data_Y = [ 2568.300049, 2540.100098, 2552.399902, 2583.899902, 2607.100098,
2603.300049, 2561.699951, 2614.899902, 2590.800049, 2578.199951]
train_X = numpy.asarray(data_X)
train_Y = numpy.asarray(data_Y)
n_samples = train_X.shape[0]
# Model parameters
rng = numpy.random
W1 = tf.Variable([rng.randn()], dtype=tf.float32, name="weight1")
# OK when W1 = tf.constant(0.)
W2 = tf.Variable([rng.randn()], dtype=tf.float32, name="weight2")
b = tf.Variable([rng.randn()], dtype=tf.float32, name="bias")
# Model input and output
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
linear_model = W1*tf.square(x) + W2*x + b
# loss
loss = tf.reduce_sum(tf.square(linear_model - y))/(2*n_samples)
# optimizer
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
train = optimizer.minimize(loss)
# training loop
init = tf.global_variables_initializer()
# Start training
with tf.Session() as sess:
sess.run(init) # reset values to wrong
for i in range(training_epochs):
sess.run(train, {x: train_X, y: train_Y})
# evaluate training accuracy
curr_W1, curr_W2, curr_b, curr_loss = sess.run([W1, W2, b, loss], {x: train_X, y: train_Y})
print("W1: %s W2: %s b: %s loss: %s"%(curr_W1, curr_W2, curr_b, curr_loss))
# Graphic display
plt.plot(train_X, train_Y, 'ro', label='Original data')
plt.plot(train_X, sess.run(W1) * numpy.square(train_X) + sess.run(W2) * train_X + sess.run(b), label='Fitted line')
plt.legend()
plt.show()
答案 0 :(得分:1)
简短回答:你的学习率太高了。使用更小的东西(~0.0001)并使用更多的纪元(~2000000)。
答案很长:W1是NaN,因为在训练期间,它的大小越来越大,直到我们得到导致NaN的数值问题。您可以通过将W1添加到传递给sess.run()
的获取列表中来观察它。
此外,你可以看到它的标志不断变化,这是超调的标志(没有双关语意)。实际上,如果您将错误linear_model - y
添加到获取列表中,那么您的标志也会不断变化。当你的学习率太高时就会发生这种情况。
在玩了不同的学习率(并用更多的纪元补偿)之后,我得到了以下内容:
当W1固定为0时: W1:0.0 W2:[4.70993948] b:[2539.71435547]损失:237.369 这将是我们的基准。
learning_rate = 0.001:
还是NaN。
learning_rate = 0.0001
training_epochs = 200000
W1:[ - -2.63166738] W2:[50.53411484] b:[2375.20996094]损失:2317.36
learning_rate = 0.0001
training_epochs = 2000000
W1:[ - 0.3543286] W2:[8.49937725] b:[2541.46655273]损失:189.766
所以最后一个可能是你想要的,因为它的损失与基线相当。但是,您应该尝试并找到最佳值。
答案 1 :(得分:1)
b
的影响相形见绌。
解决这个问题的一个好方法是重新调整数据。如果包含行
W1
那么你的数据将具有0的均值和1的范围,并且使用任一模型训练将更容易。请注意,如果您想在新数据点上测试训练模型,则需要将它们按相同的数量进行缩放。