Pytorch学习日记02-自定义模型及卷积操作

创建自己的第一个模型

 了解内容即为Pytorch官网文档 pytorch

import torch
from torch import nn

"""
    pytorch提供所有神经网络里的细节操作(卷积、线性变换、非线性变化等)。
    用户只需要在创建自己的模型时想好每步所要执行的功能,进行组合实现。
    创建模型继承官方书写的nn.Module,初始化所需变量。并在前向传播中书写自己所要执行的动作。
"""

class MyModule(nn.Module):
    def __init__(self) -> None:
        super().__init__()

    def forward(self, input):
        output = input + 1
        return output
# 断点打入,单步执行,观看程序执行步骤。
my_module = MyModule()
x = torch.tensor(1.0)
output = my_module(x)
print(output)

卷积的初步了解

nn.funcational.conv2d

 卷积的理解可能不知道其这样做究竟有啥用处,或者是这样做的过程是为了啥。自己理解的这个可以和图像处理中的滤波等价理解,(均值滤波)。开始学可以只知道他是如何计算的即可,在后面学习深度学习原理在做思考即可。
  灰度图像示例,对应图像像素值与卷积核对应相乘再相加得到卷积的输出。卷积函数中的Stride指出卷积核在图像中的移动步骤,单数字即表示横向纵向均移动x,也可为一个元组(xw,yw)。
无填充

卷积演示

官网参数解释

import torch
import torch.nn.functional as F

"""
    一个简单的测试卷积过程。并解释函数的部分参数
    torch.nn.functional.conv2d的参数需求
    conv2d()
        第一个参数为输入数据,需要形状为(minibatch,通道数,高,宽)
        卷积核 为tensor类型,也需要和上述一样的形状
        stride 即步数,每次运行走几步,可以但数字也可以元组指定高宽
        padding 在输入数据的左右两边作填充,默认不填从,单数字则指定填充大小。也可以为元组大小(H,W)
"""
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
kernel = torch.tensor([[1, 2, 1],
                       [0, 1, 0],
                       [2, 1, 0]])
# 此处就是修改输入数据的shape,使其能够满足卷积函数的输出参数的形状,第一个1为batch_size,第二个1 为一个通道,后面为宽乘高。
input = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))
print(input.shape)
print(kernel.shape)

output = F.conv2d(input, kernel, stride=1)
print(output)
# 步数改变,输出形状大小改变
output2 = F.conv2d(input, kernel, stride=2)
print(output2)
# 添加填充周围,输出形状大小均改变。
output3 = F.conv2d(input, kernel, stride=1, padding=1)
print(output3)

结果:
	torch.Size([1, 1, 5, 5])
	torch.Size([1, 1, 3, 3])
	tensor([[[[10, 12, 12],
	          [18, 16, 16],
          	[13,  9,  3]]]])
	tensor([[[[10, 12],
         	 [13,  3]]]])
	tensor([[[[ 1,  3,  4, 10,  8],
         	 [ 5, 10, 12, 12,  6],
         	 [ 7, 18, 16, 16,  8],
          	[11, 13,  9,  3,  4],
          	[14, 13,  9,  7,  4]]]])

当padding为1时:空位置默认为0
在这里插入图片描述

在这里插入图片描述

注:torch.reshape()函数的使用

  • 参数1 inpute输入需要改变的图像数据
  • 参数后面的则为变更为什么形状。batchsize,通道,高,宽
  • torch.reshape(input,(-1,3,25,25)) -1表示不知道,后面自己调节
  • 目的就是一些torch的内部函数要求数据的维度必须遵守4维度或三维度。所以需要一个变换。
  • 具体可以观察每个函数后面的需要:
  • 为下面的Conv2d的计算公式

nn.Conv2d

nn.functional是模型更细分的操作。nn是进一步对于functional的功能进行封装,更容易使用。
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 输入图像的通道数
  • out_channels 卷积后输出图像的通道数
  • kernel_size 卷积核大小,int或tuple类型 33 HW
  • stride 卷积过程中的步进大小 int或tuple类型 默认为1
  • padding 是否进行边缘填充 默认为0
  • dilation 空洞卷积,不常用默认为1
  • groups 默认为1
  • bias 偏执 默认为true
  • padding_mode 以什么形式填充边缘,一般以zeros形式填充

可以通过该动画演示查看参数对卷积过程的影响:卷积可视化
第一部分所展示的为单通道数的卷积过程,针对多通道数的图片卷积。

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

"""
    使用封装后的卷积层类进行实现自己的模型,该模型仅有一个卷积层,并测试卷积层中所需要的多个参数,得到输出数据的内容进行展示。
    本节将会对以往学习过的所有知识进行整合!依次需要的知识点有:
        图像数据的transform的变换器的使用。需要通过torchvision.transforms.Totensor()进行将PIL变换成tensor
        获取网络数据集并进行初步变化  torchvision.datasets的使用
        将数据集按照batchsize大小加载到数据加载器中,DataLoader
        神经网络的自定义模型。需要手动实现nn.Module的初始化方法和forward方法。
        进行卷积核的参数设置
        进行数据集形状的改变以满足需求,使用torch.reshape(inpute,(batchsize,channels,H,W))
        最后需要使用最初学习的tensorboard进行将卷积后的结果展示出来。writer.add_images()。
"""
# 获取数据集
dataset = torchvision.datasets.CIFAR10("../DataSet/dataset", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=False)
# 数据集切块取出
dataloader = DataLoader(dataset, batch_size=64)


# 创建自己的模型
class MyModule(nn.Module):
    def __init__(self):
        super().__init__()
        # 给自己网络配置一个卷积层  这里的卷积核是内部给定的
        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


mymodule = MyModule()
print(mymodule)

writer = SummaryWriter("conv2d")

for data in dataloader:
    imgs, targets = data
    output = mymodule(imgs)
    print(imgs.shape)
    print(output.shape)
    # torch.Size([64, 3, 32, 32])
    writer.add_images("input",imgs)
    # torch.Size([64, 6, 30, 30])
    output = torch.reshape(output,(-1,3,30,30))
    writer.add_images("output",output)
    # 此处的break仅为了展示第一个数据加载器中的处理结果。
    break

writer.close()

实验截图

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值