【论文笔记】RS-Mamba for Large Remote Sensing Image Dense Prediction(附Code)

论文作者提出了RS-Mamba(RSM)用于高分辨率遥感图像遥感的密集预测任务。RSM设计用于模拟具有线性复杂性的遥感图像的全局特征,使其能够有效地处理大型VHR图像。它采用全向选择性扫描模块,从多个方向对图像进行全局建模,从多个方向捕捉大的空间特征。

论文链接:https://arxiv.org/abs/2404.02668

code链接:https://github.com/walking-shadow/Official_Remote_Sensing_Mamba

2D全向扫描机制是本研究的主要创新点。作者考虑到遥感影像地物多方向的特点,在VMamba2D双向扫描机制的基础上增加了斜向扫描机制。

 以下是作者针对该部分进行改进的代码:

def antidiagonal_gather(tensor):# 取出矩阵所有反斜向的元素并拼接B, C, H, W = tensor.size()shift = torch.arange(H, device=tensor.device).unsqueeze(1)  # 创建一个列向量[H, 1]index = (torch.arange(W, device=tensor.device) - shift) % W  # 利用广播创建索引矩阵[H, W]# 扩展索引以适应B和C维度expanded_index = index.unsqueeze(0).unsqueeze(0).expand(B, C, -1, -1)# 使用gather进行索引选择return tensor.gather(3, expanded_index).transpose(-1,-2).reshape(B, C, H*W)def diagonal_gather(tensor):# 取出矩阵所有反斜向的元素并拼接B, C, H, W = tensor.size()shift = torch.arange(H, device=tensor.device).unsqueeze(1)  # 创建一个列向量[H, 1]index = (shift + torch.arange(W, device=tensor.device)) % W  # 利用广播创建索引矩阵[H, W]# 扩展索引以适应B和C维度expanded_index = index.unsqueeze(0).unsqueeze(0).expand(B, C, -1, -1)# 使用gather进行索引选择return tensor.gather(3, expanded_index).transpose(-1,-2).reshape(B, C, H*W)def diagonal_scatter(tensor_flat, original_shape):# 把斜向元素拼接起来的一维向量还原为最初的矩阵形式B, C, H, W = original_shapeshift = torch.arange(H, device=tensor_flat.device).unsqueeze(1)  # 创建一个列向量[H, 1]index = (shift + torch.arange(W, device=tensor_flat.device)) % W  # 利用广播创建索引矩阵[H, W]# 扩展索引以适应B和C维度expanded_index = index.unsqueeze(0).unsqueeze(0).expand(B, C, -1, -1)# 创建一个空的张量来存储反向散布的结果result_tensor = torch.zeros(B, C, H, W, device=tensor_flat.device, dtype=tensor_flat.dtype)# 将平铺的张量重新变形为[B, C, H, W],考虑到需要使用transpose将H和W调换tensor_reshaped = tensor_flat.reshape(B, C, W, H).transpose(-1, -2)# 使用scatter_根据expanded_index将元素放回原位result_tensor.scatter_(3, expanded_index, tensor_reshaped)return result_tensordef antidiagonal_scatter(tensor_flat, original_shape):# 把反斜向元素拼接起来的一维向量还原为最初的矩阵形式B, C, H, W = original_shapeshift = torch.arange(H, device=tensor_flat.device).unsqueeze(1)  # 创建一个列向量[H, 1]index = (torch.arange(W, device=tensor_flat.device) - shift) % W  # 利用广播创建索引矩阵[H, W]expanded_index = index.unsqueeze(0).unsqueeze(0).expand(B, C, -1, -1)# 初始化一个与原始张量形状相同、元素全为0的张量result_tensor = torch.zeros(B, C, H, W, device=tensor_flat.device, dtype=tensor_flat.dtype)# 将平铺的张量重新变形为[B, C, W, H],因为操作是沿最后一个维度收集的,需要调整形状并交换维度tensor_reshaped = tensor_flat.reshape(B, C, W, H).transpose(-1, -2)# 使用scatter_将元素根据索引放回原位result_tensor.scatter_(3, expanded_index, tensor_reshaped)return result_tensorclass CrossScan(torch.autograd.Function):# ZSJ 这里是把图像按照特定方向展平的地方,改变扫描方向可以在这里修改@staticmethoddef forward(ctx, x: torch.Tensor):B, C, H, W = x.shapectx.shape = (B, C, H, W)# xs = x.new_empty((B, 4, C, H * W))xs = x.new_empty((B, 8, C, H * W))# 添加横向和竖向的扫描xs[:, 0] = x.flatten(2, 3)xs[:, 1] = x.transpose(dim0=2, dim1=3).flatten(2, 3)xs[:, 2:4] = torch.flip(xs[:, 0:2], dims=[-1])# 提供斜向和反斜向的扫描xs[:, 4] = diagonal_gather(x)xs[:, 5] = antidiagonal_gather(x)xs[:, 6:8] = torch.flip(xs[:, 4:6], dims=[-1])return xs@staticmethoddef backward(ctx, ys: torch.Tensor):# out: (b, k, d, l)B, C, H, W = ctx.shapeL = H * W# 把横向和竖向的反向部分再反向回来,并和原来的横向和竖向相加# ys = ys[:, 0:2] + ys[:, 2:4].flip(dims=[-1]).view(B, 2, -1, L)y_rb = ys[:, 0:2] + ys[:, 2:4].flip(dims=[-1]).view(B, 2, -1, L)# 把竖向的部分转成横向,然后再相加,再转回最初是的矩阵形式# y = ys[:, 0] + ys[:, 1].view(B, -1, W, H).transpose(dim0=2, dim1=3).contiguous().view(B, -1, L)y_rb = y_rb[:, 0] + y_rb[:, 1].view(B, -1, W, H).transpose(dim0=2, dim1=3).contiguous().view(B, -1, L)y_rb = y_rb.view(B, -1, H, W)# 把斜向和反斜向的反向部分再反向回来,并和原来的斜向和反斜向相加y_da = ys[:, 4:6] + ys[:, 6:8].flip(dims=[-1]).view(B, 2, -1, L)# 把斜向和反斜向的部分都转成原来的最初的矩阵形式,再相加y_da = diagonal_scatter(y_da[:, 0], (B,C,H,W)) + antidiagonal_scatter(y_da[:, 1], (B,C,H,W))y_res = y_rb + y_da# return y.view(B, -1, H, W)return y_resclass CrossMerge(torch.autograd.Function):@staticmethoddef forward(ctx, ys: torch.Tensor):B, K, D, H, W = ys.shapectx.shape = (H, W)ys = ys.view(B, K, D, -1)# ys = ys[:, 0:2] + ys[:, 2:4].flip(dims=[-1]).view(B, 2, D, -1)# y = ys[:, 0] + ys[:, 1].view(B, -1, W, H).transpose(dim0=2, dim1=3).contiguous().view(B, D, -1)y_rb = ys[:, 0:2] + ys[:, 2:4].flip(dims=[-1]).view(B, 2, D, -1)# 把竖向的部分转成横向,然后再相加,再转回最初是的矩阵形式y_rb = y_rb[:, 0] + y_rb[:, 1].view(B, -1, W, H).transpose(dim0=2, dim1=3).contiguous().view(B, D, -1)y_rb = y_rb.view(B, -1, H, W)# 把斜向和反斜向的反向部分再反向回来,并和原来的斜向和反斜向相加y_da = ys[:, 4:6] + ys[:, 6:8].flip(dims=[-1]).view(B, 2, D, -1)# 把斜向和反斜向的部分都转成原来的最初的矩阵形式,再相加y_da = diagonal_scatter(y_da[:, 0], (B,D,H,W)) + antidiagonal_scatter(y_da[:, 1], (B,D,H,W))y_res = y_rb + y_dareturn y_res.view(B, D, -1)# return y@staticmethoddef backward(ctx, x: torch.Tensor):# B, D, L = x.shape# out: (b, k, d, l)H, W = ctx.shapeB, C, L = x.shape# xs = x.new_empty((B, 4, C, L))xs = x.new_empty((B, 8, C, L))# 横向和竖向扫描xs[:, 0] = xxs[:, 1] = x.view(B, C, H, W).transpose(dim0=2, dim1=3).flatten(2, 3)xs[:, 2:4] = torch.flip(xs[:, 0:2], dims=[-1])# xs = xs.view(B, 4, C, H, W)# 提供斜向和反斜向的扫描xs[:, 4] = diagonal_gather(x.view(B,C,H,W))xs[:, 5] = antidiagonal_gather(x.view(B,C,H,W))xs[:, 6:8] = torch.flip(xs[:, 4:6], dims=[-1])# return xsreturn xs.view(B, 8, C, H, W)

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

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

