loss.backward() 是否意味着在每个样本或每个批次上调用?

社会演员多 pytorch 425

原文标题Is loss.backward() meant to be called on each sample or on each batch?

我有一个包含不同大小特征的训练数据集。我理解这对网络架构的影响,并相应地设计了我的网络来处理这些异构形状。然而,当谈到我的训练循环时,我对optimizer.zero_grad()loss.backward()optimizer.step()的顺序/放置感到困惑。

由于特征大小不相等,我不能同时对一批特征进行前向传递。因此,我的训练循环手动循环遍历批次样本,如下所示:

for epoch in range(NUM_EPOCHS):
    for bidx, batch in enumerate(train_loader):
        optimizer.zero_grad()
        batch_loss = 0
        for sample in batch:
            feature1 = sample['feature1']
            feature2 = sample['feature2']
            label1 = sample['label1']
            label2 = sample['label2']

            pred_l1, pred_l2 = model(feature1, feature2)

            sample_loss = compute_loss(label1, pred_l1)
            sample_loss += compute_loss(label2, pred_l2)
            sample_loss.backward() # CHOICE 1
            batch_loss += sample_loss.item()
        # batch_loss.backward() # CHOICE 2
        optimizer.step()

我想知道在每个sample_loss上调用backward是否有意义,优化器步骤称为everyBATCH_SIZEsamples(CHOICE 1)。我认为,另一种选择是向后调用batch_loss(选择 2),我不太确定哪个是正确的选择。

原文链接:https://stackoverflow.com//questions/71681430/is-loss-backward-meant-to-be-called-on-each-sample-or-on-each-batch

回复

我来回复
  • flawr的头像
    flawr 评论

    微分是线性运算,因此理论上,您是否首先区分不同的损失并添加它们的导数,或者您是否首先添加损失然后计算它们的总和的导数都无关紧要。

    因此,出于实际目的,它们都应该导致相同的结果(忽略通常的浮点问题)。

    您可能会得到稍微不同的内存要求和计算速度(我猜第二个版本可能会稍微快一些。),但这很难预测,但您可以通过对这两个版本进行计时来轻松找到。

    2年前 0条评论