本文结合小土堆的教学视频PyTorch深度学习快速入门教程进行学习
一、 基本骨架 Containers
1. torch.nn.Module
Module 类是所有神经网络模块的基类,还可以包含其他模块,允许他们嵌套在树状结构中。
当继承 Module 父类时,需要调用 __init__() 函数进行初始化处理,并且在该函数中必须调用父类的初始化函数。同时还可以调用 forward() 函数进行前向传播。
具体代码实现如下
import torch
# 继承Module模块,创建一个属于自己的类
class Model(torch.nn.Module):
# 类的初始化
def __init__(self):
super().__init__()
# 调用forward函数
def forward(self, input):
output = input + 1
return output
model = Model()
x = torch.tensor(1.0)
output = model(x)
print(output)
程序运行结果输出 tensor(2.)
2.torch.nn.Sequential
Sequential 类继承自Module 类,是一个有顺序的容器,将特定神经网络模块按照在传入容器的顺序依次执行
具体代码实现如下
from torch import nn
# 创建Sequential实例
model = nn.Sequential(
nn.Conv2d(1,20,5), # 第一次卷积操作
nn.ReLU(), # 第一次非线性激活
nn.Conv2d(20,64,5), # 第二次卷积操作
nn.ReLU() # 第二次非线性激活
)
print(model)
程序运行结果如下
Sequential(
(0): Conv2d(1, 20, kernel_size=(5, 5), stride=(1, 1))
(1): ReLU()
(2): Conv2d(20, 64, kernel_size=(5, 5), stride=(1, 1))
(3): ReLU()
)
二、 卷积层 Convolution Layers
功能实现:提取输入图像中的特征信息
Conv2d:对二维数据进行卷积层的处理
1. torch.nn.functional.conv2d
函数定义:
torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)
参数含义:input 表示传入要进行处理的图像数据; weight 表示权重,即卷积核;bias 表示形状的可选偏置张量,默认值为 None; stride 表示卷积的步幅,默认值为1; padding 表示图像边沿填充的数目,默认值为0
具体代码实现如下
import torch
import torch.nn.functional as F
# 输入矩阵
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]])
# 卷积核
kernel = torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]])
# 由于直接使用torch.tensor传入的数据只有2个尺寸形式,而conv2d的传参要求需要4个尺寸形式
# 对输入矩阵和卷积核的尺寸进行转变
input = torch.reshape(input,(1,1,5,5))
kernel = torch.reshape(kernel,(1,1,3,3))
# 输出卷积结果
output = F.conv2d(input,kernel,stride=1) # 卷积核步长为1,边缘无填充
output2 = F.conv2d(input,kernel,stride=2) # 卷积核步长为2,边缘无填充
output3 = F.conv2d(input,kernel,stride=1,padding=1) # 卷积核步长为1,边缘填充一圈
print(output)
print(output2)
print(output3)
程序运行结果如下
tensor([[[[10, 12, 12],
[18, 16, 16],
[13, 9, 3]]]])
tensor([[[[10, 12],
[13, 3]]]])
tensor([[[[ 1, 3, 4, 10, 8],
[ 5, 10, 12, 12, 6],
[ 7, 18, 16, 16, 8],
[11, 13, 9, 3, 4],
[14, 13, 9, 7, 4]]]])
2. torch.nn.Conv2d
计算公式为
其中 N 是批量大小,C 表示多个通道,H 是输入平面的高度(以像素为单位),W 是宽度(以像素为单位)
函数定义:
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 表示输入图像中的通道数(通常为 RGB 3通道); out_channels 表示经过卷积后输出图像的通道数; kernel_size 表示卷积核的大小,输入整数 size 表示大小为 size × size,输入序列 (h,w) 表示大小为 h × w; stride 表示卷积的步幅,默认值为1; padding 表示图像边沿填充的数目,默认值为0;padding_mode 表示边沿填充模式
具体代码实现如下
import torch
from torch import nn
from torch.nn import Conv2d
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 准备并加载测试数据集
dataset = torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloder = DataLoader(dataset,batch_size=64)
# 创建model类(继承Module)
class Model(nn.Module):
# 类的初始化
def __init__(self):
super().__init__() # 父类的初始化
self.conv1 = Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0) # 定义卷积层
# forward函数
def forward(self,x):
x = self.conv1(x) # 对输入进来的x进行卷积操作
return x
model = Model() # 创建类的实例
step = 0
writer = SummaryWriter("logs")
# 通过for循环遍历数据集中的每个子集
for data in dataloder:
imgs,targets = data
output = model(imgs) # 传入图片进行卷积操作
writer.add_images("input",imgs,step) # 显示输入图片
output = torch.reshape(output,(-1,3,30,30)) # 转变输出图片尺寸(经过卷积之后图片变成30×30)
# -1表示不清楚该值要设置为多少,系统会自动根据后面的值进行计算;3表示将图片转化为三通道
writer.add_images("output",output,step) # 显示输出图片
step += 1
writer.close()
将程序运行后,在终端输入 tensorboard --logdir=logs --port=6007 ,结果显示如下

