这是我的简单逻辑回归,包含两个特征和两个类:
tf.reset_default_graph()
x = tf.placeholder(tf.float32, (None, 2))
y = tf.placeholder(tf.int32, (None,))
w = tf.Variable(tf.truncated_normal(shape=(2, 2)))
p = tf.matmul(x, w)
loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(p, y))
train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
此时一切正常。
现在,我的目标是在训练步骤之间修改输出/类的数量。 似乎有一种方法可以修改权重的形状:
n_more = tf.placeholder(tf.int32, ())
w_more = tf.truncated_normal((2, n_more))
new_w = tf.concat(concat_dim=1, values=[w, w_more])
change_w_op = tf.assign(w, new_w, validate_shape=False)
这也有效。我可以运行sess.run(change_w_op, feed_dict={n_more: 2})
再添加两个类,然后继续运行train_op
。
如果我想添加偏见词,问题就出现了:
b = tf.Variable(tf.zeros(shape=(1, 2)))
p = tf.matmul(x, w) + b
# also for adding more
b_more = tf.zeros(shape=(1, n_more))
new_b = tf.concat(concat_dim=1, values=[b, b_more])
change_b_op = tf.assign(b, new_b, validate_shape=False)
如果我在添加更多课程之前运行train_op
- 它可以正常工作。
如果我运行更改操作 - sess.run([change_w_op, change_b_op], feed_dict={n_more: 2})
它们也可以正常工作并且单独检查w和b会显示它们的大小增加。更重要的是,运行sess.run([p, loss], feed_dict={x: ..., y: ...})
也可以运行并返回更多类的预测。
唯一不起作用的是train_op
!
它给出了这个错误(形状中的3对应于传递的x和y值中的示例数):
....
InvalidArgumentError: Incompatible shapes: [3,4] vs. [1,2]
[[Node: gradients/add_grad/BroadcastGradientArgs = BroadcastGradientArgs[T=DT_INT32, _device="/job:localhost/replica:0/task:0/cpu:0"](gradients/add_grad/Shape, gradients/add_grad/Shape_1)]]
从追溯来看,它似乎来自p = tf.matmul(x, w) + b
加法操作,但不知何故与渐变计算有关。好像b项仍然是形状(1,2)而不是(1,4)。虽然单独评估b
会返回形状(1,4)数组。
我在这里做错了什么?为什么更改w
不会导致问题,但更改b
会导致问题。这是一个错误吗?
答案 0 :(得分:0)
训练时不应更改课程数量。如果发生这种情况,您必须为给定的类创建一个新模型并从中重新训练。