2 参数管理
- 访问参数,用于调试、诊断和可视化
- 参数初始化
- 在不同模型组件间共享参数
1 | '''单隐藏层的多层感知机''' |
tensor([[0.2326],
[0.2463]], grad_fn=<AddmmBackward0>)
2.1 参数访问
- 对于Sequential类模型,通过索引访问参数
1 | print(net[2].state_dict()) |
OrderedDict([('weight', tensor([[ 0.0830, -0.2212, -0.3532, 0.2318, 0.2688, -0.1233, -0.2256, -0.1163]])), ('bias', tensor([0.1769]))])
2.1.1 目标参数
- 提取第三层的偏置
1 | param = net[2].bias |
Parameter containing:
tensor([0.1769], requires_grad=True)
<class 'torch.nn.parameter.Parameter'>
tensor([0.1769])
- 参数是复合对象,包含值、梯度和额外信息
1 | # 访问每个参数的梯度 |
True
- 访问所有参数
1 | # 访问第一个全连接层的参数 |
('weight', torch.Size([8, 4])) ('bias', torch.Size([8]))
('0.weight', torch.Size([8, 4])) ('0.bias', torch.Size([8])) ('2.weight', torch.Size([1, 8])) ('2.bias', torch.Size([1]))
tensor([0.1769])
- 从嵌套块收集参数
1 | def block1(): |
tensor([[-0.2233],
[-0.2233]], grad_fn=<AddmmBackward0>)
Sequential(
(0): Sequential(
(block0): Sequential(
(0): Linear(in_features=4, out_features=8, bias=True)
(1): ReLU()
(2): Linear(in_features=8, out_features=4, bias=True)
(3): ReLU()
)
(block1): Sequential(
(0): Linear(in_features=4, out_features=8, bias=True)
(1): ReLU()
(2): Linear(in_features=8, out_features=4, bias=True)
(3): ReLU()
)
(block2): Sequential(
(0): Linear(in_features=4, out_features=8, bias=True)
(1): ReLU()
(2): Linear(in_features=8, out_features=4, bias=True)
(3): ReLU()
)
(block3): Sequential(
(0): Linear(in_features=4, out_features=8, bias=True)
(1): ReLU()
(2): Linear(in_features=8, out_features=4, bias=True)
(3): ReLU()
)
)
(1): Linear(in_features=4, out_features=1, bias=True)
)
tensor([ 0.4794, 0.4585, 0.0098, 0.1719, -0.2016, -0.3174, -0.4974, 0.4953])
2.2 参数初始化
- 默认情况下,pytorch会根据一个均匀地初始化权重和偏置
- pytorch的nn.init模块提供了多种初始化方法
2.2.1 内置初始化
- 权重初始化标准差为0.01的高斯随机变量,偏置设置为0
1 | def init_normal(m): |
tensor([ 0.0058, -0.0130, -0.0114, 0.0044]) tensor(0.)
- 初始化为常熟
1 | def init_constant(m): |
tensor([1., 1., 1., 1.]) tensor(0.)
- 不同块使用不同初始化方法:用Xavier初始化方法初始化第一层,第三层初始化为常熟42
1 | def init_xavier(m): |
tensor([ 0.2578, -0.6072, -0.2665, 0.4973])
tensor([[42., 42., 42., 42., 42., 42., 42., 42.]])
2.2.2 自定义初始化
$$ \omega = \begin{cases} U(5,10) &可能性 \frac{1}{4} \ 0 &可能性 \frac{1}{2} \ U(-10,-5) &可能性 \frac{1}{4} \ \end{cases} $$
1 | def my_init(m): |
Init weight torch.Size([8, 4])
Init weight torch.Size([1, 8])
tensor([[ 8.4257, 0.0000, -7.9400, -0.0000],
[ 0.0000, 8.8472, 5.5845, -0.0000]], grad_fn=<SliceBackward0>)
tensor([42.0000, 1.0000, -6.9400, 1.0000])
2.3 参数绑定
- 有时我们希望在多个层之间共享参数
1 | # 定义一个共享层 |
tensor([True, True, True, True, True, True, True, True])
tensor([True, True, True, True, True, True, True, True])
- 当参数绑定时,梯度会发生什么情况:由于模型参数包含梯度,因此在反向传播期间第二个隐藏层(net[2])和第三个隐藏层(net[5])的梯度会加在一起