【问题标题】:ValueError: No gradients provided for any variable - Keras Tensorflow 2.0ValueError:没有为任何变量提供渐变 - Keras Tensorflow 2.0
【发布时间】:2020-04-26 11:23:05
【问题描述】:

我正在尝试在 TensorFlow 网站上关注 this example,但它不起作用。

这是我的代码:

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', 'sequential/dense_1/kernel:0', 'sequential/dense_1/bias:0'].

为什么没有通过渐变?我做错了什么?

【问题讨论】:

    标签: python tensorflow tensorflow2.0 tf.keras


    【解决方案1】:

    如果您想在 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 用于输出而不是完整的 loss_fn(注意我也在做 mean,因为我们优化了 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)
    

    【讨论】:

    • 感谢您的帮助!如果有必要,the example 为什么不用GradientTape
    • 这很可能是一个错误。但不幸的是,我不知道确切的答案。
    • @ProQ 我发现了一些有用的东西。编辑了我的答案。
    • 看起来为了进行预测,我还需要将数据设为 float32。因此,将 vectorize 函数更改为 tf.convert_to_tensor(vector_like, dtype=tf.float32) 修复了所有问题。感谢您的洞察力!
    • 很高兴听到这个消息!
    猜你喜欢
    • 1970-01-01
    • 2016-10-19
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    相关资源
    最近更新 更多