20.神经网络 - 搭建小实战和 Sequential 的使用

打印 上一主题 下一主题

主题 541|帖子 541|积分 1623

神经网络 - 搭建小实战和 Sequential 的使用

在 PyTorch 中,Sequential 是一个容器(container)类,用于构建神经网络模子。它允许你按顺序(sequential)添加不同的网络层,并将它们串联在一起,形成一个网络模子。这样做可以方便地定义简单的前向传播过程,适用于很多基本的网络结构。
Sequential 的优点之一是其轻便性和易读性,特别适用于简单的网络结构。然而,对于更复杂的模子,可能需要使用 PyTorch 的其他模子构建方式,如使用 nn.Module 基类自定义网络结构,以满意更灵活的需求。
网站所在 : Sequential — PyTorch 1.10 documentation
Example:
把卷积、非线性激活、卷积、非线性激活使用sequantial进行组合,一起放在构建的model中。
  1. # Using Sequential to create a small model. When `model` is run,
  2. # input will first be passed to `Conv2d(1,20,5)`. The output of
  3. # `Conv2d(1,20,5)` will be used as the input to the first
  4. # `ReLU`; the output of the first `ReLU` will become the input
  5. # for `Conv2d(20,64,5)`. Finally, the output of
  6. # `Conv2d(20,64,5)` will be used as input to the second `ReLU`
  7. model = nn.Sequential(
  8.           nn.Conv2d(1,20,5),
  9.           nn.ReLU(),
  10.           nn.Conv2d(20,64,5),
  11.           nn.ReLU()
  12.         )
  13. # Using Sequential with OrderedDict. This is functionally the
  14. # same as the above code
  15. model = nn.Sequential(OrderedDict([
  16.           ('conv1', nn.Conv2d(1,20,5)),
  17.           ('relu1', nn.ReLU()),
  18.           ('conv2', nn.Conv2d(20,64,5)),
  19.           ('relu2', nn.ReLU())
  20.         ]))
复制代码
好处:代码轻便易懂
1.对 CIFAR10 进行分类的简单神经网络

CIFAR 10:根据图片内容,识别其毕竟属于哪一类(10代表有10个类别)
CIFAR-10 and CIFAR-100 datasets
[外链图片转存中…(img-WbXJRvP5-1724861831551)]
第一次卷积:起首加了几圈 padding(图像大小不变,照旧32x32),然后卷积了32次


  • Conv2d — PyTorch 1.10 documentation
  • 输入尺寸是32x32,颠末卷积后尺寸不变,如何设置参数? —— padding=2,stride=1
  • 计算公式:

  1. 其中Hout=32,Hin=32,dilation[0]=1,kernel_size[0]=5,将其带入到Hout的公式,计算过程如下:
  2. 32 =((32+2×padding[0]-1×(5-1)-1)/stride[0])+1,简化之后的式子为:
  3. 27+2×padding[0]=31×stride[0],stride[0]=2的话padding[0]要设置的很大,不合理,所以让stride[0]=1,可得padding[0]=2。
复制代码
几个卷积核就是几通道的,一个卷积核作用于RGB三个通道后会把得到的三个矩阵的对应值相加,也就是说会归并,以是一个卷积核会产生一个通道
任何卷积核在设置padding的时候为保持输出尺寸不变都是卷积核大小的一半
通道变化时通过调解卷积核的个数(即输出通道)来实现的,在 nn.conv2d 的参数中有 out_channel 这个参数,就是对应输出通道
kernel 的内容是不一样的,可以理解为不同的特征抓取,因此一个核会产生一个channel
直接搭建,实现上图 CIFAR10 model 的代码

  1. from torch import nn
  2. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
  3. class Tudui(nn.Module):
  4.     def __init__(self):
  5.         super(Tudui, self).__init__()
  6.         self.conv1 = Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2)  #第一个卷积,输入3,输出32,卷积核5,令stride=1,根据公式计算出padding为2
  7.         self.maxpool1 = MaxPool2d(kernel_size=2)   #池化
  8.         self.conv2 = Conv2d(32,32,5,padding=2)  #维持尺寸不变,所以padding仍为2
  9.         self.maxpool2 = MaxPool2d(2)
  10.         self.conv3 = Conv2d(32,64,5,padding=2)
  11.         self.maxpool3 = MaxPool2d(2)
  12.         self.flatten = Flatten()  #展平为64x4x4=1024个数据
  13.         # 经过两个线性层:第一个线性层(1024为in_features,64为out_features)、第二个线性层(64为in_features,10为out_features)
  14.         self.linear1 = Linear(1024,64)
  15.         self.linear2 = Linear(64,10)  #10为10个类别,若预测的是概率,则取最大概率对应的类别,为该图片网络预测到的类别
  16.     def forward(self,x):   #x为input
  17.         x = self.conv1(x)
  18.         x = self.maxpool1(x)
  19.         x = self.conv2(x)
  20.         x = self.maxpool2(x)
  21.         x = self.conv3(x)
  22.         x = self.maxpool3(x)
  23.         x = self.flatten(x)
  24.         x = self.linear1(x)
  25.         x = self.linear2(x)
  26.         return x
  27. tudui = Tudui()
  28. print(tudui)
