我是TensorFlow的新手,正在尝试创建一个线性回归模型。我的代码是
import numpy as npimport tensorflow as tfbias = np.ones((50, 1))trainX = np.arange(0, 10, 0.2).reshape(50, 1)trainY = (3 * trainX + np.random.rand(trainX.shape[0]) * 20 - 10) + 10trainX = np.append(bias, trainX, axis=1)X = tf.placeholder("float", shape=(1, 2))Y = tf.placeholder("float")w = tf.Variable([[0.0, 0.0]], name="weights")model = tf.matmul(X, tf.transpose(w))cost = tf.pow((Y - model), 2)init = tf.global_variables_initializer()train_op = tf.train.GradientDescentOptimizer(0.01).minimize(cost)with tf.Session() as sess: sess.run(init) for i in range(50): for (x, y) in zip(trainX, trainY): sess.run(train_op, feed_dict={X: x, Y: y}) print(sess.run(w))
我不知道自己做错了什么。我认为问题出在初始化权重上。我的想法很简单,就是预测两个最能拟合数据的权重常数。
回答:
这里有几个因素在起作用。我假设你希望trainY
的形状是(50,)
,但由于你在重塑后才添加噪声,广播导致trainX + np.random.rand(trainX.shape[0])
的形状变为(50, 50)
。如果你将代码的初始部分改为
bias = np.ones(50)trainX = np.arange(0, 10, 0.2)trainY = (3 * trainX + np.random.rand(trainX.shape[0]) * 20 - 10) + 10trainX = np.vstack([bias, trainX]).T
并确保通过
sess.run(train_op, feed_dict={X: x.reshape((1, 2)), Y: y})
正确设置形状,那么你的代码将能够运行。
然而,由于你只处理二维向量的内积,你可以完全避免重塑操作,只需简单地使用tf.tensordot
即可:
X = tf.placeholder("float", shape=(2,))Y = tf.placeholder("float")w = tf.Variable([0.0, 0.0], name="weights")model = tf.tensordot(X, w, 1)
最后,请注意,虽然在将样本分成小批次后传递给优化器(通常称为批处理)的方法在大数据集上效果很好,但在你的情况下,你也可以一次性传递整个样本;也就是说,类似于
X = tf.placeholder("float", shape=(50, 2))Y = tf.placeholder("float", shape=(50, 1))w = tf.Variable(tf.zeros([2, 1], "float"), name="weights")model = tf.matmul(X, w)cost = tf.reduce_sum(tf.pow((Y - model), 2))init = tf.global_variables_initializer()train_op = tf.train.GradientDescentOptimizer(0.0001).minimize(cost)with tf.Session() as sess: sess.run(init) for i in range(10000): sess.run(train_op, feed_dict={X: trainX, Y: trainY.reshape((50, 1))})