卷积加速算法img2col、Winograd、FFT

FFT

空间域中矩阵的卷积算子,实际等于频率域中两个矩阵元素相乘。但卷积的方向是相反的。

通常情况下,feature的尺寸要比卷积的尺寸大很多,如果对两者进行快速傅里叶变换的话,得出来的两个矩阵大小不一样,不能进行对应位置相乘。

为了可以让他们对应位置相乘,必须要对卷积核进行扩充,将其扩充到feature尺寸大小相同。也正是扩充过程,限制了方法的使用,只有当feature尺寸和卷积核尺寸大小差不多的时候,才会采用这种方法。

通常有三种卷积方式:full、same、valid

full卷积方式:会先对图像的四周进行补0,补零的行数(列数)为卷积核宽度(高度)-1,最终卷积出来的结果一定会比原图像大的


same卷积方式:这种卷积方式的结果大小一定会与原图像一样,通常补零的个数为向下取整

卷积核大小为n/2


valid卷积方式:不会对原图进行补零操作,所以会导致原图像大小变小

现在来分析,如果使用FFT来进行快速卷积,怎么补零

假设,我们输入的图像和卷积核分别如下

如果用full方式进行卷积,补零结果如下

这是因为,在用full方式进行卷积的时候,原图8x7大小,会变成10x9的大小,所以我们要把原图填充成上述样子。同理,我们需要把卷积核进行填充至10x9的大小

我们需要先对其进行水平翻转和垂直翻转,再进行卷积运算

所以对feature和核填充0后,还要再进行水平翻转和垂直翻转

def fftConvt(img,ker):
    //第一步:对图像进行填充
    img_padding = np.zeros(shape = [len(img)+len(ker)-1],[len(img)+len(ker)-1])
    img_padding[(len(ker)-1:len(ker)-1+len(img)),len(ker[0])-1:len(ker[0])-1+len(img)]=img
    ker = np.flip(ker,axis=0)
    ker = np.flip(ker,axis=1)

//第二步,对卷积核进行填充
    ker_padding = np.zeros(shape = img_padding.shape)
    ker_padding[:len(ker),:len(ker[0])]=ker
    img_padding_fft2=np.fft.fft2(img_padding)
    ker_padding_fft2=np.fft.fft2(ker_padding)
    img_fft2=img_padding_fft2*ker_padding_fft2
    return np.real(np.fft.fft2(img_fft2))

img2col

将卷积运算转换为矩阵乘法运算。

输入数据是一个三通道的features

我们有两个卷积核,每个卷积核有三个子核

如何把卷积转换为矩阵乘法呢?

传统卷积中,我们采用滑动窗口进行加权求和。将每个滑块所形成的字矩阵拉直,我们拿出第一个features进行拉直

拿出第一个卷积核中的子矩阵

现在移动滑动窗口,逐一进行拉直

然后形成了四个向量,将其堆叠起来,形成一个新的矩阵

再将卷积核拉直

现在,就可以用之前形成的矩阵和拉直的卷积核进行矩阵乘法

 

做乘法之后,每个窗口会得到一个列向量,这个列向量就是每个窗口加权平均值,即卷积值,3*3矩阵做2*2卷积,输出是2*2,将列向量reshape,即可得到最终结果。

对于多通道,我们将三个通道生成的矩阵堆叠在一起

每个卷积核的子矩阵给拉直,然后再堆叠到一起

最后实现两者的乘积,即可得到卷积结果

def img2col(img,ker):
    ker_width=len(ker[0])
    ker_height=len(ker)
    transform=np.empty(shape=((len(img[0]) - ker_width)*(len(img) - ker_height), ker_width*ker_height))
    cur=0
    for y in range(0,len(img)-ker_height):
        for x in range(0, len(img[0]) - ker_width):
            data=img[y:y+ker_height,x:x+ker_width].reshape(1,9)
            transform[cur,:]=data
            cur=cur+1
    return np.dot(transform,ker.reshape(-1,1)).reshape(len(img)-ker_height,-1)


Winograd 需要仔细阅读

Winograd算法出自CVPR 2016的一篇 paper:Fast Algorithms for Convolutional Neural Networks。,这个算法可以用来加速卷积运算,目前有很多框架如NCNN、NNPACK等,对于卷积层都采用了Winograd快速卷积算法。

