利用矩阵相乘手动实现卷积操作

卷积(Convolution) 是信号处理和图像处理中的一种重要操作,广泛应用于深度学习(尤其是卷积神经网络,CNN)中。它的核心思想是通过一个卷积核(Kernel) 或 滤波器(Filter) 对输入信号或图像进行扫描,提取局部特征。在信号处理领域,卷积可以看作是两个函数或信号在某种程度上的“重叠”运算。在图像处理中,卷积是图像滤波的核心操作。图像滤波器,例如边缘检测、模糊和锐化都是通过卷积来实现的。

1. 卷积的数学定义

一维离散卷积

给定两个离散信号 f 和 g,它们的卷积 (f∗g) 定义为:

(f * g)[n] = \sum_{m=-\infty}^{\infty} f[m] \cdot g[n - m]

二维离散卷积

对于二维信号(如图像),卷积的定义为:

(f * g)[m, n] = \sum_{k_1=-\infty}^{\infty} \sum_{k_2=-\infty}^{\infty} f[k_1, k_2] \cdot g[m - k_1, n - k_2]

2. 卷积的直观理解

卷积操作可以理解为:

  1. 滑动窗口:卷积核在输入信号或图像上滑动。

  2. 点积操作:在每个位置,卷积核与输入信号的局部区域进行点积。

  3. 特征提取:通过卷积核提取输入信号的局部特征。

3. 卷积的参数

在深度学习中,卷积操作通常包含以下参数:

  • 输入(Input):输入信号或图像,形状为 (batch_size, channels, height, width)

  • 卷积核(Kernel):滤波器,形状为 (out_channels, in_channels, kernel_height, kernel_width)

  • 步长(Stride):卷积核滑动的步长,控制输出的大小。

  • 填充(Padding):在输入信号或图像的边缘填充值(如 0),控制输出的大小。

  • 输出(Output):卷积操作的结果,形状为 (batch_size, out_channels, output_height, output_width)

4. 卷积的输出大小

卷积操作的输出大小可以通过以下公式计算:

\text{output\_height} = \left\lfloor \frac{\text{input\_height} - \text{kernel\_height}+2*\text{padding}}{\text{stride}} \right\rfloor + 1

其中:

  • input_size:输入信号或图像的大小。

  • kernel_size:卷积核的大小。

  • padding:填充大小。

  • stride:步长。

5.卷积的计算

1.单输入通道,单个卷积核

输入图片的像素值如下:

\begin{bmatrix} 1 & 1 & 1 & 0 & 0 \\ 0 & 1 & 1 & 1 & 0 \\ 0 & 0 & 1 & 1 & 1 \\ 0 & 0 & 1 & 1 & 0 \\ 0 & 1 & 1 & 0 & 0 \end{bmatrix}

卷积核为:

\begin{bmatrix} 1 & 0 &1 \\ 0 & 1 & 0 \\ 1 & 0 & 1 \\ \end{bmatrix}

计算第一个子区域和卷积核的对应元素乘积之和,如下图所示:

 Cov_feature[0,0]=1x1+1x0+1x1+0x0+1x1+1x0+0x1+0x0+1x1 =4

接着计算第二个子区域和卷积核的对应元素乘积之和,如下图所示:

Cov_feature[0,1] =1x1+1x0+0x1+1x0+1x1+1x0+0x1+1x0+1x1=3

……

2.多输入通道,单个卷积核

若输入含有多个通道,则对于某个卷积核,分别对每个通道求feature map后将对应位置相加得到最终的feature map,如下图所示:

3.多个卷积核

6. 卷积的代码实现

1.简单卷积的实现(不包含batch_size,channels):

