【深度学习实验】卷积神经网络(三):自定义二维卷积层:步长、填充、输入输出通道

目录

一、实验介绍

二、实验环境

1. 配置虚拟环境

2. 库版本介绍

三、实验内容

0. 导入必要的工具包

1. 步长、填充

a. 二维互相关运算(corr2d)

b. 二维卷积层类(Conv2D)

c. 模型测试

d. 代码整合

2. 输入输出通道

a. corr2d_multi_in

b. corr2d_multi_in_out

c. Conv2D

d. 模型测试

e. 代码整合


一、实验介绍

        本实验实现了二维卷积神经网络的卷积层设置步长、填充、输入输出通道等功能。

二、实验环境

    本系列实验使用了PyTorch深度学习框架,相关操作如下:

1. 配置虚拟环境

conda create -n DL python=3.7 
conda activate DL
pip install torch==1.8.1+cu102 torchvision==0.9.1+cu102 torchaudio==0.8.1 -f https://download.pytorch.org/whl/torch_stable.html
conda install matplotlib
 conda install scikit-learn

2. 库版本介绍

软件包本实验版本目前最新版
matplotlib3.5.33.8.0
numpy1.21.61.26.0
python3.7.16
scikit-learn0.22.11.3.0
torch1.8.1+cu1022.0.1
torchaudio0.8.12.0.2
torchvision0.9.1+cu1020.15.2

三、实验内容

ChatGPT:

        卷积神经网络(Convolutional Neural Network,简称CNN)是一种深度学习模型,广泛应用于图像识别、计算机视觉和模式识别等领域。它的设计灵感来自于生物学中视觉皮层的工作原理。

        卷积神经网络通过多个卷积层、池化层全连接层组成。

  • 卷积层主要用于提取图像的局部特征,通过卷积操作和激活函数的处理,可以学习到图像的特征表示。
  • 池化层则用于降低特征图的维度,减少参数数量,同时保留主要的特征信息。
  • 全连接层则用于将提取到的特征映射到不同类别的概率上,进行分类或回归任务。

        卷积神经网络在图像处理方面具有很强的优势,它能够自动学习到具有层次结构的特征表示,并且对平移、缩放和旋转等图像变换具有一定的不变性。这些特点使得卷积神经网络成为图像分类、目标检测、语义分割等任务的首选模型。除了图像处理,卷积神经网络也可以应用于其他领域,如自然语言处理和时间序列分析。通过将文本或时间序列数据转换成二维形式,可以利用卷积神经网络进行相关任务的处理。

0. 导入必要的工具包

import torch
from torch import nn
import torch.nn.functional as F

1. 步长、填充

承接上文:

【深度学习实验】卷积神经网络(二):自定义简单的二维卷积神经网络_QomolangmaH的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_63834988/article/details/133278280?spm=1001.2014.3001.5501

  • 卷积算子增加步长零填充
  • 改进了互相关函数 corr2d

  • 改进了卷积算子 Conv2D

  • 在 forward 方法中,对输入 x 进行了填充操作,通过在输入的边缘周围添加零值像素来处理填充。这样做可以确保卷积核在输入的边缘位置也能进行有效的卷积操作,从而保持输出尺寸与输入尺寸的一致性。

  • 在使用 Conv2D 类创建对象时,可以通过传递不同的参数来对步长和填充进行灵活的设置。这样可以根据具体任务的需求来调整卷积操作的步长和填充方式,以获得更好的性能和适应性。

a. 二维互相关运算(corr2d)

        修改为:

