RegNet论文阅读笔记

1.解决问题

现有的配准方法中,雅可比矩阵的计算常常是采用数值计算,只利用了邻域的像素信息,使得优化对初始值的设定十分敏感。为了解决这一问题,这篇文章提出了一个基于两张图像特征图的雅可比矩阵学习网络,来增大收敛范围,增加配准网络的性能。

 

2.创新点

提出一个基于两张图像特征图的雅可比矩阵学习网络,增大收敛范围,增加准确度和鲁棒性。

3.重点

1.采用特征矩阵误差来代替光度误差,特征矩阵误差比光度误差更平滑,并且有更明显的最值,特征金字塔使得收敛范围更大。

2.深度预测网络中使用基础深度图的线性加权叠加形式联合训练得到最终的深度预测图,相比针对单个像素进行深度预测更容易。

3.雅可比矩阵采用学习网络得到,而不是通过数值计算得到,加大收敛范围。

4.整个网络采用“粗-精”的分层训练方式。利用最小化特征矩阵误差来估计转换矩阵,在重投影误差的限制下学习雅可比矩阵。

4.模型介绍

4.1整体流程介绍

                                                    图1 整体流程图

由上图可知,在这篇文章中,输入两幅图像I1和I2,通过特征学习网络得到特征图f1,f2。F2与深度学习网络相连使用LM算法与相对姿态估计网络进行联合训练。这篇文章中采用特征矩阵误差来代替光度误差,特征矩阵误差比光度误差更平滑,并且有更明显的最值,特征金字塔使得收敛范围更大。深度预测网络中使用基础深度图的线性加权叠加形式联合训练得到最终的深度预测图,相比针对单个像素进行深度预测更容易。雅可比矩阵采用学习网络得到,而不是通过数值计算得到,加大收敛范围。

深度学习网络中使用权重向量w:   来预测深度基础图B,并表示深度图D。W通过最小化特征度量误差r 和转换矩阵T一起进行联合优化。

                                                                                                   (1)

                                                                                       (2)

公式(2)表示像素xi的特征度量误差,M是由图像分辨率决定的像素数。Xi代表图像I1中的像素坐标,通过函数  转换到I2空间。fk=F(Ik) , k=0,1表示从图像 中学习到的特征表示。{w,T}通过最小化特征矩阵误差r的L2范式来实现:

                                                                                      (3)

式(3)通过LM算法进行优化计算:

                                                                                             (4)

为了克服对于初始值敏感的问题,加大收敛范围,其中雅可比矩阵J通过连接特征图,和雅可比网络学习得到。深度预测网络和特征金字塔网络公用基础网络,整体网络框架图如下:

                                                           图2    网络架构图

 

4.2特征金字塔网络

                                                                     图3    特征学习网络

使用类似U-Net的结构来预测不同分辨率下的特征图,使用卷积层提取特征,然后使用平均池化层进行下采样得到256维的16*12的L0层,来做初始配准。特征层使用双线性插值进行上采样,并在每个level上添加跳过连接进行扩展。这篇论文中,使用l0到l2的特征层进行粗略的配准,此时不需要对深度预测网络进行的优化。基于l2层进行初始姿势估计,特征层l3被用于准确配准以及深度预测图的优化。雅可比矩阵预测网络采用第一幅图像的特征图和第二幅图像的变换特征图进行输入,预测整个雅可比矩阵。

4.3雅可比矩阵学习网络

                                                                         图4   雅可比矩阵预测网络

相比于对特征矩阵进行数值雅可比矩阵计算,这篇文章对特征矩阵误差求偏导。并且由于对各个偏导数的可学习参数,有效的消除了特征表示上的平滑约束。在常用的数值计算迭代算法中,每一次迭代过程视为线性方程,整个过程是线性最小二乘法的叠加,通过对雅可比矩阵的学习,弥补了这一点。另外在神经网络中引入f1的信息,可以为雅可比矩阵添加更多约束,得到更稳健的结果。

 

4.4深度预测网络

使用U-Net作为编码器与特征金字塔共享特征。对于解码器,微调最后一层卷积到128通道,并使用这些特征图作为基础深度图进行优化。最后的深度图是基础深度图的线性组合【17】:

                                                                                            (5)

解码器中采用三个上采样层和一个卷积层,最后一个卷积层生成128个基础深度图,上采样层采用如下结构【18】,进行快速计算:

                                                                      图5    上采样层                   

4.5训练

采用分层的方式进行训练。首先,采用预训练的深度图作为初始值,仅预测l0层特征图,并与雅可比预测网络联合训练,用于优化。基于从上一层提供的初始相对变换,训练下一层来优化结果。对于雅可比预测网络,仅在第一层训练来进行初始化,后面的层使用数值雅可比行列式进行优化,因为初始值在收敛范围内。利用真实转换矩阵 和深度图 ,来最小化重投影误差:

                                                                     (6)

在最后一层中,联合训练特征提取网络和深度图预测网络:

                                                                            (7)