卷积神经网络中的Winograd快速卷积算法

  • Winograd算法通过减少乘法次数来实现提速,但是加法的数量会相应增加,同时需要额外的transform计算以及存储transform矩阵,随着卷积核和tile的尺寸增大,就需要考虑加法、transform和存储的代价,而且tile越大,transform矩阵越大,计算精度的损失会进一步增加,所以一般Winograd只适用于较小的卷积核和tile(对大尺寸的卷积核,可使用FFT加速),在目前流行的网络中,小尺寸卷积核是主流,典型实现如F(6×6,3×3)𝐹(6×6,3×3)、F(4×4,3×3)𝐹(4×4,3×3)、F(2×2,3×3)𝐹(2×2,3×3)等,可参见NCNN、FeatherCNN、ARM-ComputeLibrary等源码实现。
  • 就卷积而言,Winograd算法和FFT类似,都是先通过线性变换将input和filter映射到新的空间,在那个空间里简单运算后,再映射回原空间。
  • 与im2col+GEMM+col2im相比,winograd在划分时使用了更大的tile,就划分方式而言,F(1×1,r×r)𝐹(1×1,𝑟×𝑟)与im2col相同。
def Winograd(img,ker):
    U = G.dot(ker).dot(G.T)
    res=np.empty(shape=[98,98])
    for y in range(0,len(img)-8,6):
        for x in range(0, len(img[0])-8,6):
            tile=img[y:y+8,x:x+8]
            V=BT.dot(tile.T).dot(BT.T)
            res[y:y+6,x:x+6]=AT.dot(U*V).dot(AT.T).T
    return res

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【JS红宝书学习笔记】第25章 客户端存储

第25章 客户端存储 Cookie HTTP是无状态的,也就是说,你这次访问服务器,关闭后再次访问服务器,服务器是意识不到又是你来访问的。 登录时,浏览器需要帮我们在每一次请求里加入用户名和密码,这样才能做到保…

盲盒一番赏小程序:开启惊喜之旅,探索无限创意!

在这个充满无限想象与惊喜的时代,盲盒已成为连接心灵与梦想的奇妙桥梁。为了将这份独特的乐趣与探索精神传递给每一位热爱生活、追求新鲜的你,我们自豪地推出了“盲盒一番赏”小程序——一个集创意、趣味、互动与社交于一体的盲盒新纪元,邀您…

三大知名向量化模型比较分析——m3e,bge,bce

先聊聊出处。 M3E 是 Moka Massive Mixed Embedding 的缩写, Moka,此模型由 MokaAI 训练,开源和评测,训练脚本使用 uniem ,评测 BenchMark 使用 MTEB-zhMassive,此模型通过千万级 (2200w) 的中文句对数据…

【C++】——类和对象(中)

文章目录 类的默认成员函数构造函数析构函数拷贝构造函数赋值运算符重载运算符重载 const成员函数 类的默认成员函数 在C中,类(class)可以拥有多种成员函数,其中一些成员函数在类定义中没有显式声明时,编译器会隐式地…

微软最新AI:GraphRAG+Chainlit实现跨文档智能检索分析打造私人AI助手

文章目录 前言一、GraphRAG安装二、Chainlit安装学习资料 前言 本月初,微软发布最强 RAG 知识库开源方案 GraphRAG,项目上线即爆火,现在星标量已经达到 10.9 k。 https://github.com/microsoft/graphrag 一、GraphRAG安装 1.创建一个新项目…

电脑使用干货 · 阻止更换主题时改变鼠标指针样式

大家在使用主题的时候会发现,可能更改主题时会自动变换鼠标指针。 本教程将向您展示如何在Windows 10和Windows 11中允许或阻止主题更改您的鼠标指针。 防止主题更改鼠标指针 下载 防止主题更改鼠标指针.reg 运行 > 确定,即可 REG文件内容供参考 …

Bean的作用域配置

ApplicationContext在初始化的时候, 就实例化所有单列的Bean什么意思呢? ApplicationContext context new ClassPathXmlApplicationContext("applicationContext.xml"); 这种实例化模式是可以修改的,也就是可以改变Spring框架在底…

基于Faster R-CNN的安全帽目标检测

