Python ValueError:没有为任何变量提供梯度-Keras Tensorflow 2.0

Python ValueError:没有为任何变量提供梯度-Keras Tensorflow 2.0,python,tensorflow,tensorflow2.0,tf.keras,Python,Tensorflow,Tensorflow2.0,Tf.keras,我正试图跟踪TensorFlow网站,但它不起作用 这是我的密码: import tensorflow as tf def vectorize(vector_like): return tf.convert_to_tensor(vector_like) def batchify(vector): '''Make a batch out of a single example''' return vectorize([vector]) data = [(batchif

我正试图跟踪TensorFlow网站,但它不起作用

这是我的密码:

import tensorflow as tf

def vectorize(vector_like):
    return tf.convert_to_tensor(vector_like)

def batchify(vector):
    '''Make a batch out of a single example'''
    return vectorize([vector])

data = [(batchify([0]), batchify([0, 0, 0])), (batchify([1]), batchify([0, 0, 0])), (batchify([2]), batchify([0, 0, 0]))]
num_hidden = 5
num_classes = 3

opt = tf.keras.optimizers.SGD(learning_rate=0.1)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(num_hidden, activation='relu'))
model.add(tf.keras.layers.Dense(num_classes, activation='sigmoid'))
loss_fn = lambda: tf.keras.backend.cast(tf.keras.losses.mse(model(input), output), tf.float32)
var_list_fn = lambda: model.trainable_weights
for input, output in data:
    opt.minimize(loss_fn, var_list_fn)
有一段时间,我收到了关于丢失函数的错误数据类型(int而不是float)的警告,这就是为什么我将转换添加到丢失函数中

我得到的不是网络培训,而是错误:

ValueError:没有为任何变量提供渐变: ['sequential/dense/kernel:0','sequential/dense/bias:0', '顺序/密集_1/内核:0','顺序/密集_1/偏差:0']


为什么梯度没有通过?我做错了什么?

如果要在TF2中操作梯度,需要使用
梯度带。例如,下面的工作


opt = tf.keras.optimizers.SGD(learning_rate=0.1)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(num_hidden, activation='relu'))
model.add(tf.keras.layers.Dense(num_classes, activation='sigmoid'))

with tf.GradientTape() as tape:
  loss = tf.keras.backend.mean(tf.keras.losses.mse(model(input),tf.cast(output, tf.float32)))

gradients = tape.gradient(loss, model.trainable_variables)
opt.apply_gradients(zip(gradients, model.trainable_variables))
编辑

通过执行以下更改,您实际上可以使您的示例正常工作

  • 仅对输出使用cast,而不是完整的
    损失fn
    (注意,在优化w.r.t损失平均值时,我也在做
    平均值
所谓“工作”,我的意思是它不会抱怨。但您需要进一步调查,以确保它按预期工作

loss_fn = lambda: tf.keras.backend.mean(tf.keras.losses.mse(model(input), tf.cast(output, tf.float32)))
var_list_fn = lambda: model.trainable_weights

opt.minimize(loss_fn, var_list_fn)

如果要在TF2中操作渐变,则需要使用
GradientTape
。例如,下面的工作


opt = tf.keras.optimizers.SGD(learning_rate=0.1)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(num_hidden, activation='relu'))
model.add(tf.keras.layers.Dense(num_classes, activation='sigmoid'))

with tf.GradientTape() as tape:
  loss = tf.keras.backend.mean(tf.keras.losses.mse(model(input),tf.cast(output, tf.float32)))

gradients = tape.gradient(loss, model.trainable_variables)
opt.apply_gradients(zip(gradients, model.trainable_variables))
编辑

通过执行以下更改,您实际上可以使您的示例正常工作

  • 仅对输出使用cast,而不是完整的
    损失fn
    (注意,在优化w.r.t损失平均值时,我也在做
    平均值
所谓“工作”,我的意思是它不会抱怨。但您需要进一步调查,以确保它按预期工作

loss_fn = lambda: tf.keras.backend.mean(tf.keras.losses.mse(model(input), tf.cast(output, tf.float32)))
var_list_fn = lambda: model.trainable_weights

opt.minimize(loss_fn, var_list_fn)

谢谢你的帮助!如果有必要,为什么不使用
GradientTape
?这很可能是一个bug。但不幸的是,我不知道确切的答案。@ProQ认为我发现了一些有用的东西。编辑了我的答案。看起来为了做出预测,我还需要数据是一个浮点数。因此,将
vectorize
函数更改为
tf.convert\u to\u tensor(类似向量,dtype=tf.float32)
修复了所有问题。谢谢你的洞察力!很高兴听到这个消息!谢谢你的帮助!如果有必要,为什么不使用
GradientTape
?这很可能是一个bug。但不幸的是,我不知道确切的答案。@ProQ认为我发现了一些有用的东西。编辑了我的答案。看起来为了做出预测,我还需要数据是一个浮点数。因此,将
vectorize
函数更改为
tf.convert\u to\u tensor(类似向量,dtype=tf.float32)
修复了所有问题。谢谢你的洞察力!很高兴听到这个消息!