李沐pytorch学习-卷积网络及其实现

news/2024/10/17 5:35:42/

一、卷积定义

        卷积计算过程如图1所示,即输入矩阵和核函数对应的位置相乘,然后相加得到输出对应位置的数。

 图1. 卷积计算过程

        该过程可以形象地从图2中展现。

图2. 二维卷积示意图

二、代码实现

2.1 实现互相关运算

import torch
from torch import nn
from d2l import torch as d2ldef corr2d(X, K): #@save"""计算二维互相关运算"""h, w = K.shapeY = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i, j] = (X[i:i + h, j:j + w] * K).sum()return Y

        h,w为卷积核的行、列数

        Y为输出矩阵,它的行、列数为X.shape[0] - h + 1和 X.shape[1] - w + 1X.shape[0] 为输入矩阵的行数,X.shape[0] - h 为卷积核可以向右移动的步数,因为移动步数为零时也会计算出一个值,所以 X.shape[0] - h + 1 为输出结果的行数,列数同理。

        X[i:i + h, j:j + w] * K 表示从输入矩阵中提取一个子矩阵,索引范围为\left\{\begin{matrix} i\leqslant row< i+h\\ j\leqslant col< j+w \end{matrix}\right.,即包含左边不包含右边,乘法表示对应元素相乘。

2.2 训练卷积网络的简单实现

import torch
from torch import nn
from d2l import torch as d2lX = torch.ones((6, 8))
X[:, 2:6] = 0Y = torch.zeros((6, 7))# 构造一个二维卷积层,它具有1个输出通道和形状为(1,2)的卷积核
conv2d = nn.Conv2d(1,1, kernel_size=(1, 2), bias=False)# 这个二维卷积层使用四维输入和输出格式(批量大小、通道、高度、宽度),
# 其中批量大小和通道数都为1
X = X.reshape((1, 1, 6, 8))
Y = Y.reshape((1, 1, 6, 7))
lr = 3e-2 # 学习率for i in range(10):Y_hat = conv2d(X)l = (Y_hat - Y) ** 2conv2d.zero_grad()l.sum().backward()# 迭代卷积核conv2d.weight.data[:] -= lr * conv2d.weight.gradif (i + 1) % 2 == 0:print(f'epoch {i+1}, loss {l.sum():.3f}')

三、填充与步幅

        填充(padding)指在输入矩阵周围添加行列,使卷积后得到的结果行列数更多。效果如图3所示。

 图3. 卷积填充示意图

import torch
from torch import nn# 为了方便起见,我们定义了一个计算卷积层的函数。
# 此函数初始化卷积层权重,并对输入和输出提高和缩减相应的维数def comp_conv2d(conv2d, X):# 这里的(1,1)表示批量大小和通道数都是1X = X.reshape((1, 1) + X.shape)Y = conv2d(X)# 省略前两个维度:批量大小和通道return Y.reshape(Y.shape[2:])# 请注意,这里每边都填充了1行或1列,因此总共添加了2行或2列
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1)X = torch.rand(size=(8, 8))
comp_conv2d(conv2d, X).shape# 上下各填充2行,左右各填充1列,总计填充4行2列
conv2d = nn.Conv2d(1, 1, kernel_size=(5, 3), padding=(2, 1))
comp_conv2d(conv2d, X).shape

        步幅(stride)指卷积核每次移动距离,增加步幅可以在不增加卷积核尺寸的条件下使得到的结果行列数更少。效果如图4所示。

图4. 卷积步幅示意图

 

import torch
from torch import nn# 向右移动的步幅与向下移动的步幅均为2
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2)X = torch.rand(size=(8, 8))
print(comp_conv2d(conv2d, X).shape) # 输出 torch.Size([4, 4])X = torch.rand(size=(8, 8))# padding之后,size=(8,10),输出行数=1+(8-3)/3=2,输出列数=1+(10-5)/4=2
# 行向移动的stride=3,列向移动的stride=4
conv2d = nn.Conv2d(1, 1, kernel_size=(3, 5), padding=(0, 1), stride=(3, 4))
print(comp_conv2d(conv2d, X).shape) # 输出 torch.Size([2, 2])

http://www.ppmy.cn/news/1043677.html

相关文章

聊聊@Accessors和@Builder

目录 Accessors和BuilderAccessors(chaintrue)BuilderAccessors和Builder的区别Accessors和Builder使用的坑 详细看看Accessors注解Accessors的源码Accessors属性说明fluent属性chain属性makeFinal属性prefix属性 Accessors和Builder Accessors(chaintrue) 就是new一个对象后…

【LeetCode】581.最短无序连续子数组

题目 给你一个整数数组 nums &#xff0c;你需要找出一个 连续子数组 &#xff0c;如果对这个子数组进行升序排序&#xff0c;那么整个数组都会变为升序排序。 请你找出符合题意的 最短 子数组&#xff0c;并输出它的长度。 示例 1&#xff1a; 输入&#xff1a;nums [2,6…

管理类联考——逻辑——真题篇——按知识分类——汇总篇——二、论证逻辑——支持加强——第四节——分类4——比例支持

文章目录 第四节 支持加强-分类4-比例支持题-支持加强-分类4-比例支持(数据支持)-同比削弱,差比支持真题(2011-54)-支持加强-分类4-比例支持(数据支持)-同比削弱,差比支持第四节 支持加强-分类4-比例支持 题-支持加强-分类4-比例支持(数据支持)-同比削弱,差比支持…

ISBN号码(NOIP2008 普及组第一题)

ISBN号码 说明 每一本正式出版的图书都有一个ISBN号码与之对应&#xff0c;ISBN码包括9位数字、1位识别码和3位分隔符&#xff0c;其规定格式如“x-xxx-xxxxx-x”&#xff0c;其中符号“-”就是分隔符&#xff08;键盘上的减号&#xff09;&#xff0c;最后一位是识别码&#x…

跟着美团学设计模式(感处)

读了着篇文章之后发现真的是&#xff0c;你的思想&#xff0c;你的思维是真的比比你拥有什么技术要强的。 注 开闭原则 开闭原则&#xff08;Open-Closed Principle&#xff09;是面向对象设计中的基本原则之一&#xff0c;它的定义是&#xff1a;一个软件实体应该对扩展开放…

noip2017普及组初赛 快速幂 求x^p%m的值。

说明 求xp mod m x^p \bmod m xpmodm 的值。 输入格式 三个不超过 10000 的正整数 x&#xff0c;p&#xff0c;m。 输出格式 1个整数。 样例 输入数据 1 2 10 100 Copy 输出数据 1 24 Copy 提示 noip2017普及组初赛 #include<bits/stdc.h> using namespace std; long l…

Linux 黑话解析:什么是 LUKS 加密?

导读LUKS 是 Linux 用户中流行的磁盘加密机制。在这篇术语解析文章中&#xff0c;可以了解更多关于 LUKS 的信息。 计算机安全旨在保护私密信息。有许多方法可以保护系统。一些用户使用简单的用户名/密码登录方案进行基本保护。其他用户可能会通过加密以不同的方式增加额外的保…

工具推荐:Chat2DB一款开源免费的多数据库客户端工具

文章首发地址 Chat2DB是一款开源免费的多数据库客户端工具&#xff0c;适用于Windows和Mac操作系统&#xff0c;可在本地安装使用&#xff0c;也可以部署到服务器端并通过Web页面进行访问。 相较于传统的数据库客户端软件如Navicat、DBeaver&#xff0c;Chat2DB具备了与AIGC…