Pytorch搭建神经网络步骤
进入Pytorch官网,点击Docs下的Pytorch,在右侧点击 torch.nn,可以看到搭建神经网络以下步骤中出现的每个类的定义和使用方法。
1.神经网络骨架:继承Containers中的Module类
Containers译为容器,可以形象得翻译为骨架或框架,该包在torch.nn中。而其中一般只使用Module类,重写该类后,相当于完成了对我们要搭建的神经网络的骨架设计,后续的所有操作,包括卷积、池化等都在该类中写明。例如,一个简易的重写该类代码为:
import torch
from torch import nn
class test_Model(nn.Module):
def __init__(self):
# 必须包含该语句,意为执行父类,即Module的初始化函数
super().__init__()
def forward(self, input):
output = input + 1
return output
test_model = test_Model()
x = torch.tensor(1.0)
output = test_model(x)
print(output)
可以看到,Module类中,需重写两个函数,一个是初始化init函数,该函数中必须包含继承父类初始化的语句;另一个是forward前向传播(正向传播)函数,该函数是该类的主体,通过直接传参调用。
2.卷积操作:Conv2d类
Conv2d类为进行卷积操作的类,其中的2d代表是对二维数据操作,或者说卷积核为二维,该类的官方定义为:
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=‘zeros’, device=None, dtype=None)
其中的参数分别表示:
in_channels:输入图像的通道数,即channel,彩色图像为3;
out_channels:卷积后输出的通道数,实际上输出多少层通道数便会令卷积核有多少层;
kernel_size:卷积核大小,可以是一个数,也可以是一个元组,如果是一个数x,则卷积核大小为xx,如果为一个元组如(x, y),则卷积核大小为xy;
stride:步长,即每次卷积核移动长度,默认值为1;
padding:对输入图像进行边缘填充,如果为1则上下左右各自加一排填充,即如果原来输入图像尺寸是xx,填充后为(x+2)(x+2)。默认值为0;
padding_mode:选择填充方式,即填充的数是什么,默认是’zeros’;
不常用参数:
dilation:卷积核间的距离,默认值为1;
group:一般只用默认值,默认值为1;
bias:是否添加偏置,即kx+b中的b,为True则为添加,默认值为True。
例如要构建只有一层3*3的卷积网络,输入时通道数channel为3,输出时channel为6,则有如下代码:
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("../data", train=False, transform=torchvision.transforms.ToTensor(),
download=True)
dataloader = DataLoader(dataset, batch_size=64)
class test_Model(nn.Module):
def __init__(self):
super(test_Model, self).__init__()
self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)
def forward(self, x):
x = self.conv1(x)
return x
test_model = test_Model()
writer = SummaryWriter("../logs")
step = 0
for data in dataloader:
imgs, targets = data
output = test_model(imgs)
print(imgs.shape)
print(output.shape)
# 输入前图像img尺寸为torch.Size([64, 3, 32, 32]),其中64是我们的打包个数所以其实输入的是一个四维的数据
writer.add_images("input", imgs, step)
# 输出图像output尺寸为torch.Size([64, 6, 30, 30]),我们想要将其转化为[xxx, 3, 30, 30],所以reshape
output = torch.reshape(output, (-1, 3, 30, 30))
writer.add_images("output", output, step)
step = step + 1
writer.close()
3.池化操作:MaxPool2d类
池化操作包括很多种,有最小池化,平均池化,最大池化等,最常用的是最大池化MaxPool2d。该类的官方定义为:
torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
其中参数分别表示:
kernel_size:池化核大小,用于取多大的空间中的最大值,和卷积核一样,可以是一个数,也可以是一个元组,如果是一个数x,则卷积核大小为xx,如果为一个元组如(x, y),则卷积核大小为xy;
stride:步长,和卷积中一样,不过其默认值为kerenel_size,也就是每次取下一个块与上一个块没有重合部分;
padding:填充,和卷积中完全一样;
dilation:核间距离,一般不设置,可去官网查看,官网的动图较为形象理解;
return_indices:用得极少,一般不设置;
ceil_mode:是否取不足的部分;池