import  torchdef  matrix_muti_for_cov(x,kernel,stride=1):# kernel.shape ->(h,w)output_h= int((x.shape[0]-kernel.shape[0])/stride) +1   # 计算输入的高output_w= int((x.shape[1]-kernel.shape[1])/stride) +1   # 计算输入的宽output =torch.zeros(output_h,output_w) #  初始化为(output_h,output_w)的矩阵for i in range (0,x.shape[0]-kernel.shape[0]+1,stride): # 遍历高的维度for j in range (0,x.shape[1]-kernel.shape[1]+1,stride): # 遍历宽的维度area = x[i:i+kernel.shape[0],j:j+kernel.shape[1]] # 获取卷积核滑过区域output[i,j] =torch.sum(area*kernel)  实现卷积操作return  output

 调用函数,求卷积结果


input =torch.randn(5,5)
kernel =torch.randn(3,3)  
output =matrix_muti_for_cov(input,kernel)
print(output)

 输出为

tensor([[-2.0837, -1.1043,  3.2571],
        [-1.1638,  0.7576,  3.2776],
        [ 0.3669,  0.4015,  0.9808]])

使用torch.nn.functional.conv2d(input,jernel) 来测试:

在conv2d函数中,要求

input.shape(batch_size,in_channels,hight,weight)

kernel.shape(out_channels,in_channels,kernel_hight,kernel_weight)

input =input.reshape((1,1,input.shape[0],input.shape[1]))
kernel =kernel.reshape((1,1,kernel.shape[0],kernel.shape[1]))
cov_out =F.conv2d(input,kernel)
print(cov_out.squeeze(0).squeeze(0))

 输出为

tensor([[-2.0837, -1.1043,  3.2571],
        [-1.1638,  0.7576,  3.2776],
        [ 0.3669,  0.4015,  0.9808]])

cov_out.squeeze(0).squeeze(0)是为了将batch_size维度和channels维度的数据剔出,和上面的output的数据维度相对应。

对上述代码进行简单的升级操作

def  matrix_muti_for_cov(x,kernel,stride=1,padding=0):# kernel.shape ->(h,w)output_h= int((x.shape[0]-kernel.shape[0])/stride) +1output_w= int((x.shape[1]-kernel.shape[1])/stride) +1output =torch.zeros(output_h,output_w)area_matrix = torch.zeros(output.numel(),kernel.numel())kernel_matrix =kernel.reshape(kernel.numel(),-1)for i in range (0,x.shape[0]-kernel.shape[0]+1,stride):for j in range (0,x.shape[1]-kernel.shape[1]+1,stride):area = x[i:i+kernel.shape[0],j:j+kernel.shape[1]]area_matrix[i+j] = torch.flatten(area)output_matrix =area_matrix@ kernel_matrixoutput = output_matrix.reshape(output_h, output_w)return  output

2.简易完整卷积的实现(包含batch_size,channels,stride,padding):

def  matrix_muti_for_cov2(input,kernel,stride=1,padding=1):# input.size ---> [batch_size,channels,hight,weight]batch,channel,x_h,x_w =input.shape# input.size ---> [out_channels,in_channels,kernel_hight,kernel_weight]channel_out,channels_in,kernel_h,kernel_w =kernel.shape# math.floor() 函数的作用是向下取整,也称为取底。 它返回小于或等于给定数值的最大整数output_h= (math.floor((x_h+2*padding-kernel_h)/stride) +1)output_w= (math.floor((x_w+2*padding-kernel_w)/stride) +1)output =torch.zeros(batch,channel_out,output_h,output_w)  # 初始化矩阵input_padded = torch.zeros(batch, channel, x_h+2*padding, x_w+2*padding) #  实现padding操作input_padded[:,:,padding:x_h+padding,padding:x_w+padding] =input  # 将input的值赋值给input_padded对应的区域for  b in range(batch):   # 遍历batch维度for c_out  in  range(channel_out):  # 遍历out_channel维度for i in range (0,output_h,stride): # 遍历hight维度for j in range (0,output_w,stride):  # 遍历 weight维度area = input_padded[b,:,i:i+kernel_h,j:j+kernel_w]output[b,c_out,i,j] =torch.sum(area*kernel[c_out])                   return output

调用函数, 测试结果

