小样本目标检测(FSOD)之FADI代码解析

相对于最原始的faster rcnn做了如下7处改动
1.使用wordnet计算与新类最相似的类别
2.在roi_head.bbox_head上新增加了CosineSimBBoxHead类(来自TFA的cos头)
3.冻结某些层unfreeze_layers
4.新增加FewShotVOCDataset和FewShotVOCTestDataset的dataset类
-----------------------discrimination---------------
5.修改了rpn_head为FADIRPNHead,适应不同的框架
6.在roi_head.bbox_head中新增了FADIBBoxHead
7.新增加了SetSpecializedMarginLoss损失

改动二:CosineSimBBoxHead类

import torch
import torch.nn as nn
from mmdet.models.builder import HEADS
from mmdet.models.roi_heads.bbox_heads import ConvFCBBoxHead


@HEADS.register_module()
class CosineSimBBoxHead(ConvFCBBoxHead):
    def __init__(self,
                 fc_out_channels=1024,
                 scale=20.,
                 with_margin=False,
                 *args,
                 **kwargs):
        super(CosineSimBBoxHead,
              self).__init__(num_shared_convs=0,
                             num_shared_fcs=2,
                             num_cls_convs=0,
                             num_cls_fcs=0,
                             num_reg_convs=0,
                             num_reg_fcs=0,
                             fc_out_channels=fc_out_channels,
                             *args,
                             **kwargs)
        self.fc_cls = nn.Linear(self.cls_last_dim,
                                self.num_classes + 1,
                                bias=False)
        self.scale = scale
        self.with_margin = with_margin

    def forward(self, x, return_fc_feat=False):
        x = x.flatten(1)
        for fc in self.shared_fcs:
            x = self.relu(fc(x))

        # normalize the input x along the `input_size` dimension
        x_norm = torch.norm(x, p=2, dim=1).unsqueeze(1).expand_as(x)
        x_normalized = x.div(x_norm + 1e-5)

        # normalize weight
        temp_norm = torch.norm(self.fc_cls.weight.data, p=2,
                               dim=1).unsqueeze(1).expand_as(
                                   self.fc_cls.weight.data)
        self.fc_cls.weight.data = self.fc_cls.weight.data.div(temp_norm + 1e-5)
        cos_dist = self.fc_cls(x_normalized)
        scores = self.scale * cos_dist
        bbox_preds = self.fc_reg(x)
        if return_fc_feat:
            return scores, bbox_preds, x_normalized
        return scores, bbox_preds

    def forward_cls(self, x):
        x = x.flatten(1)

        for fc in self.shared_fcs:
            x = self.relu(fc(x))

        # normalize the input x along the `input_size` dimension
        x_norm = torch.norm(x, p=2, dim=1).unsqueeze(1).expand_as(x)
        x_normalized = x.div(x_norm + 1e-5)

        # normalize weight
        temp_norm = torch.norm(self.fc_cls.weight.data, p=2,
                               dim=1).unsqueeze(1).expand_as(
                                   self.fc_cls.weight.data)
        self.fc_cls.weight.data = self.fc_cls.weight.data.div(temp_norm + 1e-5)
        cos_dist = self.fc_cls(x_normalized)
        scores = self.scale * cos_dist
        return scores

    def forward_bbox(self, x):
        x = x.flatten(1)

        for fc in self.shared_fcs:
            x = self.relu(fc(x))

        bbox_preds = self.fc_reg(x)
        return bbox_preds

    def init_weights(self):
        # conv layers are already initialized by ConvModule
        if self.with_cls:
            nn.init.normal_(self.fc_cls.weight, 0, 0.01)
        if self.with_reg:
            nn.init.normal_(self.fc_reg.weight, 0, 0.001)
            nn.init.constant_(self.fc_reg.bias, 0)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值