【问题标题】:tf.keras GradientTape: get gradient with respect to inputtf.keras GradientTape:获取相对于输入的梯度
【发布时间】:2020-02-09 17:15:48
【问题描述】:

Tensorflow 版本:Tensorflow 2.1

我想获得相对于输入的梯度,而不是相对于可训练权重的梯度。我将示例从https://www.tensorflow.org/guide/keras/train_and_evaluate 调整为

import tensorflow as tf
import numpy as np

physical_devices = tf.config.experimental.list_physical_devices('GPU')
assert len(physical_devices) > 0, 'Not enough GPU hardware devices available'
tf.config.experimental.set_memory_growth(physical_devices[0], True)

def loss_fun(y_true, y_pred):
    loss = tf.reduce_mean(tf.square(y_true - y_pred), axis=-1)
    return loss

# Create a dataset
x = np.random.rand(10, 180, 320, 3).astype(np.float32)
y = np.random.rand(10, 1).astype(np.float32)
dataset = tf.data.Dataset.from_tensor_slices((x, y)).batch(1)

# Create a model
base_model = tf.keras.applications.MobileNet(input_shape=(180, 320, 3), weights=None, include_top=False)
x = tf.keras.layers.GlobalAveragePooling2D()(base_model.output)
output = tf.keras.layers.Dense(1)(x)
model = tf.keras.models.Model(inputs=base_model.input, outputs=output)

for input, target in dataset:

    for iteration in range(400):
        with tf.GradientTape() as tape:
            # Run the forward pass of the layer.
            # The operations that the layer applies
            # to its inputs are going to be recorded
            # on the GradientTape.
            prediction = model(input, training=False)  # Logits for this minibatch

            # Compute the loss value for this minibatch.
            loss_value = loss_fun(target, prediction)

        # Use the gradient tape to automatically retrieve
        # the gradients of the trainable variables with respect to the loss.
        grads = tape.gradient(loss_value, model.inputs)
        print(grads)  # output: [None]
        # Run one step of gradient descent by updating
        # the value of the variables to minimize the loss.
        optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
        optimizer.apply_gradients(zip(grads, model.inputs))

        print('Iteration {}'.format(iteration))

但是,这不起作用,因为 grads = tape.gradient(loss_value, model.inputs) 返回 [None]。这是预期的行为吗?如果是,推荐的获取输入梯度的方法是什么?

【问题讨论】:

    标签: python tensorflow tf.keras


    【解决方案1】:

    要让它工作,需要添加两件事:

    1. 将图像转换为 tf.Variable
    2. 使用 tape.watch 观察所需变量的梯度

      image = tf.Variable(input)
      for iteration in range(400):
          with tf.GradientTape() as tape:
              tape.watch(image)
              # Run the forward pass of the layer.
              # The operations that the layer applies
              # to its inputs are going to be recorded
              # on the GradientTape.
              prediction = model(image, training=False)  # Logits for this minibatch
      
              # Compute the loss value for this minibatch.
              loss_value = loss_fun(target, prediction)
      
          # Use the gradient tape to automatically retrieve
          # the gradients of the trainable variables with respect to the loss.
          grads = tape.gradient(loss_value, image)
          #print(grads)  # output: [None]
          # Run one step of gradient descent by updating
          # the value of the variables to minimize the loss.
          optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
          optimizer.apply_gradients(zip([grads], [image]))
      
          print('Iteration {}'.format(iteration))
      

    【讨论】:

      猜你喜欢
      • 2019-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多