相关文章

AJAX——ajax原理

1.XMLHttpRequest 定义:XMLHttpRequest(XHR)对象用于与服务器交互。通过XMLHttpRequest可以在不刷新页面的情况下请求特定URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest在AJA…

Compose 布局

文章目录 Compose 布局ColumnColumn属性使用 RowRow属性使用 BoxBox属性使用 ConstraintLayoutLazyColumnLazyColumn属性使用使用多类型使用粘性标题回到顶部 LazyRowLazyRow属性使用 LazyVerticalGridLazyVerticalGrid属性使用 Compose 布局 Column Compose中的”垂直线性布…

Can‘t log out of macbook account 【macbook 账户无法退出】

参考: https://iboysoft.com/news/cant-sign-out-of-icloud-mac.html

【数据结构-树和二叉树-森林-哈夫曼树】

目录 1 树1.1 树的描述(基本术语) 2 二叉树(树的度最大为2)2.1 注意事项-五种基本形态2.2 二叉树的抽象数据类型定义 3 二叉树的性质3.1 两种特殊形式的二叉树-重点会计算3.2 题目练习: 4 二叉树的存储结构4.1 顺序存储…

【融合ChatGPT等AI模型】Python-GEE遥感云大数据分析、管理与可视化及多领域应用

随着航空、航天、近地空间遥感平台的持续发展,遥感技术近年来取得显著进步。遥感数据的空间、时间、光谱分辨率及数据量均大幅提升,呈现出大数据特征。这为相关研究带来了新机遇,但同时也带来巨大挑战。传统的工作站和服务器已无法满足大区域…