三、 池化层 Pooling Layers
功能实现:提取窗口的特征数据,保留输入的特征,减小需要计算的数据量
MaxPool2d:直接计算池化窗口内的原始数据,选择池化核覆盖的范围中的最大值
函数定义:
torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
参数含义: kernel_size 表示池化核的窗口大小; stride 表示池化核窗口的步长(默认值为kernel_size); padding 表示图像边沿填充的数目; ceil_mode 当值为 True 时,表示将使用 ceil 而不是 floor 来计算输出形状,即保存大小不足为kernel_size的数据,自动补足NAN至kernel_size大小,值为 False表示直接舍弃大小不足为 kernel_size 的数据
具体代码实现如下(矩阵数据)
import torch
from torch import nn
from torch.nn import MaxPool2d
# 输入矩阵
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]],dtype=torch.float32) # 转为浮点数的tensor类型
# 对输入矩阵的尺寸进行转变,因为MaxPool2d的传参要求需要4个尺寸形式
input = torch.reshape(input,(1,1,5,5))
class Model(nn.Module):
def __init__(self):
super().__init__()
# 池化核大小为3×3,并保存大小不足为kernel_size的数据
self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)
def forward(self,input):
output = self.maxpool1(input)
return output
model = Model()
output = model(input)
print(output)
程序运行结果如下
tensor([[[[2., 3.],
[5., 1.]]]])
若将 ceil_mode 的值赋为 False,则程序运行结果为 tensor([[[[2.]]]])
在调试过程中出现了 RuntimeError: "max_pool2d" not implemented for 'Long' 的报错,是由于我们传入数据的类型不符合 long 型,故需要在传入数据后添加 dtype=torch.float32
具体代码实现如下(图像数据)
import torch
from torch import nn
from torch.nn import MaxPool2d
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 准备并加载测试数据集
dataset = torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloder = DataLoader(dataset,batch_size=64)
class Model(nn.Module):
def __init__(self):
super().__init__()
# 池化核大小为3×3,并保存大小不足为kernel_size的数据
self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)
def forward(self,input):
output = self.maxpool1(input)
return output
model = Model()
step = 0
writer = SummaryWriter("logs")
# 通过for循环遍历数据集中的每个子集
for data in dataloder:
imgs,targets = data
output = model(imgs) # 传入图片进行池化操作
writer.add_images("input",imgs,step) # 显示输入图片
writer.add_images("output",output,step) # 显示输出图片
step += 1
writer.close()
将程序运行后,在终端输入 tensorboard --logdir=logs --port=6007 ,结果显示如下

四、 非线性激活 Non-linear Activations
功能实现:向神经网络引入一些非线性的特质
1. torch.nn.ReLU
函数定义: torch.nn.ReLU(inplace=False)
参数含义: inplace 若设置为 True ,则函数会把输出结果覆盖到输入变量中(默认值为 False)
计算公式:
具体代码实现如下
import torch
from torch import nn
from torch.nn import ReLU
# 输入数据矩阵
input = torch.tensor([[1,-0.5],
[-1,3]])
input = torch.reshape(input,(-1,1,2,2)) # 转化数据尺寸
class Model(nn.Module):
def __init__(self):
super().__init__()
self.relu1 = ReLU() # 定义非线性激活函数
def forward(self,input):
output = self.relu1(input)
return output
model = Model()
output = model(input)
print(output)
程序运行结果如下
tensor([[[[1., 0.],
[0., 3.]]]])
2. torch.nn.Sigmoid
函数定义: torch.nn.Sigmoid(*args, **kwargs)
计算公式:
具体代码实现如下
from torch import nn
from torch.nn import Sigmoid
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 准备并加载测试数据集
dataset = torchvision.datasets.CIFAR10("./dataset",train=False,download=False,
transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset,batch_size=64)
class Model(nn.Module):
def __init__(self):
super().__init__()
self.sigmoid1 = Sigmoid() # 定义非线性激活函数
def forward(self,input):
output = self.sigmoid1(input)
return output
model = Model()
step = 0
writer = SummaryWriter("logs")
for data in dataloader:
imgs,targets = data
writer.add_images("input",imgs,step)
output = model(imgs)
writer.add_images("output",output,step)
step += 1
writer.close()
将程序运行后,在终端输入 tensorboard --logdir=logs --port=6007 ,结果显示如下

