问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

神经网络入门实战:卷积层搭建

创作时间:
作者:
@小白创作中心

神经网络入门实战:卷积层搭建

引用
CSDN
1.
https://m.blog.csdn.net/qq_51409113/article/details/144188442

卷积层的功能与计算

1. 卷积层的功能与作用

卷积层通过卷积运算对输入数据进行特征提取。卷积运算是一种特殊的线性运算,使用卷积核(也称为滤波器)在输入数据(通常是图像)上滑动,计算每个局部区域的加权和,从而生成特征图(Feature Map)。这些特征图反映了输入数据中不同局部区域的特征,如边缘、线条、纹理和形状等。

通过不断的训练,会形成一个卷积核,此卷积核对应于图像的一个特征,测试的时候通过用此卷积核扫描图片,就能找到具有此特征的图片。类比为:有三张图片“笔”、“水杯”、“纸”,此时脑海里有一支笔的样子,眼睛扫过这三个图片,有笔的图片因为相似度最大,所以选择那一张。

2. 卷积的计算

卷积核不能超出原始图片的边界。即使经过填充层,使周围填充了一圈之后,形成新图形,卷积核依然不能超出新图片的边界。

3. 卷积的结果

①输出单通道矩阵

对于多通道(n)的输入,会配有一个同样通道数(n)的卷积核,并且最后将所有通道的卷积结果相加,形成一个新的单通道输出矩阵。

②输出多通道(m通道)矩阵

想输出m通道矩阵,那么就要配备m个卷积核,每个卷积核都和输入拥有相同通道数(n),最后将这m个单通道结果组合成一个m通道输出。这也是后面的卷积核Weights的形状要定为m × n × H × W的原因。

卷积层搭建(Convolution Layers库)

卷积层可以改变通道数

  • nn.Conv1d:一维卷积层
  • nn.Conv2d:二维卷积层(最常用)
  • nn.Conv3d:三维卷积层

有两种库函数可以调用。

1. 第一种:torch.nn.Conv2d(主要,比较简洁)

参数介绍:

Tips:

  • 上述计算公式中的padding[0]和padding[1]表示padding元组的元素值,设置padding=1时,可以看成padding[0]=1,padding[1]=1;stride、kernel_size类似。(具体看下面的参数详解)
  • 而dilation表示空洞卷积的参数,一般按照默认值,有兴趣可以去了解一下。在pytorch中默认为1,表示卷积核矩阵的元素是紧密排列的。
  • padding和stride往往是先决定一个的值,再去按照公式计算另一个的值。

①函数调用

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)(灰度图像通道数为1)。
  • out_channels:输出通道数。一般 out_channels = 卷积核的数量。
  • kernel_size:卷积核的大小。设置kernel_size=3,即高和宽为3×3;kernel_size=(3,5),即高和宽为3×5。不用手动设置卷积核的内容 weight ,函数第一次会对一些分布函数进行采样,从而初始化 weight 的值,后续这些值都是要通过训练学习的!!多通道的图片,在运算过程中,每个通道都会有有一个对应的卷积核
  • stride:卷积核的步长。可以是单个数字或元组(sH, sW)。默认值:1。
  • padding:输入图像四周的隐式填充。可以是字符串{'valid', 'same'}、单个数字或元组(padH, padW)。默认值:0 ('valid'表示无填充)。
    ①想要输出图像的尺寸和输入图像的尺寸相同,那么就要根据上面图片中的Hout和Wout计算公式来反推出padding的值,此时一般默认 stride =1。
    ②padding = 单个数字时,表示填充几圈0。
    ③画画图就能知道为什么尺寸不变时,padding该设置成这个数字。
  • padding_mode:填充方式。可以是'zeros' , 'reflect' , 'replicate'或者 'circular' . 默认是: 'zeros'。
  • bias(很少用到):可选的偏置张量。默认为True。
  • groups(很少用到):默认是1.

②函数示例