汇编语言(详解)

汇编语言安装指南 第一步:在github上下载汇编语言的安装包 网址:GitHub - HaiPenglai/bilibili_assembly: B站-汇编语言-pdf、代码、环境等资料B站-汇编语言-pdf、代码、环境等资料. Contribute to HaiPenglai/bilibili_assembly development by creat…

人工智能入门(一):基于Pytorch的手写数字识别模型

前言: 因为还在上学,时间不太够用,很多内容写到后面心有余力不足,未来有时间我会慢慢补充。人工智能的知识涉猎范围广又杂乱无章,啃书或上课学到的知识往往很早就过时了或者离实际的项目无关。所以,我很希…

【Redis】List 数据类型

文章目录 常用命令lpush & lpushxrpush & rpushxlrange & lpop & rpoplindex & linsertllen 阻塞版本的命令内部编码 列表类型是⽤来存储多个有序的字符串,⼀个列表最多可以存储 2^32 - 1 个元素,允许有重复的元素。 列表在两端都可…

YOLOv9改进策略 | Conv篇 | 利用YOLO-MS的MSBlock二次创新RepNCSPELAN4(全网独家创新)

一、本文介绍 本文给大家带来的改进机制是利用YOLO-MS提出的一种针对于实时目标检测的MSBlock模块(其其实不能算是Conv但是其应该是一整个模块),我们将其用于RepNCSPELAN中组合出一种新的结构,来替换我们网络中的模块可以达到一种轻量化的作用&#xff…

TVbox三端助手MAC+Windows+手机版带接口

Vbox这个目前大热的电视播放器,由于是空壳,于是接口成为非常核心的一环,很多网友制作的接口会进行加密,以防被人复制使用。 最近发现有人对此做了个专门解密的工具,解不解密的不重要的,分享迷倒是觉得这工…

Python 全栈安全(二)

原文:annas-archive.org/md5/712ab41a4ed6036d0e8214d788514d6b 译者:飞龙 协议:CC BY-NC-SA 4.0 第二部分:认证与授权 本书的第二部分是最具商业价值的部分。我这样说是因为它充满了大多数系统需要具备的实用工作流示例&#xf…

Web3钱包和身份验证:安全和去中心化的新标准

引言 在数字化的今天,我们正处于一个互联网技术迅速发展的时代。Web3作为一个革命性的概念,正在逐渐改变我们对互联网的看法和使用习惯。在这一变革中,Web3钱包和身份验证成为了核心组成部分,它们不仅为我们提供了安全和去中心化…