优化器。apply_gradients在tf.function中创建变量
我已经通过急切的执行创建了神经风格的转移,但是当我尝试将其变成tf.function时,它行不通。 错误消息说:
ValueError: tf.function only supports singleton tf.Variables created on the first call. Make sure the tf.Variable is only created once or created outside tf.function. See https://www.tensorflow.org/guide/function#creating_tfvariables for more information.
但是,该函数内部没有创建变量。这是代码的简化版本,它只是一个带有一个图像的神经样式传输(目标是使生成的图像看起来完全像内容图像):
import tensorflow as tf
import numpy as np
from PIL import Image
#Get and process the images
image = np.array(Image.open("frame7766.jpg")).reshape(1, 720, 1280, 3)/255
content_image = tf.convert_to_tensor(image, dtype = tf.float32)
# variable is defined outside of tf.function
generated_image = tf.Variable(np.random.rand(1, 720, 1280, 3)/2 + content_image/2, dtype = tf.float32)
def clip_0_1(image): # keeps image values between 0 and 1
return tf.clip_by_value(image, clip_value_min=0, clip_value_max=1)
@ tf.function
def train_step(generated_image, content_image): #turn generated image into tf variable
optimizer = tf.keras.optimizers.Adam(learning_rate = 0.01)
with tf.GradientTape() as tape:
cost = tf.reduce_sum(tf.square(generated_image - content_image))
grad = tape.gradient(cost, generated_image)
optimizer.apply_gradients([(grad, generated_image)]) # More information below
generated_image.assign(clip_0_1(generated_image))
return generated_image
generated_image = train_step(generated_image, content_image)
错误消息指向
optimizer.apply_gradients([(grad, generated_image)])
我试图更改输入的 行Optimizer.Apply_gradients
to zip([Grad],[Generated_image])
,以及我能想到的列表和元组的每个组合,但错误仍然存在。我还浏览了 https://wwwww.tensorflow.org/guide/guide/guide/function/function#creating_tfvariables 和 https:> https://wwwww.tensorflow.org/api_org/api_org/api_docs/pypy/pypy/pypypypytyononon /tf/keras/optimizers/optimizer ,但它们都没有显示未明确定义变量的示例。 我可以得出的唯一结论是,我的命令之一(最有可能emptimizer.apply_gradients
)创建了一个变量,因为我较早的代码中存在问题。那是对的吗?
I have created a neural style transfer with Eager Execution, but it does not work when I try to turn it into a tf.function.
The error message says:
ValueError: tf.function only supports singleton tf.Variables created on the first call. Make sure the tf.Variable is only created once or created outside tf.function. See https://www.tensorflow.org/guide/function#creating_tfvariables for more information.
However, no variable is being created inside the function. Here is a simplified version of the code, which is just a neural style transfer with one image (the goal is to make the generated image look exactly like the content image):
import tensorflow as tf
import numpy as np
from PIL import Image
#Get and process the images
image = np.array(Image.open("frame7766.jpg")).reshape(1, 720, 1280, 3)/255
content_image = tf.convert_to_tensor(image, dtype = tf.float32)
# variable is defined outside of tf.function
generated_image = tf.Variable(np.random.rand(1, 720, 1280, 3)/2 + content_image/2, dtype = tf.float32)
def clip_0_1(image): # keeps image values between 0 and 1
return tf.clip_by_value(image, clip_value_min=0, clip_value_max=1)
@ tf.function
def train_step(generated_image, content_image): #turn generated image into tf variable
optimizer = tf.keras.optimizers.Adam(learning_rate = 0.01)
with tf.GradientTape() as tape:
cost = tf.reduce_sum(tf.square(generated_image - content_image))
grad = tape.gradient(cost, generated_image)
optimizer.apply_gradients([(grad, generated_image)]) # More information below
generated_image.assign(clip_0_1(generated_image))
return generated_image
generated_image = train_step(generated_image, content_image)
The error message points to the line
optimizer.apply_gradients([(grad, generated_image)])
I have tried to change the input of optimizer.apply_gradients
to zip([grad], [generated_image])
, and every combination of lists and tuples I can think of, but the error still remains. I have also looked through https://www.tensorflow.org/guide/function#creating_tfvariables and https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/Optimizer, but neither of them shows examples where the variable is not explicitly defined.
The only conclusion that I can come to is that one of my commands (most likely optimizer.apply_gradients
) creates a variable because of an issue in my earlier code. Is that correct?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于
adam
创建了其他变量来存储模型变量的动量项。通过在每个培训步骤中创建新的优化器,这些变量也会重新创建,从而导致错误消息。请注意,在没有tf功能的情况下执行此操作也是一个坏主意(这不会丢下错误),这正是因为动量项将在每个步骤重新定位,而不是按应有的方式正确积累。这就是为什么您应该在培训开始时一次在训练步骤之外创建优化器的原因。
The problem is that
Adam
creates additional variables to store the momentum terms for the model variables. By creating a new optimizer every training step, these variables are also re-created, resulting in the error message.Note that it would also be a bad idea to do this without tf.function (which would not throw an error), precisely because the momentum terms would be re-initialized at every step, instead of being accumulated properly as they should be. This is why you should create the optimizer outside the training step, one time, at the beginning of training.