使用内置的优化器优化功能

时间:2020-01-27 22:55:40

标签: python tensorflow2.0

我正在尝试从此处https://github.com/tensorflow/docs/blob/master/site/en/tutorials/generative/deepdream.ipynb

修改代码

以便我可以运行任何任意的优化器,而不仅仅是像在其代码的梯度上升部分中那样实现梯度下降。

这是相关代码的原始版本:

class DeepDream(tf.Module):
   def __init__(self, model):
   self.model = model

 @tf.function(
  input_signature=(
    tf.TensorSpec(shape=[None,None,3], dtype=tf.float32),
    tf.TensorSpec(shape=[], dtype=tf.int32),
    tf.TensorSpec(shape=[], dtype=tf.float32),)
 )
 def __call__(self, img, steps, step_size):
  print("Tracing")

  loss = tf.constant(0.0)
  for n in tf.range(steps):
    with tf.GradientTape() as tape:
      # This needs gradients relative to `img`
      # `GradientTape` only watches `tf.Variable`s by default
      tape.watch(img)
      loss = calc_loss(img, self.model)

    # Calculate the gradient of the loss with respect to the pixels of the input image.
    gradients = tape.gradient(loss, img)

    # Normalize the gradients.
    gradients /= tf.math.reduce_std(gradients) + 1e-8 

    # In gradient ascent, the "loss" is maximized so that the input image increasingly "excites" the layers.
    # You can update the image by directly adding the gradients (because they're the same shape!)
    img = img + gradients*step_size
    img = tf.clip_by_value(img, -1, 1)

  return loss, img

我尝试将其更改为此:

class DeepDream(tf.Module):
   def __init__(self, model):
   self.model = model

 @tf.function(
  input_signature=(
    tf.TensorSpec(shape=[None,None,3], dtype=tf.float32),
    tf.TensorSpec(shape=[], dtype=tf.int32),
    tf.TensorSpec(shape=[], dtype=tf.float32),)
 )
 def __call__(self, img, steps, step_size):
  print("Tracing")
  opt=tf.optimizers.SGD(step_size)
  loss = tf.constant(0.0)
  for n in tf.range(steps):
    with tf.GradientTape() as tape:
      # This needs gradients relative to `img`
      # `GradientTape` only watches `tf.Variable`s by default
      tape.watch(img)
      loss = calc_loss(img, self.model)

    # Calculate the gradient of the loss with respect to the pixels of the input image.
    gradients = tape.gradient(loss, img)

    # Normalize the gradients.
    gradients /= tf.math.reduce_std(gradients) + 1e-8 

    # In gradient ascent, the "loss" is maximized so that the input image increasingly "excites" the layers.
    # You can update the image by directly adding the gradients (because they're the same shape!)
    # img = img + gradients*step_size
    opt.apply_gradients(zip([gradients],[img]))
    img = tf.clip_by_value(img, -1, 1)

  return loss, img

进行此更改时,出现以下错误:

NotImplementedError :(“尝试更新张量”,)

我知道img需要一个tf.Variable实例。但是,我尝试了多种方法来执行此操作,例如,将img初始化为函数外部的tf.Variable,但似乎无济于事。

执行此操作的正确方法是什么?

0 个答案:

没有答案