五、 线性层 Linear Layers
功能实现:将前面计算得到的特征向量进行线性变换,转化成一维向量
函数定义: torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
参数含义: in_features 表示每次输入样本的大小; out_features 表示每次输出样本的大小;bias 表示偏置量
具体代码实现如下
import torch
from torch import nn
from torch.nn import Linear
import torchvision
from torch.utils.data import DataLoader
# 准备并加载测试数据集
dataset = torchvision.datasets.CIFAR10("./dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloder = DataLoader(dataset,batch_size=64,drop_last=True)
class Model(nn.Module):
def __init__(self):
super().__init__()
self.linear1 = Linear(196608,10) # 将输入图片的大小196608转化为10
def forward(self,x):
x = self.linear1(x)
return x
model = Model()
for data in dataloder:
imgs,targets = data
# output = torch.reshape(imgs,(1,1,1,-1)) # 将图片数据扁平化
output = torch.flatten(imgs) # 可以替代上面的reshape函数的功能
print(output.shape)
output = model(output)
print(output.shape)
六、 搭建神经网络模型小实战(结合 CIFAR10 模型)
CIFAR10 模型结构如下

具体实战代码实现如下
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.tensorboard import SummaryWriter
class Model(nn.Module):
def __init__(self) -> None:
super(Model,self).__init__()
self.conv1 = Conv2d(3,32,5,padding=2) # 第一次卷积
self.maxpool1 = MaxPool2d(2) # 第一次最大池化
self.conv2 = Conv2d(32,32,5,padding=2) # 第二次卷积
self.maxpool2 = MaxPool2d(2) # 第二次最大池化
self.conv3 = Conv2d(32,64,5,padding=2) # 第三次卷积
self.maxpool3 = MaxPool2d(2) # 第三次最大池化
self.flatten = Flatten() # 数据扁平化
self.linear1 = Linear(1024,64) # 第一次线性变换
self.linear2 = Linear(64,10) # 第二次线性变换
def forward(self,x):
x = self.conv1(x)
x = self.maxpool1(x)
x = self.conv2(x)
x = self.maxpool2(x)
x = self.conv3(x)
x = self.maxpool3(x)
x = self.flatten(x)
x = self.linear1(x)
x = self.linear2(x)
return x
model = Model()
print(model)
input = torch.ones((64,3,32,32)) # 构建一个值全为1的矩阵
output = model(input)
print(output.shape)
writer = SummaryWriter("logs")
writer.add_graph(model,input)
writer.close()
程序运行结果如下
Model(
(conv1): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(maxpool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv2): Conv2d(32, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(maxpool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(conv3): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(maxpool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(flatten): Flatten(start_dim=1, end_dim=-1)
(linear1): Linear(in_features=1024, out_features=64, bias=True)
(linear2): Linear(in_features=64, out_features=10, bias=True)
)
torch.Size([64, 10])
具体代码实现如下(结合 Sequential 类)
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.tensorboard import SummaryWriter
class Model(nn.Module):
def __init__(self) -> None:
super(Model,self).__init__()
self.model1 = Sequential(
Conv2d(3,32,5,padding=2),
MaxPool2d(2),
Conv2d(32,32,5,padding=2),
MaxPool2d(2),
Conv2d(32,64,5,padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024,64),
Linear(64,10)
)
def forward(self,x):
x = self.model1(x)
return x
model = Model()
print(model)
input = torch.ones((64,3,32,32))
output = model(input)
print(output.shape)
writer = SummaryWriter("logs")
writer.add_graph(model,input)
writer.close()
程序运行结果如下
Model(
(model1): Sequential(
(0): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(2): Conv2d(32, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(4): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Flatten(start_dim=1, end_dim=-1)
(7): Linear(in_features=1024, out_features=64, bias=True)
(8): Linear(in_features=64, out_features=10, bias=True)
)
)
torch.Size([64, 10])
将程序运行后,在终端输入 tensorboard --logdir=logs --port=6007 ,结果显示如下
本文通过小土堆的教程,介绍了如何使用PyTorch构建基础深度学习模型,包括Module和Sequential类的使用、卷积层(Conv2d)、池化层(MaxPool2d)、非线性激活ReLU和Sigmoid,以及线性层(Linear)的应用,最后以CIFAR10数据集为例,展示了如何搭建一个简单的神经网络模型。
1456

被折叠的 条评论
为什么被折叠?



