PyTorch学习笔记(6)–神经网络:卷积层
本博文是PyTorch的学习笔记,第6次内容记录,主要介绍神经网络卷积层的基本使用。
目录
- PyTorch学习笔记(6)--神经网络:卷积层
- 1.卷积操作是什么
- 2.卷积层
- 2.1卷积层相关参数
- 2.2卷积层应用实例
- 2.3卷积层input和output尺寸信息
- 3.学习小结
1.卷积操作是什么
关于具体什么是卷积操作,不是本文要讲的重点,但是本文的后续操作都是建立在卷积操作之上的,因此在学习卷积层的相关知识之前,很有必要弄清楚什么是卷积操作,这里推荐大家参照一下PyTorch官网中相关页面的动态图片展示卷积操作动态展示,此外还推荐大家参考下述博文中对卷积操作的详细讲解:卷积网络和卷积计算。
在进行下面的卷积层学习之前,至少要弄清楚卷积操作的基本步骤和方法。
2.卷积层
2.1卷积层相关参数
在PyTorch官网中,详细介绍了常用的卷积操作函数:nn.Conv1d、nn.Conv2d、nn.Conv3d等,其中Conv1d针对一维的向量,Conv2d针对二维的向量,Conv3d针对三维的向量。在图像处理中,Conv2d的使用次数较多,因此本文以Conv2d为重点进行卷积层的介绍。
在官网中关于卷积层的参数,描述如下:
Conv2d(in_channels, out_channels, kernel_size, stride=1,padding=0, dilation=1, groups=1,bias=True, padding_mode=‘zeros’)
上述Conv2d函数一共涉及了9个参数,其中前5个参数是较为常用的参数,在使用过程中对其设置要注意其基本含义及作用。现对这9个参数的作用描述如下:- in_channels:
输入的通道数目 【必选】- out_channels:
输出的通道数目 【必选】- kernel_size:
卷积核的大小,类型为int 或者元组,当卷积是方形的时候,只需要一个整数边长即可,卷积不是方形,要输入一个元组表示 高和宽。【必选】(例如:设置kernel_size=3时,会自动生成一个3×3的卷积核)- stride=1:
卷积每次滑动的步长为多少,默认是 1 【可选】(例如:设置stride=1时,卷积核每次向右滑动一步,向下滑动一步;设置stride=2时,卷积核每次向右滑动2步,向下滑动2步)- padding=0:
设置在所有边界增加 值为 0 的边距的大小(也就是在feature map 外围增加几圈 0 ),例如当 padding =1 的时候,如果原来大小为 3 × 3 ,那么之后的大小为 5 × 5 。即在外围加了一圈 0 (外围包括上下左右的一圈)。【可选】- dilation=1:
控制卷积核之间的间距。不常用,一般设置为dilation=0【可选】具体解释可参见博文:Conv2d用法讲解- groups=1:
控制输入和输出之间的连接。(不常用)【可选】- bias=True:
是否将一个 学习到的 bias 增加输出中,默认是 True 。【可选】- padding_mode=‘zeros’:
字符串类型,接收的字符串只有 “zeros” 和 “circular”。当为“zero”时,表示在padding操作时,在外一圈是填充的0,【可选】关于padding是采用half padding 还是full padding,可以参照这个博文:卷积神经网络CNN理论到实践(3) 注意:参数 kernel_size,stride,padding,dilation 都可以是一个整数或者是一个元组,一个值的情况将会同时作用于高和宽 两个维度,两个值的元组情况代表分别作用于 高
和 宽
维度。
2.2卷积层应用实例
现以CIFAR10数据集为例,详细介绍卷积层的使用方法。
1. 通过下述代码下载数据集,并且实现自己的神经网络类Test:
# coding :UTF-8
# 文件功能: 代码实现神经网络--卷积层功能
# 开发人员: dpp
# 开发时间: 2021/8/16 4:18 下午
# 文件名称: nn_conv2d.py
# 开发工具: PyCharm
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("CIFAR10", train=False, transform=torchvision.transforms.ToTensor(),
download=True)
dataloader = DataLoader(dataset, batch_size=64)
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
# 定义卷积操作相关参数 输入通道3 输出通道6 卷积核大小3 步长1 原图不进行边缘填充
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 = Test()
print(test)
在上述代码中最后一行print(test)
是来查看神经网络的基本参数信息。输出结果如下,从输出结果可知,输入通道为3,输出通道为6,卷积核结构为3×3,步长为1。
/Users/dpp/opt/anaconda3/python.app/Contents/MacOS/python /Users/dpp/PycharmProjects/PyTorch_learning/nn_conv2d.py
Files already downloaded and verified
Test(
(conv1): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
)
Process finished with exit code 0
2. 当设置DataLoader的参数batch_size=64
时,表示一次性加载64张照片,写代码实现imgs和target的读取:
# coding :UTF-8
# 文件功能: 代码实现神经网络--卷积层功能
# 开发人员: dpp
# 开发时间: 2021/8/16 4:18 下午
# 文件名称: nn_conv2d.py
# 开发工具: PyCharm
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("CIFAR10", train=False, transform=torchvision.transforms.ToTensor(),
download=True)
dataloader = DataLoader(dataset, batch_size=64)
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
# 定义卷积操作相关参数 输入通道3 输出通道6 卷积核大小3 步长1 原图不进行边缘填充
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 = Test()
print(test)
for data in dataloader:
imgs, targets = data
output = test(imgs)
print(imgs.shape) # 输出原始图像的形状 torch.Size([64, 3, 32, 32])
print(output.shape) # 输出卷积之后图像的形状 torch.Size([64, 6, 30, 30])
输出结果如下:
print(imgs.shape)
语句输出结果为 torch.Size([64, 3, 32, 32]),64表示一次性读取的照片的数量,3表示输入通道数为3,32表示输入图像的尺寸为32×32。
print(output.shape)
语句输出结果为 torch.Size([64, 6, 30, 30]),64表示一次性读取的照片的数量,6表示输出通道数为6,这是在之前代码self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)
中设置的,30表示输入图像的尺寸为30×30。(30的计算过程:输入图像是32×32,卷积尺寸是3×3,于是输出图像的尺寸为:32-3+1=30,也就是30×30)。
3. 现借助Tensorboard观察卷积操作之后的图像情况,代码如下:
# coding :UTF-8
# 文件功能: 代码实现神经网络--卷积层功能
# 开发人员: dpp
# 开发时间: 2021/8/16 4:18 下午
# 文件名称: nn_conv2d.py
# 开发工具: PyCharm
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("CIFAR10", train=False, transform=torchvision.transforms.ToTensor(),
download=True)
dataloader = DataLoader(dataset, batch_size=64)
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
# 定义卷积操作相关参数 输入通道3 输出通道6 卷积核大小3 步长1 原图不进行边缘填充
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 = Test()
print(test)
writer = SummaryWriter("logs")
step = 0
for data in dataloader:
imgs, targets = data
output = test(imgs)
print(imgs.shape) # 输出原始图像的形状 torch.Size([64, 3, 32, 32])
print(output.shape) # 输出卷积之后图像的形状 torch.Size([64, 6, 30, 30])
# 原始图像的形状:torch.Size([64, 3, 32, 32])
writer.add_images("input", imgs, step)
# 卷积之后的图像的形状:torch.Size([64, 6, 30, 30]) --> [xxx, 3, 30, 30]
output = torch.reshape(output, (-1, 3, 30, 30))
writer.add_images("output", output, step)
step = step + 1
writer.close()
上述代码仍是读取CIFAR10的图像数据,其中值得关注的是原始输入图像的尺寸、输出图像的尺寸,由于卷积操作之后的channels=6,因此需要借助reshape操作将通道数改成3,代码为:output = torch.reshape(output, (-1, 3, 30, 30))
。
在tensorboard中观察其结果,如下所示:
2.3卷积层input和output尺寸信息
在input和output中,要重点关注尺寸信息,对于输入和输出的尺寸信息计算关系如下所示,更多细节可参照PyTorch官网信息PyTorch官网。
3.学习小结
在本文中总结了神经网络的卷积层的基本使用方法,并通过构建一个类Test介绍n二维的卷积conv2d的具体使用方法,在下一篇博文,将开始介绍神经网络的池化层。