cov_out =matrix_muti_for_cov2(input,kernel)
# print(cov_out)
cov_out2 =F.conv2d(input,kernel,padding=1)
# print(cov_out2)
if torch.allclose(cov_out, cov_out2, rtol=1e-05, atol=1e-08):print("两个卷积结果近似相等。") 
else:print("两个卷积结果不相等。")  print("最大绝对误差:", torch.max(torch.abs(cov_out - cov_out2))) 

 输出为“ 两个卷积结果近似相等。”

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

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

相关文章

前端面试场景题葵花宝典之四

87.场景面试之大数运算:超过js中number最大值的数怎么处理 在 JavaScript 中,Number.MAX_SAFE_INTEGER(即 2^53 - 1,即 9007199254740991)是能被安全表示的最大整数。超过此值时,普通的 Number 类型会出现…

Linux中死锁问题的探讨

在 Linux 中,死锁(Deadlock) 是指多个进程或线程因为竞争资源而相互等待,导致所有相关进程或线程都无法继续执行的状态。死锁是一种严重的系统问题,会导致系统资源浪费,甚至系统崩溃。 死锁的定义 死锁是指…

【基于Mesh组网的UWB技术讨论】

基于Mesh组网的UWB技术讨论 Mesh 组网无线Mesh与无线中继的区别 基于Mesh拓扑的UWB技术可行性星型拓扑 / Mesh拓扑的UWB技术比较 Mesh 组网 Mesh(网格)是一种无中心、自组织的高度业务协同的网络。通常分为无线Mesh和有线Mesh,但在实际应用场景,有线Mes…

Python Cookbook-3.1 计算昨天和明天的日期

