首先我们自定义一个网络层, 定义一个网络层,使其不包含模型参数,并在forward()函数中进行运算:
import torch from torch import nn class non_param_layer(nn.Module): def __init__(self, **kwargs): super(non_param_layer, self).__init__(**kwargs) def forward(self, x): return x - x.mean()这个层中没有模型参数,只在forward中定义了计算:减去数据平均值
实例化该层并进行前向计算:
layer = non_param_layer() layer(torch.tensor([1, 2, 3, 4, 5], dtype=troch.float))输出:
tensor([-2., -1., 0., 1., 2.])我们将该层网络加入网络中:
net = nn.Sequential(nn.Linear(8, 128), non_param_layer())进行前向计算并输出自定义层的输出的均值:
y = net(torch.rand(4, 8)) y.mean().item() # 0因为我们自定义的网络层所做的操作是:,每个输入减去所有数据的均值,所以其输出的各个数值取均值的结果为0
与上面一节不同,我们要自定义一个含有模型参数的网络层: 之前的blog有讲过构造深度学习模型有很多种方法,其中,使用ParameterList和ParameterDict定以模型比较特别,接下来我们使用这两种方式自定义网络层。
class my_dense(nn.Module): def __init__(self): super(my_dense, self).__init__() self.params = nn.ParameterList([nn.Parameter(torch.randn(4, 4)) for i in range(3)]) self.params.append(nn.Parameter(torch.randn(4, 1))) def forward(self, x): for i in range(len(self.params)): x = torch.mm(x, self.params[i]) return x net = my_dense() print(net)输出:
MyDense( (params): ParameterList( (0): Parameter containing: [torch.FloatTensor of size 4x4] (1): Parameter containing: [torch.FloatTensor of size 4x4] (2): Parameter containing: [torch.FloatTensor of size 4x4] (3): Parameter containing: [torch.FloatTensor of size 4x1] ) )接下来使用ParameterDict网络模型并且自定义网络传播路径
class dict_dense(nn.Module): def __init__(self): super(dict_dense, self).__init() self.params = nn.ParameterDict( { "liner1" : nn.Parameter(troch.randn(4, 4)) "liner2" : nn.Parameter(torch.randn(4, 1)) } ) self.params.update({"liner3 : nn.Parameter(torch.randn(4, 2))"}) def forward(self, x, choice="liner1"): return torch.mm(x, self.params[choice]) net = dict_dense() pritn(net)输出:
MyDictDense( (params): ParameterDict( (linear1): Parameter containing: [torch.FloatTensor of size 4x4] (linear2): Parameter containing: [torch.FloatTensor of size 4x1] (linear3): Parameter containing: [torch.FloatTensor of size 4x2] ) )然后可以自己指定网络训练的传播路径:
x = torch.ones(1, 4) print(net(x, "liner1"))同时,我们还可以使用Sequential将我们自定义的网络层加入到网络中:
mix_net = nn.Sequential( dict_dense(), my_dense() , )