最近学习李沐老师pytorch课程,在software回归一节中
模型建立首先进行初始化参数(权重……),课程代码如下:
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))
#nn.Flatten将多维张量压缩为二维(一行)进而进行线性操作、
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights);
其中用到了nn.Linear 、net.apply(), 查阅了相关资料,并自己敲码后略有所得:
nn.Linear可以看做输出层最后的一个线性变换:
x为输入层,A为权重层(所谓的w),b为偏置量
简单演示nn.Linear的作用,代码如下:
初始化权重:
import torch
from torch.nn.parameter import Parameter
m = torch.nn.Linear(2,3) #定义权重层大小
w=torch.normal(0, 0.01, size=(3,2), requires_grad=True) #生成与权重大小相同的tensor
m.weight = Parameter(w) #w类型转换后赋值给权重,这里的类型转换是必要的,不能直接 m.weight = torch.normal(0, 0.01, size=(3,2), requires_grad=True)
print(m.weight)
输出:
Parameter containing:
tensor([[ 0.0017, 0.0039],
[-0.0170, -0.0005],
[-0.0012, -0.0021]], requires_grad=True)
通过Linear线性层作用:
input = torch.randn(4,2) #定义一个4*2的张量
output=m(input)
print(input)
print(output)
输出:
tensor([[-1.0365, 1.6971],
[-0.3920, 0.8152],
[-1.4433, -0.5139],
[-0.0709, -0.5784]])
tensor([[-0.4125, -0.1429, 0.3137],
[-0.4148, -0.1535, 0.3148],
[-0.4218, -0.1350, 0.3188],
[-0.4197, -0.1583, 0.3173]], grad_fn=)
回到最初的函数,在每次以batch_size为最小单位的训练中,每次遇到线性层的nn.Linear(),都会先进性权重初始化,以保证权重均值和方差不会过大。
补:
其实在运行另一位博主https://medlen.blog.csdn.net/article/details/105258389
的代码下,我发现其实nn.Linear()中权重以及偏差实际上函数框架下会自动初始化
m = torch.nn.Linear(2, 3)
input = torch.randn(4, 2)
out = m(input)
print(input)
print(m.weight)
print(out)
'''
输出
tensor([[ 1.6054, -0.0685],
[-1.3096, -1.2594],
[ 1.5781, 0.5274],
[ 1.1647, -1.1867]])
Parameter containing:
tensor([[-0.0828, -0.6366],
[ 0.2552, -0.6134],
[-0.6397, 0.5804]], requires_grad=True)
tensor([[-0.4256, -0.0214, -1.6740],
[ 0.5740, -0.0347, -0.5006],
[-0.8027, -0.3939, -1.3107],
[ 0.3228, 0.5521, -2.0412]], grad_fn=)
'''
参考:
https://medlen.blog.csdn.net/article/details/105258389
tensor转化为parameter后才能赋值给了线性层的权重