【问题标题】:Correct way to apply gradients in TF2 custom training loop with multiple Keras models在具有多个 Keras 模型的 TF2 自定义训练循环中应用梯度的正确方法
【发布时间】:2020-02-25 13:09:29
【问题描述】:

我正在使用 GradientTape 实现一个涉及多个 Keras 模型的自定义训练循环。 我有 3 个网络,model_a、model_b 和 model_c。我创建了一个列表来保存他们的trainbale_weights:

trainables = list() 
trainables.append(model_a.trainable_weights) # CovNet 
trainables.append(model_b.trainable_weights) # CovNet 
trainables.append(model_c.trainable_weights) # Fully Connected Network

然后我计算损失并尝试将梯度应用为:

loss = 0.
optimizer = tf.keras.optimizers.Adam()
for _, (x, y) in enumerate(train_dataset):
   with tf.GradientTape() as tape:
     y = ...
     loss = ... # custom loss function!
gradients = tape.gradient(loss, trainables)
optimizer.apply_gradients(zip(gradients, trainables))    

但我收到以下错误,我不确定错误在哪里:

AttributeError: 'list' object has no attribute '_in_graph_mode'

如果我迭代渐变和可训练对象,然后应用渐变,它会起作用,但我不确定这是否是正确的方法。

for i in range(len(gradients)):
   optimizer.apply_gradients(zip(gradients[i], trainables[i]))

【问题讨论】:

  • 问题在于tape.gradient 期望trainables 是可训练变量的平面列表。 trainables = model_a.trainable_weights + model_b.trainable_weights + model_c.trainable_weights 解决问题了吗?
  • 不。它会抛出 ValueError: too many values to unpack (expected 2) 错误。
  • 这到底发生在哪里?恐怕这可能是另一个问题
  • 调用“optimizer.apply_gradients”时
  • trainables = model_a.trainable_weights + model_b.trainable_weights + model_c.trainable_weights,解决了这个问题。 @rvinas。我之前认为我错过了一些东西。

标签: tensorflow keras python-3.6 tensorflow2.0


【解决方案1】:

问题在于tape.gradient 期望trainables 是可训练变量的平面列表,而不是列表列表。您可以通过将所有可训练的权重连接到一个平面列表中来解决此问题:

trainables = model_a.trainable_weights + model_b.trainable_weights + model_c.trainable_weights

【讨论】:

    猜你喜欢
    • 2021-05-15
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2021-10-02
    相关资源
    最近更新 更多