【发布时间】:2018-09-01 23:03:31
【问题描述】:
假设我想将 PyTorch(继承自 torch.nn.Module 的类的实例)中神经网络的所有参数乘以 0.9。我该怎么做?
【问题讨论】:
假设我想将 PyTorch(继承自 torch.nn.Module 的类的实例)中神经网络的所有参数乘以 0.9。我该怎么做?
【问题讨论】:
让net 成为神经网络nn.Module 的一个实例。
然后,将所有参数乘以0.9:
state_dict = net.state_dict()
for name, param in state_dict.items():
# Transform the parameter as required.
transformed_param = param * 0.9
# Update the parameter.
param.copy_(transformed_param)
如果您只想更新 权重 而不是每个参数:
state_dict = net.state_dict()
for name, param in state_dict.items():
# Don't update if this is not a weight.
if not "weight" in name:
continue
# Transform the parameter as required.
transformed_param = param * 0.9
# Update the parameter.
param.copy_(transformed_param)
【讨论】:
state_dict 是对大张量(例如 16x512x64x64)的引用的小集合(例如 10)。 * 0.9 操作由通常是“矢量化”的外部 C++ 库运行。从 Python 调用 * 0.9 操作非常便宜(每次调用 1 微秒 * 10 次调用 = 10 微秒),因为 Python 不执行任何实际计算。
param.copy_(transformed_param) 避免再次查找state_dict[name] 吗?我不认为state_dict 会覆盖__setattr__ 无论如何...实际上它只是一个OrderedDict,只有在调用net.state_dict() 时才会创建。
实现此目的的另一种方法是使用tensor.parameters()。
初始化模块:
>>> a = torch.nn.Linear(2, 2)
>>> a.state_dict()
OrderedDict([('weight',
tensor([[-0.1770, -0.2151],
[-0.6543, 0.6637]])),
('bias', tensor([-0.0524, 0.6807]))])
更改参数:
for p in a.parameters():
p.data *= 0
看效果:
>>> a.state_dict()
OrderedDict([('weight',
tensor([[-0., -0.],
[-0., 0.]])),
('bias', tensor([-0., 0.]))])
【讨论】: