tensorflow GradientDescentOptimizer:运算输入和计算输入梯度之间的形状不兼容
tensorflow GradientDescentOptimizer: Incompatible shapes between op input and calculated input gradient
模型在优化步骤之前运行良好。然而,当我想优化我的模型时,出现了错误信息:
Incompatible shapes between op input and calculated input gradient.
Forward operation: softmax_cross_entropy_with_logits_sg_12. Input
index: 0. Original input shape: (16, 1). Calculated input gradient
shape: (16, 16)
以下是我的代码。
import tensorflow as tf;
batch_size = 16
size = 400
labels = tf.placeholder(tf.int32, batch_size)
doc_encode = tf.placeholder(tf.float32, [batch_size, size])
W1 = tf.Variable(np.random.rand(size, 100), dtype=tf.float32, name='W1')
b1 = tf.Variable(np.zeros((100)), dtype=tf.float32, name='b1')
W2 = tf.Variable(np.random.rand(100, 1),dtype=tf.float32, name='W2')
b2 = tf.Variable(np.zeros((1)), dtype=tf.float32, name='b2')
D1 = tf.nn.relu(tf.matmul(doc_encode, W1) + b1)
D2 = tf.nn.selu(tf.matmul(D1, W2) + b2)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=D2))
optim = tf.train.GradientDescentOptimizer(0.01).minimize(cost, aggregation_method=tf.AggregationMethod.EXPERIMENTAL_TREE)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
_cost, _optim = sess.run([cost, optim], {labels:np.array([1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1]), doc_encode: np.random.rand(batch_size, size)})
更正以下内容。
首先,
将占位符输入形状更改为此
X = tf.placeholder(tf.int32, shape=[None,400]
Y = tf.placeholder(tf.float32, shape=[None,1]
为什么要 None 因为这让您可以自由喂食任何尺寸。这是首选,因为在训练时你想使用小批量,但在预测或推理时间时,你通常会提供单一的东西。将其标记为 None,即可处理。
其次,
更正您的权重初始化,您输入的是随机值,它们也可能是负值。始终建议使用轻微的正值进行初始化。 (我看到你正在使用 relu 作为激活,负权重值的梯度为零,所以这些权重在梯度下降中永远不会更新,换句话说那些是无用的权重)
第三,
Logits 是您从 W2*x + b2
获得的结果。 tf.nn.softmax_cross.....(..)
自动应用 softmax 激活。所以最后一层不需要SeLu。
模型在优化步骤之前运行良好。然而,当我想优化我的模型时,出现了错误信息:
Incompatible shapes between op input and calculated input gradient. Forward operation: softmax_cross_entropy_with_logits_sg_12. Input index: 0. Original input shape: (16, 1). Calculated input gradient shape: (16, 16)
以下是我的代码。
import tensorflow as tf;
batch_size = 16
size = 400
labels = tf.placeholder(tf.int32, batch_size)
doc_encode = tf.placeholder(tf.float32, [batch_size, size])
W1 = tf.Variable(np.random.rand(size, 100), dtype=tf.float32, name='W1')
b1 = tf.Variable(np.zeros((100)), dtype=tf.float32, name='b1')
W2 = tf.Variable(np.random.rand(100, 1),dtype=tf.float32, name='W2')
b2 = tf.Variable(np.zeros((1)), dtype=tf.float32, name='b2')
D1 = tf.nn.relu(tf.matmul(doc_encode, W1) + b1)
D2 = tf.nn.selu(tf.matmul(D1, W2) + b2)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=D2))
optim = tf.train.GradientDescentOptimizer(0.01).minimize(cost, aggregation_method=tf.AggregationMethod.EXPERIMENTAL_TREE)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
_cost, _optim = sess.run([cost, optim], {labels:np.array([1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1]), doc_encode: np.random.rand(batch_size, size)})
更正以下内容。
首先,
将占位符输入形状更改为此
X = tf.placeholder(tf.int32, shape=[None,400]
Y = tf.placeholder(tf.float32, shape=[None,1]
为什么要 None 因为这让您可以自由喂食任何尺寸。这是首选,因为在训练时你想使用小批量,但在预测或推理时间时,你通常会提供单一的东西。将其标记为 None,即可处理。
其次,
更正您的权重初始化,您输入的是随机值,它们也可能是负值。始终建议使用轻微的正值进行初始化。 (我看到你正在使用 relu 作为激活,负权重值的梯度为零,所以这些权重在梯度下降中永远不会更新,换句话说那些是无用的权重)
第三,
Logits 是您从 W2*x + b2
获得的结果。 tf.nn.softmax_cross.....(..)
自动应用 softmax 激活。所以最后一层不需要SeLu。