动手学深度学习5.2 PyTorch教程 参数管理
因为在训练的过程中,我们的目标就是找到让损失函数最小化的参数值。经过训练之后我们需要将这些参数拿出来做预测,或者在其他地方使用。
所以为了以后方便,我们现在就要摘出来单独讲一下:
访问参数,用于调试、诊断和可视化。
参数初始化。
在不同模型组件间共享参数。
import torch from torch import nn net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1)) X = torch.rand(size=(2, 4)) net(X) 复制代码
这还是简易实现了一个多层感知机,然后弄了一个X做输入。
当通过Sequential
类定义模型时,我们可以通过索引来访问模型的任意层。
print(net) 复制代码
可以看到输出为:
>> Sequential( (0): Linear(in_features=4, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=1, bias=True) ) 复制代码
我们可以通过前边的序号得到想要的层。
print(net[0]) print(net[1]) print(net[2].state_dict()) 复制代码
>> Linear(in_features=4, out_features=8, bias=True) ReLU() OrderedDict([('weight', tensor([[-0.0264, -0.0906, 0.3497, 0.3284, -0.0173, 0.0124, 0.0136, 0.0782]])), ('bias', tensor([0.2243]))]) 复制代码
不出意外,我们看到了前两层是什么。
至于第三个输出,我们可以看到,这个层包含两个参数。
[ ( 'weight', tensor([[-0.0264, -0.0906, 0.3497, 0.3284, -0.0173, 0.0124, 0.0136, 0.0782]]) ), ( 'bias', tensor([0.2243]) ) ] 复制代码
print(type(net[2].bias)) print(type(net[0].weight)) 复制代码
>> <class 'torch.nn.parameter.Parameter'> <class 'torch.nn.parameter.Parameter'> 复制代码
可以看到每个参数都表示为参数(parameter)类的一个实例。
print(net[2].bias) print(net[0].weight) 复制代码
Parameter containing: tensor([-0.1431, 0.1381, -0.2775, 0.0038, -0.0269, 0.0631, -0.1791, 0.1291], requires_grad=True) Parameter containing: tensor([[-0.4736, 0.2223, -0.0059, 0.4146], [-0.1052, 0.2813, -0.2315, 0.2931], [-0.4990, -0.1991, -0.1453, 0.0369], [-0.4676, 0.0669, -0.0069, -0.4932], [-0.4223, 0.0659, -0.3783, -0.1145], [-0.0460, 0.2386, -0.1586, 0.2148], [-0.0085, -0.3642, 0.0265, 0.0487], [ 0.2703, -0.2903, 0.1822, -0.3782]], requires_grad=True) 复制代码
相应的层序号+方法调用,提取网络的偏置或参数。
print(*[(name, param.shape) for name, param in net[0].named_parameters()]) print(*[(name, param.shape) for name, param in net.named_parameters()]) print(*net.named_parameters(),end="\n",sep='\n') # 这里*是一个解包器 ,用于输出列表的每一个元素 复制代码
>> ('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])) ('0.weight', Parameter containing: tensor([[ 0.3700, 0.3270, -0.3741, -0.1365], [ 0.2200, 0.0786, 0.1241, -0.2834], [ 0.3143, 0.3718, 0.3278, 0.0949], [ 0.1565, 0.4639, -0.1515, -0.4962], [ 0.3102, -0.0025, -0.0099, -0.4132], [ 0.1754, -0.1320, -0.3762, -0.1371], [-0.3860, -0.0369, 0.3743, -0.0892], [ 0.0280, -0.2877, -0.1884, 0.2915]], requires_grad=True)) ('0.bias', Parameter containing: tensor([ 0.4722, -0.4143, 0.0858, -0.2280, 0.4349, 0.3954, 0.0971, -0.1192], requires_grad=True)) ('2.weight', Parameter containing: tensor([[ 0.0984, 0.0207, -0.1292, 0.0530, -0.0693, 0.0413, -0.2231, -0.3125]], requires_grad=True)) ('2.bias', Parameter containing: tensor([0.1844], requires_grad=True)) 复制代码
关于解包器看这里:Python * ** 打包解包详解 - 掘金 (juejin.cn)
我把三个输出分开了。
第一个是解包net的第0层的参数参数名称和参数形状
第二个是解包net所有层的参数名称和参数形状
第三个是解包net的参数列表
还可以这样获取参数列表:
print(net.state_dict()['2.bias'].data) print(net.state_dict()['0.weight']) 复制代码
>> tensor([0.1844]) tensor([[ 0.3700, 0.3270, -0.3741, -0.1365], [ 0.2200, 0.0786, 0.1241, -0.2834], [ 0.3143, 0.3718, 0.3278, 0.0949], [ 0.1565, 0.4639, -0.1515, -0.4962], [ 0.3102, -0.0025, -0.0099, -0.4132], [ 0.1754, -0.1320, -0.3762, -0.1371], [-0.3860, -0.0369, 0.3743, -0.0892], [ 0.0280, -0.2877, -0.1884, 0.2915]]) 复制代码
后边不管加不加.data
都可以直接输出参数的值。
作者:LolitaAnn
链接:https://juejin.cn/post/7032234371461414943