【PyTorch学习笔记】自用 零基础详细标注-6.卷积层 Convolution Layers

卷积层 Convolution Layers

nn.Conv1d:一维卷积;nn.Conv2d:二维;nn.Conv3d:三维。以conv2d作为例子。

nn.Conv2d

torch.nn是对torch.nn.functional的封装,只需要学习torch.nn即可。

官方文档:https://pytorch.org/docs/stable/nn.html?highlight=torch+nn#module-torch.nn

(1)参数

in_channels (int):输入图像的通道数

out_channels (int):通过卷积后产生的输出通道数

weight:权重,卷积核

kernel_size (int or tuple):卷积核大小

bias:偏置,卷积后结果是否再加上一个偏置值

stride:步长,卷积核每次移动距离,可以设置左右和上下移动相同,则输入一个数。若需要左右移动和上下移动距离不同,输入元祖(sH, sW)。默认值为1

padding:在输入图像的周围进行填充,可以给一个数或者一个元祖

dilation:空洞卷积,卷积核之间空一个一个

在这里插入图片描述

(2)卷积原理

在这里插入图片描述

计算过程:

在这里插入图片描述

对应相乘再相加,以第一步为例,output为11+22+01+00+11+20+12+21+1*0

卷积核每次移动步长由stride决定。

padding=1的情况,填充部分是0

在这里插入图片描述
在这里插入图片描述

简单的卷积实现:

#实现(2)中第一个计算
import torch
import torch.nn.functional as F     #卷积函数一般这样import

#需要tensor类型数据,打两个中括号说明是二维的矩阵
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]]) 

kernel = torch.tensor([[1, 2, 1]
                       [0, 1, 0]
                       [2, 1, 0]])

#conv2d中要求的input和weight的尺寸都需要四个数字,但上面自己创建的shape只有两个数字(高和宽)
#所以需要使用到pytorch中的尺寸变化,torch.reshape(),对照需求文档进行调整尺寸操作

#input一个平面,通道1,batchsize也为1
input = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))

output = F.conv2d(input, kernel, stride=1)
#padding之后再练习,此处默认为0
print(output)

#尝试stride为2
output2 = F.conv2d(input, kernel, stride=2)
print(output2)

#加入padding的情况
output3 = F.conv2d(input, kernel, stride=1, padding=1)
print(output3)

使用到CIFAR10数据集,做一个卷积网络,并对之前知识进行一个回顾:

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

#准备数据集,在参数中直接进行tensor转换,可以直接用在网络当中
dataset = torchvision.datasets.CIFAR10("./data", train=False, transform=torchvision.transforms.ToTensor(),
																				download=True)
dataloader = DataLoader(dataset, batch_size=64)

class MyNet(nn.Module):
    def __init__(self):
        super().__inti__()
        self.conv1 = Conv2d(3, 6, 3, stride=1, padding=0)
        #输入channel为3层,输出为6层,kernel_size为3

    def forward(self, x):
        x = self.conv1(x)
        return x

mynet = MyNet()

writer = SummaryWriter("logs")    #更直观的查看结果方法
step = 0

for data in dataloader:
    imgs, targets = data
    output = mynet(imgs)
    print(imgs.shape)
    print(output.shape)    #对比原图像和输出图像的shape
    *#torch.Size([64, 3, 32, 32])*
    writer.add_images("input", imgs, step)
    
    *#torch.Size([64, 6, 30, 30]),*直接使用add_images会报错,因为默认处理是三个通道,这个有六通道
    #下面是一种不太严谨的处理办法。reshape时不清楚该变成多少时写-1,会自动根据其他信息变化
    output = torch.reshape(output, (-1, 3, 30, 30))
    writer.add_images("input", imgs, step)

    step += 1

(3)其他问题

  1. nn.Conv2d和F.conv2d区别

nn.Conv2d是类式接口,F.conv2d是函数式接口。(一般大写都是类,小写是函数。)

nn.Conv2d是[2D卷积层],而F.conv2d是[2D卷积操作]。

(1)nn.Conv2d

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)

(2)F.conv2d

torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)

  1. 重要的推导公式

输入和输出、stride和padding不同的对应公式,比如怎么设置,长宽才会不变等问题。

input: ( N , C i n , H i n , W i n ) (N,C_{in},H_{in},W_{in}) (N,Cin,Hin,Win)

output: ( N , C o u t , H o u t , W o u t ) (N,C_{out},H_{out},W_{out}) (N,Cout,Hout,Wout)

H o u t = [ H i n + 2 × p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] × ( k e r n e l _ s i z e [ 0 ] − 1 ) s t r i d e [ 0 ] + 1 ] H_{out}=[{\frac{H_{in}+2×padding[0]-dilation[0]×(kernel\_size[0]-1)}{stride[0]}}+1] Hout=[stride[0]Hin+2×padding[0]dilation[0]×(kernel_size[0]1)+1]

W o u t = [ W i n + 2 × p a d d i n g [ 1 ] − d i l a t i o n [ 1 ] × ( k e r n e l _ s i z e [ 1 ] − 1 ) s t r i d e [ 1 ] + 1 ] W_{out}=[{\frac{W_{in}+2×padding[1]-dilation[1]×(kernel\_size[1]-1)}{stride[1]}}+1] Wout=[stride[1]Win+2×padding[1]dilation[1]×(kernel_size[1]1)+1]

k: kernel_size;s: stride;p:padding

经常希望经过卷积后张量尺寸不变,常用以下(k, s, p)组合:

(k, s, p) = (1, 1, 0) or (3, 1, 1) or (5, 1, 2) or (7, 1, 3)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值