def corr2d(X, K, s): h, w = K.shapeY = torch.zeros(((X.shape[0] - h + 1)//s , (X.shape[1] - w + 1)//s))for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i, j] = (X[i*s:i*s + h, j*s:j*s + w] * K).sum()return Y

        添加了一个步长参数 s。通过指定步长,可以控制卷积操作在输入上的滑动步长,从而实现对输出大小的调整。在原始代码中,步长相当于固定为1,而修改后的代码可以通过调整 s 的值来改变步长。

b. 二维卷积层类(Conv2D)

        修改为:

class Conv2D(nn.Module):def __init__(self, kernel_size, stride=1, padding=0, weight=None):super().__init__()if weight is not None:self.weight = weightelse:self.weight = nn.Parameter(torch.rand(kernel_size))self.bias = nn.Parameter(torch.zeros(1))self.stride = strideself.padding = paddingdef forward(self, x):new_x = torch.zeros((x.shape[0] + 2*self.padding, x.shape[1] + 2*self.padding))new_x[self.padding:x.shape[0] + self.padding,self.padding:x.shape[1] + self.padding] = xreturn corr2d(new_x, self.weight, self.stride) + self.bias
  • 添加了步长和填充参数:
    • 步长参数 stride 控制卷积核在输入上的滑动步长
    • 填充参数 padding 在输入的边缘周围添加零值像素,以控制输出尺寸。
      • 在 forward 方法中,对输入 x 进行了填充操作,通过在输入的边缘周围添加零值像素来处理填充。(这样做可以确保卷积核在输入的边缘位置也能进行有效的卷积操作,从而保持输出尺寸与输入尺寸的一致性。)

c. 模型测试

# 由于卷积层还未实现多通道,所以我们的图像也默认是单通道的
fake_image = torch.randn((5,5))# 需要为步长和填充指定参数,若未指定,则使用默认的参数1和0
narrow_conv = Conv2D(kernel_size=(3,3))
output1 = narrow_conv(fake_image)
print(output1.shape)wide_conv = Conv2D(kernel_size=(3,3),stride=1,padding=2)
output2 = wide_conv(fake_image)
print(output2.shape)same_width_conv = Conv2D(kernel_size=(3,3),stride=1,padding=1)
output3 = same_width_conv(fake_image)
print(output3.shape)

输出:

torch.Size([3, 3])
torch.Size([7, 7])
torch.Size([5, 5])

d. 代码整合

# 导入必要的工具包
import torch
from torch import nn
import torch.nn.functional as F# 修改后的互相关函数
def corr2d(X, K, s):h, w = K.shapeY = torch.zeros(((X.shape[0] - h + 1)//s , (X.shape[1] - w + 1)//s))for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i, j] = (X[i*s:i*s + h, j*s:j*s + w] * K).sum()return Y# 修改后的卷积算子
class Conv2D(nn.Module):def __init__(self, kernel_size, stride=1, padding=0, weight=None):super().__init__()if weight is not None:self.weight = weightelse:self.weight = nn.Parameter(torch.rand(kernel_size))self.bias = nn.Parameter(torch.zeros(1))self.stride = strideself.padding = paddingdef forward(self, x):new_x = torch.zeros((x.shape[0] + 2*self.padding, x.shape[1] + 2*self.padding))new_x[self.padding:x.shape[0] + self.padding,self.padding:x.shape[1] + self.padding] = xreturn corr2d(new_x, self.weight, self.stride) + self.bias# 由于卷积层还未实现多通道,所以我们的图像也默认是单通道的
fake_image = torch.randn((5,5))# 需要为步长和填充指定参数,若未指定,则使用默认的参数1和0
narrow_conv = Conv2D(kernel_size=(3,3))
output1 = narrow_conv(fake_image)
print(output1.shape)wide_conv = Conv2D(kernel_size=(3,3),stride=1,padding=2)
output2 = wide_conv(fake_image)
print(output2.shape)same_width_conv = Conv2D(kernel_size=(3,3),stride=1,padding=1)
output3 = same_width_conv(fake_image)
print(output3.shape)

2. 输入输出通道

a. corr2d_multi_in

def corr2d_multi_in(X, K, s):# 先遍历“X”和“K”的第0个维度(通道维度),再把它们加在一起return sum(corr2d(x, k, s) for x, k in zip(X, K))

        遍历输入张量 X 和核张量 K 的第一个维度(通道维度),并对每个通道执行互相关操作,然后将结果加在一起。

b. corr2d_multi_in_out

def corr2d_multi_in_out(X, K, s):# 迭代“K”的第0个维度,每次都对输入“X”执行互相关运算。# 最后将所有结果都叠加在一起return torch.stack([corr2d_multi_in(X, k, s) for k in K], 0)

        用于处理多通道输入和多通道输出。它迭代核张量 K 的第一个维度,并对输入张量 X 执行多通道的互相关操作,将所有结果叠加在一起。

c. Conv2D

        进一步修改:

class Conv2D(nn.Module):def __init__(self, in_channels, out_channels, kernel_size=None, stride=1, padding=0, weight=None):super().__init__()self.in_channels = in_channelsself.out_channels = out_channelsif weight is not None:h, w = weight.shapeweight = weight * torch.ones(in_channels, out_channels, h, w)self.weight = nn.Parameter(weight)else:self.weight = nn.Parameter(torch.rand((in_channels, out_channels, kernel_size, kernel_size)))self.bias = nn.Parameter(torch.zeros(1))self.stride = strideself.padding = paddingdef forward(self, x):new_x = torch.zeros((x.shape[0], x.shape[1] + 2 * self.padding, x.shape[2] + 2 * self.padding))new_x[:, self.padding:x.shape[1] + self.padding, self.padding:x.shape[2] + self.padding] = xreturn corr2d_multi_in_out(new_x, self.weight, self.stride)
  • 在 Conv2D 类的构造函数中,添加了输入通道数 in_channels 和输出通道数 out_channels 的参数。根据输入参数的不同,可以创建具有不同输入和输出通道数的卷积算子。

  • 在 Conv2D 类中,对权重参数进行了一些修改。如果传入了 weight 参数,则将其扩展为具有相同形状的多通道权重。否则,将随机生成一个具有指定输入和输出通道数的权重。

  • 在 forward 方法中,对输入张量 x 进行扩展,以适应填充操作。然后调用新的互相关函数 corr2d_multi_in_out 进行多通道的互相关操作。

d. 模型测试

fake_image = torch.randn((3,5,5))
conv = Conv2D(in_channels=3, out_channels=1, kernel_size=3, stride=2,padding=1)
output = conv(fake_image)
print(output.shape)

e. 代码整合

# 导入必要的工具包
import torch
from torch import nn
import torch.nn.functional as F# 修改后的互相关函数
def corr2d(X, K, s):h, w = K.shapeY = torch.zeros(((X.shape[0] - h + 1) // s, (X.shape[1] - w + 1) // s))for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i, j] = (X[i * s:i * s + h, j * s:j * s + w] * K).sum()return Y# 修改后的卷积算子
# X为输入图像,K是输入的二维的核数组
def corr2d_multi_in(X, K, s):# 先遍历“X”和“K”的第0个维度(通道维度),再把它们加在一起return sum(corr2d(x, k, s) for x, k in zip(X, K))def corr2d_multi_in_out(X, K, s):# 迭代“K”的第0个维度,每次都对输入“X”执行互相关运算。# 最后将所有结果都叠加在一起return torch.stack([corr2d_multi_in(X, k, s) for k in K], 0)class Conv2D(nn.Module):def __init__(self, in_channels, out_channels, kernel_size=None, stride=1, padding=0, weight=None):super().__init__()self.in_channels = in_channelsself.out_channels = out_channelsif weight is not None:h, w = weight.shapeweight = weight * torch.ones(in_channels, out_channels, h, w)self.weight = nn.Parameter(weight)else:self.weight = nn.Parameter(torch.rand((in_channels, out_channels, kernel_size, kernel_size)))self.bias = nn.Parameter(torch.zeros(1))self.stride = strideself.padding = paddingdef forward(self, x):new_x = torch.zeros((x.shape[0], x.shape[1] + 2 * self.padding, x.shape[2] + 2 * self.padding))new_x[:, self.padding:x.shape[1] + self.padding, self.padding:x.shape[2] + self.padding] = xreturn corr2d_multi_in_out(new_x, self.weight, self.stride)fake_image = torch.randn((3,5,5))
conv = Conv2D(in_channels=3, out_channels=1, kernel_size=3, stride=2,padding=1)
output = conv(fake_image)
print(output.shape)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/144773.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【冰糖R语言】创建R包(打包R程序)

目标:将现有R程序打包 可能涉及知识点:devtools包、usethis包、Rstudio软件 一、R包的类型 通常一个R包中包含以下元素: 1)R文件夹:函数代码 2)man文件夹:存放每个函数的注释文件 3&#x…

KNN(上):数据分析 | 数据挖掘 | 十大算法之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据…

36 二叉树中序遍历

二叉树中序遍历 题解1 递归题解2 迭代 给定一个二叉树的根节点 root &#xff0c;返回它的 中序 遍历 。 提示&#xff1a; 树中节点数目在范围 [0, 100] 内-100 < Node.val < 100 进阶: 递归算法很简单&#xff0c;你可以通过迭代算法完成吗&#xff1f; 题解1 递归…

解决大模型行业落地三大挑战,华为云GaussDB向量数据库正式发布

随着AI大模型产品及应用呈现爆发式增长,新的AI时代已经到来。向量数据库可与大语言模型配合使用,解决大模型落地过程中的痛点,已成为企业数据处理和应用大模型的必选项。在近日举行的华为全联接大会2023期间,华为云正式发布GaussDB向量数据库。GaussDB向量数据库基于GaussD…

Nodejs+vue高校机房设备管理系统jt07u

开发语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 集成IDE对高校机房设备管理系统统进行开发,整合系统的各个模块。 拟开发的高校机房设备管理系统通过测试,确保在最大负载的情况下…

亚马逊无线鼠标FCC认证办理 FCC ID

无线鼠标是指无线缆直接连接到主机的鼠标&#xff0c;采用无线技术与计算机通信&#xff0c;从而省却电线的束缚。通常采用无线通信方式&#xff0c;包括蓝牙、Wi-Fi (IEEE 802.11)、Infrared (IrDA)、ZigBee (IEEE 802.15.4)等多个无线技术标准。随着人们对办公环境和操作便捷…

Polygon Miden:扩展以太坊功能集的ZK-optimized rollup

1. 引言 Polygon Miden定位为zkVM&#xff0c;定于2023年Q4上公开测试网。 zk、zkVM、zkEVM及其未来中指出&#xff0c;当前主要有3种类型的zkVM&#xff0c;括号内为其相应的指令集&#xff1a; mainstream&#xff08;WASM, RISC-V&#xff09;EVM&#xff08;EVM bytecod…

C理解(一):内存与位操作

本文主要探讨C语言的内存和为操作操作相关知识。 冯诺依曼结构和哈佛结构 冯诺依曼结构&#xff1a;数据和代码放在一起,便于读取和修改,安全性低 哈佛结构是&#xff1a;数据和代码分开存放,安全性高,读取和修麻烦 内存 内存是用来存储全局变量、局…

Cloudflare进阶技巧:缓存利用最大化

1. 引言 cloudflare我想你应该知道是什么&#xff0c;一家真正意义上免费无限量的CDN&#xff0c;至今未曾有哥们喷它的。当然&#xff0c;在国内的速度确实比较一般&#xff0c;不过这也不能怪它。 CDN最大的特色&#xff0c;我想就是它的缓存功能&#xff0c;达到防攻击&am…

云原生之使用Docker部署PDF多功能工具Stirling-PDF

云原生之使用Docker部署PDF多功能工具Stirling-PDF 一、Stirling-PDF介绍1.1 Stirling-PDF简介1.2 Stirling-PDF功能 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Stirli…

redis查看耗时久的命令

redis查看耗时久的命令主要有两招&#xff1a;latency和slow log 【latency】 在Redis中&#xff0c;latency命令用于监视和测量Redis实例的延迟。 先进入redis: redis-cli -h 127.0.0.1 -p 24000[查看延迟监视器阈值] CONFIG GET latency-monitor-threshold这个值返回0&…

【计算机视觉】3.传统计算机视觉方法

传统计算机视觉方法 一、大纲图像分割人脸检测行人检测 二、图像分割基于阈值检测的方法基于边缘检测的方法基于区域的分割方法基于图论的分割方法 三、人脸检测四、行人检测五、SVM六、DPM 一、大纲 图像分割 基于阈值、基于边缘 基于区域、基于图论 人脸检测 Haar-like 特征…

Java实现使用多线程,实现复制文件到另一个目录,起不一样的名字,创建100万个数据

目录 1 需求2 实现 1 需求 我现在有一个300MB 的文件&#xff0c;想要根据这个文件&#xff0c;创建100万个大小一样的&#xff0c;名称不一样&#xff0c;如何实现&#xff0c;如何比较快点实现 2 实现 1 先准备好这个文件 2 准备好目录 3 写代码 private static void crea…

python:bottle + eel 模仿 mdict 查英汉词典

Eel 是一个轻量的 Python 库&#xff0c;用于制作简单的类似于离线 HTML/JS GUI 应用程序&#xff0c;并具有对 Python 功能和库的完全访问权限。 Eel 托管一个本地 Web 服务器&#xff0c;允许您使用 Python 注释函数&#xff08;annotate functions&#xff09;&#xff0c;…

(附源码)springboot体检预约APP 计算机毕设16370

目 录 摘要 1 绪论 1.1开发背景 1.2研究现状 1.3springboot框架介绍 1.4论文结构与章节安排 2 Springboot体检预约APP系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 操作可行性分析 2.2 系统流程分析 2.2.1 数据添加流程 2.2.2 数据…

ShowDoc部署与应用:文档管理的最佳实践

在项目开发和协作中&#xff0c;文档管理扮演着至关重要的角色。ShowDoc作为一款卓越的开源文档管理工具&#xff0c;不仅提供强大的文档管理功能&#xff0c;还具备简单易用的协作和部署特性。我们的项目团队最初选择了ShowDoc作为文档管理工具&#xff0c;用以促进前后端协作…

【算法】莫队

这篇博客起源于本人把一道 p o w ( 2 , n ) pow(2,n) pow(2,n) 的问题考虑成求组合数前缀和的问题qwq&#xff0c;于是接触到了这个新算法来总结一下 参考自这篇文章&#xff0c;写得太好了 首先是一道模板题 题目意思是&#xff0c;给出一个数组a&#xff0c;再给出多个区…

nginx 多层代理 + k8s ingress 后端服务获取客户真实ip 配置

1.nginx http 七层代理 修改命令空间&#xff1a; namespace: nginx-ingress : configmap&#xff1a;nginx-configuration kubectl get cm nginx-configuration -n ingress-nginx -o yaml添加如上配置 compute-full-forwarded-for: “true” forwarded-for-header: X-Forwa…

点击、拖拉拽,BI系统让业务掌握数据分析主动权

在今天的商业环境中&#xff0c;数据分析已经成为企业获取竞争优势的关键因素之一。然而&#xff0c;许多企业在面对复杂的数据分析工具时&#xff0c;却常常感到困扰。这些工具往往需要专业的技术人员操作&#xff0c;而且界面复杂&#xff0c;难以理解和使用。对业务人员来说…

JDK17新特性

为什么要升级JDK17 JDK17带来了哪些变化 swtich语句增强 // jdk8switch int statusCode 0; String statusName ""; switch (statusCode) {case 1:statusName "开始";break;case 2:statusName "进行中";break;case 3:statusName "结束…