假設我有一個簡單的神經網路:
import torch
import torch.nn as nn
import torch.optim as optim
from torch.nn.utils import parameters_to_vector
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.fc1 = nn.Linear(1, 2)
self.fc2 = nn.Linear(2, 3)
self.fc3 = nn.Linear(3, 1)
def forward(self, x):
x = self.fc1(x)
x = torch.relu(x)
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x
net = Model()
opt = optim.Adam(net.parameters())
還有一些特點
features = torch.rand((3,1))
我可以使用以下方法正常訓練它:
for i in range(10):
opt.zero_grad()
out = net(features)
loss = torch.mean(torch.square(torch.tensor(5) - torch.sum(out)))
loss.backward()
opt.step()
但是,我有興趣在批處理中的每個示例之后更新每層的權重。也就是說,將實際權重值更新為每層不同的某個量。
我可以列印每一層的引數:
for i in range(1):
opt.zero_grad()
out = net(features)
print(parameters_to_vector(net.fc1.parameters()))
print(parameters_to_vector(net.fc2.parameters()))
print(parameters_to_vector(net.fc3.parameters()))
loss = torch.mean(torch.square(torch.tensor(5) - torch.sum(out)))
loss.backward()
opt.step()
如何在不影響梯度的情況下更改反向傳播之前的權重值?
假設我希望根據以下功能更新圖層權重:
def first_layer_update(weight):
return weight 1e-3*weight
def second_layer_update(weight):
return 1e-2*weight
def third_layer_update(weight):
return weight - 1e-1*weight
uj5u.com熱心網友回復:
- 使用torch.no_grad背景關系管理器。
這允許您對張量執行(就地或非就地)操作,而無需 Autograd 跟蹤這些更改。正如@user3474165 所解釋的:
def first_layer_update(weight):
with torch.no_grad():
return weight 1e-3*weight
def second_layer_update(weight):
with torch_no_grad():
return 1e-2*weight
def third_layer_update(weight):
with torch.no_grad():
return weight - 1e-1*weight
或者在呼叫它們時不使用背景關系管理器更改函式的情況不同:
with torch.no_grad():
first_layer_update(net.fc1.weight)
second_layer_update(net.fc2.weight)
third_layer_update(net.fc3.weight)
- 使用@torch.no_grad裝飾器。
一個變體是使用@torch.no_grad裝飾器:
@torch.no_grad()
def first_layer_update(weight):
return weight 1e-3*weight
@torch.no_grad():
def second_layer_update(weight):
return 1e-2*weight
@torch.no_grad():
def third_layer_update(weight):
return weight - 1e-1*weight
并與呼叫這些:first_layer_update(net.fc1.weight),second_layer_update(net.fc2.weight),等...
- 變異torch.Tensor.data。
使用torch.no_grad背景關系包裝您的操作的另一種方法是使用它們的data屬性來改變權重。這意味著呼叫您的函式:
>>> first_layer_update(net.fc1.weight.data)
>>> second_layer_update(net.fc2.weight.data)
>>> third_layer_update(net.fc3.weight.data)
這將使用各自的更新策略改變三層的權重(而不是偏差)。
簡而言之,如果你想改變 a 的所有引數,nn.Module你可以這樣做:
>>> with torch.no_grad():
... update_policy(parameters_to_vector(net.layer.parameters()))
或者
>>> update_policy(parameters_to_vector(net.layer.parameters().data))
uj5u.com熱心網友回復:
從 pytorch docs,您基本上走在正確的軌道上。可以回圈遍歷每一層中的所有引數,然后直接添加到它們中
with torch.no_grad():
for param in layer.parameters():
param.weight = 1e-3 # or whatever
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/339246.html
