从零开始复现 Recurrent VLN-BERT

从零开始复现 Recurrent VLN-BERT

视觉语言导航任务(Vision-and-Language Navigation)依托于 Matterport3D 仿真器,通过 introduction(语言)和环境交互(Vision and Action)完成指定的导航任务。本文主要记录博主如何从零开始复现 Recurrent VLN-BERT 模型。

本文如需转载,请联系本人,并在转载文章中说明出处。

目录与基础

本文内容包括:

  1. 下载 Matterport3D 数据集
  2. 构建 Matterport3D 仿真器
  3. 复现 Recurrent VLN-BERT

本文的实现基础:

  1. 基于 Ubuntu 20.04 LTS 环境
  2. 主机已安装英伟达(Nvidia)显卡驱动
  3. 了解 conda 的基本操作
  4. 了解 docker 的基本操作

一、数据准备

1.1 签署声明,获取数据集下载资格

Matterport3D官网,“Dataset Download” 一栏点击 “Terms of Use”,签署 agreement 的 PDF 后发送到邮箱 matterport3d@googlegroups.com,大约在美国时间次日上午会收到回邮,提供相应的数据集下载 python 文件

签署PDF

在这里插入图片描述

1.2 数据集下载

由于下载数据集的 download_mp.py 是基于 python2 编译的,为了不修改源码,建议使用 conda 创建一个全新的 python2 环境,并在 conda 环境内下载数据集:

conda create -n python2 python=2
conda activate python2
python download_mp.py -o [directory] --type matterport_skybox_images undistorted_depth_images undistorted_camera_parameters

说明:完整的 Matterport3D 数据集有1.3T大小,如果仅仿真离散环境,则只需要下载 RGB 图像 matterport_skybox_images(大小约23G);如果后续希望进行连续环境下的 VLN 的相关研究,或希望在可视化过程中观察深度信息,则需要下载深度图 undistorted_depth_images以及相机位姿 undistorted_camera_parameters(总共166G大小)。[directory]修改为数据存放路径。

代码运行后会默认下载 90 个场景,如果网断了或者卡住了可以手动点击终端中的链接进行网页下载。

1.3 数据集解压

这里提供一个简单的脚本文件用以解压数据集,所有文件需要解压到各自对应的场景号文件夹下,“17DRP5sb8fy” 代表场景号,一共 90 个场景。

#!/bin/bash
# author: Yongjian Zhang
# time: 2023.03.31
# 数据集下载压缩包存放路径
zip_folder="/media/zhangyj85/Dataset/Matterport3D/zipfiles/v1/scans"
# 解压数据集存放路径
data_rootpath="/media/zhangyj85/Dataset/Matterport3D/dataset/v1/scans"
if [ ! -d $data_rootpath ];then
    # 如果不存在数据目录下, 则新建
    mkdir -p $data_rootpath
