我有以下代码
pred_raw = create_feedforward_nn_model(x, weights, biases)
pred = tf.round(tf.nn.sigmoid(pred_raw))
cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=pred, logits=y))
train_op = tf.train.AdamOptimizer(learning_rate).minimize(cost)
在这里,create_feedforward_nn_model 只是创建一个 2 层前馈 DNN 并返回最后一层(即 logits)。所以,当我运行这段代码时,出现以下错误,
ValueError: No gradients provided for any variable, check your graph for ops that do not support gradients, between variables
["<tf.Variable 'Variable:0' shape=(28, 20) dtype=float32_ref>", "<tf.Variable 'Variable_1:0' shape=(20, 8) dtype=float32_ref>", "<tf.Variable 'Variable_2:0' shape=(8, 1) dtype=float32_ref>", "<tf.Variable 'Variable_3:0' shape=(20,) dtype=float32_ref>", "<tf.Variable 'Variable_4:0' shape=(8,) dtype=float32_ref>", "<tf.Variable 'Variable_5:0' shape=(1,) dtype=float32_ref>"]
and loss Tensor("Mean_8:0", shape=(), dtype=float32).
所以,我试了一下,发现 tf.round 导致了这个问题,因为当我运行它时,更改了以下行
pred = tf.round(tf.nn.sigmoid(pred_raw))
到
pred = tf.nn.sigmoid(pred_raw)
它工作正常。
tf.round 不应该也支持渐变吗?我在这里遗漏了什么吗?
我正在使用 Tensorflow 1.4 版
请您参考如下方法:
round 没有梯度,因为该函数是分段常数且不连续的。也就是说,对于结果相同的任何范围(例如范围 (0.5, 1.5)),梯度将为 0,并且在边界值(0.5、1.5 等)处未定义.).在任何情况下,0 的梯度都没有用。
我认为您在代码中混淆了一些东西。在二进制分类中,您确实希望在末尾有类输出(即 0 或 1),但对于训练,您通常希望使用连续概率。也就是说,sigmoid 输出没有四舍五入。除此之外,内置的 Tensorflow 交叉熵损失实际上在内部应用 sigmoid 并期望 pre-sigmoid 值(logits),这有点像它们的名字所暗示的(例如 tf .nn.sigmoid_cross_entropy_with_logits)。因此,在您的代码段中,您应该将 logits = pred_raw 传递给损失。
顺便说一句,您还混淆了 labels 和 logits -- logits 是您的模型输出,labels 是真实的标签。