是指深度图之间的BerHu损失,D0是初始深度图,D1是优化的深度图,D* 是真实深度图,μ 是深度图损失和投影损失之间的比例常数。

5.不足

1.LM 算法中由于阻尼因子的存在,不可微,所以不能直接进行反向传递来训练特征学习网络。

2.只能处理刚性变换

<think>我们正在查找与RegNet相关的代码实现。RegNet是一种卷积神经网络架构,由FacebookAI提出,旨在设计更高效、可扩展的模型结构。根据用户需求,我们需要提供RegNet的代码实现,可能基于PyTorch框架。由于用户要求提供代码实现,我们可以参考公开的RegNet实现,例如在PyTorch官方模型库(torchvision)中已经包含了RegNet的实现。因此,我们可以直接使用torchvision中的RegNet模型。下面我们将展示如何使用torchvision中的RegNet模型,包括如何安装、导入以及使用预训练的RegNet进行图像分类。步骤:1.安装torchvision(如果尚未安装)。2.导入torchvision.models.regnet模块。3.选择RegNet的变体(如RegNetX_400MF,RegNetX_800MF,RegNetX_1_6GF等)并加载预训练模型。4.使用模型进行预测。注意:由于用户没有指定具体的RegNet变体,我们将以RegNetX_400MF为例。代码示例:```pythonimporttorchfromtorchvisionimportmodelsimporttorchvision.transformsastransformsfromPILimportImage#加载预训练的RegNet模型model=models.regnet.regnet_x_400mf(pretrained=True)model.eval()#设置为评估模式#图像预处理preprocess=transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485,0.456,0.406],std=[0.229,0.224,0.225]),])#加载图像并预处理image=Image.open("path_to_your_image.jpg")input_tensor=preprocess(image)input_batch=input_tensor.unsqueeze(0)#创建batch维度#如果有GPU,则使用GPUiftorch.cuda.is_available():input_batch=input_batch.to('cuda')model.to('cuda')#前向传播withtorch.no_grad():output=model(input_batch)#获取预测结果probabilities=torch.nn.functional.softmax(output[0],dim=0)#读取类别标签#这里需要下载ImageNet的类别标签,假设我们有一个包含1000个类别的文件'imagenet_classes.txt'withopen('imagenet_classes.txt')asf:categories=[line.strip()forlineinf.readlines()]#获取预测概率最高的前5个类别top5_prob,top5_catid=torch.topk(probabilities,5)foriinrange(top5_prob.size(0)):print(categories[top5_catid[i]],top5_prob[i].item())```说明:-上述代码首先加载了预训练的RegNetX_400MF模型。-然后对输入图像进行预处理(调整大小、裁剪、归一化等)。-将图像转换为张量并传递给模型进行预测。-最后输出预测概率最高的前5个类别。注意:用户需要备一张图像,并替换代码中的`path_to_your_image.jpg`为实际路径。同时,需要下载ImageNet的类别标签文件(imagenet_classes.txt),该文件通常包含1000个类别的名称,每行一个。如果用户需要训练自己的RegNet模型,可以参考以下步骤:1.使用torchvision提供的RegNet模型结构(如regnet_x_400mf)创建模型(不加载预训练权重)。2.备自己的数据集,并设置数据加载器。3.定义损失函数和优化器。4.进行训练循环。由于训练整个网络需要大量计算资源和时间,用户也可以考虑使用迁移学习,即加载预训练模型并在自己的数据集上微调。微调示例代码:```python#加载预训练模型,但不使用预训练权重(或者使用预训练权重并替换最后一层)model=models.regnet.regnet_x_400mf(pretrained=True)#替换分类头(假设我们的数据集有10类)num_classes=10model.fc=torch.nn.Linear(model.fc.in_features,num_classes)#训练设置criterion=torch.nn.CrossEntropyLoss()optimizer=torch.optim.SGD(model.parameters(),lr=0.001,momentum=0.9)#然后进行训练循环...```以上是关于RegNet代码实现的基本介绍。如果用户需要更详细的信息,可以参考torchvision官方文档或RegNet的原始论文。参考文献:[^1]:[RegNet:DesigningNetworkDesignSpaces](https://arxiv.org/abs/2003.13678)[^2]:[torchvision.models.regnet—Torchvision0.12documentation](https://pytorch.org/vision/stable/models/regnet.html)§§相关问题§§1.RegNet与其他卷积神经网络(如ResNet)相比有什么优势?2.如何在自己的数据集上微调RegNet模型?3.RegNet的设计理念是什么?它是如何通过设计空间搜索来优化网络结构的?</think>### RegNet 代码实现 RegNet 是由 Facebook AI 提出的高效卷积神经网络架构,其核心思想是通过**设计空间搜索**(Design Space Exploration)自动生成最优网络结构。以下是基于 PyTorch 的 RegNet 实现详解: --- #### 1. **核心模块实现** ```python import torch import torch.nn as nn class Stem(nn.Module): """ 输入特征预处理模块 """ def __init__(self, in_channels=3, out_channels=32): super().__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=2, padding=1, bias=False) self.bn = nn.BatchNorm2d(out_channels) self.relu = nn.ReLU(inplace=True) def forward(self, x): return self.relu(self.bn(self.conv(x))) class XBlock(nn.Module): """ RegNet 基础残差块 (类似 ResNeXt) """ def __init__(self, in_channels, out_channels, group_width, stride=1): super().__init__() groups = out_channels // group_width # 分组卷积参数 self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False) self.bn1 = nn.BatchNorm2d(out_channels) self.conv2 = nn.Conv2d( out_channels, out_channels, kernel_size=3, stride=stride, padding=1, groups=groups, bias=False ) self.bn2 = nn.BatchNorm2d(out_channels) self.conv3 = nn.Conv2d(out_channels, out_channels, kernel_size=1, bias=False) self.bn3 = nn.BatchNorm2d(out_channels) self.relu = nn.ReLU(inplace=True) # 下采样捷径 self.downsample = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(out_channels) ) if stride != 1 or in_channels != out_channels else nn.Identity() def forward(self, x): identity = self.downsample(x) out = self.relu(self.bn1(self.conv1(x))) out = self.relu(self.bn2(self.conv2(out))) out = self.bn3(self.conv3(out)) out += identity return self.relu(out) ``` --- #### 2. **网络主体结构** ```python class RegNet(nn.Module): """ RegNet 完整架构 """ def __init__(self, block_config, in_channels=3, num_classes=1000): super().__init__() # block_config 示例: [(输出通道数, 块数量, 步长), ...] # 如 RegNetY_400MF: [(48, 8, 2), (104, 8, 2), (208, 8, 2), (440, 8, 2)] self.stem = Stem(in_channels) current_channels = 32 # 构建阶段(stages) self.stages = nn.ModuleList() for out_channels, num_blocks, stride in block_config: stage = self._make_stage( XBlock, current_channels, out_channels, num_blocks, stride, group_width=out_channels//2 ) self.stages.append(stage) current_channels = out_channels # 分类头 self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) self.fc = nn.Linear(current_channels, num_classes) def _make_stage(self, block, in_channels, out_channels, num_blocks, stride, group_width): layers = [] # 第一个块处理下采样 layers.append(block(in_channels, out_channels, group_width, stride)) # 后续块保持分辨率 for _ in range(1, num_blocks): layers.append(block(out_channels, out_channels, group_width, stride=1)) return nn.Sequential(*layers) def forward(self, x): x = self.stem(x) for stage in self.stages: x = stage(x) x = self.avgpool(x) x = torch.flatten(x, 1) return self.fc(x) ``` --- #### 3. **预训练模型调用** 可直接使用 TorchVision 内置模型: ```python from torchvision.models import regnet_y_400mf, RegNet_Y_400MF_Weights # 加载预训练模型 model = regnet_y_400mf(weights=RegNet_Y_400MF_Weights.IMAGENET1K_V1) model.eval() # 图像预处理 transform = RegNet_Y_400MF_Weights.IMAGENET1K_V1.transforms() preprocessed_img = transform(input_image).unsqueeze(0) # 推理 with torch.no_grad(): output = model(preprocessed_img) ``` --- #### 4. **关键设计特点** 1. **量化线性参数化** 通过线性约束设计空间: $$ \begin{aligned} u_j &= u_0 + w_a \cdot j \\ d_j &= \lfloor u_j \rfloor \end{aligned} $$ 其中 $d_j$ 为第 $j$ 阶段通道数,$u_0, w_a$ 为可学习参数[^1]。 2. **阶段统一结构** 每个阶段保持相同数量的残差块,仅通过通道数和分辨率区分。 3. **SE 模块扩展 (RegNetY)** 在 XBlock 基础上添加通道注意力: ```python class YBlock(XBlock): def __init__(self, *args, reduction_ratio=16): super().__init__(*args) self.se = nn.Sequential( nn.AdaptiveAvgPool2d(1), nn.Conv2d(self.out_channels, self.out_channels // reduction_ratio, 1), nn.ReLU(), nn.Conv2d(self.out_channels // reduction_ratio, self.out_channels, 1), nn.Sigmoid() ) def forward(self, x): out = super().forward(x) scale = self.se(out) return out * scale ``` --- ### 典型置示例 | 模型 | 阶段置 (通道, 块数, 步长) | 参数量 | |---------------|---------------------------------------|--------| | RegNetX_400MF | `[(32,8,2), (64,8,2), (96,8,2)]` | 5.2M | | RegNetY_800MF | `[(48,8,2), (112,8,2), (288,8,2)]` | 6.3M | [^1]: [RegNet: Designing Network Design Spaces](https://arxiv.org/abs/2003.13678) 提出参数化设计空间方法 [^2]: TorchVision 官方实现参考 [regnet.py](https://github.com/pytorch/vision/blob/main/torchvision/models/regnet.py)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值