赞
踩
视觉语言导航任务(Vision-and-Language Navigation)依托于 Matterport3D 仿真器,通过 introduction(语言)和环境交互(Vision and Action)完成指定的导航任务。本文主要记录博主如何从零开始复现 Recurrent VLN-BERT 模型。
本文如需转载,请联系本人,并在转载文章中说明出处。
本文内容包括:
本文的实现基础:
在 Matterport3D官网,“Dataset Download” 一栏点击 “Terms of Use”,签署 agreement 的 PDF 后发送到邮箱 matterport3d@googlegroups.com,大约在美国时间次日上午会收到回邮,提供相应的数据集下载 python 文件。
由于下载数据集的 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 个场景,如果网断了或者卡住了可以手动点击终端中的链接进行网页下载。
这里提供一个简单的脚本文件用以解压数据集,所有文件需要解压到各自对应的场景号文件夹下,“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
这一步是为了安装 Matterport3D 仿真器时,仿真器可以识别数据集路径,因此必须使用绝对路径。
export MATTERPORT_DATA_DIR=<PATH>
# 参考:
# export MATTERPORT_DATA_DIR=/Dataset/Matterport3D/v1/scans
使用如下 git 命令,或直接在 Github 中下载压缩包并解压:
# Make sure to clone with --recursive
git clone --recursive https://github.com/peteanderson80/Matterport3DSimulator.git
cd Matterport3DSimulator
这里以 Ubuntu 20.04 系统为例,其他系统的安装方法相似,可参考官网的安装教程。
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg
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
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
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world
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 会报错。
安装 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
首先搭载 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 ../
为了加快数据加载速度并减少内存使用,可以将原有数据集 mattport_skybox_images
中每个观测点的6张单个图像组合到一起 。仍在 docker 容器内,运行以下脚本(需等待半天方可完成):
./scripts/downsize_skybox.py
如果期望同时输出 RGB 和深度信息,则继续运行以下脚本(需等待2天,建议周末运行该脚本):
./scripts/depth_to_skybox.py
应当注意,多视角融合得到的深度图仍然存在无深度值的空洞,且 RGB 和深度图并非完全 align。
在 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
# 获取超级用户权限
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
# 进行后续操作
查看 Recurrent VLN-BERT 的环境依赖:
而 mattersim docker 中的环境为:
这是因为 Matterport3D Simulator 是2017年的工作,而 VLN-BERT 是2021年的工作,这期间存在软件的版本迭代。我们需要更新 mattersim docker 中的 pytorch 和 CUDA 版本,同时安装 pytorch-transformers 库。具体操作如下(注意!以下操作需要在 mattersim docker 内进行
):
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
取消:
同意条款:
取消安装显卡驱动:
安装成功:
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 环境:
# 安装 pytorch-transformers 和 tensorboardX
pip3 install pytorch-transformers
pip3 install tensorboardX
下载 Recurrent VLN-BERT repo 到 Matterport3DSimulator 文件夹下,然后逐一下载下述文件,并放置到 repo 对应的文件夹下。仍然在 Matterport3DSimulator 文件夹下进行下列操作:
connectivity
:cp -r connectivity Recurrent-VLN-BERT-main
data
# 使用 wget 下载相应的 json 文件,也可以到 .sh 文件内根据相应的链接手动下载
sh tasks/R2R/data/download.sh
cp -r tasks/R2R/data Recurrent-VLN-BERT-main/data
data/prevalent
img_features
Oscar/pretrained_models/base-no-labels
(参考 r2r_src/vlnbert/vlnbert_init.py
中 get_tokenizer
的定义进行修改)# 仅需要下载预训练模型`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
Prevalent/pretrained_model
snap
run/test_agent.bash
文件中的 vlnbert
来选择 oscar 或 prevalent BERT模型权重,修改 load
以选择 snap
中作者提供的不同的预训练权重。CUDA_VISIBLE_DEVICE=1
,比如单卡应设置为0。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
目录下,训练过程如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。