這篇文章解決了anchor手動生成的問題,
其想法也很簡單,
在最近的論文中,產生了一種類似利用分割圖的思想,比如FSAF,很有意思
這篇文章就是利用如上的思想,
原始框架如上圖所示,
不過是把原來的RPN改爲Guide anchoring,都是產生anchor和原始特徵圖。
Faster-RCNN是根據anchor產生的,該文則是直接預測每個點是否是anchor中心點。如下圖所示:
對於每個點還應預測其anchor 的高度和寬度,
當然與fater rcnn不同的是,rpga 的feature map不再是原圖,而是通過卷積後的圖,即feature adaption,通過一個dcn來獲取更多的特徵信息。
class FeatureAdaption(nn.Module): #DCN操作
def __init__(self,
in_channels,
out_channels,
kernel_size=3,
deformable_groups=4):
super(FeatureAdaption, self).__init__()
offset_channels = kernel_size * kernel_size * 2
self.conv_offset = nn.Conv2d(
2, deformable_groups * offset_channels, 1, bias=False)
self.conv_adaption = DeformConv(
in_channels,
out_channels,
kernel_size=kernel_size,
padding=(kernel_size - 1) // 2,
deformable_groups=deformable_groups)
self.relu = nn.ReLU(inplace=True)
def init_weights(self):
normal_init(self.conv_offset, std=0.1)
normal_init(self.conv_adaption, std=0.01)
def forward(self, x, shape):
offset = self.conv_offset(shape.detach())
x = self.relu(self.conv_adaption(x, offset))
return x
def _init_layers(self):
self.relu = nn.ReLU(inplace=True)
self.conv_loc = nn.Conv2d(self.feat_channels, 1, 1) #預測中心點
self.conv_shape = nn.Conv2d(self.feat_channels, self.num_anchors * 2,
1)#預測寬高
self.feature_adaption = FeatureAdaption(
self.feat_channels,
self.feat_channels,
kernel_size=3,
deformable_groups=self.deformable_groups)
self.conv_cls = MaskedConv2d(self.feat_channels,
self.num_anchors * self.cls_out_channels,
1)
self.conv_reg = MaskedConv2d(self.feat_channels, self.num_anchors * 4,
1)
def forward_single(self, x):
loc_pred = self.conv_loc(x)
shape_pred = self.conv_shape(x)
x = self.feature_adaption(x, shape_pred)
# masked conv is only used during inference for speed-up
if not self.training:
mask = loc_pred.sigmoid()[0] >= self.loc_filter_thr
else:
mask = None
cls_score = self.conv_cls(x, mask)
bbox_pred = self.conv_reg(x, mask)
return cls_score, bbox_pred, shape_pred, loc_pred