我正在Pytorch中实现一个三元组网络,其中3个实例(子网络)具有相同的权重。由于权重是共享的,因此我将其实现为单个实例网络,该网络被调用三次以生成锚点,正嵌入和负嵌入。通过优化triplet loss来学习嵌入。这是一个用于说明的小片段:
from dependencies import *
model = SingleSubNet() # represents each instance in the triplet net
for epoch in epochs:
for anch, pos, neg in enumerate(train_loader):
optimizer.zero_grad()
fa, fp, fn = model(anch), model(pos), model(neg)
loss = triplet_loss(fa, fp, fn)
loss.backward()
optimizer.step()
# Do more stuff ...
我的完整代码可以按预期工作。但是,在这种情况下,我不了解loss.backward()
是如何计算梯度的。我很困惑,因为在每个学习步骤中都有3个损耗梯度 (梯度公式are here)。我假设在执行optimizer.step()
之前先对梯度求和。但是从the equations中可以看出,如果对梯度进行求和,它们将相互抵消并产生零更新项。当然,事实并非如此,因为网络最终会学习有意义的嵌入。
预先感谢