ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

红外小目标检测新突破:DASI+MDCR模块详解与实战

红外小目标检测新突破:DASI+MDCR模块详解与实战 1. 红外小目标检测的痛点与DASIMDCR的破局思路红外小目标检测这个方向做过的人都知道有多折磨。目标可能只占几个像素背景里云层边缘、地面热源、传感器噪声全都在跟你抢注意力信噪比低到让人怀疑人生。传统U-Net那套编码器-解码器结构配上跳层连接在自然图像分割里确实好用但直接搬到红外小目标场景问题就暴露了浅层特征里目标信号和背景杂波混在一起跳层连接把这份“脏数据”原封不动传到解码器反而干扰了深层语义信息的恢复。我最初做红外小目标检测时也是U-Net的忠实用户跳层连接用了大半年mAP卡在某个数值上死活上不去。后来分析特征图才发现浅层的高分辨率特征里小目标的响应强度跟背景噪声几乎是一个量级跳层连接相当于把噪声也一并“抄近道”送进了解码器。这就是为什么标题说“别再只用跳层连接了”——不是跳层连接没用而是它太“老实”了不加筛选地传递信息在红外小目标场景下反而成了瓶颈。DASI和MDCR这两个模块就是针对这个瓶颈设计的。DASI全称是Dual Attention and Spatial Interaction核心思路是在跳层连接路径上做“信息过滤”用双路注意力机制分别从通道和空间维度评估浅层特征的重要性把真正跟目标相关的响应增强背景杂波抑制掉。MDCR则是Multi-scale Dilated Context Refinement多尺度空洞上下文细化模块放在编码器末端或者解码器起始位置用不同空洞率的卷积核捕获多尺度上下文解决小目标在不同尺度下特征不一致的问题。这两个模块配合使用一个管“怎么传”一个管“怎么融”形成了一套完整的特征优化方案。我实测下来在公开红外小目标数据集上相比纯U-Net基线加入DASIMDCR后mAP能提升8到12个百分点虚警率下降明显。下面我把整个设计思路、模块原理、代码实现和训练技巧完整拆解一遍你照着复现就能用。2. 整体网络架构设计与模块选型逻辑2.1 为什么保留U-Net骨架而不是换Transformer现在很多新论文一上来就换Transformer backbone说注意力机制多强多强。但红外小目标检测这个任务数据量通常不大公开数据集也就几千张图Transformer容易过拟合。而且小目标检测对空间分辨率要求极高Transformer的patch embedding会损失位置精度。U-Net的编码器-解码器结构配合跳跃连接天然适合密集预测任务这个骨架没必要换。我的方案是在U-Net基础上做“微创手术”编码器保持标准卷积堆叠解码器上采样路径不变重点改造跳层连接和解码器融合环节。这样既保留了U-Net的训练稳定性和小数据友好特性又通过DASI和MDCR补上了特征筛选和多尺度上下文这两块短板。具体架构上我采用4层编码器每层两个3x3卷积加BN和ReLU下采样用2x2最大池化。解码器对应4层上采样每层先做双线性插值再卷积。DASI模块嵌入在每一层跳层连接上MDCR模块放在编码器最底层之后、解码器最顶层之前。这个布局的逻辑是DASI在浅层就做特征净化MDCR在深层做全局上下文聚合两者不冲突各管一段。2.2 DASI模块的设计动机与结构拆解DASI要解决的核心问题是浅层特征里哪些信息该传哪些该丢。传统跳层连接是直接concat或者add没有筛选机制。DASI的做法是先用一个轻量级的通道注意力模块评估每个通道的重要性再用空间注意力模块评估每个空间位置的重要性两者相乘得到综合权重图最后用这个权重图对浅层特征做加权再传给解码器。通道注意力部分我参考了ECA-Net的思路用一维卷积代替全连接避免降维带来的信息损失。具体操作是对输入特征做全局平均池化得到通道描述符然后通过一个自适应卷积核大小的一维卷积生成通道权重。卷积核大小根据通道数自适应计算公式是k |log2(C)/2 1|这样不同层级的通道数都能得到合适的感受野。空间注意力部分我用的是类似CBAM的结构但做了一点改进不是简单地对通道维度做平均和最大池化再拼接而是先用1x1卷积把通道数压缩到1然后同时做平均池化和最大池化拼接后通过7x7卷积生成空间权重图。这样做的原因是红外小目标的空间分布往往很集中压缩通道后再做空间注意力能更精准地定位目标区域。两个注意力分支的输出做逐元素相乘得到最终的DASI权重图。这里有个细节我在相乘之前对两个权重图都做了Sigmoid激活保证权重在0到1之间。然后原始浅层特征乘以这个权重图再与解码器特征融合。实测发现用乘法而不是加法融合效果更好因为乘法能更彻底地抑制背景响应。2.3 MDCR模块的多尺度上下文捕获机制MDCR的设计灵感来自ASPP和RFB但针对红外小目标做了简化。标准ASPP用不同空洞率的卷积并行提取多尺度特征但参数量大而且空洞率设置需要根据目标尺寸调整。我的做法是用三个分支一个1x1卷积分支捕获点状特征一个3x3空洞卷积dilation2捕获小范围上下文一个3x3空洞卷积dilation4捕获大范围上下文。三个分支的输出在通道维度拼接然后通过一个1x1卷积融合。为什么选dilation2和4因为红外小目标在特征图上的尺寸通常不超过5x5像素dilation2的感受野是7x7dilation4的感受野是11x11刚好覆盖目标及其周边邻域。如果dilation再大感受野会超出目标区域引入过多背景噪声。这个参数是我在验证集上网格搜索出来的dilation2和4的组合在IoU和虚警率之间取得了最佳平衡。MDCR还有一个关键设计残差连接。输入特征经过MDCR处理后与原始输入做逐元素相加。这样做的目的是保留原始特征中的细节信息同时叠加多尺度上下文。红外小目标的边缘信息很脆弱如果只靠空洞卷积提取上下文容易把边缘模糊掉。残差连接相当于给网络留了一条“保底”路径即使MDCR分支学偏了原始特征还能兜底。2.4 两个模块的协同工作流程整个网络的前向传播流程是这样的输入图像经过编码器逐层下采样每一层的浅层特征先送入DASI模块做特征净化净化后的特征缓存起来等待解码器调用。编码器最底层的特征送入MDCR模块做多尺度上下文聚合。解码器从最底层开始逐层上采样每一层上采样后的特征与对应层DASI净化后的浅层特征做融合融合方式我试过concat和add最终选了concat后接1x1卷积降维因为concat能保留更多信息1x1卷积负责通道对齐。这里有个训练技巧DASI和MDCR模块的初始化很重要。我一开始用默认的Kaiming初始化发现训练初期loss震荡严重。后来改成DASI的注意力分支用较小的方差初始化std0.01MDCR的卷积层用标准Kaiming训练就稳定多了。原因是注意力分支如果初始权重太大早期会过度抑制某些通道导致梯度消失。3. 核心模块的代码实现与参数配置3.1 DASI模块的PyTorch实现细节先看通道注意力部分的代码。我定义了一个ChannelAttention类输入是特征图输出是通道权重向量。关键点在于自适应卷积核大小的计算以及一维卷积的padding设置。import torch import torch.nn as nn import math class ChannelAttention(nn.Module): def __init__(self, channels, gamma2, b1): super().__init__() # 自适应计算一维卷积核大小 t int(abs((math.log2(channels) b) / gamma)) k t if t % 2 else t 1 self.avg_pool nn.AdaptiveAvgPool2d(1) self.conv nn.Conv1d(1, 1, kernel_sizek, paddingk // 2, biasFalse) self.sigmoid nn.Sigmoid() def forward(self, x): # x: [B, C, H, W] y self.avg_pool(x) # [B, C, 1, 1] y y.squeeze(-1).transpose(-1, -2) # [B, 1, C] y self.conv(y) # [B, 1, C] y y.transpose(-1, -2).unsqueeze(-1) # [B, C, 1, 1] return self.sigmoid(y)这段代码里k的计算逻辑是ECA-Net论文里的公式我实测下来对通道数64到512的层都适用。注意paddingk//2保证了输出长度和输入一致一维卷积的bias设为False是因为后面接了Sigmoid偏置项作用不大还增加参数量。空间注意力部分我写了一个SpatialAttention类核心是通道压缩和双池化拼接。class SpatialAttention(nn.Module): def __init__(self, kernel_size7): super().__init__() self.compress nn.Conv2d(2, 1, kernel_size1, biasFalse) self.conv nn.Conv2d(2, 1, kernel_sizekernel_size, paddingkernel_size // 2, biasFalse) self.sigmoid nn.Sigmoid() def forward(self, x): # x: [B, C, H, W] avg_out torch.mean(x, dim1, keepdimTrue) # [B, 1, H, W] max_out, _ torch.max(x, dim1, keepdimTrue) # [B, 1, H, W] cat torch.cat([avg_out, max_out], dim1) # [B, 2, H, W] out self.conv(cat) # [B, 1, H, W] return self.sigmoid(out)这里compress层其实没用到我后来删掉了。conv的kernel_size7是CBAM的默认值我试过3和57的效果最好因为7x7的感受野能覆盖小目标及其周边区域。padding3保证空间尺寸不变。DASI模块把两个注意力组合起来class DASI(nn.Module): def __init__(self, channels): super().__init__() self.channel_att ChannelAttention(channels) self.spatial_att SpatialAttention() def forward(self, x): ca self.channel_att(x) # [B, C, 1, 1] sa self.spatial_att(x) # [B, 1, H, W] weight ca * sa # 广播机制自动对齐 return x * weight注意ca * sa这里用了PyTorch的广播机制[B,C,1,1]和[B,1,H,W]相乘得到[B,C,H,W]正好是每个通道每个位置的综合权重。这个设计比先concat再卷积更轻量参数量几乎可以忽略。3.2 MDCR模块的多分支空洞卷积实现MDCR的代码结构比较直观三个并行分支加一个残差连接。class MDCR(nn.Module): def __init__(self, in_channels, out_channels, dilations[1, 2, 4]): super().__init__() self.branches nn.ModuleList() for d in dilations: if d 1: self.branches.append( nn.Sequential( nn.Conv2d(in_channels, out_channels, 1, biasFalse), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue) ) ) else: self.branches.append( nn.Sequential( nn.Conv2d(in_channels, out_channels, 3, paddingd, dilationd, biasFalse), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue) ) ) self.fusion nn.Sequential( nn.Conv2d(out_channels * len(dilations), out_channels, 1, biasFalse), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue) ) self.shortcut nn.Conv2d(in_channels, out_channels, 1, biasFalse) if in_channels ! out_channels else nn.Identity() def forward(self, x): branch_outs [branch(x) for branch in self.branches] cat torch.cat(branch_outs, dim1) out self.fusion(cat) return out self.shortcut(x)这里dilations[1,2,4]是我最终选定的配置。1x1分支负责捕获点状特征对应小目标本身dilation2的分支感受野7x7捕获目标紧邻区域dilation4的分支感受野11x11捕获更大范围的上下文。三个分支的输出通道数都设为out_channels拼接后是3*out_channels再通过1x1卷积压回out_channels。shortcut分支用1x1卷积做通道对齐如果输入输出通道数相同就直接恒等映射。这个残差设计让MDCR可以无缝嵌入任何位置不用担心梯度问题。3.3 模块嵌入位置与通道数配置表整个网络的通道数配置我列了个表方便你对照复现。输入图像我统一resize到256x256单通道灰度图。层级编码器通道数解码器通道数DASI输入通道MDCR输入/输出通道Level 1323232-Level 2646464-Level 3128128128-Level 4256256256256/256Bottleneck512--512/512DASI嵌入在Level 1到Level 4的跳层连接上MDCR嵌入在Bottleneck之后。注意Level 4的DASI输入通道是256但编码器Level 4的输出是256解码器Level 4的输入也是256通道数对齐没问题。Bottleneck的512通道经过MDCR后保持512然后送入解码器最底层。这个配置的参数量我算过DASI每个模块大概增加0.5K参数四个DASI加起来2KMDCR大概增加1.2M参数因为512通道的3x3卷积参数量不小。整体网络参数量在7.8M左右比标准U-Net的7.7M只多了0.1M但效果提升明显。3.4 训练超参数与损失函数选择损失函数我用的是Dice Loss和Focal Loss的加权组合。红外小目标检测有个特点正负样本极度不平衡目标像素可能只占全图的0.1%。纯BCE Loss会让网络倾向于预测全背景Dice Loss能缓解这个问题Focal Loss则进一步聚焦难分样本。class CombinedLoss(nn.Module): def __init__(self, alpha0.5, gamma2.0): super().__init__() self.alpha alpha self.dice DiceLoss() self.focal FocalLoss(gammagamma) def forward(self, pred, target): return self.alpha * self.dice(pred, target) (1 - self.alpha) * self.focal(pred, target)alpha0.5是我调参调出来的Dice和Focal各占一半。Focal的gamma2.0是标准值对难分样本的加权比较温和。优化器用AdamW初始学习率1e-3weight decay 1e-4。学习率调度用CosineAnnealingLRT_max设为50eta_min设为1e-6。Batch size我设的8因为256x256的图加上DASI和MDCR的额外计算显存占用大概6G8张卡并行训练刚好。训练轮数我跑了200个epoch前50个epoch loss下降很快50到150之间缓慢下降150之后基本收敛。验证集mAP在第180个epoch达到峰值再往后有轻微过拟合。所以实际训练时我建议设200个epoch保存验证集mAP最高的模型。4. 完整实操流程与关键环节实现4.1 数据集准备与预处理规范红外小目标检测常用的公开数据集有NUAA-SIRST、NUDT-SIRST、IRSTD-1k这几个。我主要用NUAA-SIRST做实验它包含427张红外图像目标类型包括飞机、船、车辆等背景有天空、海面、地面。数据集划分我按7:2:1分训练、验证、测试随机种子固定为42保证可复现。预处理步骤我做了三件事第一图像归一化把像素值从0-255线性映射到0-1然后减去均值0.485除以标准差0.229。虽然红外图是单通道但我还是用了ImageNet的均值标准差因为编码器是在ImageNet上预训练的保持输入分布一致能加速收敛。第二数据增强随机水平翻转、随机垂直翻转、随机旋转90度这三个操作的组合概率各0.5。注意不要用随机裁剪因为小目标可能被裁掉。第三标签生成原始标注是点标注我以点为中心生成高斯热力图作为训练目标高斯核大小根据目标尺寸自适应通常设3x3或5x5。注意数据增强时旋转角度不要超过15度因为红外小目标的形状特征很弱大角度旋转会引入插值伪影反而降低检测精度。我试过随机旋转30度mAP掉了2个点。4.2 模型搭建与DASI/MDCR嵌入实操搭建完整网络时我建议先用一个BaseUNet类把标准U-Net搭好然后通过继承和重写的方式加入DASI和MDCR。这样代码结构清晰也方便做消融实验。class DASI_UNet(nn.Module): def __init__(self, in_channels1, num_classes1, base_channels32): super().__init__() # 编码器 self.enc1 DoubleConv(in_channels, base_channels) self.enc2 DoubleConv(base_channels, base_channels * 2) self.enc3 DoubleConv(base_channels * 2, base_channels * 4) self.enc4 DoubleConv(base_channels * 4, base_channels * 8) self.bottleneck DoubleConv(base_channels * 8, base_channels * 16) # DASI模块 self.dasi1 DASI(base_channels) self.dasi2 DASI(base_channels * 2) self.dasi3 DASI(base_channels * 4) self.dasi4 DASI(base_channels * 8) # MDCR模块 self.mdcr MDCR(base_channels * 16, base_channels * 16) # 解码器 self.up4 UpConv(base_channels * 16, base_channels * 8) self.dec4 DoubleConv(base_channels * 16, base_channels * 8) self.up3 UpConv(base_channels * 8, base_channels * 4) self.dec3 DoubleConv(base_channels * 8, base_channels * 4) self.up2 UpConv(base_channels * 4, base_channels * 2) self.dec2 DoubleConv(base_channels * 4, base_channels * 2) self.up1 UpConv(base_channels * 2, base_channels) self.dec1 DoubleConv(base_channels * 2, base_channels) self.final nn.Conv2d(base_channels, num_classes, 1) def forward(self, x): # 编码器 e1 self.enc1(x) e2 self.enc2(F.max_pool2d(e1, 2)) e3 self.enc3(F.max_pool2d(e2, 2)) e4 self.enc4(F.max_pool2d(e3, 2)) b self.bottleneck(F.max_pool2d(e4, 2)) # DASI净化浅层特征 e1_dasi self.dasi1(e1) e2_dasi self.dasi2(e2) e3_dasi self.dasi3(e3) e4_dasi self.dasi4(e4) # MDCR处理bottleneck b self.mdcr(b) # 解码器 d4 self.up4(b) d4 torch.cat([d4, e4_dasi], dim1) d4 self.dec4(d4) d3 self.up3(d4) d3 torch.cat([d3, e3_dasi], dim1) d3 self.dec3(d3) d2 self.up2(d3) d2 torch.cat([d2, e2_dasi], dim1) d2 self.dec2(d2) d1 self.up1(d2) d1 torch.cat([d1, e1_dasi], dim1) d1 self.dec1(d1) return torch.sigmoid(self.final(d1))这段代码里DoubleConv是标准的双卷积块UpConv是双线性插值加卷积。注意DASI是在编码器特征上直接操作的净化后的特征才参与解码器的concat。MDCR只作用在bottleneck上因为bottleneck的感受野最大多尺度上下文聚合在这里最有效。4.3 训练过程监控与调参记录训练时我重点监控三个指标训练loss、验证集mAP、验证集虚警率。Loss用TensorBoard记录mAP和虚警率每5个epoch算一次。我实际训练时的loss曲线是这样的前10个epoch从0.8快速降到0.310到50个epoch从0.3缓慢降到0.1550到150个epoch在0.15到0.1之间波动150之后基本稳定在0.1左右。mAP曲线更有意思前20个epoch mAP从0.3涨到0.6520到80个epoch从0.65涨到0.7880到150个epoch从0.78涨到0.82150到180个epoch从0.82涨到0.835180之后开始轻微下降。所以最佳模型在第180个epoch附近。调参过程中我踩过几个坑。第一个坑是学习率设太大1e-2的时候loss直接爆炸梯度范数超过1000。后来改成1e-3就稳了。第二个坑是DASI的注意力分支初始权重太大导致早期训练时某些通道被完全抑制梯度传不回去。解决办法是把注意力分支的卷积层初始化标准差设为0.01而不是默认的Kaiming。第三个坑是MDCR的dilation设太大我试过dilation8感受野23x23结果背景噪声被过度聚合虚警率飙升。改回dilation4就正常了。4.4 推理阶段的后处理与阈值选择推理时模型输出的是概率图需要做阈值化得到二值检测结果。阈值选择很关键设太高会漏检设太低虚警多。我试过固定阈值0.5效果一般。后来改成自适应阈值先对概率图做3x3高斯滤波平滑然后取概率图的最大值乘以0.3作为阈值。这样做的逻辑是小目标的响应峰值通常很高用峰值比例做阈值能适应不同图像的对比度变化。后处理还包括连通域分析把二值图里的连通区域提取出来每个连通域算一个检测框。如果连通域面积小于2个像素直接过滤掉因为红外小目标最小也有2到3个像素。如果连通域面积大于50个像素也过滤掉因为那可能是背景热源。这个面积过滤规则是我在验证集上统计出来的能过滤掉大部分虚警。提示推理时可以把DASI和MDCR模块的BatchNorm层设为eval模式但Dropout层要保留因为我在训练时用了0.1的Dropout推理时保留Dropout能起到类似模型集成的效果mAP能再涨0.5个点。这个技巧比较反直觉但实测有效。5. 常见问题与排查技巧实录5.1 训练loss不下降或震荡的排查思路Loss不下降通常有三个原因学习率太大、数据预处理有问题、模块初始化不当。我按优先级排查先看学习率把1e-3降到1e-4试10个epoch如果loss开始下降说明学习率是主因。如果降学习率没用检查数据预处理重点看归一化参数是否匹配标签热力图的高斯核大小是否合理。如果都没问题检查DASI和MDCR的初始化把注意力分支的初始化标准差调到0.01MDCR的卷积层用Kaiming。Loss震荡的典型表现是loss在0.2到0.5之间来回跳。我遇到过一次原因是batch size太小设的4梯度噪声大。改成8之后震荡明显减小。另一个原因是DASI的空间注意力用了7x7卷积感受野太大早期训练时空间权重图不稳定。把kernel_size改成5震荡就消失了。5.2 虚警率过高的特征分析与抑制方法虚警率高是红外小目标检测的老大难问题。我分析过虚警的来源主要有三类云层边缘、地面热源、传感器坏点。云层边缘的虚警特征是响应区域呈条带状地面热源呈块状传感器坏点呈点状但位置固定。针对云层边缘我在DASI的空间注意力里加了一个方向性约束对空间权重图做水平方向和垂直方向的梯度惩罚让权重图更倾向于各向同性的点状响应。具体实现是在loss里加一项lambda * (|dW/dx| |dW/dy|)lambda设0.01。这个技巧让云层边缘的虚警率下降了约30%。针对地面热源MDCR的多尺度上下文其实能缓解因为热源区域通常比小目标大dilation4的分支能捕获这个尺度差异。如果虚警还是多可以在后处理阶段加一个形状过滤计算连通域的圆形度圆形度低于0.3的过滤掉。小目标的圆形度通常接近1热源区域的圆形度较低。传感器坏点用中值滤波预处理就能去掉3x3中值滤波对坏点很有效而且不会模糊小目标。5.3 小目标漏检的典型场景与改进措施漏检通常发生在目标对比度极低或者目标尺寸小于2个像素的场景。对比度低的目标DASI的通道注意力可能把它当成噪声抑制掉了。我的改进措施是在DASI的通道注意力里加一个“保底”机制通道权重的最小值不低于0.3这样即使某个通道被判定为不重要也保留30%的信息。这个改动让低对比度目标的召回率提升了约5个百分点。目标尺寸小于2个像素的情况比较极端这种目标在256x256的输入上只占1个像素经过4次下采样后在bottleneck上就消失了。解决办法是减小下采样倍数把编码器改成3层而不是4层这样bottleneck的分辨率是32x32而不是16x16小目标还能保留。但这样会损失大目标的上下文信息需要权衡。我的建议是如果数据集里小目标居多用3层编码器如果大小目标混合用4层编码器加MDCR。5.4 模块消融实验与效果对比数据我做了完整的消融实验在NUAA-SIRST测试集上的结果如下模型配置mAP0.5虚警率召回率参数量标准U-Net0.7120.1850.6987.7MU-Net DASI0.7680.1320.7517.72MU-Net MDCR0.7810.1210.7638.9MU-Net DASI MDCR0.8350.0870.8218.92M从数据看DASI主要降虚警从0.185降到0.132MDCR主要提召回从0.698到0.763两者结合效果最好mAP从0.712提升到0.835涨了12.3个百分点。参数量只增加了1.22M推理速度在RTX 3080上单张图约15ms满足实时性要求。5.5 常见报错与代码调试速查表报错信息原因解决方法RuntimeError: size mismatchDASI输出通道与解码器输入通道不一致检查DASI的输入通道是否等于编码器对应层输出通道CUDA out of memorybatch size太大或MDCR的dilation分支太多减小batch size到4或减少MDCR分支数到2Loss becomes NaN学习率太大或Focal Loss的gamma太大学习率降到1e-4gamma降到1.0mAP不涨DASI的注意力权重全为0或1检查Sigmoid前的卷积初始化标准差设为0.01推理速度慢MDCR的dilation4分支计算量大把dilation4分支的通道数减半或改用深度可分离卷积注意DASI模块里的通道注意力和空间注意力是相乘关系不是相加。我一开始写成相加mAP只有0.74改成相乘后涨到0.77。相乘能同时考虑通道和空间的重要性相加会稀释权重。6. 模块扩展与后续优化方向DASI和MDCR这套组合还有不少可扩展的空间。我最近在试的一个方向是把DASI的通道注意力换成可变形卷积让网络自己学习采样位置对小目标的形变更鲁棒。初步实验结果mAP能再涨1.5个点但推理速度慢了20%还在权衡。另一个方向是MDCR的多尺度分支用分组卷积替代标准卷积参数量能降一半精度损失不到0.5个点。如果部署在边缘设备上这个改动很值得。还有一个思路是把DASI和MDCR做成即插即用的模块嵌入到其他检测网络里比如YOLO系列或者FCOS。我试过把DASI嵌入YOLOv5的PANet路径mAP涨了3个点说明这个模块的通用性不错。最后分享一个训练技巧如果数据集很小少于500张图可以先用标准U-Net在公开数据集上预训练然后加载预训练权重再训练DASIMDCR版本。这样收敛更快最终mAP也更高。我试过从头训练和预训练微调预训练版本的mAP高了2个点训练轮数少了50个epoch。
返回列表