fi
for zipfile in ${zip_folder}/*/*.zip; do
	# 输出当前解压文件路径
	echo "Unzip file: $zipfile"
	# 指定解压路径
	unzip -d $data_rootpath $zipfile
done
exit 0

1.4 为数据集添加临时环境变量

这一步是为了安装 Matterport3D 仿真器时,仿真器可以识别数据集路径,因此必须使用绝对路径。

export MATTERPORT_DATA_DIR=<PATH>
# 参考:
# export MATTERPORT_DATA_DIR=/Dataset/Matterport3D/v1/scans

1.5 下载 Matterport3D 仿真器仓库代码

使用如下 git 命令,或直接在 Github 中下载压缩包并解压:

# Make sure to clone with --recursive
git clone --recursive https://github.com/peteanderson80/Matterport3DSimulator.git
cd Matterport3DSimulator

二、环境准备

2.1 安装 Docker

这里以 Ubuntu 20.04 系统为例,其他系统的安装方法相似,可参考官网的安装教程

  1. 更新 apt,并安装需要的包:
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg
  1. 添加 docker 官方密钥:
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
  1. 设置仓库:
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  1. 再次更新 apt:
sudo apt-get update
  1. 安装 docker:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  1. 测试安装是否成功(输出 Hello World! 即为成功,网络问题可通过下一步更换镜像源解决):
sudo docker run hello-world

在这里插入图片描述

  1. 配置 docker 镜像源,添加 daemon.json 文件:
sudo mkdir -p /etc/docker   # 创建 docker 文件夹
sudo gedit /etc/docker/daemon.json  # 创建并编辑 daemon.json 文件

添加如下内容配置 docker 中科大镜像源

{
    "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn" ]
}

如果不需要配置镜像源,也需要创建 daemon.json 文件,并写入一对花括号,否则后续安装 nvidia-docker 会报错。

2.2 安装 nvidia-docker 2.0

安装 nvidia-docker 2.0 需要英伟达显卡驱动版本大于等于 396.37。需要先安装 nvidia-container-toolkit,然后安装 nvidia-docker 2.0。

# 设置仓库密钥
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
      && curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
      && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \
            sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
            sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# 更新 apt,下载 nvidia-container-toolkit
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

# 配置 docker 的 daemon.json 文件,启动 docker 时允许调用 nvidia cuda toolkit
sudo nvidia-ctk runtime configure --runtime=docker

# 重启 docker
sudo systemctl restart docker

# 测试 nvidia-container-toolkit 安装正常(需要网速正常)
sudo docker run --rm --runtime=nvidia --gpus all nvidia/cuda:11.6.2-base-ubuntu20.04 nvidia-smi

输出结果与 nvidia-smi指令的输出一致,则表示 nvidia-container-toolkit 安装成功。
在这里插入图片描述

然后,安装 nvidia-docker 2.0,这一步是因为安装 Matterport3D 仿真器过程中调用了 nvidia-docker 指令。

sudo apt-get install nvidia-docker2
sudo pkill -SIGHUP dockerd

2.3 安装 Matterport3D 仿真器

首先搭载 docker 的 image,该操作需要在 /Matterport3DSimulator路径下进行操作:

# 创建名为 mattersim:9.2-devel-ubuntu18.04 的环境,最后一个"."会调用当前路径下的 Dockerfile 文件。
docker build -t mattersim:9.2-devel-ubuntu18.04 .

Dockerfile 中默认使用官方源安装包,如果因为网速问题无法正常安装,修改 Dockerfile 中的安装代码,添加镜像源,例如代码第22行可修改为:

RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python==4.1.0.25 torch==1.1.0 torch

在这里插入图片描述

搭建 Matterport3D 仿真器一共有 13 个步骤,程序会自主完成搭建工作,最终搭建速度取决于网速和CPU,搭建成功则有下图结果:

在这里插入图片描述

使用 docker images,则能看到目前已安装的3个 docker 镜像,分别是 Matterport3D 仿真器的环境(命名为 mattersim),英伟达显卡 hellow world 的环境(命名为nvidia/cuda),docker 的 hellow world 环境(命名为 hello-world)。

在这里插入图片描述

接下来,使用 nvidia-docker运行该容器:

# 运行 mattersim 容器
# 并将数据集路径挂载到指定位置,使用该数据
nvidia-docker run -it --mount type=bind,source=$MATTERPORT_DATA_DIR,target=/root/mount/Matterport3DSimulator/data/v1/scans --volume `pwd`:/root/mount/Matterport3DSimulator mattersim:9.2-devel-ubuntu18.04

最后,在 mattersim 容器内,对 Matterport3D 仿真器进行编译:

cd /root/mount/Matterport3DSimulator
mkdir build && cd build
cmake -DEGL_RENDERING=ON ..
make
cd ../

在这里插入图片描述

2.4 数据预处理

为了加快数据加载速度并减少内存使用,可以将原有数据集 mattport_skybox_images中每个观测点的6张单个图像组合到一起 。仍在 docker 容器内,运行以下脚本(需等待半天方可完成):

./scripts/downsize_skybox.py

如果期望同时输出 RGB 和深度信息,则继续运行以下脚本(需等待2天,建议周末运行该脚本):

./scripts/depth_to_skybox.py

应当注意,多视角融合得到的深度图仍然存在无深度值的空洞,且 RGB 和深度图并非完全 align。

2.5 测试 Matterport3D 仿真环境

在 mattersim 容器内运行:

./build/tests ~Timing

在这里插入图片描述

输出结果 All tests passed则表示仿真器搭建成功,此时在 sim_imgs内将包含部分测试过程由仿真器渲染的RGB图像。如果想要测试渲染帧率可运行如下脚本,但需要运行内存大于50GB:

./build/tests Timing

为了进一步测试仿真器,可选择跑一跑官方提供的 Demo 代码。首先退出当前容器:

exit

为了运行交互式 Demo,在启动容器时选择共享主机的 X server 和图形化界面(如果提示权限不足,那就切换 root 用户再执行即可):

# 获取超级用户权限
su root
# 使所有用户均可访问 Xserver
xhost +
# 启动容器及图像化界面
nvidia-docker run -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --mount type=bind,source=$MATTERPORT_DATA_DIR,target=/root/mount/Matterport3DSimulator/data/v1/scans,readonly --volume `pwd`:/root/mount/Matterport3DSimulator mattersim:9.2-devel-ubuntu18.04
# 跳转到仿真器环境
cd /root/mount/Matterport3DSimulator

使用 python3运行 Demo:

python3 src/driver/driver.py

在这里插入图片描述

  • 如果需要显示深度,需要首先完成数据预处理阶段的深度图渲染,并设置 src/driver/driver.py中第20行代码 sim.setDepthEnabled(True)

  • 交互式可视化阶段,按q表示退出,awds表示方向,数字1-9表示选择视角。

  • 如果显示框没有正常渲染图像,则根据错误提示进行 Debug 即可,例如我遇到的问题是:

在这里插入图片描述

在这里插入图片描述

根据报错提示 X Error: BadShmSeg (invalid shared segment parameter)得知是 X server 没有正常工作,使用如下指令解决:

# 添加环境临时变量
export QT_GRAPHICSSYSTEM=native

2.6 其他

2.6.1 重新进入容器
# 获取超级用户权限
su root
# 添加数据集路径的临时环境变量
export MATTERPORT_DATA_DIR=<PATH>
# 使用 nvidia-docker 进入容器
nvidia-docker run -it --mount type=bind,source=$MATTERPORT_DATA_DIR,target=/root/mount/Matterport3DSimulator/data/v1/scans --volume `pwd`:/root/mount/Matterport3DSimulator mattersim:9.2-devel-ubuntu18.04
# 跳转到 Matterport3D Simulator 路径
cd /root/mount/Matterport3DSimulator
# 进行后续操作

3. 复现 Recurrent VLN-BERT

3.1 环境配置

查看 Recurrent VLN-BERT 的环境依赖:

  • python=3.6
  • pytorch==1.6.0
  • cudatoolkit=10.2
  • cudnn==7.6.5

而 mattersim docker 中的环境为:

  • python=2.7, python3=3.6
  • pytorch==1.1.0
  • CUDA=9.0

在这里插入图片描述

这是因为 Matterport3D Simulator 是2017年的工作,而 VLN-BERT 是2021年的工作,这期间存在软件的版本迭代。我们需要更新 mattersim docker 中的 pytorch 和 CUDA 版本,同时安装 pytorch-transformers 库。具体操作如下(注意!以下操作需要在 mattersim docker 内进行):

  1. 重新进入 mattersim docker (参考本文 2.6.1)
  2. 升级 CUDA:到 CUDA toolkit 11.3 download 官网下载 CUDA 安装包,这里选择 CUDA=11.3 版本(只要 CUDA>=10.2 版本,且 NVIDIA 显卡驱动支持所选安装版本的 CUDA 即可),选择 .run 文件进行安装:
wget https://developer.download.nvidia.com/compute/cuda/11.3.0/local_installers/cuda_11.3.0_465.19.01_linux.run
sh cuda_11.3.0_465.19.01_linux.run

应注意,通过 nvidia-docker 启动的 docker 使用了本机的显卡驱动环境,因此在安装 CUDA 时不需要重复安装显卡驱动,故在安装过程中将 Driver 取消:

  • 同意条款:
    在这里插入图片描述

  • 取消安装显卡驱动:
    在这里插入图片描述

  • 安装成功:
    在这里插入图片描述

  1. 升级 pytorch:到官网下载与 CUDA 对应的 pytorch 版本,使用 pip3 进行安装:
# 更新 docker 中的 pip3,保证之后可以顺利找到新版 pytorch
pip3 install --upgrade pip
# 使用 pip3 安装 pytorch
pip3 install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113 -i https://pypi.tuna.tsinghua.edu.cn/simple
  • 更新 pytorch:
    在这里插入图片描述

  • 更新后的 docker 环境:
    在这里插入图片描述

  1. 安装其他依赖:
# 安装 pytorch-transformers 和 tensorboardX
pip3 install pytorch-transformers
pip3 install tensorboardX

3.2 数据准备

下载 Recurrent VLN-BERT repo 到 Matterport3DSimulator 文件夹下,然后逐一下载下述文件,并放置到 repo 对应的文件夹下。仍然在 Matterport3DSimulator 文件夹下进行下列操作:

cp -r connectivity Recurrent-VLN-BERT-main
# 使用 wget 下载相应的 json 文件,也可以到 .sh 文件内根据相应的链接手动下载
sh tasks/R2R/data/download.sh
cp -r tasks/R2R/data Recurrent-VLN-BERT-main/data
# 仅需要下载预训练模型`base-no-labels`
# 添加环境临时变量
export MODEL_NAME=base-no-labels
# 下载所需数据
wget https://biglmdiag.blob.core.windows.net/oscar/pretrained_models/$MODEL_NAME.zip
# 解压到指定文件夹下
unzip $MODEL_NAME.zip -d Recurrent-VLN-BERT-main/Oscar/pretrained_models/base-no-labels

3.3 复现测试结果

  • 通过修改 run/test_agent.bash 文件中的 vlnbert 来选择 oscar 或 prevalent BERT模型权重,修改 load 以选择 snap 中作者提供的不同的预训练权重。
  • 由于 docker 中包含 python2 和 python3,默认 python=python2,因此需要修改 test_agent.bash 文件中的指令,将最后一行 python 改为 python3。
  • 按需修改 CUDA_VISIBLE_DEVICE=1,比如单卡应设置为0。
  • 由于我们使用的是 Matterport3D Simulator V1.0,而原代码使用 V0.1,因此需要修改 r2r_src 下的部分代码:
# vlnbert_init.py 修改导入函数
# from transformer.pytorch_transformer.modeling_bert import ... ->
from pytorch_transformer.modeling_bert import ...

# env.py 修改仿真器初始化方法
# sim.init() ->
sim.initialize()

# utils.py & env.py 修改所有 newEpisode 的传入参数, 变更为 list, 例如
# env.py: self.sims[i].newEpisode(scanId, viewpointId, heading, 0) ->
self.sims[i].newEpisode([scanId], [viewpointId], [heading], [0])


# env.py & utils.py & agent.py, 修改 sim.getState() ->
state = sim.getState()[0]
# 此外还要修改 agent.py 的 self.env_actions 参数,添加 list
env_actions = {
    'left': ([0], [-1], [0]),
    ...
}

# utils.py, env.py, agent.py: sim.makeAction(index, heading, elevation) 的每个输入变量改为 list:
sim.makeAction([index], [heading], [elevation])

# BERT 初始化方法改变, vlnbert_PREVALENT.py & vlnbert_OSCAR.py:
# self.apply(self.init_weights) ->
self.init_weights()

这里提供修改后的 Recurrent-VLN-BERT,以供参考和使用。对修改后的代码,运行测试样例:

# 运行测试样例
cd Recurrent-VLN-BERT-main
bash run/test_agent.bash

复现结果如下图所示,导航成功率等指标与论文描述一致:
在这里插入图片描述

从零开始训练网络,使用以下命令:

# 训练结果默认存储在 snap/ . 目录下,注意修改 tran_agent.bash 文件
bash run/train_agent.bash

训练 log 存放在 logs 目录下,训练 state_dict 存放在 snap 目录下,训练过程如下:
在这里插入图片描述

4 主要参考链接

  1. Github: Matterport3DSimulator
  2. Github: Recurrent-VLN-BERT
  3. docker documentation
  4. nvidia-container-toolkit documentation
  5. Matterport3D 搭建与 VLNBERT 实现
  6. Github: Recurrent-VLN-BERT based on MP3DS V1.0
  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值