有两个模型A和B。模型A输出一个城市所有站点的自行车部署计划,模型B以这个计划作为输入,并给出每个站点的评估。
现在,模型B已经预训练,我希望使用模型B给出的评估作为损失来优化模型A的参数。
以下是示例代码。
A = modelA()B = modelB()optimizer = torch.optim.Adam(A.parameters())def my_loss(deploy): shape = deploy.size() state = torch.zeros((shape[0], shape[1], 2 + shape[1]), dtype=torch.long) # 注意:这一步会复制deploy state[:, :, 2:] = torch.reshape(deploy, (shape[0], 1, shape[1])) state[:, :, 0] = torch.arange(0, shape[1]) state = torch.reshape(state, (-1, 2 + shape[1])) eval = B(state) eval = torch.reshape(eval, (shape[0], shape[1])) return torch.mean(eval)# 训练模型Afor epoch in range(EPOCHS): for batch_idx, (x, useless_y) in enumerate(dataloader): optimizer.zero_gard() pred = A(x) loss = my_loss(pred) loss.backward() optimizer.step()
但实际上,在训练过程中没有任何变化,模型A的参数没有更新。我也尝试了
optimizer = torch.optim.Adam([{'params': A.parameters()}, {'params': B.parameters(), 'lr':0}])
同样没有任何变化。
有什么建议吗?
回答:
计算图在state
处被切断,因此损失无法反向传播到A。
尝试;
state = torch.zeros((shape[0], shape[1], 2 + shape[1]), dtype=torch.long)->state = torch.zeros((shape[0], shape[1], 2 + shape[1]), requires_grad=True) # 添加requires_grad=True,dtype=torch.long可能会引发错误
然而,我仍然认为您的代码不会生效。其他建议;
- 我认为
state_tensors
没有定义。 - 原地操作
state[:, :, 2:] =
可能不好。(在我这里,这会引发错误)要复制张量,可以使用.expand()
或.repeat()
,要扩展维度,可以使用.unsqueeze()
,这些方法可以避免这个问题。