含义
将feature map当作一个一个网格,其中输出结果y中,点p这个坐标的值,取决于,其中为权重,为论文中引入的modulation scalar factor。而需要根据三个参数之和作为输入,代表的是原坐标,是相对于坐标 的相对位移。例如,一个的卷积核,则,以上都是标准卷积。本文提出Deformable_Conv就在于加入了新的参数,即需要网络去学习的一个learnable offset。根据论文offset=和mask=都需要进行学习。
原文(The modulation scalar lies in the range [0,1], while is a real number with unconstrained range.)就是 是一个0到1的数,这也很容易理解,它是一个模型响应参数,随便取。
原文(the initial values of and are 0 and 0.5, respectively. )初始化。
操作
class net(nn.Module):
def __init__(self):
super(net, self).__init__()
self.conv = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)
def forward(self, x):
out = self.relu(self.conv(x))
return out
class net(nn.Module):
def __init__(self):
super(dcn, self).__init__()
self.conv = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1) #原卷积
self.conv_offset = nn.Conv2d(3, 18, kernel_size=3, stride=1, padding=1)
init_offset = torch.Tensor(np.zeros([18, 3, 3, 3]))
self.conv_offset.weight = torch.nn.Parameter(init_offset) #初始化为0
self.conv_mask = nn.Conv2d(3, 9, kernel_size=3, stride=1, padding=1)
init_mask = torch.Tensor(np.zeros([9, 3, 3, 3])+np.array([0.5]))
self.conv_mask.weight = torch.nn.Parameter(init_mask) #初始化为0.5
def forward(self, x):
offset = self.conv_offset(x)
mask = torch.sigmoid(self.conv_mask(x)) #保证在0到1之间
out = torchvision.ops.deform_conv2d(input=x, offset=offset,
weight=self.conv.weight,
mask=mask, padding=(1, 1))
return out
应用
需要注意的点有deform_conv2d的stride默认为(1, 1),padding默认为(0, 0),dilation默认为(1, 1)。最后,随便用mnist数据集跑跑(训练集和验证集都加入了随机旋转,网络为四层卷积,三层全连接,加入了dropout,参数都一样,没有仔细调整)可以发现不仅收敛的更快,同时精度更高。deform_conv确实发挥了作用。