如何训练多输出深度学习模型?

How is a multiple-outputs deep learning model trained?

我想我不了解多输出网络。

尽管我了解实现方式并成功训练了这样一个模型,但我不了解多输出深度学习网络是如何训练的。我的意思是,训练期间网络内部发生了什么?

以来自 keras functional api guide 的网络为例:

您可以看到两个输出(aux_output 和 main_output)。反向传播是如何工作的?

我的直觉是该模型进行了两次反向传播,每个输出一次。 每个反向传播然后更新出口前层的权重。 但事实并非如此: 来自 here (SO),我得到的信息是尽管有多个输出,但只有一个反向传播; 使用的损失根据输出加权。

但是,我仍然不明白网络及其辅助分支是如何训练的;辅助分支权重如何更新,因为它没有直接连接到主输出?辅助分支的根和主要输出之间的网络部分是否与损失的权重有关?或者权重只影响连接到辅助输出的网络部分?

另外,我正在寻找关于这个主题的好文章。我已经阅读了 GoogLeNet/Inception 文章 (v1,v2-v3),因为该网络正在使用辅助分支。

Keras 计算是基于图形的,并且只使用一个优化器

优化器也是图的一部分,在它的计算中它得到了整组权重的梯度。 (不是两组梯度,一个用于每个输出,而是一组用于整个模型的梯度)。

从数学上讲,它并不复杂,你有一个最终的损失函数:

loss = (main_weight * main_loss) + (aux_weight * aux_loss) #you choose the weights in model.compile

一切由你定义。加上一系列其他可能的权重(样本权重、class 权重、正则项等)

其中:

  • main_loss 是一个 function_of(main_true_output_data, main_model_output)
  • aux_loss 是一个 function_of(aux_true_output_data, aux_model_output)

并且所有权重的梯度都只是 ∂(loss)/∂(weight_i)

一旦优化器有了梯度,它就会执行一次优化步骤。

问题:

how are the auxiliary branch weights updated as it is not connected directly to the main output?

  • 您有两个输出数据集main_output 的一个数据集和 aux_output 的另一个数据集。您必须将它们传递给 model.fit(inputs, [main_y, aux_y], ...)
  • 中的 fit
  • 您还有两个损失函数,每个损失函数一个,其中 main_lossmain_ymain_out;和aux_loss takex aux_yaux_out
  • 两次损失相加:loss = (main_weight * main_loss) + (aux_weight * aux_loss)
  • 函数loss计算一次梯度,这个函数连接整个模型。
    • aux 项将影响反向传播中的 lstm_1embedding_1
    • 因此,在下一次前向传递中(权重更新后),它将最终影响主分支。 (好坏只看辅助输出有没有用)

Is the part of the network which is between the root of the auxiliary branch and the main output concerned by the the weighting of the loss? Or the weighting influences only the part of the network that is connected to the auxiliary output?

权重是简单的数学运算。您将在 compile:

中定义它们
model.compile(optimizer=one_optimizer, 

              #you choose each loss   
              loss={'main_output':main_loss, 'aux_output':aux_loss},

              #you choose each weight
              loss_weights={'main_output': main_weight, 'aux_output': aux_weight}, 

              metrics = ...)

并且损失函数将在loss = (weight1 * loss1) + (weight2 * loss2)中使用它们。
剩下的就是每个权重的∂(loss)/∂(weight_i)的数学计算。