Эта топика c обсуждалась несколько раз, но мой вопрос действительно относится к конкретному c контексту, где я хочу реорганизовать код так, чтобы я вычислял потери отдельно, а затем применял градиенты. Это кажется тривиальной задачей, поэтому я запутался в ошибке.
Давайте обратимся к учебнику publi c, в данном случае CVAE - https://www.tensorflow.org/tutorials/generative/cvae
Вместо использования (которое прекрасно работает в колабе)
def compute_apply_gradients(model, x, optimizer):
with tf.GradientTape() as tape:
loss = compute_loss(model, x)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
...
for epoch in range(1, epochs + 1):
for train_x in train_dataset:
compute_apply_gradients(model, train_x, optimizer)
...
, если я рефакторинг на
def apply_grad(loss, model, optimizer):
with tf.GradientTape() as tape:
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
...
for epoch in range(1, epochs + 1):
for train_x in train_dataset:
loss = compute_loss(model, train_x)
apply_grad(loss, model, optimizer)
...
, я получу ошибку
ValueError: No gradients provided for any variable: ['conv2d/kernel:0', 'conv2d/bias:0', 'conv2d_1/kernel:0', 'conv2d_1/bias:0', 'dense/kernel:0', 'dense/bias:0', 'dense_1/kernel:0', 'dense_1/bias:0', 'conv2d_transpose/kernel:0', 'conv2d_transpose/bias:0', 'conv2d_transpose_1/kernel:0', 'conv2d_transpose_1/bias:0', 'conv2d_transpose_2/kernel:0', 'conv2d_transpose_2/bias:0'].
Единственное отличие, кажется чтобы быть более влажными, мы вычисляем потери в рамках GradientTape, который сам по себе не включает GradientTape. Более того, официальный учебник (первый блок кода) использовал tape
вне области видимости, что также очень смущает меня.
Может ли кто-нибудь просветить меня по этому вопросу? Спасибо!