【问题标题】:How to compute loss of chained models with Keras?如何使用 Keras 计算链式模型的损失?
【发布时间】:2020-11-06 14:32:27
【问题描述】:

为了测试,我将一个模型分成两个模型,我想计算损失并将梯度应用于两个模型,就像它是一个模型一样。

这是我的两个简单模型:

model1 = tf.keras.models.Sequential([
    tf.keras.layers.Dense(10, activation="relu", input_shape=(10,)),
])

model2 = tf.keras.models.Sequential([
    tf.keras.layers.Dense(10, activation="softmax", input_shape=(10,)),
])

然后我通过两个模型运行前向传递,计算第二个模型的损失并应用梯度:

optimizer = tf.keras.optimizers.SGD()
loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True)

x = tf.random.normal((1, 10)) # Input of the 1st model
y = tf.random.normal((1, 10)) # Expected output of the 2nd model

with tf.GradientTape() as tape:
    pred1 = model1(x, training=True)
    pred2 = model2(pred1, training=True)
    loss_value2 = loss(y, pred2) # Compute the loss for the second model prediction

grads = tape.gradient(loss_value2, model2.trainable_variables)
optimizer.apply_gradients(zip(grads, model2.trainable_variables))

但是我如何获得第一个模型和第二个模型的预期输出来计算损失并对其应用梯度?

编辑:

测试的最终目标是拥有两个模型 1,将它们的输出发送到第三个模型。并让每个模型 1 在两个 GPU 上进行训练:

with tf.device('/gpu:0'):
    pred1_1 = model1_1(x, training=True)

with tf.device('/gpu:1'):
    pred1_2 = model1_2(x, training=True)

pred1 = tf.keras.layers.concatenate([pred1_1, pred1_2])

with tf.device('/gpu:0'):
    pred2 = model2(pred1, training=True)

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    @Begoodpy, 我建议你将这 2 个模型组合成一个模型,然后像往常一样训练它。

    supermodel = keras.Sequential(
        [
          model1(),
          model2(),
        ]
    

    如果您需要对模型进行更多控制,请尝试以下操作:

    all_vars = model1.trainable_variables + model2.trainable_variables
    
    grads = tape.gradient(loss_value2, all_vars)
    optimizer.apply_gradients(zip(grads, all_vars))
    

    【讨论】:

    • 谢谢,但我打算将每个模型分别发送到一个 GPU,所以我不能将它们放在一个模型中
    • 有了 2 个 GPU,为什么不将我的答案与 Alexandre Catalano 的另一个答案结合起来呢? TF 将为您在 GPU 之间进行拆分。
    • 因为这些是变通方法,并不能解决我的问题。我有一些限制,比如模型大小无法容纳在一个 GPU 中,组合模型和分布式策略都无济于事。
    • 您可以加入 2 个 var 列表并将其传递给 backprop 函数。我在上面添加了一个示例。
    • 看起来棒极了!和tape.gradient(loss_value2, model1.trainable_variables)tape.gradient(loss_value2, model2.trainable_variables)调用两次不一样吗?
    猜你喜欢
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 2018-07-21
    • 2020-10-08
    • 2016-08-28
    • 1970-01-01
    相关资源
    最近更新 更多