需求:
- 完整的SLAM框架
- 精度起码是主流水平上
- 深度学习要能实时
分析:
目前特征点法SLAM开源框架就是ORBSLAM了。基本上没得挑,PTAM太老更麻烦,自己写精度上比不过主流水平。
问题:
ORB-SLAM是二值化的特征点,而训练出来的特征点一般为浮点值,这个是主要矛盾。
要么将ORB前端改了,由于在ORBSLAM系统中其实只有第一次初始化用到了原始描述点,其后就是用的BoW找到的对应,这个改成浮点描述子是可以完成的,而且速度上损失不会太多。
要么将深度网络二值化。
待解决:
- 有一个神经网络模型(成功)
- 神经网络输出二值化(暂时搁置)
- 修改网络以适应实时性(成功)
- pytorch模型加载到c++中(成功)
- 在c++中写NMS等函数来处理网络输出
- 训练词袋模型对应的图片集
- 训练对应网络的BoW
- 修改ORBSLAM框架
- 部署到实际硬件
神经网络二值化
目前研究二值化论文挺多的,我研究下这个问题的需要其实只用二值化激活层就可以,权重不需要二值化。
二值化本身都会有精度上损失(具体任务不同),而如果只是有限的得到二值输出其实损失应该不会很高。
所以主要关注点是二值化网络最后一层
所谓二值化激活层就是在那一层上对forward和backward使用不同的策略
forward时候使用sign()
backward时候保留梯度,其实就是hardTanh()
在此基础上又有很多的变形
class ActivationBinarizerFunction(Function):
@staticmethod
def forward(ctx, input):
ctx.input = input
return input.sign()
@staticmethod
def backward(ctx, grad_output):
x = ctx.input.clamp(-1, 1)
return (2 - 2 * x * x.sign()) * grad_output
class ActivationBinarizer(nn.Module):
def forward(self, input):
return ActivationBinarizerFunction.apply(input)
class HardNetNeiMask(nn.Module):
def __init__(self, MARGIN, C):
super(HardNetNeiMask, self).__init__()
self.MARGIN = MARGIN
self.C = C
self.features = nn.Sequential(
nn.Conv2d(1, 32, kernel_size=3, padding=1, bias=False),
nn.ELU(),
nn.Conv2d(32, 32, kernel_size=3, padding=1, bias=False),
nn.ELU(),
nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1, bias=False),
nn.ELU(),
nn.Conv2d(64, 64, kernel_size=3, padding=1, bias=False),
nn.ELU(),
nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1, bias=False),
nn.ELU(),
nn.Conv2d(128, 128, kernel_size=3,padding=1, bias=False),
nn.ELU(),
nn.Conv2d(128, 256, kernel_size=3, stride=2, padding=1, bias=False),
nn.ELU(),
nn.Conv2d(256, 256, kernel_size=4, bias=False),
)
def forward(self, input):
x_features = self.features(self.input_norm(input))
x = x_features.view(x_features.size(0), -1)
x = x / torch.norm(x, p=2, dim=-1, keepdim=True)
x = ActivationBinarizer()(x)
# pdb.set_trace()
return x
loss 函数就是hanming距离
__C.LOSS.SCORE = 100000
__C.LOSS.PAIR = 0.001
# detector learning rate
__C.TRAIN.DET_LR = 0.1
# descriptor learning rate
__C.TRAIN.DES_LR = 0.01
训练十几个epoch的结果

其实网络还是能学到对应的,但是就是这个上限有点低啊。
在提取特征点描述patch时候,直接把边界值复制扩展比较好,因为这里面涉及到假设就是边界之外同边界大概率是相似的。
网友评论