torch.nn
卷积层 Convolution Layers
torch.nn提供的包 | 针对场景 |
---|---|
nn.Conv1d | 对由多个输入平面组成的输入信号应用一维卷积。 |
nn.Conv2d | 在由多个输入平面组成的输入信号上应用 2D 卷积。 |
nn.Conv3d | 对由多个输入平面组成的输入信号应用 3D 卷积。 |
… | … |
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 )
该模块支持TensorFloat32。
参数:
in_channels :int, 输入图像中的通道数
out_channels : int, 卷积产生的通道数
kernel_size : (int / tuple),卷积核的大小
stride
控制互相关、单个数字或元组的步幅。
padding
控制应用于输入的填充量。它可以是一个字符串 {‘valid’, ‘same’} 或一个整数元组,给出在两边应用的隐式填充量。
dilation
控制内核点之间的间距;也称为 à trous 算法。很难描述,但是这个链接 很好地可视化了dilation
它的作用。
groups
控制输入和输出之间的连接。 in_channels
并且out_channels
都必须能被 整除 groups
。例如,
- 在 groups=1 时,所有输入都卷积到所有输出。
- 在 groups=2 时,该操作等效于并排有两个卷积层,每个卷积层看到一半的输入通道并产生一半的输出通道,并且随后将两者连接起来。
- 在 groups=
in_channels
处,每个输入通道都与自己的一组过滤器
in_channels :int, 输入图像中的通道数
out_channels : int, 卷积产生的通道数
in_channels=1,out_channels =1,则卷积层生成一个卷积核进行卷积计算,将卷积计算后的结果作为输出;
in_channels=1,out_channels =2,卷积层会生成两个卷积核,得到两个卷积后的计算结果,将这两个计算后的结果当作一个输出结果进行输出。两个卷积核不一定相等。
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("../DataSet", train=False, transform=torchvision.transforms.ToTensor(),
download=True)
dataloader = DataLoader(dataset, batch_size=64)
# 搭建简单的神经网络
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
# 设置conv1,因为输入图像为彩色图像in_ch=3, 想输出6层out_ch=6,使用卷积核3*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
writer = SummaryWriter()
tudui = Tudui()
# print(tudui)
for da in dataloader:
imgs, targets = da
output = tudui(imgs)
print(imgs.shape) # torch.Size([64, 3, 32, 32])
print(output.shape) # torch.Size([64, 6, 30, 30])
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()
print(imgs.shape) # torch.Size([64, 3, 32, 32])
DataLoader(dataset, batch_size=64)
中batch_size=64
print(output.shape) # torch.Size([64, 6, 30, 30])
卷积计算之后的形状输出,
DataLoader(dataset, batch_size=64)
中batch_size=64
pytorch池化层相关内容的
nn.MaxPool1d | Applies a 1D max pooling over an input signal composed of several input planes. |
---|---|
nn.MaxPool2d | Applies a 2D max pooling over an input signal composed of several input planes. |
nn.MaxPool3d | Applies a 3D max pooling over an input signal composed of several input planes. |
nn.MaxUnpool1d | Computes a partial inverse of MaxPool1d . |
nn.MaxUnpool2d | Computes a partial inverse of MaxPool2d . |
MaxPool 最大池化,也被成为下采样
MaxUnPool ,上采样
AvgPool,平均池化
…
最常用的是MaxPool2d。
torch.nn.MaxPool2d( kernel_size , stride = None , padding = 0 , dilation = 1 , return_indices = False , ceil_mode = False )
kernel_size
True
,将返回最大索引以及输出。torch.nn.MaxUnpool2d
以后有用参数kernel_size
, stride
, padding
,dilation
可以是:
- 单个
int
- 在这种情况下,高度和宽度尺寸使用相同的值- a
tuple
of two int – 在这种情况下,第一个int用于高度维度,第二个int用于宽度维度,及(2,3)为 高2,宽3的矩阵
dilation – 控制窗口中元素步幅的参数,相关的空洞卷积
标准卷积与空洞卷积在实现上基本相同,标准卷积可以看做空洞卷积的特殊形式。
空洞卷积有什么作用呢?
从这里可以看出,空洞卷积可以任意扩大感受野,且不需要引入额外参数,但如果把分辨率增加了,算法整体计算量肯定会增加。
比如,一个5*5大小的输入图像,池化核大小为3(3*3),stride默认同池化核大小一致。
stride默认与池化核大小一致,则向后移动,出现如图所示,仅有6个元素被池化核覆盖。
最后,逐步完成池化
具体的代码实现:
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)
input = torch.reshape(input, (-1, 1, 5, 5))
print(input.shape)
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=False)
def forward(self, input):
output = self.maxpool1(input)
return output
tudui = Tudui()
output = tudui(input)
print(output)
# 当ceil_mode=False时,输出tensor([[[[2.]]]])
tensor([[[[2., 3.],
[5., 1.]]]])
import torch
import torchvision
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("../data", train=False, download=True,
transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=False)
def forward(self, input):
output = self.maxpool1(input)
return output
tudui = Tudui()
writer = SummaryWriter("../logs_maxpool")
step = 0
for data in dataloader:
imgs, targets = data
writer.add_images("input", imgs, step)
output = tudui(imgs)
writer.add_images("output", output, step)
step = step + 1
writer.close()
(1)保留主要特征的同时减少参数和计算量,防止过拟合。
(2)invariance(不变性),这种不变性包括translation(平移),rotation(旋转),scale(尺度)。
Pooling 层说到底还是一个特征选择,信息过滤的过程。也就是说我们损失了一部分信息,这是一个和计算性能的一个妥协,随着运算速度的不断提高,妥协会越来越小。
现在有些网络都开始少用或者不用pooling层了。