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

目录

一、实验介绍

二、实验环境

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.mzph.cn/news/92289.shtml

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

相关文章

mysql的mvcc详解

一 MVCC的作用 1.1 mvcc的作用 1.MVCC(Multiversion Concurrency Control)多版本并发控制。即通过数据行的多个版本管理来实现数据库的并发控制,使得在InnoDB事务隔离级别下执行一致性读操作有了保障。 2.mysql中的InnoDB中实现了MVCC主要…

前端面试:01.图中输入什么?

~~~~~~~~~~~~~ 先自行想一想,答案在~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~ 先自行想一想,答案在~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~ 先自行想一想,答案在~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~ 先自行想一想,答案在~~~~~~~~~~~~~~~~~ ~~~~~~~~…

ciscn_2019_s_9

ciscn_2019_s_9 Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments32位,啥也没开,开心愉悦写shellcode int pwn() {char s[24]; // [esp8…

智能回答机器人的“智能”体现在哪里?

人工智能的广泛应用已经成为当今社会科技发展的趋势之一。通过人工智能技术,我们可以在不同领域中实现自动化、智能化和高效化,从而大大提升生产和生活效率。智能回答机器人的出现和使用便能很好的证明这一点。今天我们就来探讨一下智能会打机器人的“智…

python爬取百度图片

1.查询数据 打开网页。 https://cn.bing.com/images/search?q%E7%99%BE%E5%BA%A6%E5%9B%BE%E7%89%87&formHDRSC2&first1&cw1585&ch924 我们右键查看网页源代码,发现能找到我们需要的img衔接,但是这是一个动态网页。我们每次向下滑动网页,会发现图…

C++核心编程--多态篇

4.7、多态 4.7.1、多态的基本概念 多态是C面向对象三大特征之一 多态分为两类 静态多态:函数重载和运算符重载属于静态多态,复用函数名动态多态:派生类和虚函数实现运行时多态 静态多态和动态多态区别: 静态多态的函数地址早…

校物联网智慧安全用电平台的设计和运用-安科瑞黄安南

一.前言 安全用电历来都是学校安全工作的一个重点,然而每年因此发生的人身伤害以及火灾事故却在继续着,究其原因,主观上是我们的防患意识淡薄,客观上则是由于学生在宿舍使用违规电器、乱拉电线造成的。 现代的大学生宿舍&#x…

【生物信息学】使用谱聚类(Spectral Clustering)算法进行聚类分析

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 3. IDE 三、实验内容 0. 导入必要的工具 1. 生成测试数据 2. 绘制初始数据分布图 3. 循环尝试不同的参数组合并计算聚类效果 4. 输出最佳参数组合 5. 绘制最佳聚类结果图 6. 代码整合 一、实验介绍…

HashMap底层源码,数据结构

HashMap的底层结构在jdk1.7中由数组链表实现,在jdk1.8中由数组链表红黑树实现,以数组链表的结构为例。 JDK1.8之前Put方法: JDK1.8之后Put方法: HashMap基于哈希表的Map接口实现,是以key-value存储形式存在&#xff0c…

K8S内容分发网络之集群,nginx,负载均衡,防火墙

K8S内容分发网络之集群,nginx,负载均衡,防火墙 一、Kubernetes 区域可采用 Kubeadm 方式进行安装。1.所有节点,关闭防火墙规则,关闭selinux,关闭swap交换2.修改主机名3.所有节点修改hosts文件4.调整内核参数…

闪击笔试题

选择题 ping命令不涉及什么协议? A:DNS B: TCP C: ARP D: ICMP B,ping基于ICMP协议,解析路由会用到ARP和DNS a、b、c三人参加学科竞赛,每个学科按一二三名次给x、y、z分,已知a得22分,b和c得9分&#xf…

【图论C++】链式前向星(图(树)的存储)

/*** file * author jUicE_g2R(qq:3406291309)————彬(bin-必应)* 一个某双流一大学通信与信息专业大二在读 * * brief 一直在竞赛算法学习的路上* * copyright 2023.9* COPYRIGHT 原创技术笔记:转载需获得博主本人…

人工智能的学习算法

1956年,几个计算机科学家相聚在达特茅斯会议,提出了 “人工智能” 的概念,梦想着用当时刚刚出现的计算机来构造复杂的、拥有与人类智慧同样本质特性的机器。其后,人工智能就一直萦绕于人们的脑海之中,并在科研实验室中…

数组和切⽚ - Go语言从入门到实战

数组和切⽚ - Go语言从入门到实战 数组的声明 package main import "fmt" func main() { var a [3]int //声明并初始化为默认零值 a[0] 1 fmt.Println("a:", a) // 输出: a: [1 0 0] b : [3]int{1, 2, 3} //声明同时初始化 fmt.Println("b:…

Airtool for Mac——高效便捷的系统菜单栏网络工具!

在我们的数字化生活中,对于网络连接的稳定性和速度有着越来越高的需求。为了满足您对网络质量的实时监测和分析的需求,我们向大家介绍一款强大的Mac系统菜单栏网络工具——Airtool! Airtool是一款专为Mac设计的网络工具,它能够提…

番外5:下载+安装+配置Linux

任务前期工作: 01. 电脑已安装好VMware Workstation软件; 02.提前下载好Rhel-8.iso映像文件(文件较大一般在9.4GB,建议采用迅雷下载),本人使用的以下版本(地址ed2k://|file|rhel-8.4-x86_64-dvd…

基于PHP+MySQL的养老院管理系统

摘要 随着21世纪互联网时代的兴起,我们见证了人们生活方式的巨大改变。这个时代不仅深刻影响了我们的生活,还改变了我们对信息科学的看法。社会的各个领域都在不断发展,人们的思维也在不断进步,与此同时,信息的需求也与…

【React】React组件生命周期以及触发顺序(部分与vue做比较)

最近在学习React,发现其中的生命周期跟Vue有一些共同点,但也有比较明显的区别,并且执行顺序也值得讨论一下,于是总结了一些资料在这里,作为学习记录。 v17.0.1后生命周期图片 初始化阶段 由ReactDOM.render()触发 —…

百度交易中台之内容分润结算系统架构浅析

作者 | 交易中台团队 导读 随着公司内容生态的蓬勃发展,内容产出方和流量提供方最关注的“收益结算”的工作,也就成为重中之重。本文基于内容分润结算业务为入口,介绍了实现过程中的重难点,比如千万级和百万级数据量下的技术选型和…

用Java打印长方形、平行四边形 、三角形、菱形、空心菱形

今天复习使用嵌套for来完成一些任务,于是想着打印一些图形来练习 思考感悟 长方形 行数 和 每行的星星数嵌套遍历即可 平行四边形 核心:每行空格数总行数-行数 行数空格数132231 三角形 核心:每行星星数2*当前行数-1 行数星星数1123…