任务 获得今天的日期,并以此计算昨天和明天的日期。 解决方案 方案一: 无论何时遇到有关“时间变化”或者“时间差”的问题,先考虑datetime包: import datetime today datetime.date.today() yesterday today - datetime.timedelta(day…

USB 模块 全面解析(二)

本文是我整理的一些 USB 的学习心得,希望能对大家有所帮助。 文章目录 前言🍍USB 协议层数据格式🍇包格式🍓 PID 域🍓 令牌包🍓 数据包🍓 握手包 🍇传输类型🍓 批量传输&…

从基础到实践(十):MOS管的全面解析与实际应用

MOS管(金属-氧化物半导体场效应晶体管)是现代电子技术的基石,凭借高输入阻抗、低功耗和易集成特性,成为数字电路、电源管理和信号处理的核心元件。从微处理器到新能源汽车电驱系统,其高效开关与放大功能支撑了计算机、…

AES/CBC/PKCS5Padding加密

1、加密代码如下 public static String encryptAEs_CBC(String data,String key,byte[] iv) {Cipher cipher = null;try {cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//位数不够,自动补一个长度int blocksize = cipher.getBlockSize();byte[] dataBytes …

指纹细节提取(Matlab实现)

指纹细节提取概述指纹作为人体生物特征识别领域中应用最为广泛的特征之一,具有独特性、稳定性和便利性。指纹细节特征对于指纹识别的准确性和可靠性起着关键作用。指纹细节提取,即从指纹图像中精确地提取出能够表征指纹唯一性的关键特征点,是…

Python 图像处理之 Pillow 库:玩转图片

哈喽,大家好,我是木头左! Pillow 库作为 Python 图像处理的重要工具之一,为提供了便捷且功能丰富的接口,让能够轻松地对图像进行各种操作,从简单的裁剪、旋转到复杂的滤镜应用、图像合成等,几乎无所不能。接下来,就让一起深入探索如何使用 Pillow 库来处理图片,开启一…

Android Flow 示例

在Android开发的世界里,处理异步数据流一直是一个挑战。随着Kotlin的流行,Flow作为Kotlin协程库的一部分,为开发者提供了一种全新的方式来处理这些问题。今天,我将深入探讨Flow的设计理念,并通过具体的例子展示如何在实…

记录uniapp小程序对接腾讯IM即时通讯无ui集成(2)

完成以上步骤之后开始进行登录,登陆就需要账号。这个账号我们可以在腾讯云中创建。 有了账号之后开始去小程序进行登陆操作。腾讯云接口文档 这里除了帐号还需要一个校验值userSig正常项目开发这个字段可以在登陆后让后端返回,现在是测试我们直接去控制…

北京航空航天大学计算机复试上机真题

北京航空航天大学计算机复试上机真题 2023北京航空航天大学计算机复试上机真题 在线评测&#xff1a;https://app2098.acapp.acwing.com.cn/ 阶乘和 题目描述 求Sn1!2!3!4!5!…n!之值&#xff0c;其中n是一个数字。 输入格式 输入一个n&#xff08;n<20&#xff09; …

阿里万相,正式开源

大家好&#xff0c;我是小悟。 阿里万相正式开源啦。这就像是AI界突然开启了一扇通往宝藏的大门&#xff0c;而且还是免费向所有人敞开的那种。 你想想看&#xff0c;在这个科技飞速发展的时代&#xff0c;AI就像是拥有神奇魔法的魔法师&#xff0c;不断地给我们带来各种意想…

算法之数据结构

目录 数据结构 数据结构与算法面试题 数据结构 《倚天村 • 图解数据结构》 | 小傅哥 bugstack 虫洞栈 ♥数据结构基础知识体系详解♥ | Java 全栈知识体系 线性数据结构 | JavaGuide 数据结构与算法面试题 数据结构与算法面试题 | 小林coding

零基础学习之——深度学习算法介绍01

第一节.基础骨干网络 物体分类是计算机视觉&#xff08;computer vision&#xff0c;CV&#xff09;中最经典的、也是目前研究得最为透彻的一 个领域&#xff0c;该领域的开创者也是深度学习领域的“名人”级别的人物&#xff0c;例如 Geoffrey Hinton、Yoshua Bengio 等。物…

弧度与角度之间的转换公式

Radian 弧度的英语 简称 Rad Degree 角度的英语 简称 Deg 角度转弧度 RadDeg*180/π CogMuisc.DegToRad(double degress) DegRad/180*π CogMuisc.RadToDeg(double radians) 总结: 角度大 弧度小 弧度转角度 肯定要乘以一个大于1的数 那就是…

css之英文换行样式

在 CSS 中&#xff0c;要实现英文文本自动换行但不从单词中间断开的效果&#xff0c;可以使用 word-wrap 或 overflow-wrap 属性。以下是相关的 CSS 属性和它们的配置&#xff1a; 使用 overflow-wrap 或 word-wrap /* This property is used to handle word breaking */ .wo…

40岁开始学Java:Java中单例模式(Singleton Pattern),适用场景有哪些?

在Java中&#xff0c;单例模式&#xff08;Singleton Pattern&#xff09;用于确保一个类只有一个实例&#xff0c;并提供全局访问点。以下是详细的实现方式、适用场景及注意事项&#xff1a; 一、单例模式的实现方式 1. 饿汉式&#xff08;Eager Initialization&#xff09; …

【前端基础】3、HTML的常用元素(h、p、img、a、iframe、div、span)、不常用元素(strong、i、code、br)

HTML结构 一个HTML包含以下部分&#xff1a; 文档类型声明html元素 head元素body元素 例&#xff08;CSDN&#xff09;&#xff1a; 一、文档类型声明 HTML最一方的文档称为&#xff1a;文档类型声明&#xff0c;用于声明文档类型。即&#xff1a;<!DOCTYPE html>…

文本挖掘+情感分析+主题建模+K-Meas聚类+词频统计+词云(景区游客评论情感分析)

本文通过情感分析技术对景区游客评论进行深入挖掘,结合数据预处理、情感分类和文本挖掘,分析游客评价与情感倾向。利用朴素贝叶斯和SVM等模型进行情感预测,探讨满意度与情感的关系。通过KMeans聚类和LDA主题分析,提取游客关心的话题,提供优化建议,为未来研究提供方向。 …