复制代码
[外链图片转存中…(img-YRNV8yil-1724861831552)]
运行后可以看到网络结构:
[外链图片转存中…(img-iRZ4X2hO-1724861831552)]
实际过程中如何查抄网络的精确性?

焦点:肯定尺寸的数据颠末网络后,能够得到我们想要的输出
对网络结构进行查验的代码:
  1. input = torch.ones((64,3,32,32))  #全是1,batch_size=64,3通道,32x32
  2. output = tudui(input)
  3. print(output.shape)
复制代码

运行结果:
  1. torch.Size([64, 10])
复制代码

若不知道flatten之后的维度是多少该怎么办?

这个1024是我们算出来的,若不会算,删除forward中self.flatten(x)后两行,运行代码
  1. import torch
  2. from torch import nn
  3. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
  4. class Tudui(nn.Module):
  5.     def __init__(self):
  6.         super(Tudui, self).__init__()
  7.         self.conv1 = Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2)  #第一个卷积
  8.         self.maxpool1 = MaxPool2d(kernel_size=2)   #池化
  9.         self.conv2 = Conv2d(32,32,5,padding=2)  #维持尺寸不变,所以padding仍为2
  10.         self.maxpool2 = MaxPool2d(2)
  11.         self.conv3 = Conv2d(32,64,5,padding=2)
  12.         self.maxpool3 = MaxPool2d(2)
  13.         self.flatten = Flatten()  #展平为64x4x4=1024个数据
  14.         # 经过两个线性层:第一个线性层(1024为in_features,64为out_features)、第二个线性层(64为in_features,10为out_features)
  15.         self.linear1 = Linear(1024,64)
  16.         self.linear2 = Linear(64,10)  #10为10个类别,若预测的是概率,则取最大概率对应的类别,为该图片网络预测到的类别
  17.     def forward(self,x):   #x为input
  18.         x = self.conv1(x)
  19.         x = self.maxpool1(x)
  20.         x = self.conv2(x)
  21.         x = self.maxpool2(x)
  22.         x = self.conv3(x)
  23.         x = self.maxpool3(x)
  24.         x = self.flatten(x)
  25.         return x
  26. tudui = Tudui()
  27. print(tudui)
  28. input = torch.ones((64,3,32,32))  #全是1,batch_size=64(64张图片),3通道,32x32
  29. output = tudui(input)
  30. print(output.shape)  # torch.Size([64,1024])
复制代码
看到输出的维度是(64,1024),64可以理解为64张图片,1024就是flatten之后的维度了
运行结果:

用 Sequential 搭建,实现上图 CIFAR10 model 的代码

可以看到上面神经网络进行搭建时非常繁琐,在init中进行了多个操作以后,需要在forward中逐次进行调用,因此我们使用sequential方法,在init方法中直接定义一个model,然后在下面的forward方法中直接使用一次model即可。
  1. 在init方法中:
  2. self.model1 = Sequential(
  3.      Conv2d(...)
  4.      MaxPool2d(...)
  5.      Linear(...)
  6. )
  7. 在forward方法中:
  8. x = self.model(x)
  9. return x
复制代码
作用:代码更加轻便
  1. import torch
  2. from torch import nn
  3. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
  4. class Xiazhi(nn.Module):
  5.     def __init__(self):
  6.         super(Xiazhi, self).__init__()
  7.         self.model1 = Sequential(
  8.             Conv2d(3, 32, 5, padding=2),
  9.             MaxPool2d(2),
  10.             Conv2d(32, 32, 5, padding=2),
  11.             MaxPool2d(2),
  12.             Conv2d(32, 64, 5, padding=2),
  13.             MaxPool2d(2),
  14.             Flatten(),
  15.             Linear(1024, 64),
  16.             Linear(64, 10)
  17.         )
  18.     def forward(self, x):  # x为input
  19.         x = self.model1(x)
  20.         return x
  21. input = torch.ones((64, 3, 32, 32))  # 全是1,batch_size=64,3通道,32x32
  22. output = xiazhi(input)
  23. print(output.shape)
复制代码
运行结果:

2.引入 tensorboard 可视化模子结构

在上述代码反面加上以下代码:
  1. from torch.utils.tensorboard import SummaryWriter
  2. writer = SummaryWriter("logs_seq")
  3. writer.add_graph(tudui,input)   # add_graph 计算图
  4. writer.close()
复制代码
运行后在 terminal 里输入:
  1. tensorboard --logdir=logs_seq
复制代码
打开网址,双击图片中的矩形,可以放大每个部分:
[外链图片转存中…(img-gZPZzalR-1724861831555)]
  1. writer = SummaryWriter("logs_seq")
  2. writer.add_graph(tudui,input)   # add_graph 计算图
  3. writer.close()
复制代码
运行后在 terminal 里输入:
  1. tensorboard --logdir=logs_seq
复制代码
打开网址,双击图片中的矩形,可以放大每个部分:
[外链图片转存中…(img-gZPZzalR-1724861831555)]

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小秦哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表