import torchvision
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
from torch import nn
from torch.utils.data import DataLoader

dataclass_transform = transforms.Compose([
    transforms.ToTensor(),
])

test_dataset = torchvision.datasets.CIFAR10(root='E:\\4_Data_sets\\species recognition', train=False,transform=dataclass_transform, download=True)
test_dataloader = DataLoader(dataset=test_dataset,batch_size=64)

class testNet(nn.Module):
    def __init__(self):
        super(testNet, self).__init__()
        self.conv1 = nn.Conv2d(3, 3 , 3,1,0)
    def forward(self, input):
        output = self.conv1(input)
        return output

testNet_Instance = testNet()
writer = SummaryWriter('logs')
step = 0
for data in test_dataloader:
    imgs, labels = data
    writer.add_images("test_conv2d_input", imgs, step)
    outputs = testNet_Instance(imgs)
    writer.add_images("test-conv2d_output", outputs, step)
    step += 1
writer.close()

2. 第二种:torch.nn.functional.conv2d(基本不用,但是参数的形状和维度可以看看)

①函数参数

  • input:输入的数据。其形状由四个维度组成:
  • minibatch:批次大小,即一次处理的样本数量。
  • in_channels:输入通道数(彩色图像的RGB三个通道对应3)(灰度图像通道数为1)。
  • iH:输入图像的高度。
  • iW:输入图像的宽度。
  • weight: 卷积核的参数。其形状由四个维度组成:
    多通道的图片,在运算过程中,每个通道都会有有一个对应的卷积核
  • out_channels:输出通道数,即卷积操作后生成的特征图数量。
  • in_channels/groups:每个组内的输入通道数,当groups参数大于1时,用于分组卷积。
  • kH:卷积核的高度。
  • kW:卷积核的宽度。
  • bias:可选的偏置张量。形状为(out_channels)。默认值:None。
  • stride:卷积核的步长。可以是单个数字或元组(sH, sW)。默认值:1。
    stride 定义了卷积核在输入数据上移动的步长。步长越大,输出特征图的空间尺寸越小。
  • sH:卷积核在高度方向上的步长。
  • sW:卷积核在宽度方向上的步长。
  • padding:输入图像四周的隐式填充。可以是字符串{'valid', 'same'}、单个数字或元组(padH, padW)。默认值:0 ('valid'表示无填充)。
    padding 用于在输入数据的边界周围添加零填充,以控制输出特征图的空间尺寸。
    这里的padding只能在四周填充0。
  • ‘valid’:表示无填充,输出特征图的空间尺寸会比输入小。
  • ‘same’:填充输入,使得输出特征图的空间尺寸与输入相同。但此模式不支持除1以外的任何步长值
  • padH:在高度方向上添加的填充量。
  • padW:在宽度方向上添加的填充量。

②函数示例

import torch
import torch.nn.functional as F

input = torch.tensor([[1, 2, 3, 4, 2],
                      [4, 5, 6, 2, 1],
                      [7, 8, 9, 7, 2],
                      [3, 4, 2, 0, 2],
                      [0, 3, 2, 4, 1]])
kernel = torch.tensor([[1, 2, 3],
                       [4, 5, 6],
                       [7, 8, 9]])

input_new = torch.reshape(input, (1, 1, 5, 5)) # conv2d的输入和输出都得是四维的,第一维对应的数值 1 表示batch_size=1
kernel_new = torch.reshape(kernel, (1, 1, 3, 3))

print(input_new.shape)
print(kernel_new.shape)

output = F.conv2d(input_new, kernel_new, stride=1, padding=1)

print(output)

运行结果:

torch.Size([1, 1, 5, 5])
torch.Size([1, 1, 3, 3])
tensor([[[[ 94, 154, 148, 111,  48],
          [186, 285, 273, 194,  86],
          [166, 225, 186, 128,  58],
          [104, 136, 146, 104,  57],
          [ 36,  44,  54,  42,  25]]]])
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号