我有一个训练数据集,其中包含不同大小的特征。我理解这在网络体系结构方面的含义,并相应地设计了我的网络来处理这些异构的形状。然而,当谈到我的训练循环时,我对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
上使用名为每个BATCH_SIZE
样本的优化器步骤(选择1)向后调用是否有意义。我认为,另一种选择是向后调用batch_loss
(选择2),而我不太确定哪一个是正确的选择。
发布于 2022-03-30 20:05:24
微分是一种线性运算,所以从理论上讲,不管你是先区分不同的损失,再加上它们的导数,还是先把损失加起来,然后再计算它们的求和导数。
因此,就实际目的而言,两者都应导致相同的结果(不考虑通常的浮点问题)。
您可能会得到稍微不同的内存需求和计算速度(我猜第二个版本可能会稍微快一些),但这是很难预测的,但是您可以很容易地通过对这两个版本进行计时来了解这一点。
https://stackoverflow.com/questions/71681430
复制相似问题