基于Faster R-CNN的安全帽目标检测项目通常旨在解决工作场所,特别是建筑工地的安全监管问题。这类项目使用计算机视觉技术,特别是深度学习中的Faster R-CNN算法,来自动检测工人是否正确佩戴了安全帽,从而确保遵守安全规定并减少事…

深入Python网络编程:基础、工具和实践

深入Python网络编程:基础、工具和实践 网络编程是Python应用领域中的一个强大且核心的部分,它为开发者提供了与互联网或其他网络设备进行交互的能力。无论是构建Web服务、APIs,还是创建网络客户端,Python都提供了丰富的库来简化这…

Java基础知识——继承

目录 一、什么是继承 二、类的继承格式 三、继承的特点 四、继承的类型 五、继承的关键字 六、为什么使用继承 一、什么是继承 继承是面向对象编程(OOP)的四大基本原则之一,它允许我们创建一个新类,继承并扩展现有类的属性和…

[MySQL][表的增删查改][二][Retrieve][SELECT][WHERE]详细讲解

目录 1.Retrieve1.基本语法2.SELECT列1.全列查询2.查询字段为表达式3.为查询结果指定别名4.结果去重 3.WHERE条件1.比较运算符2.逻辑运算符3.示例 4.结果排序1.基本语法2.示例 5.筛选分页结果 1.Retrieve 1.基本语法 SELECT [DISTINCT] * | {column [, column] ...} [FROM ta…

【笔记-MyBatis】StatementHandler

Author:赵志乾 Date:2024-07-15 Declaration:All Right Reserved!!! 1. 简介 StatementHandler封装了对JDBC各类Statement的操作,如设置fetchSize属性、设置查询超时时间、与数据库进行交互等&…

MySQL中,如何定位慢查询

MySQL慢查询的表象:页面加载过慢、接口压测响应时间过长(超过1s) 我们当时做压测的时候有的接口非常的慢,接口的响应时间超过了2秒以上,因为我们当时的系统部署了运维的监控系统Skywalking,在展示的报表中…

Quectel EM05-CE 模块测试

作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生在读,研究方向无线联邦学习 擅长领域:驱动开发,嵌入式软件开发,BSP开发 作者主页:一个平凡而乐于分享的小比特的个人主页…

【ACM出版】第七届计算机信息科学与人工智能国际学术会议(CISAI 2024)

第七届计算机信息科学与人工智能国际学术会议(CISAI 2024) 2024 7th International Conference on Computer Information Science and Artificial Intelligence 2024年9月13-15日 | 地点:浙江-绍兴 欢迎 www.iccisai.org 第七届计算机信息科学与人工智能国际…

服务器数据恢复—RAID5阵列重建重建导致数据丢失的数据恢复案例

服务器数据恢复环境&故障: 一台服务器,有一组由5块硬盘组建的raid5磁盘阵列。 服务器在运行过程中一块有磁盘掉线,由于raid5阵列支持一块磁盘掉线的特性,服务器还在正常工作。不久之后服务器出现故障,管理员在不了…

字节抖音电商 后端开发岗位 一面

笔者整理答案,以供参考 自我介绍 项目(20分钟) RocketMQ延时消息的底层实现 回答: 延时消息的实现主要依赖于RocketMQ中的定时任务机制。消息被发送到Broker时,会先存储在一个特定的延时消息队列中。Broker会定时扫…

外贸行业汽车销售配件展示企业网站源码系统 带完整的源代码包以及搭建教程

系统概述 随着全球贸易的不断深化,外贸行业对于高效、专业的网站需求日益凸显。特别是对于汽车销售配件企业而言,一个功能全面、展示效果出色的网站源码系统,无疑是企业开拓海外市场、提升品牌形象的关键。本文将详细介绍一款专为外贸行业汽…

MySQL运维实战之ProxySQL(9.10)proxysql监控

作者:俊达 stats数据库 从stats数据库中可以查到proxysql一些内部组件的状态,如内存使用情况、连接池信息、会话信息、SQL执行状态等。 mysql> show tables from stats; --------------------------------------- | tables …

前端a-tree遇到的问题

在使用a-tree时候,给虚拟滚动的高度,然后展开a-tree滑动一段距离 比如这样 随后你切换页面,在返回这个页面的时候 就会出现这样的bug 解决方法: onBeforeRouteLeave((to, from, next) > {// 可以在路由参数变化时执行的逻辑ke…