本文重点
其实如果我们使用pytorch封装好的网络层的时候,我们并不需要对模型的参数初始化,因为这些都是pytorch帮助我们完成的,但是如果我们自己搭建模型(不使用pytorch中的封装好的网络层)或者对pytorch中封装好的模型初始化参数不满意,那么此时我们对模型进行参数初始化。
用pytorch已经封装好的层来搭建网络模型
import torch
import numpy as np
from torch import nn
class Simple_net(nn.Module):
def __init__(self):
super(Simple_net,self).__init__()
self.layer1=nn.Linear(4,3)
def forward(self,x):
return self.layer1(x)
net=Simple_net()
print(net)
print(net.layer1.weight.shape) #torch.Size([3, 4])
data=torch.randn(5,4)
out=net(data)
print(out.shape)#torch.Size([5, 3])
这里我们是使用pytorch已经封装好的nn.Linear层,这里我们需要注意一点,全连接层的输入维度为4,输出维度为3,那么它的参数shape=[3,4],所以这是需要注意的一点,如果我们要是不使用pytorch中的Linear而是自己定义全连接层,那么我们就要这个设置参数,也就是说如果我们想要让输入层的维度为4,输出层的维度为3,那么我们就要设置自定义的全连接层的参数矩阵的时候shape应该是[3,4],而不是[4,3],下面我们不使用pytorch中封装好的Linear层来,来复现上面的模型。
import torch
import numpy as np
from torch import nn
class Simple_net(nn.Module):
def __init__(self,in_features,out_features):
super(Simple_net,self).__init__()
self.w=nn.Parameter(torch.randn(out_features,in_features))
self.b=nn.Parameter(torch.randn(out_features))
def forward(self,x):
x=x@self.w.t()+self.b
return x
net=Simple_net(4,3)
print(net.w.shape)#torch.Size([3, 4])
data=torch.randn(5,4)
out=net(data)
print(out.shape)#torch.Size([5, 3])
我们可以看到构建self.w的时候不是torch.randn(in_features,out_features),而是torch.randn(out_features,in_features),这样表示该全连接层的输入维度为in_feature,然后输出维度为out_features
除此之外还要注意的一点是前向传播forward的计算方式
x的维度为[5,4],然后w的维度是[3,4],所以需要用x乘上w的转置(x@self.w.t()),这样输出就是[5,3],我们可以看到forward中就是这样做的。
以上证明了什么
以上的代码证明了什么呢?主要想说的一点就是如果我们要是nn.Linear()构建全连接层的时候,它就已经包含了参数w和b,已经进行初始化了,如果我们对这个初始化不满意怎么办?我们可以将满意的初始化参数赋值给它