仿淘宝网站,网页设计制作源代码,html网页表单设计,怎么查看域名是一级还是二级域名前言
文章标题#xff1a;《SSA-Seg: Semantic and Spatial Adaptive Pixel-level Classiffer for Semantic Segmentation》 助力语义分割涨点!SSA:一种新颖的语义和空间自适应分类器#xff0c;显著提高了基线模型的分割性能#xff0c;比如SegNeXt、OCRNet和UperNet等模型…前言
文章标题《SSA-Seg: Semantic and Spatial Adaptive Pixel-level Classiffer for Semantic Segmentation》 助力语义分割涨点!SSA:一种新颖的语义和空间自适应分类器显著提高了基线模型的分割性能比如SegNeXt、OCRNet和UperNet等模型而计算成本的增加却很小代码已开源! 单位:华为诺亚浙江大学 问题
语义域特征偏差由于测试图像的内容和分布可能与训练数据存在很大差异如背景复杂、对象分布多样测试图像中的像素特征可能与训练时学习的固定语义原型不一致导致分类性能下降。 举一个例子金斧头银斧头你却只认得铁斧头 空间域信息丢失传统方法未充分利用目标对象的空间结构信息导致边界模糊以及对小目标的识别能力不足。
创新 语义和空间自适应分类器SSA-Seg
空间原型自适应SPPA利用位置编码获得空间特征通过粗分割掩码计算空间域中心建模像素特征与空间之间的关系生成空间原型改进像素与空间原型之间的关系提升边界和小目标分割性能。语义原型自适应SEPA使用粗分割掩码计算语义域中心生成自适应的语义原型改进像素与语义原型之间的相似性提升语义类别对齐能力。
源码下载
githubhttps://github.com/xwmaxwma/SSA-Seg
实现 SPPA 对于从骨干和分类头输出的语义特征 S f S_f Sf我们首先通过位置编码生成空间特征 P f P_f Pf。然后我们保留原始的1x1卷积以生成粗级Mask: M c M_c Mc。在 M c M_c Mc的引导下空间域的中心 P c P_c Pc并将其与一个可学习的位置编码 P p P_p Pp融合生成空间原型 SEPA 对于从骨干和分类头输出的语义特征 S f S_f Sf我们保留原始的1x1卷积以生成粗级Mask: M c M_c Mc。在 M c M_c Mc的引导下语义中心 S c S_c Sc并将其与固定的语义原型 S S S和 S c S_c Sc融合以生成语义原型 S p S_p Sp SSA 空间原型 P p P_p Pp语义原型 S p S_p Sp*语义特征 S f S_f Sf空间特征 P f P_f PfOutput
class SEPA_SPPA(nn.Module):def __init__(self, num_classes, channels):super(SEPA_SPPA, self).__init__()self.channels channels # 通道数用于特征图的维度self.num_classes num_classes # 类别数用于位置嵌入和预测# SEPA模块生成特征位置编码self.get_feat_pos nn.Conv2d(self.channels, self.channels, 3, 1, 1, biasTrue, groupsself.channels) # 使用深度可分离卷积生成特征位置编码self.center_pos nn.Embedding(self.num_classes, self.channels) # 可学习的向量类别位置嵌入大小为(类别数, 通道数)self.center_pos_proj nn.Sequential(nn.Linear(self.channels * 2, self.channels // 2, biasFalse), # 降维nn.ReLU(inplaceTrue), # 激活函数nn.Linear(self.channels // 2, self.channels), # 恢复到原通道维度)self.feat_proj nn.Identity() # 特征映射不做额外操作# SPPA模块生成语义原型self.center_content_proj nn.Sequential(nn.Linear(self.channels * 2, self.channels // 2, biasFalse), # 原型降维nn.ReLU(inplaceTrue), # 激活函数nn.Linear(self.channels // 2, self.channels), # 恢复到原通道数)self.center_proj nn.Linear(self.channels, self.channels, biasFalse) # 最终类中心特征的线性映射# 获取中心位置编码def get_center_pos(self, attn, feat_pos):根据注意力图(attn)和特征位置编码(feat_pos)计算中心位置编码center_pos self.center_pos.weight # 获取类中心位置嵌入b, k, h, w attn.size() # 批量大小、类别数、高度、宽度c feat_pos.shape[1] # 特征图通道数# 将注意力和特征图展平用于矩阵计算attn attn.reshape(b, k, -1) # (b, k, h*w)feat_pos feat_pos.reshape(b, c, -1).permute(0, 2, 1) # (b, h*w, c)# 归一化注意力并计算中心位置attn F.softmax(attn, dim-1) # 在像素维度上进行softmaxcenter_pos center_pos.unsqueeze(0).repeat(b, 1, 1) # 扩展为(b, k, c)center_pos torch.cat([center_pos, torch.matmul(attn, feat_pos)], dim-1) # 拼接原始位置编码和计算出的编码 (b, k, 2c)center_pos self.center_pos_proj(center_pos) # 投影到中心位置编码 (b, k, c)return center_pos# 生成像素分类预测def get_pred(self, x, proto):根据特征图和语义原型生成像素分类预测b, c, h, w x.size() # 批量大小、通道数、高度、宽度if len(proto.shape) 3: # 如果原型是三维的 (b, k, c)cls_num proto.size(1) # 类别数x x / (torch.norm(x, 2, 1, True) 1e-12) # 对特征进行L2归一化proto proto / (torch.norm(proto, 2, -1, True) 1e-12) # 对原型进行L2归一化x x.contiguous().view(b, c, h * w) # 展平特征 (b, c, h*w)pred proto x # 点乘生成预测 (b, cls, h*w)elif len(proto.shape) 2: # 如果原型是二维的 (k, c)cls_num proto.size(0) # 类别数x x / (torch.norm(x, 2, 1, True) 1e-12) # 特征归一化proto proto / (torch.norm(proto, 2, 1, True) 1e-12) # 原型归一化x x.contiguous().view(b, c, h * w) # 展平特征proto proto.unsqueeze(0) # 扩展维度为 (1, cls, c)pred proto x # 点乘生成预测 (b, cls, h*w)pred pred.contiguous().view(b, cls_num, h, w) # 恢复为原始大小return pred * 15 # 放大预测值# 前向传播def forward(self, feat, pred, proto):输入特征图、注意力图和原型输出像素分类预测语义特征featpred是预测输出值proto固定的语义原型通过调用主干网络的分割头权重赋值self.conv_seg.weight.squeeze()# SPPA模块feat_pos self.get_feat_pos(feat) # 获取特征位置编码center_pos self.get_center_pos(attnpred, feat_posfeat_pos) # 空间原型# SEPA模块raw_x feat.clone()b, c, h, w raw_x.shape[:]pred pred.view(b, proto.shape[0], h * w)pred F.softmax(pred, 1) # b, n, hwpred_proto (pred raw_x.view(b, c, h * w).permute(0, 2, 1)) / (pred.sum(-1).unsqueeze(-1) 1e-12)pred_proto torch.cat([pred_proto, proto.unsqueeze(0).repeat(pred_proto.shape[0], 1, 1)], -1) # b, n, 2cpred_proto self.center_content_proj(pred_proto) #语义原型# 语义特征featfeat_pos空间特征feat self.feat_proj(featfeat_pos) # 对特征图进行投影# pred_proto语义原型 center_pos空间原型center self.center_proj(pred_proto center_pos) # 结合语义原型和位置编码生成类中心特征pred self.get_pred(feat, center) # 根据类中心特征生成像素分类预测return pred
if __name__ __main__:# 初始化模型num_classes 21 # 类别数channels 256 # 特征图通道数model SEPA_SPPA(num_classesnum_classes, channelschannels) # 实例化模型# 构造测试输入b, c, h, w 4, 256, 64, 64 # 批量大小、通道数、高度、宽度k num_classes # 类别数feat torch.randn(b, c, h, w) # 模拟特征图attn torch.randn(b, k, h, w) # 模拟注意力图proto torch.randn(k, c) # 模拟语义原型# 前向传播测试pred model(feat, attn, proto) # 获取预测结果print(f预测结果形状: {pred.shape}) # 打印预测结果的形状
实验
SSA-Seg在最新通用(顶部)和轻量化(底部)方法上的性能比较。FLOPS(G)的计算基于ADE20K和COCO-Stuff-10K的512x512输入大小以及PASCAL-Context的480x480输入大小。延迟(ms)的计算基于V100 GPU的512x512的输入大小。绿色数字表示相对于基线的增加