1. 无监督单目深度估计
单目深度估计是指,借助于深度神经网络,从单张输入视图中推理场景的稠密深度信息;该技术可以广泛用于自动驾驶、虚拟现实、增强现实等依赖于三维场景感知理解的领域,同时也可以为其他视觉任务提供多模态深度信息,辅助其他任务感知的精确性。
由于不需要标签信息而仅依据单目视频序列 or 双目立体图像对 即可训练的这一巨大优势,无监督单目深度估计框架收到了越来越多的关注,并且当前的性能已经能比肩早期有监督训练方法。
随着monodepth2框架在网络预训练、损失函数设计等方面的创新,无监督训练得到的单目深度估计模型在对场景中几何细节方面的深度感知方面表现出了令人满意的性能和精度。
本文以及自监督单目深度估计的榜单,MDEB,对当前基于单目图像序列的自监督单目深度估计的SOTA/最优方案,MonoViT,进行介绍,并对其开源代码进行复现,开源代码地址:GitHub - zxcqlf/MonoViT: Self-supervised monocular depth estimation with a vision transformerSelf-supervised monocular depth estimation with a vision transformer - GitHub - zxcqlf/MonoViT: Self-supervised monocular depth estimation with a vision transformerhttps://github.com/zxcqlf/MonoViT
2. MonoViT
MonoViT 发表于2022年三维视觉国际会议 3DV, 凭借其出色的精确性和泛化性,一经发表便得到了大量的关注,并有望成为新的基线方法!
和monodepth2相比, MonoViT的创新点主要在于深度估计网络框架的设计,简单来说,采用CNN+Transformer的网络结构替代了之前常用的resnet网络结构,凭借CNN局部细节感知能力与Transformer全局长程特征提取能力的结合,实现在KITTI数据集上的SOTA性能!
其编码器采用了发表于2022 CVPR的MPVIT结构,主要特点是该编码器将CNN和Transformer框架的有机融合,实现了十分有效的图像特征提取能力;解码器部分,主要源自HR-Depth方法中设计的多尺度特征融合解码,促进不同尺度特征的有效融合。
该方案在KITTI 数据集上的精确性表现十分惊讶,首次将Abs_Rel 误差指标打到了0.1以下,同时精确性指标σ1达到了0.9以上。
同时,凭借Transformer+CNN在前景背景关系,尺度变化感知等方向的有效性,其在不同天气状况下的泛化性同样表现惊人,与同期最优方法相比,优势明显!同时,在最新的针对单目深度估计方法的泛化性榜单RoboDepth上,MonoViT的泛化性结果同样是一骑绝尘!
3. 复现
虽然MonoViT开源了相关代码以及模型,但是由于版权限制,其github上的代码并不完整,有些重要地方没有被作者公开,从而使得在复现过程中可能会有碰到复现结果和论文结果性能存在差异性的问题。
3.1 环境配置
在环境配置上,依照官方建议版本设定按照相关依赖,这一般不会有问题,注意一点的是mmcv-full需要多等待一会,有些耐心,安装相对较慢!
conda create -n monovit python=3.8
pip3 install torch==1.9.0+cu111 torchvision==0.10.0+cu111 torchaudio==0.9.0
pip install dominate==2.4.0 Pillow==6.1.0 visdom==0.1.8
pip install tensorboardX==1.4 opencv-python matplotlib scikit-image
pip3 install mmcv-full==1.3.0 mmsegmentation==0.11.0
pip install timm einops IPython
3.2 代码完善
首先下载monodepth2这一最基础代码库,参照官方给的readme.md文件以及trainer,py文件,对trainer.py文件进行修改:
将monodepth2/trainer.py文件中深度模型定义部分(54-62行)修改为:
# self.models["encoder"] = networks.ResnetEncoder(
# self.opt.num_layers, self.opt.weights_init == "pretrained")
self.models["encoder"] = networks.mpvit_small()
self.models["encoder"].num_ch_enc = [64,128,216,288,288]
self.models["encoder"].to(self.device)
#self.parameters_to_train += list(self.models["encoder"].parameters())
self.models["depth"] = networks.DepthDecoder(
self.models["encoder"].num_ch_enc, self.opt.scales)
self.models["depth"].to(self.device)
self.parameters_to_train += list(self.models["depth"].parameters())
将优化器部分(102-104行)修改为:
self.params = [ {
"params":self.parameters_to_train,
"lr": self.opt.learning_rate
#"weight_decay": 0.01
},
{
"params": list(self.models["encoder"].parameters()),
"lr": self.opt.learning_rate/2
#"weight_decay": 0.01
} ]
self.model_optimizer = optim.AdamW(self.params)
self.model_lr_scheduler = optim.lr_scheduler.ExponentialLR(
self.model_optimizer,0.9)
这两步改完,基本就可以了,但是训练后会发现,得到的模型Abs_Rel指标基本都在0.102左右,其实这是因为pytorch版本不同导致function中部分参数发生变化导致的,这一点似乎被作者忽略了,所以使得复现的结果总是不令人满意!所以还需要进一步将一个函数进行修改:
F.grid_sample(inputs[("color", frame_id, source_scale)],
outputs[("sample", frame_id, scale)],
padding_mode="border", align_corners=True)
至此,就可以很轻松的复现出原文的结果了!!!