文章目录

  • 1 概述
  • 2 模块
    • 2.1 SelectiveIGEV和IGEV的差异
    • 2.2 上下文空间注意力
      • 2.2.1 通道注意力
      • 2.2.2 空间注意力
    • 2.3 SRU
  • 3 效果
  • 参考资料

1 概述

本文主要结合代码对Selective的创新点进行针对性讲解,相关的背景知识可以参考我写的另两篇文章论文阅读-RaftStereo和论文阅读-IGEV。
SelectiveStereo的创新点总结来说就只有一项,在RaftStereo和IGEV的基础上,提出了分别提取图像高频信息和低频信息并融合的迭代算子SRU(Selective Recurrent Unit),另一个Contextual Spatial Attention(CSA)模块是为其服务的。
SelectiveStereo对RaftStereo和IGEV都进行了改进,下面以IGEV为例进行具体说明。

2 模块

2.1 SelectiveIGEV和IGEV的差异

从代码上看,SelectiveStereo和IGEV的差异只有两处。一处是在计算inp_list的时候,SelectiveStereo用到了通道注意力self.cam,并使用空间注意力self.sam进一步得到了注意力图att;另一处是在使用self.update_block进行计算的时候,SelectiveIGEV额外多了att作为输入。
SelectiveStereo的相关代码为

class IGEVStereo(nn.Module):def forward(self, image1, image2, iters=12, flow_init=None, test_mode=False):# 此处省略部分代码...cnet_list = self.cnet(image1, num_layers=self.args.n_gru_layers)net_list = [torch.tanh(x[0]) for x in cnet_list]inp_list = [torch.relu(x[1]) for x in cnet_list]# 不同点1inp_list = [self.cam(x) * x for x in inp_list]att = [self.sam(x) for x in inp_list]# 此处省略部分代码...for itr in range(iters):disp = disp.detach()geo_feat = geo_fn(disp, coords)with autocast(enabled=self.args.mixed_precision, dtype=getattr(torch, self.args.precision_dtype, torch.float16)):# 不同点2net_list, mask_feat_4, delta_disp = self.update_block(net_list, inp_list, geo_feat, disp, att)

IGEV的相关代码为

class IGEVStereo(nn.Module):def forward(self, image1, image2, iters=12, flow_init=None, test_mode=False):# 此处省略部分代码...cnet_list = self.cnet(image1, num_layers=self.args.n_gru_layers)net_list = [torch.tanh(x[0]) for x in cnet_list]inp_list = [torch.relu(x[1]) for x in cnet_list]# 不同点1inp_list = [list(conv(i).split(split_size=conv.out_channels//3, dim=1)) for i,conv in zip(inp_list, self.context_zqr_convs)]# 此处省略部分代码...for itr in range(iters):disp = disp.detach()geo_feat = geo_fn(disp, coords)with autocast(enabled=self.args.mixed_precision, dtype=getattr(torch, self.args.precision_dtype, torch.float16)):# 不同点2net_list, mask_feat_4, delta_disp = self.update_block(net_list, inp_list, geo_feat, disp, iter16=self.args.n_gru_layers==3, iter08=self.args.n_gru_layers>=2)

2.2 上下文空间注意力

为实现不同感受野和频率信息的融合,上下文空间注意力(Contextual Spatial Attention,简称CSA)模块通过提取上下文信息作为引导的多层级注意力图谱。如图2-1所示,CSA可划分为两个子模块:通道注意力增强(Channel Attention Enhancement,简称CAE)和空间注意力提取器(Spatial Attention Extractor,简称SAE)。这两个子模块源自CBAM框架,作者进行了简化以更好地适配立体匹配任务。
上下文注意力示意图

图2-1 上下文注意力示意图

2.2.1 通道注意力

