一、卷积层原理
./ 当前目录;…/ 上级目录
父类(也称为基类或超类)是指在类继承体系中被其他类继承的类。也就是被其他子类进行调用的类
当In_channel=1时,输出的out_channel=1
当out_channel=2时,然后有连个卷积核,将他们进行卷积输出得到两个输出结果
输出的两个图层就会叠加起来
二、相关函数的概念
向前传播forward函数
前向传播(Forward Propagation)是指在神经网络中,输入数据经过每一层的计算,最终产生输出的过程。在PyTorch中,forward函数是nn.Module类的一个必需方法。当你创建一个自定义的层或模型时,你需要重写这个方法来定义前向传播的行为。
in_channels和out_channels这两个术语通常用于描述卷积层(Convolutional Layer)的输入和输出特征通道数。
in_channels:指的是卷积层输入数据的通道数。在图像处理中,例如,一个RGB图像有3个通道(红色、绿色、蓝色),因此in_channels将是3。对于灰度图像,in_channels将是1。
out_channels:指的是卷积层输出数据的通道数。这通常对应于卷积层中卷积核(或滤波器)的数量。在卷积神经网络中,通过改变out_channels的数量,可以控制网络的容量和复杂性。例如,如果你想要让卷积层输出更多的特征图,你可以增加out_channels的数量。
kernel_size:一般是指卷积核的大小
stride指的是卷积路径的大小
三、卷积层的应用
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
# 加载CIFAR-10数据集,设置为不下载训练集,只下载测试集,并且将图片转换为Tensor格式
dataset = torchvision.datasets.CIFAR10("../data", train=False, transform=torchvision.transforms.ToTensor(),download=True)
# 创建一个DataLoader,用于批量加载数据,这里设置批量大小为64
dataloader = DataLoader(dataset, batch_size = 64)
class Sen(nn.Module):
def __init__(self):
super(Sen, self).__init__()
# 定义一个卷积层,输入通道数为3(RGB图像),输出通道数为3,卷积核大小为3x3,步长为1,无填充
self.conv1 = Conv2d(in_channels=3,out_channels=3,kernel_size=3,stride=1,padding=0)
def forward(self, x):
x = self.conv1(x)
return x
sen = Sen()
writer = SummaryWriter("./logs")
step = 0
for data in dataloader:
imgs, targets = data
output = sen(imgs)
writer.add_images("input", imgs, step)
writer.add_images("output", output, step)
step = step + 1
运行结果:
卷积后出现颜色不一样是因为卷积核的生成是随机的,所以会出现不同颜色的情况,因为我们没有定义卷积核。
四、最大池化原理
最大池化的运用场合有很多,像例如将1080p的视频压缩成720p,还有马赛克也是最大池化作用出来的。
在最大池化中,池化核数也就是步长,像下面的是池化核是3,那么他的步长也是3
池化核框框经过3个步长进行取框框内的最大值,但如下图所示,因为池化核的框框超出了输入图像,所以就根据Ceiling_model为True还是False来进行判断。
Ceiling and Floor 的判断准则:
当取Floor时,2.31往下取整,当为Ceiling时,2.31往上取整
当Ceiling_model = True时,镂空也可以去取其中的最大值
当Ceiling_model = False时,镂空则取值为0
五、最大池化案例
最大池化的input通常应用于多维数据,如图像数据。在卷积神经网络(CNN)中,输入通常是三维的(高度、宽度、通道数)
代码用dtype=torch.float32这句话的原因。
默认情况下,torch.tensor 可能会将输入数据解释为整数(torch.int64),尤其是当你没有指定 dtype 时,上面的代码会创建一个整数 Tensor。如果你的神经网络层(如卷积层或池化层)要求输入是浮点数(例如,torch.float32),那么你必须将输入 Tensor 转换为浮点数类型。否则,计算可能会出错或产生不正确的结果。
通过使用 dtype=torch.float32,你可以确保 Tensor 具有正确的数据类型,从而避免潜在的数据类型不匹配和计算错误。
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必须是四维的,所以需要用reshape进行格式的变换
input = torch.reshape(input,(-1, 1, 5, 5))
print(input.shape)
class Sen(nn.Module):
def __init__(self):
super(Sen,self).__init__()
self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)
def forward(self,input):
output = self.maxpool1(input)
return output
sen = Sen()
output = sen(input)
print(output)
运行结果:
与我们自己计算的结果相比:
可以看出当Ceiling_model = True时,运算结果就是【2, 3,5, 1】
用图片运行来显示一下最大池化:
import torch
import torchvision.datasets
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import dataloader
dataset = torchvision.datasets.CIFAR10("../data", train=False, download=True,
transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)
class Sen(nn.Module):
def __init__(self):
super(Sen, self).__init__()
self.maxpool1 = MaxPool2d(kernel_size=3,ceil_mode=True)
def forward(self,input):
output = self.maxpool1(input)
return output
sen = Sen()
writer = SummaryWriter("logs_maxpool")
step = 0
for data in dataloader:
imgs, targets = data
writer.add_images("input", imgs, step)
output = sen(imgs)
writer.add_images("output",output, step)
step = step + 1
writer.close()
运行结果:
从上图中可以看到,图片进行了压缩,也就是画质降低,是不是很像马赛克