Learning notes for Pytorch(2)

mac2022-06-30  30

Module

例1 class MyNet(torch.nn.Module): def __init__(self): super(MyNet, self).__init__() self.conv1 = torch.nn.Conv2d(3, 32, 3, 1, 1) self.relu1 = torch.nn.ReLU() self.max_pooling1=torch.nn.MaxPool2d(2,1) self.conv2 = torch.nn.Conv2d(3, 32, 3, 1, 1) self.relu2=torch.nn.ReLU() self.max_pooling2=torch.nn.MaxPool2d(2,1) self.dense1 = torch.nn.Linear(32 * 3 * 3, 128) self.dense2 = torch.nn.Linear(128, 10) def forward(self, x): x = self.conv1(x) x = self.relu1(x) x = self.max_pooling1(x) x = self.conv2(x) x = self.relu2(x) x = self.max_pooling2(x) x = self.dense1(x) x = self.dense2(x) return x # relu可以不在init函数里写, 直接在forward()函数中写x=torch.nn.ReLU(x)即可 例2 通过Sequential来包装层 import torch.nn as nn from collections import OrderedDict model = nn.Sequential() model.add_module("conv1",nn.Conv2d(1,20,5)) model.add_module('relu1', nn.ReLU()) model.add_module('conv2', nn.Conv2d(20,64,5)) model.add_module('relu2', nn.ReLU()) class MyNet(nn.Module): def __init__(self): super(MyNet, self).__init__() self.conv_block = nn.Sequential( nn.Conv2d(3, 32, 3, 1, 1), nn.ReLU(), nn.MaxPool2d(2)) self.dense_block = nn.Sequential( nn.Linear(32 * 3 * 3, 128), nn.ReLU(), nn.Linear(128, 10) ) # 在这里实现层之间的连接关系,其实就是所谓的前向传播 def forward(self, x): conv_out = self.conv_block(x) res = conv_out.view(conv_out.size(0), -1) out = self.dense_block(res) return out 例3 自定义模型

总的来说,即在init函数中使用torch.nn.Parameter定义参数, 在forward函数中进行计算 ‘’’ 这个层实现的功能是:y=weights*sqrt(x2+bias),所以有两个参数: 权值矩阵weights 偏置矩阵bias 输入 x 的维度是(in_features,) 输出 y 的维度是(out_features,) 故而 bias 的维度是(in_fearures,),注意这里为什么是in_features,而不是out_features,注意体会这里和Linear层的区别所在 weights 的维度是(in_features, out_features)注意这里为什么是(in_features, out_features),而不是(out_features, in_features),注意体会这里和Linear层的区别所在 ‘’’

class MyLayer(torch.nn.Module): def __init__(self, in_features, out_features, bias=True): super(MyLayer, self).__init__() # 调用父类的构造函数 self.in_features = in_features self.out_features = out_features self.weight = torch.nn.Parameter(torch.Tensor(in_features, out_features)) # 由于weights是可以训练的,所以使用Parameter来定义 if bias: self.bias = torch.nn.Parameter(torch.Tensor(in_features)) # 由于bias是可以训练的,所以使用Parameter来定义 else: self.register_parameter('bias', None) def forward(self, input): input_=torch.pow(input,2)+self.bias y=torch.matmul(input_,self.weight) return y

利用自定义层构建自定义模型

import torch from my_layer import MyLayer # 自定义层 N, D_in, D_out = 10, 5, 3 # 一共10组样本,输入特征为5,输出特征为3 # 先定义一个模型 class MyNet(torch.nn.Module): def __init__(self): super(MyNet, self).__init__() # 第一句话,调用父类的构造函数 self.mylayer1 = MyLayer(D_in,D_out) def forward(self, x): x = self.mylayer1(x) return x

实现模型, 进行训练

# 构造模型实例 model = MyNet() print(model) '''运行结果为: MyNet( (mylayer1): MyLayer() # 这就是自己定义的一个层 ) ''' # 构造损失函数 loss_fn = torch.nn.MSELoss(reduction='sum') # 构造一个optimizer对象 optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) for t in range(10): # # 第一步:数据的前向传播,计算预测值p_pred y_pred = model(x) # 第二步:计算计算预测值p_pred与真实值的误差 loss = loss_fn(y_pred, y) print(f"第 {t} 个epoch, 损失是 {loss.item()}") # 在反向传播之前,将模型的梯度归零 optimizer.zero_grad() # 第三步:反向传播误差 loss.backward() # 第四部:直接通过梯度一步到位,更新完整个网络的训练参数 optimizer.step()
最新回复(0)