澄海建网站,网站首页布局自适应,网站做弹幕广告,广告设计就业前景分析#x1f4dc; Probing Synergistic High-Order Interaction in Infrared and Visible Image Fusion #x1f355; 源码#xff1a; https://github.com/zheng980629/SHIP 先前融合规则与我们提出的范式之间的比较。之前的工作要么#xff08;a#xff09;缺乏明确的交互 Probing Synergistic High-Order Interaction in Infrared and Visible Image Fusion 源码 https://github.com/zheng980629/SHIP 先前融合规则与我们提出的范式之间的比较。之前的工作要么a缺乏明确的交互要么b仅实现了 2 n d 2^{n d} 2nd阶空间交互而c我们的SHIP融合了高阶空间和通道交互以探索模态之间在空间细粒度细节和全局统计中的协同相关性逐步整合并区分互补信息
如何将二阶交互扩展到任意高阶而又不会显著增加计算量呢论文并不仅仅只是将低阶计算平庸地升阶而是考虑了计算量的问题这就为以后潜在的实际应用增添了可能性 贡献
本研究中的新型协同高阶交互范式SHIP探索了红外与可见光图像融合中复杂的高阶交互。通过在空间和通道维度上融入高阶交互SHIP作为一种开创性方法研究了模态之间的协同相关性该范式研究了涉及空间细粒度细节和全局统计的高阶交互协同整合互补信息并从源模态中区分相互依赖性展示了其在全色锐化任务中的有效性 理解空间和通道上的阶数 普通卷积vanilla convolution传统的卷积操作通过对输入图像的局部区域进行加权求和来提取特征。然而这种操作本质上无法捕捉特定位置与其邻近区域之间的空间交互。换句话说卷积核的权重是固定的无法根据输入内容动态调整因此难以建模复杂的空间依赖关系。 动态卷积动态卷积通过根据输入生成动态权重来改进普通卷积。这种改进引入了一阶空间交互即卷积核的权重会根据输入内容自适应调整。 自注意力机制Transformer 通过自注意力机制实现了二阶空间交互。其核心是通过矩阵乘法计算查询queries、键keys和值values之间的关系。 SE 模块SE 模块通过一阶统计量来重新校准通道响应。具体来说它首先对每个通道进行全局平均池化squeeze然后通过全连接层学习通道权重excitation最后用这些权重对特征图进行加权。 所提出的协同高阶交互范式SHIP的详细框架包括在L次迭代中执行的交替空间和通道高阶交互。具体来说空间高阶交互充分挖掘了两种模态之间的协作并通过高阶建模整合了空间细粒度的互补信息。随后基于全局一阶统计量均值的通道高阶相互作用进一步研究了全局统计量区分了可见光和红外模态之间的相互依赖性 高阶空间交互 I F SHIP L ( ψ ( I R ) , ϕ ( I V ) ) I_{\mathcal{F}}\operatorname{SHIP}_L\left(\psi\left(I_{\mathcal{R}}\right), \phi\left(I_{\mathcal{V}}\right)\right) IFSHIPL(ψ(IR),ϕ(IV))整体结构也是比较简单的就是一个相同的模块重复处理了好多次得到结果效果好不好全靠模块设计
传统的注意力机制 O S ( ( F V ) 2 ) F V S 1 softmax ( Q ⊗ K T d k ) ⊗ V A ⊗ V \mathcal{O}_S\left(\left(F_{\mathcal{V}}\right)^2\right)F_{\mathcal{V}_S}^1\operatorname{softmax}\left(\frac{\mathbf{Q} \otimes \mathbf{K}^T}{\sqrt{d_k}}\right) \otimes \mathbf{V}\mathbf{A} \otimes \mathbf{V} OS((FV)2)FVS1softmax(dk Q⊗KT)⊗VA⊗V文中提出了一种近似形式 A i j ⟨ q i , k j ⟩ \mathbf{A}_{i j}\left\langle\mathbf{q}_i, \mathbf{k}_j\right\rangle Aij⟨qi,kj⟩ A F − 1 ( F ( F V W Q ) ⊙ F ( F R W K ) ‾ ) \mathbf{A}\mathcal{F}^{-1}\left(\mathcal{F}\left(F_{\mathcal{V}} \mathbf{W}^Q\right) \odot \overline{\mathcal{F}\left(F_{\mathcal{R}} \mathbf{W}^K\right)}\right) AF−1(F(FVWQ)⊙F(FRWK)) O S ( ( F V ) 2 ) F V S 1 Norm ( A ) ⊙ ( F R W V ) \mathcal{O}_S\left(\left(F_{\mathcal{V}}\right)^2\right)F_{\mathcal{V}_S}^1\operatorname{Norm}(\mathbf{A}) \odot\left(\mathrm{F}_{\mathcal{R}} \mathbf{W}^{\mathrm{V}}\right) OS((FV)2)FVS1Norm(A)⊙(FRWV)本质上就是把矩阵乘法转到频域中变为点乘再转回去空间域其实说不上创新而且在计算上面是不是变得高效也难说呀 O S ( ( F V S i − 1 ) 2 ) F V S i Attention ( Q i , K i , V i ) , Q i F V S i − 1 W Q i , K i F R W K i , V i F R W v i \begin{aligned} \mathcal{O}_S\left(\left(F_{\mathcal{V}_S}^{i-1}\right)^2\right)F_{\mathcal{V}_S}^i\operatorname{Attention}\left(\mathbf{Q}_i, \mathbf{K}_i, \mathbf{V}_i\right), \\ \mathbf{Q}_iF_{\mathcal{V}_S}^{i-1} \mathbf{W}^{\mathbf{Q}_i}, \mathbf{K}_iF_{\mathcal{R}} \mathbf{W}^{\mathbf{K}_i}, \mathbf{V}_iF_{\mathcal{R}} \mathbf{W}^{\mathbf{v}_i} \end{aligned} OS((FVSi−1)2)FVSiAttention(Qi,Ki,Vi),QiFVSi−1WQi,KiFRWKi,ViFRWvi F V → O S ( ( F V ) 2 ) → F V S 1 → O S ( ( F V S 1 ) 2 ) → F V S 2 ⋯ → O S ( ( F V S i ) 2 ) → F V S i 1 … O S ( ( F V S L − 1 ) 2 ) → F V S L \begin{aligned} F_{\mathcal{V}} \rightarrow \mathcal{O}_S\left(\left(F_{\mathcal{V}}\right)^2\right) \rightarrow F_{\mathcal{V}_{\mathcal{S}}}^1 \rightarrow \mathcal{O}_S\left(\left(F_{\mathcal{V}_{\mathcal{S}}}^1\right)^2\right) \rightarrow F_{\mathcal{V}_{\mathcal{S}}}^2 \cdots \\ \rightarrow \mathcal{O}_S\left(\left(F_{\mathcal{V}_{\mathcal{S}}}^i\right)^2\right) \rightarrow F_{\mathcal{V}_{\mathcal{S}}}^{i1} \ldots \mathcal{O}_S\left(\left(F_{\mathcal{V}_{\mathcal{S}}}^{L-1}\right)^2\right) \rightarrow F_{\mathcal{V}_{\mathcal{S}}}^L \end{aligned} FV→OS((FV)2)→FVS1→OS((FVS1)2)→FVS2⋯→OS((FVSi)2)→FVSi1…OS((FVSL−1)2)→FVSL之前的多个自注意力模块堆叠集中在索引上集中在一个模态另一个模态的键值对并没有因为模块的堆叠而更新而本文可以提高到任意阶 O S ( ( F V i − 1 ) j ) F V s j i Norm ( F V s j − 1 i W Q j ) ⊙ ( F R s j − 1 i W V ) F V s j − 1 i Norm ( F V s i − 2 i W Q j − 1 ) , F R s j − 1 i F R s j − 2 i W V j − 1 i \begin{aligned} \mathcal{O}_S\left(\left(F_{\mathcal{V}}^{i-1}\right)^j\right)F_{\mathcal{V}_s^j}^i\operatorname{Norm}\left(F_{\mathcal{V}_s^{j-1}}^i \mathbf{W}^{\mathbf{Q} \mathbf{j}}\right) \odot\left(F_{\mathcal{R}_s^{j-1}}^i \mathbf{W}^{\mathbf{V}}\right)\\ F_{\mathcal{V}_s^{j-1}}^i\operatorname{Norm}\left(F_{\mathcal{V}_s^{i-2}}^i \mathbf{W}^{\mathbf{Q} \mathbf{j}-1}\right), F_{\mathcal{R}_s^{j-1}}^iF_{\mathcal{R}_s^{j-2}}^i \mathbf{W}^{\mathbf{V}_{\mathbf{j}-1}^{\mathbf{i}}} \end{aligned} OS((FVi−1)j)FVsjiNorm(FVsj−1iWQj)⊙(FRsj−1iWV)FVsj−1iNorm(FVsi−2iWQj−1),FRsj−1iFRsj−2iWVj−1i F V → O S ( ( F V ) N ) → F V S 1 → O S ( ( F V s 1 ) N ) → F V S 2 … → O S ( ( F V S i ) N ) → F V S i 1 … O S ( ( F V S L − 1 ) N ) → F V S L \begin{aligned} F_{\mathcal{V}} \rightarrow \mathcal{O}_S\left(\left(F_{\mathcal{V}}\right)^N\right) \rightarrow F_{\mathcal{V}_{\mathcal{S}}}^1 \rightarrow \mathcal{O}_S\left(\left(F_{\mathcal{V}_s}^1\right)^N\right) \rightarrow F_{\mathcal{V}_{\mathcal{S}}}^2 \ldots \\ \rightarrow \mathcal{O}_S\left(\left(F_{\mathcal{V}_S}^i\right)^N\right) \rightarrow F_{\mathcal{V}_{\mathcal{S}}}^{i1} \ldots \mathcal{O}_S\left(\left(F_{\mathcal{V}_{\mathcal{S}}}^{L-1}\right)^N\right) \rightarrow F_{\mathcal{V}_S}^L \end{aligned} FV→OS((FV)N)→FVS1→OS((FVs1)N)→FVS2…→OS((FVSi)N)→FVSi1…OS((FVSL−1)N)→FVSL 在不同的空间高阶交互步骤中每次交互后的特征可视化。例如 F V s 3 2 F_{\mathcal{V}_s^3} ^2 FVs32表示 2 n d 2^{nd} 2nd空间高阶相互作用中三阶相互作用后的特征。这些可视化从两个角度说明了高阶空间相互作用的有效性1在每个高阶相互作用中特征响应随着顺序的增加而升级突出了突出的对象2 不同的高阶相互作用产生独特的响应展示了特征表示的多样性
class spatialInteraction(nn.Module):def __init__(self, channelin, channelout):super(spatialInteraction, self).__init__()# 定义三个卷积序列用于处理融合特征self.reflashFused1 nn.Sequential(nn.Conv2d(channelin, channelout, 3, 1, 1), # 3x3卷积输入通道为channelin输出通道为channeloutpadding为1nn.ReLU(), # ReLU激活函数nn.Conv2d(channelout, channelout, 3, 1, 1) # 再次3x3卷积)self.reflashFused2 nn.Sequential(nn.Conv2d(channelin, channelout, 3, 1, 1),nn.ReLU(),nn.Conv2d(channelout, channelout, 3, 1, 1))self.reflashFused3 nn.Sequential(nn.Conv2d(channelin, channelout, 3, 1, 1),nn.ReLU(),nn.Conv2d(channelout, channelout, 3, 1, 1))# 定义三个卷积序列用于处理红外特征self.reflashInfrared1 nn.Sequential(nn.Conv2d(channelin, channelout, 3, 1, 1),nn.ReLU(),nn.Conv2d(channelout, channelout, 3, 1, 1))self.reflashInfrared2 nn.Sequential(nn.Conv2d(channelin, channelout, 3, 1, 1),nn.ReLU(),nn.Conv2d(channelout, channelout, 3, 1, 1))self.reflashInfrared3 nn.Sequential(nn.Conv2d(channelin, channelout, 3, 1, 1),nn.ReLU(),nn.Conv2d(channelout, channelout, 3, 1, 1))# 定义四个LayerNorm层用于归一化self.norm1 LayerNorm(channelout, LayerNorm_typeWithBias)self.norm2 LayerNorm(channelout, LayerNorm_typeWithBias)self.norm3 LayerNorm(channelout, LayerNorm_typeWithBias)self.norm4 LayerNorm(channelout, LayerNorm_typeWithBias)def forward(self, vis, inf, i, j):# 获取可见光图像的尺寸_, C, H, W vis.size()# 对可见光和红外图像进行快速傅里叶变换FFTvis_fft torch.fft.rfft2(vis.float())inf_fft torch.fft.rfft2(inf.float())# 计算可见光和红外图像的频域注意力图atten vis_fft * inf_fftatten torch.fft.irfft2(atten, s(H, W)) # 逆FFT变换回空间域atten self.norm1(atten) # 归一化fused_OneOrderSpa atten * inf # 一阶空间融合特征# 通过第一个融合卷积序列处理一阶融合特征fused_OneOrderSpa self.reflashFused1(fused_OneOrderSpa)fused_OneOrderSpa self.norm2(fused_OneOrderSpa) # 归一化infraredReflash1 self.reflashInfrared1(inf) # 处理红外特征fused_twoOrderSpa fused_OneOrderSpa * infraredReflash1 # 二阶空间融合特征# 通过第二个融合卷积序列处理二阶融合特征fused_twoOrderSpa self.reflashFused2(fused_twoOrderSpa)fused_twoOrderSpa self.norm3(fused_twoOrderSpa) # 归一化infraredReflash2 self.reflashInfrared2(infraredReflash1) # 处理红外特征fused_threeOrderSpa fused_twoOrderSpa * infraredReflash2 # 三阶空间融合特征# 通过第三个融合卷积序列处理三阶融合特征fused_threeOrderSpa self.reflashFused3(fused_threeOrderSpa)fused_threeOrderSpa self.norm4(fused_threeOrderSpa) # 归一化infraredReflash3 self.reflashInfrared3(infraredReflash2) # 处理红外特征fused_fourOrderSpa fused_threeOrderSpa * infraredReflash3 # 四阶空间融合特征# 将最终融合特征与原始可见光图像相加fused fused_fourOrderSpa vis# 返回融合后的特征和处理后的红外特征return fused, infraredReflash3高阶通道交互
传统的SEsqueeze and excitation模块 Z i 1 H × W ∑ x 1 H ∑ y 1 W F i ( x , y ) O C ( ( F i ) 1 ) F C i σ ( W Z 1 i Z i ) ⋅ F i \begin{gathered} Z^i\frac{1}{H \times W} \sum_{x1}^H \sum_{y1}^W F^i(x, y) \\ \mathcal{O}_C\left(\left(F^i\right)^1\right)F_C^i\sigma\left(\mathbf{W}^{\mathbf{Z}_1^i} Z^i\right) \cdot F^i \end{gathered} ZiH×W1x1∑Hy1∑WFi(x,y)OC((Fi)1)FCiσ(WZ1iZi)⋅Fi其中 F i concat [ F V S i , F R S i ] F^i \operatorname{concat}\left[F_{\mathcal{V}_S}^i, F_{\mathcal{R}_S}^i\right] Ficoncat[FVSi,FRSi] Z c Z_c Zc 表示一阶统计量 σ \sigma σ 表示 Sigmoid 函数。 W Z \mathbf{W}^{\mathbf{Z}} WZ 包括两个线性变换和一个 ReLU 函数。作者将其扩展到了高阶形式 O C ( ( F i ) j ) F C j i σ ( W Z j i Z j − 1 i ) ⋅ ( W F j i F j − 1 i ) , Z j − 1 i σ ( W F j − 1 i Z j − 2 i ) , F j − 1 i W F j − 1 i F j − 2 i F V → O S ( ( F V ) N ) → O C ( ( F V S 1 ) N ) → O S ( ( F V C 1 ) N ) → O C ( ( F V S 2 ) N ) → … O S ( ( F V C L − 1 ) N ) → O C ( ( F V S L ) N ) \begin{aligned} \mathcal{O}_C\left(\left(F^i\right)^j\right)F_{C j}^i\sigma\left(\mathbf{W}^{\mathbf{Z}_j^i} Z_{j-1}^i\right) \cdot\left(\mathbf{W}^{\mathbf{F}_j^i} F_{j-1}^i\right), \\ Z_{j-1}^i\sigma\left(\mathbf{W}^{\mathbf{F}_{j-1}^i} Z_{j-2}^i\right), F_{j-1}^i\mathbf{W}^{\mathbf{F}_{j-1}^i} F_{j-2}^i \\ F_{\mathcal{V}} \rightarrow \mathcal{O}_S\left(\left(F_{\mathcal{V}}\right)^N\right) \rightarrow \mathcal{O}_C\left(\left(F_{\mathcal{V}_{\mathcal{S}}}^1\right)^N\right) \rightarrow \mathcal{O}_S\left(\left(F_{\mathcal{V}_{\mathcal{C}}}^1\right)^N\right) \\ \rightarrow \mathcal{O}_C\left(\left(F_{\mathcal{V}_{\mathcal{S}}}^2\right)^N\right) \rightarrow \ldots \mathcal{O}_S\left(\left(F_{\mathcal{V}_C}^{L-1}\right)^N\right) \rightarrow \mathcal{O}_C\left(\left(F_{\mathcal{V}_{\mathcal{S}}}^L\right)^N\right) \end{aligned} OC((Fi)j)FCjiσ(WZjiZj−1i)⋅(WFjiFj−1i),Zj−1iσ(WFj−1iZj−2i),Fj−1iWFj−1iFj−2iFV→OS((FV)N)→OC((FVS1)N)→OS((FVC1)N)→OC((FVS2)N)→…OS((FVCL−1)N)→OC((FVSL)N)具体原理不是很懂但好像是做一次变换就可以升一次阶数具体可能需要结合代码来看 不同阶次在通道索引上的通道交互。这个观察结果为有力证据表明不同阶次的交互探索了红外和可见模态之间的多样化相互依赖关系
class channelInteraction(nn.Module):def __init__(self, channelin, channelout):super(channelInteraction, self).__init__()# 初始化各个卷积层包括通道注意力模块和融合模块self.chaAtten nn.Sequential(nn.Conv2d(channelin * 2, channelout, kernel_size1, padding0, biasTrue), # 1x1卷积nn.ReLU(),nn.Conv2d(channelout, channelin * 2, kernel_size1, padding0, biasTrue) # 1x1卷积)# 重构通道注意力模块1、2、3用于逐步改进注意力特征self.reflashChaAtten1 nn.Sequential(nn.Conv2d(channelin * 2, channelout, kernel_size1, padding0, biasTrue),nn.ReLU(),nn.Conv2d(channelout, channelin * 2, kernel_size1, padding0, biasTrue))self.reflashChaAtten2 nn.Sequential(nn.Conv2d(channelin * 2, channelout, kernel_size1, padding0, biasTrue),nn.ReLU(),nn.Conv2d(channelout, channelin * 2, kernel_size1, padding0, biasTrue))self.reflashChaAtten3 nn.Sequential(nn.Conv2d(channelin * 2, channelout, kernel_size1, padding0, biasTrue),nn.ReLU(),nn.Conv2d(channelout, channelin * 2, kernel_size1, padding0, biasTrue))# 融合模块用于融合不同通道的特征self.reflashFused1 nn.Sequential(nn.Conv2d(channelin * 2, channelout * 2, 3, 1, 1), # 3x3卷积nn.ReLU(),nn.Conv2d(channelout * 2, channelout * 2, 3, 1, 1) # 3x3卷积)self.reflashFused2 nn.Sequential(nn.Conv2d(channelin * 2, channelout * 2, 3, 1, 1),nn.ReLU(),nn.Conv2d(channelout * 2, channelout * 2, 3, 1, 1))self.reflashFused3 nn.Sequential(nn.Conv2d(channelin * 2, channelout * 2, 3, 1, 1),nn.ReLU(),nn.Conv2d(channelout * 2, channelout * 2, 3, 1, 1))# 自适应平均池化层将输入大小调整为 (batch_size, channels, 1, 1)self.avgpool nn.AdaptiveAvgPool2d(1)# 后处理模块用于处理融合后的特征self.postprocess nn.Sequential(InvBlock(DenseBlock, 2 * channelin, channelout),nn.Conv2d(2 * channelout, channelout, 1, 1, 0) # 1x1卷积减少通道数)def forward(self, vis, inf, i, j):# 输入vis和inf是两个不同的特征图例如视觉和信息特征图# 首先将这两个特征图按通道维度拼接vis_cat torch.cat([vis, inf], 1)# 使用通道注意力机制对拼接后的特征图进行处理chanAtten self.chaAtten(self.avgpool(vis_cat)).softmax(1)channel_response self.chaAtten(self.avgpool(vis_cat))# 使用通道注意力对特征图进行加权fused_OneOrderCha vis_cat * chanAtten# 通过第一个重构模块reflashFused1进一步处理fused_OneOrderCha self.reflashFused1(fused_OneOrderCha)chanAttenReflash1 self.reflashChaAtten1(chanAtten).softmax(1)fused_twoOrderCha fused_OneOrderCha * chanAttenReflash1# 通过第二个重构模块reflashFused2进一步处理fused_twoOrderCha self.reflashFused2(fused_twoOrderCha)chanAttenReflash2 self.reflashChaAtten2(chanAttenReflash1).softmax(1)fused_threeOrderCha fused_twoOrderCha * chanAttenReflash2# 通过第三个重构模块reflashFused3进一步处理fused_threeOrderCha self.reflashFused3(fused_threeOrderCha)chanAttenReflash3 self.reflashChaAtten3(chanAttenReflash2).softmax(1)fused_fourOrderCha fused_threeOrderCha * chanAttenReflash3# 最终的后处理模块生成最终的输出output self.postprocess(fused_fourOrderCha)return output损失函数 L L int λ L gra \mathcal{L}\mathcal{L}_{\text {int }}\lambda \mathcal{L}_{\text {gra }} LLint λLgra L i n t ∥ ( ω V ∘ I V ω R ∘ I R ) − I F ∥ 1 \mathcal{L}_{\mathrm{int}}\left\|\left(\omega_{\mathcal{V}} \circ I_{\mathcal{V}}\omega_{\mathcal{R}} \circ I_{\mathcal{R}}\right)-I_{\mathcal{F}}\right\|_1 Lint∥(ωV∘IVωR∘IR)−IF∥1 ω V S V / ( S V − S R ) and S R 1 − S V \omega_{\mathcal{V}}S_{\mathcal{V}} /\left(S_{\mathcal{V}}-S_{\mathcal{R}}\right) \text { and } S_{\mathcal{R}}1-S_{\mathcal{V}} ωVSV/(SV−SR) and SR1−SV L gra 1 H W ∥ ∇ I F − max ( ∇ I R , ∇ I V ) ∥ 1 \mathcal{L}_{\text {gra }}\frac{1}{H W}\left\|\nabla I_{\mathcal{F}}-\max \left(\nabla I_{\mathcal{R}}, \nabla I_{\mathcal{V}}\right)\right\|_1 Lgra HW1∥∇IF−max(∇IR,∇IV)∥1损失函数中规中矩因为重点不在这边重点在于前面的模块设计。实验部分有兴趣的可以自行去看我觉得没有什么亮点就不说了 本文的源代码中作者引用了Facebook研究的一个注册器可以用来组织代码结构使得整个代码部分更加容易管理
# 修改自: https://github.com/facebookresearch/fvcore/blob/master/fvcore/common/registry.py # noqa: E501class Registry():提供名称 - 对象映射的注册表用于支持第三方用户的自定义模块。创建一个注册表例如创建一个骨干网络的注册表:.. code-block:: pythonBACKBONE_REGISTRY Registry(BACKBONE)注册一个对象.. code-block:: pythonBACKBONE_REGISTRY.register()class MyBackbone():...或者.. code-block:: pythonBACKBONE_REGISTRY.register(MyBackbone)def __init__(self, name):构造函数参数:name (str): 注册表的名称self._name name# key: 数据集/模型等的类名value: 对应的类对象self._obj_map {}def _do_register(self, name, obj):# 注册一个对象assert (name not in self._obj_map), (f名为 {name} 的对象已经在 {self._name} 注册表中注册过了!)self._obj_map[name] objdef register(self, objNone):使用给定对象的名称 obj.__name__ 注册该对象。可以作为装饰器使用也可以不使用装饰器。参见本类的文档字符串了解使用方法。if obj is None:# 用作装饰器def deco(func_or_class):name func_or_class.__name__# print(name)self._do_register(name, func_or_class)return func_or_classreturn deco# 作为函数调用时name obj.__name__self._do_register(name, obj)def get(self, name):# 获取对应类的对象ret self._obj_map.get(name)if ret is None:raise KeyError(f在 {self._name} 注册表中没有找到名为 {name} 的对象)return retdef __contains__(self, name):# 判断某个对象是否已经注册return name in self._obj_mapdef __iter__(self):# 迭代器方法return iter(self._obj_map.items())def keys(self):# 获取所有注册的对象的名称return self._obj_map.keys()# 以下是不同模块的注册表实例DATASET_REGISTRY Registry(dataset) # 数据集注册表
ARCH_REGISTRY Registry(arch) # 网络架构注册表
MODEL_REGISTRY Registry(model) # 模型注册表
LOSS_REGISTRY Registry(loss) # 损失函数注册表
METRIC_REGISTRY Registry(metric) # 指标注册表