通道注意力的代码实现如下所示,结合图2-1左侧的示意图应该比较容易理解。在给定上下文信息图 c∈RC×H×Wc∈R^{ C×H×W}cRC×H×W 的情况下,首先对空间维度进行平均池化和最大池化操作,分别得到两个特征图favgf_{avg}favgfmax∈RC×1×1f_{max}∈R^{C×1×1}fmaxRC×1×1。接着通过两个独立的卷积层对这些特征图进行特征变换,也就是代码中的self.fc,是一个bottleneck结构,如果改成残差的形式就和yolo中的bottleneck一致了。随后将这两个特征图相加,并使用sigmoid函数将其转换为0到1之间的权重Mc∈RC×1×1M_c∈R^{C×1×1}McRC×1×1。最后通过逐元素乘积运算,初始特征图能够捕捉哪些通道具有数值高的特征值需要增强,哪些通道具有数值低的特征值需要抑制。

class ChannelAttentionEnhancement(nn.Module):def __init__(self, in_planes, ratio=16):super(ChannelAttentionEnhancement, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.max_pool = nn.AdaptiveMaxPool2d(1)self.fc = nn.Sequential(nn.Conv2d(in_planes, in_planes // 16, 1, bias=False),nn.ReLU(),nn.Conv2d(in_planes // 16, in_planes, 1, bias=False))self.sigmoid = nn.Sigmoid()def forward(self, x):avg_out = self.fc(self.avg_pool(x))max_out = self.fc(self.max_pool(x))out = avg_out + max_outreturn self.sigmoid(out)

回看2.1节中SelectiveStereo对应的代码,self.cam生成了inp_list,而IGEV中是通过简单的卷积生成的inp_list,因此SelectiveStereo的inp_list特征表达能力会更强一些。
那么这个inp_list的作用是什么呢?看过我的另一篇博客论文阅读-IGEV的话可以知道inp_list对应于ConvGRU中的偏置项,而在SelectiveStereo中,作者选择使用了RaftConvGRU,那么inp_list就不是偏置项了,直接作为卷积的输入了。我觉得作者应该是认为经过sigmoid的结果作为偏置项不太合适才选择了RaftConvGRU。
这里也把ConvGRU和RaftConvGRU的代码放出来,方便读者查看。
RaftConvGRU代码如下,inp_list被concat在x当中。

class RaftConvGRU(nn.Module):def __init__(self, hidden_dim=128, input_dim=256, kernel_size=3, dilation=1):super(RaftConvGRU, self).__init__()self.convz = nn.Conv2d(hidden_dim+input_dim, hidden_dim, kernel_size, padding=(kernel_size+(kernel_size-1)*(dilation-1))//2, dilation=dilation)self.convr = nn.Conv2d(hidden_dim+input_dim, hidden_dim, kernel_size, padding=(kernel_size+(kernel_size-1)*(dilation-1))//2, dilation=dilation)self.convq = nn.Conv2d(hidden_dim+input_dim, hidden_dim, kernel_size, padding=(kernel_size+(kernel_size-1)*(dilation-1))//2, dilation=dilation)def forward(self, h, x):hx = torch.cat([h, x], dim=1)z = torch.sigmoid(self.convz(hx))r = torch.sigmoid(self.convr(hx))q = torch.tanh(self.convq(torch.cat([r*h, x], dim=1)))h = (1-z) * h + z * qreturn h

ConvGRU代码如下,inp_list就是[cz, cr, cq]

class ConvGRU(nn.Module):def __init__(self, hidden_dim, input_dim, kernel_size=3):super(ConvGRU, self).__init__()self.convz = nn.Conv2d(hidden_dim+input_dim, hidden_dim, kernel_size, padding=kernel_size//2)self.convr = nn.Conv2d(hidden_dim+input_dim, hidden_dim, kernel_size, padding=kernel_size//2)self.convq = nn.Conv2d(hidden_dim+input_dim, hidden_dim, kernel_size, padding=kernel_size//2)def forward(self, h, cz, cr, cq, *x_list):x = torch.cat(x_list, dim=1)hx = torch.cat([h, x], dim=1)z = torch.sigmoid(self.convz(hx) + cz)r = torch.sigmoid(self.convr(hx) + cr)q = torch.tanh(self.convq(torch.cat([r*h, x], dim=1)) + cq)h = (1-z) * h + z * qreturn h

2.2.2 空间注意力

空间注意力的代码如下所示,结合图2-1右侧的示意图应该比较容易理解。采用和通道注意力相同的池化操作,但这次将池化维度调整为通道维度,对应于代码中的avg_outmax_out。随后将这些池化结果拼接成R2×H×WR^{2×H×W}R2×H×W的图像,并通过带有sigmoid函数的卷积层生成最终注意力图。回顾之前的处理流程可以发现,该注意力图在需要高频信息的区域具有高权重值,因为这些信息在上下文信息中具有较高的特征价值。而对需要低频信息的区域则赋予较低权重。总体而言,该注意力图能明确区分不同频率信息需求的区域。这个图有点像边缘图,物体的边缘即使图像中的高频信息区域。

class SpatialAttentionExtractor(nn.Module):def __init__(self, kernel_size=7):super(SpatialAttentionExtractor, self).__init__()self.samconv = nn.Conv2d(2, 1, kernel_size, padding=kernel_size//2, bias=False)self.sigmoid = nn.Sigmoid()def forward(self, x):avg_out = torch.mean(x, dim=1, keepdim=True)max_out, _ = torch.max(x, dim=1, keepdim=True)x = torch.cat([avg_out, max_out], dim=1)x = self.samconv(x)return self.sigmoid(x)

2.3 SRU

SRU看代码就非常容易理解了,它设计了两个GRU。一个GRU的kernel_size小,捕获图像中的高频信息,只需要小的感受野,如边缘,最终的结果和表示图像中高频区域的注意力att相乘;另一个GRU的kernel_size大,捕获图像中的低频信息,如平面,最终的结果和表示图像中低频区域的注意力1-att相乘。如果既不是高频也不是低频的,att就会趋于0.5,那么就会结合self.small_gruself.large_gru两者的信息。

class SelectiveConvGRU(nn.Module):def __init__(self, hidden_dim=128, input_dim=256, small_kernel_size=1, large_kernel_size=3):super(SelectiveConvGRU, self).__init__()self.small_gru = RaftConvGRU(hidden_dim, input_dim, small_kernel_size)self.large_gru = RaftConvGRU(hidden_dim, input_dim, large_kernel_size)def forward(self, att, h, *x):x = torch.cat(x, dim=1)h = self.small_gru(h, x) * att + self.large_gru(h, x) * (1 - att)return h

SRU的示意图如下图2-2所示。
SRU示意图

图2-2 SRU示意图

3 效果

加入SelectiveStereo之后,RaftStereo和IGEV的效果在不同的update次数下都有提升,如下表3-1所示。
不同update次数下SelectiveStereo的效果

表3-1 不同update次数下SelectiveStereo的效果

IGEV和SelectiveIGEV可视化效果对比如下图3-1所示,SelectiveIGEV的细节部分效果明显更好。
IGEV和SelectiveIGEV可视化效果对比

图3-1 IGEV和SelectiveIGEV可视化效果对比

SelectiveStereo在SceneFlow数据集和不同模型的EPE指标对比如下表3-2所示。
SelectiveStereo在SceneFlow数据集和不同模型的EPE指标对比

表3-2 SelectiveStereo在SceneFlow数据集和不同模型的EPE指标对比

SelectiveStereo在KITTI数据集和不同模型的EPE指标对比如下表3-3所示。
SelectiveStereo在KITTI数据集和不同模型的EPE指标对比

表3-3 SelectiveStereo在KITTI数据集和不同模型的EPE指标对比

整体来说,使用了SelectiveStereo后效果方面会得到全方面的提升,不过速度方面是会下降的,因为引入了把一个GRU标成了大小两个GRU,且多了注意力的计算步骤。

参考资料

[1] Selective-Stereo: Adaptive Frequency Information Selection for Stereo Matching
[2] https://github.com/Windsrain/Selective-Stereo.git
[3] https://github.com/gangweix/IGEV.git

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

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

相关文章

深入分析神马 M56S+ 202T 矿机参数与性能特点

引言在比特币(BTC)和比特币现金(BCH)等主流加密货币的挖掘过程中,矿机的选择直接关系到挖矿的效率与收益。神马 M56S 202T矿机是SHA-256算法的矿机,凭借其强大的算力和高效的能效比,成为了矿工们…

36.2Linux单总线驱动DS18B20实验(详细讲解代码)_csdn

想必看过我很多次博客的同学,都知道了编写驱动的流程! 这里我们还是按照以前的习惯来一步一步讲解! 单总线驱动,在F103和51单片机的裸机开发中是经常见的。 linux驱动代码编写实际上就是,端对端的编程! 就是…

【杂类】应对 MySQL 处理短时间高并发的请求:缓存预热

一、什么是缓存预热?1. 核心概念​​缓存预热(Cache Warm-up)​​ 是指在系统​​正式对外提供服务之前​​,或​​某个高并发场景来临之前​​,​​主动​​将后续极有可能被访问的热点数据从数据库(MySQL…

点评项目(Redis中间件)第三部分短信登录,查询缓存

可以直接看后面Redis实现功能的部分基于session实现短信登录发送短信验证码前端请求样式业务层代码Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {Overridepublic Result sendCode(String phone, HttpSession se…

线性方程求解器的矩阵分裂

大概思路是对的&#xff0c;但是查老师可能会出现幻觉&#xff0c;小心食用 &#x1f603;这段代码是在初始化迭代法求解器&#xff0c;构建迭代矩阵和分裂矩阵。以下是详细解释&#xff1a; if init_from_func or init_from_input:# 1. 存储刚度矩阵self.stiff_p stiff_p# 2.…

【Beetle RP2350】雷达模块 CEM5861G-M11 开发使用指南

一、硬件介绍 1、产品特点 Beetle RP2350【RP2350A_QFN60】是一款基于RP2350微控制器的高性能迷你开发板&#xff0c;双核双架构设计&#xff08;支持 Arm Cortex-M33或Hazard3 RISC-V内核&#xff09;为开发者提供灵活的性能配置。 双核双架构&#xff0c;性能自由切换 采…

高通Android 13 开机黑屏问题深度剖析与解决方案

1. 问题概述 在 Android 13 系统定制化开发过程中&#xff0c;开机流程的调试与优化颇具挑战性。一个典型问题是&#xff1a;当开机动画播放完毕后&#xff0c;设备会先出现数秒黑屏&#xff0c;然后才进入锁屏界面。本文基于开机日志分析&#xff0c;结合实际项目经验&#x…

腾讯推出AI CLI工具CodeBuddy,国内首家同时支持插件、IDE和CLI三种形态的AI编程工具厂商

2025年9月9日&#xff0c;腾讯正式推出自研AI CLI工具CodeBuddy code&#xff0c;成为国内首家同时支持插件、IDE和CLI三种形态的AI编程工具厂商。这一创新不仅填补了国内市场在全形态AI编程工具领域的空白&#xff0c;更以编码时间缩短40%、AI生成代码占比超50%的硬核数据&…

零基础学习QT的第二天-组件基础知识

组件声明以及设置属性 所有的组件的基类为&#xff1a;QtObject&#xff0c;在c中名称为&#xff1a;QObject。 在qml和c名称有所区别&#xff0c;例如在Qml中QtObject&#xff0c;在C会省略一个t(QObject) 声明组件的方式&#xff1a; 组件名 {属性名:值}在实际应用中&#xf…

像素图生成小程序开发全解析:从图片上传到Excel图纸

像素图生成小程序开发全解析&#xff1a;从图片上传到Excel图纸 前言 在数字化创作和工艺设计领域&#xff0c;像素图生成工具具有广泛的应用价值&#xff0c;无论是十字绣设计、LED灯阵布置还是复古游戏美术创作。本文将详细解析一个功能完整的像素图生成小程序的开发过程&…

mac-intel操作系统go-stock项目(股票分析工具)安装与配置指南

1. 项目基础介绍 go-stock 是一个基于Wails和NaiveUI开发的AI赋能股票分析工具。旨在为用户提供自选股行情获取、成本盈亏展示、涨跌报警推送等功能。它支持A股、港股、美股等市场&#xff0c;能够进行市场整体或个股的情绪分析、K线技术指标分析等功能。所有数据均保存在本地…

spring-单例bean是线程安全的吗

其中可修改的成员变量有线程不安全问题&#xff0c;不可修改的无状态的 userService是没有线程安全问题的 spring框架中有一个 Scope注解&#xff0c;默认的值就是singleton&#xff0c;单例的。 不是线程安全的&#xff0c;一般来说&#xff0c;我们在bean中注入的对象都是无状…

CM1033系列 3串锂电池保护IC - 高精度±25mV 内置延时 多型号可选(含铁锂)

1. 核心亮点 高精度多重保护&#xff1a;专为3串电池组设计&#xff0c;提供过充、过放、三级过流&#xff08;含短路&#xff09;、充电过流及断线检测等全方位保护&#xff0c;电压检测精度高达25mV。超低功耗&#xff1a;工作电流典型值仅7μA&#xff0c;休眠电流低至4μA&…

【第23话:定位建图】SLAM后端优化方法详解

SLAM 后端优化方法详解 SLAM&#xff08;Simultaneous Localization and Mapping&#xff09;后端优化是SLAM系统中的关键环节&#xff0c;负责对前端输出的传感器数据进行全局一致性优化&#xff0c;消除累积误差。后端通常基于图优化框架&#xff08;如g2o、GTSAM&#xff09…

MongoDB 备份与恢复终极指南:mongodump 和 mongorestore 深度实战

MongoDB 备份与恢复终极指南&#xff1a;mongodump 和 mongorestore 深度实战引言&#xff1a;数据守护者的使命第一部分&#xff1a;基础概念与核心原理1.1 逻辑备份 vs. 物理备份&#xff1a;根本性的区别1.2 核心工具介绍第二部分&#xff1a;mongodump 备份实战详解2.1 基础…

鸿蒙的“分布式架构”理念:未来操作系统的关键突破

一、引言&#xff1a;为什么需要分布式架构&#xff1f; 随着移动互联网的发展&#xff0c;智能设备不断普及。用户身边可能同时拥有 手机、平板、PC、电视、手表、耳机、智能音箱、车机 等多种终端设备。 但现实中&#xff0c;我们常遇到以下问题&#xff1a; 不同设备系统割…

MySQL 事务管理与锁机制:解决并发场景下的数据一致性问题

前言在电商下单、金融转账、库存扣减等并发业务场景中&#xff0c;若不控制数据操作的原子性与隔离性&#xff0c;极易出现 “超卖”“重复扣款”“脏读数据” 等问题。MySQL 的事务管理与锁机制是解决这些问题的核心技术&#xff0c;也是后端开发者必须掌握的生产环境能力。本…

MySQL集群高可用架构

一、MySQL高可用之组复制&#xff08;MGR&#xff09;1.1 组复制核心特性与优势MySQL Group Replication&#xff08;MGR&#xff09;是基于分布式一致性协议&#xff08;Paxos&#xff09;实现的高可用集群方案&#xff0c;核心特性包括&#xff1a;自动故障检测与恢复&#x…

判别模型 VS 生成模型

1. 判别模型&#xff08;Discriminative Models&#xff09;判别模型直接学习输入特征&#xff08;X&#xff09;与输出标签&#xff08;Y&#xff09;之间的映射关系&#xff0c;即直接对条件概率P(Y|X)进行建模。判别模型关注于如何区分不同类别的数据。特点&#xff1a;直接…

代码随想录算法训练营第三十一天 | 合并区间、单调递增的数字

合并区间&#xff1a; 这里还是先对左区间进行排序&#xff0c;判断重叠区间&#xff0c;首先判断是否存在元素&#xff0c;存在那么就将元素的第一个放到结果中&#xff0c;那么判断重叠就是当前元素的左区间和结果集里的最后元素的右区间进行判断&#xff0c;如果重叠&#x…