有兩個模型A和B。模型A為一個城市的所有站點輸出一個自行車部署計劃,模型B將這個計劃作為輸入,并給出每個站點的評價。
現在,模型B已被預訓練,我想使用模型B給出的評價作為損失來優化模型A的引數。
下面是示例代碼。
A = modelA()
B = modelB()
優化器 = torch.optimation.Adam(A.parameters())
def my_loss(deploy)。
shape = deploy.size()
state = torch.zeros((shape[0], shape[1], 2 shape[1>), dtype=torch.long)
# Notice: this step will copy deploy.
state[:, :, 2:] = torch.reshape(deploy, (shape[0, 1, shape[1])
state[:, :, 0] = torch.range(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)
# 訓練模型A。
for 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()
優化器.step()
但事實上,在訓練程序中,什么都沒有發生,模型A的引數沒有更新。 我也試過
optimizer = torch.optimizer.Adam([{'params': A.引數()}, {'params': B.引數(), 'lr':0}] )
而且也沒有發生什么。
有什么想法嗎?
uj5u.com熱心網友回復:
你沒有更新A的引數的原因是loss,我的my_loss的結果沒有連接到計算圖,即到模型A的輸出。如果你看一下你的實作,這顯然是一種情況:
state = torch.reshape(state_tensors, (-1, 2 shape[1] )
eval = B(state)
eval = torch.reshape(eval, (shape[0], shape[1])
變數state是從state_tensors中定義的,而在你的例子中沒有定義,所以要么是打錯了,要么就是要從state中定義。無論如何,產生的張量my_loss輸出應該有一個grad_fn附加到它。請確保它是這樣的。這里的最后一個操作是一個平均值,所以你必須有類似于:
>>> my_loss(loss)
tensor(0.7742, grad_fn=<MeanBackward0>)
在解決了這個問題之后,你的梯度應該能夠反向傳播到模型A的引數。
uj5u.com熱心網友回復:
計算圖在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) # add requires_grad=True, dtype=torch.long may throw error。
然而,我仍然認為它不會與你的代碼一起作業。 可選的建議;
- 我認為
state_tensors沒有被定義。 - 就地操作
state[:, :, 2:] =可能不好。(在我的例子中,這拋出了錯誤)要復制張量,.expand()或.repeat()。 和擴展dim,.unsqueeze()可能有用,以避免這種情況。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/329658.html
標籤:
