代码部署步骤
1 虚拟环境
1.1 创建虚拟环境
conda create -n patchnetvlad python=3.9 numpy pytorch-gpu torchvision natsort tqdm opencv pillow scikit-learn faiss matplotlib-base -c conda-forge
NOTE:
①这里环境创建完后还缺少h5py
、tensorboardX
、pandas
使用pip3 install xxx
安装即可;
②按照以上指令下载下来的Numpy版本为1.25.1,而代码需要的numpy版本是1.21,否则会出现版本不兼容问题,因此需要建立完环境后再执行下述指令:
pip uninstall numpy
pip3 install numpy=1.21
(小tips)
在实际操作中,其实这种创建虚拟环境的办法是不规范的,因为这里相当于在用conda安装包,这样会很慢。
规范的方法有两种:
①先指定python版本创建虚拟环境,再使用pip3依次安装相应的依赖包
conda create -n patchnetvlad python=3.9
pip install xxx
②先指定python版本创建虚拟环境,再建立requirments.txt指定所需要的依赖包
conda create -n patchnetvlad python=3.9
requirements.txt
内写:
numpy=1.21
pytorch-gpu
torchvision
natsort tqdm
opencv
pillow
scikit-learn
faiss
matplotlib-base
1.2 激活虚拟环境
conda activate patchnetvlad
注意每次想要运行此程序都要保证是在此虚拟环境下。
2 下载预训练模型和配置文件
2.1 法一:自动下载
第一次执行pretrained_models
特征提取时,预训练的模型将自动下载(就是这步可以忽略)
2.2 法二:手动下载(意思就是非想自己下也可以…)
# 步骤① You can use the download script which automatically downloads the models:
python ./download_models.py
# 步骤② Manual download:
cd pretrained_models
wget -O mapillary_WPCA128.pth.tar https://cloudstor.aarnet.edu.au/plus/s/vvr0jizjti0z2LR/download
wget -O mapillary_WPCA512.pth.tar https://cloudstor.aarnet.edu.au/plus/s/DFxbGgFwh1y1wAz/download
wget -O mapillary_WPCA4096.pth.tar https://cloudstor.aarnet.edu.au/plus/s/ZgW7DMEpeS47ELI/download
wget -O pittsburgh_WPCA128.pth.tar https://cloudstor.aarnet.edu.au/plus/s/2ORvaCckitjz4Sd/download
wget -O pittsburgh_WPCA512.pth.tar https://cloudstor.aarnet.edu.au/plus/s/WKl45MoboSyB4SH/download
wget -O pittsburgh_WPCA4096.pth.tar https://cloudstor.aarnet.edu.au/plus/s/1aoTGbFjsekeKlB/download
快捷/模块化方式使用 Patch-NetVLAD
如果您想使用快捷方式patchnetvlad-match-two、patchnetvlad-feature-match和patchnetvlad-feature-extract,您还需要运行:
pip3 install --no-deps -e .
3 准备数据集
3.1 用于特征提取和匹配的数据集
1、创建存放数据集的文件夹
在Patch_NetVLAD/patchnetvlad
下创建名为dataset
的文件夹。
该程序共提到了使用Pittsburgh250k
、tokyo247
和nordland
数据集
因此在Patch_NetVLAD/patchnetvlad/dataset
文件下再分别创建存放不同种类数据集的文件夹,文件路径分别为Patch_NetVLAD/patchnetvlad/dataset/Pittsburgh250k
、Patch_NetVLAD/patchnetvlad/dataset/tokyo247
、Patch_NetVLAD/patchnetvlad/dataset/nordland
2、下载数据集
Pittsburgh250k:下载000.tar–007.tar、queries_reals,下载完成后提取到Pittsburgh250k
文件夹内。
注意此网站需要使用美国的网络。
3.2 用于模型训练的数据集
1、创建存放数据集的文件夹
在Patch_NetVLAD/patchnetvlad/dataset
文件下创建用于存放Mapillary数据集的文件夹,文件路径为Patch_NetVLAD/patchnetvlad/dataset/Mapillary
2、下载数据集
在Mapillary Street-level Sequences中下载数据集。(下载需要注册并登录账号,需要选择美国的VPN,且下载过程需要一定的时间。)
网页中各目录存放内容为
- msls_images_vol_X.zip: 图像,分为 6 部分以便于下载.
- msls_metadata.zip: 单独用于存放metadata的压缩包.
- msls_patch_vX.Y.zip: 更新数据集中的补丁以进行升级.
选择下载下列文件
- msls_images_vol_1.zip
- msls_images_vol_2.zip
- msls_metadata.zip
- msls_patch_v1.1.zip
下载并解压完成后按照下列格式将msls_images_vol_X
与msls_metadata
合并
- train_val
city
- query / database
- images/
key
.jpg - seq_info.csv
- subtask_index.csv
- raw.csv
- postprocessed.csv
- images/
- query / database
- test
city
- query / database
- images/
key
.jpg - seq_info.csv
- subtask_index.csv
- images/
- query / database
4 运行程序
4.1 特征提取Feature extraction
确保此时终端所在路径为Patch_NetVLAD文件夹下,环境为patchnetvlad虚拟环境下,按照下面提示修改并运行下述指令
python feature_extract.py \
--config_path patchnetvlad/configs/performance.ini \
--dataset_file_path=pitts30k_imageNames_index.txt \
--dataset_root_dir=/path/to/your/pitts/dataset \
--output_features_dir patchnetvlad/output_features/pitts30k_index
其中
①performance.ini
可替换为speed.ini
或storage.ini
(所在文件路径为 /Patch_NetVLAD/patchnetvlad/configs )
- `performance.ini` `speed.ini` `storage.ini` 脚本为程序运行的配置文件,但是所凸出的功能不同,分别为提高性能/速度/存储空间;
②改写dataset_file_path
。所给的示例是使用的pitts30k_imageNames_index.txt
,可以替换为tokyo247
或nordland
数据集(所在文件路径为 /Patch_NetVLAD/patchnetvlad/dataset_imagenames )
③改写dataset_root_dir
。
因为dataset_file_path
中pitts30k_imageNames_index.txt
的内容是存放数据集图片的地址(./Pittsburgh250k/000/000829_pitch1_yaw1.jpg
),是相对的,所以要使用dataset_root_dir指明数据集所在的绝对地址来表示./
(这里是patchnetvlad/dataset
)
修改之后的指令可参考下述语句
参考图片:
python feature_extract.py \
--config_path patchnetvlad/configs/storage.ini \
--dataset_file_path=pitts30k_imageNames_index.txt \
--dataset_root_dir=patchnetvlad/dataset \
--output_features_dir patchnetvlad/output_features/pitts30k_index
查询图片:
python feature_extract.py \
--config_path patchnetvlad/configs/storage.ini \
--dataset_file_path=pitts30k_imageNames_query.txt \
--dataset_root_dir=patchnetvlad/dataset \
--output_features_dir patchnetvlad/output_features/pitts30k_query
④ 使用_query
替换所有_index
,重复查询图像(包括ataset_file_path和output_features_dir)
⑤ 将.ini文件中的[feture extact]下的batchsize修改为2,否则--output_features_dir
输出的文件特别大,可能会使进程无法进行下去
输出结果
查询/参考数据集的特征文件
使用自己的数据集
(1)照片数据集:需要按照pitts30k_imageNames_index.txt、pitts30k_imageNames_query.txt的格式制作数据集的地址文件
(2)实时视频数据集:可能需要配合着realsense使用,实时拍摄视频并提取照片
4.2 特征匹配Feature matching
确保此时终端所在路径为Patch_NetVLAD文件夹下,环境为patchnetvlad虚拟环境下,按照下面提示修改并运行下述指令
python feature_match.py \
--config_path patchnetvlad/configs/performance.ini \
--dataset_root_dir=/path/to/your/pitts/dataset \
--query_file_path=pitts30k_imageNames_query.txt \
--index_file_path=pitts30k_imageNames_index.txt \
--query_input_features_dir patchnetvlad/output_features/pitts30k_query \
--index_input_features_dir patchnetvlad/output_features/pitts30k_index \
--ground_truth_path patchnetvlad/dataset_gt_files/pitts30k_test.npz \
--result_save_folder patchnetvlad/results/pitts30k
其中
①dataset_root_dir
与特征提取部分一样,这里是patchnetvlad/dataset
Note:
①提供ground_truth_path
是可选的
②result_save_folder
指定的输出地址内会产生三个输出文件:
recalls.txt
:纯文本输出 仅当指明了ground_truth_path
时)NetVLAD_predictions.txt
:包含使用Kapture format格式 "vanilla "NetVLAD获得的每个查询图像的前100张参考图像PatchNetVLAD_predictions.txt
:通过Patch-NetVLAD重新排序的前100张参考图片,同样采用 Kapture format格式。
输出结果
这将在指定的文件夹中创建三个输出文件result_save_folder:
recalls.txt
为纯文本输出 (仅当ground_truth_path
给定时),显示召回率NetVLAD_predictions.txt
由NetVLAD 获得的与每个查询图像相匹配的前 100 个参考图像,格式为Kapture formatPatchNetVLAD_predictions.txt
由 Patch-NetVLAD 重新排名的上面的前 100 张参考图像,格式仍然为 Kapture format
修改之后的指令可参考下述语句
python feature_match.py \
--config_path patchnetvlad/configs/storage.ini \
--dataset_root_dir=patchnetvlad/dataset \
--query_file_path=pitts30k_imageNames_query.txt \
--index_file_path=pitts30k_imageNames_index.txt \
--query_input_features_dir patchnetvlad/output_features/pitts30k_query \
--index_input_features_dir patchnetvlad/output_features/pitts30k_index \
--ground_truth_path patchnetvlad/dataset_gt_files/pitts30k_test.npz \
--result_save_folder patchnetvlad/results/pitts30k
使用自己的数据集
需要制作真值文件(ground_truth)
4.3 特征匹配(仅匹配一对图像)Feature matching(two files)
下面是计算两个给定图像的 Patch-NetVLAD 特征和匹配的脚本
python match_two.py \
--config_path patchnetvlad/configs/performance.ini \
--first_im_path=patchnetvlad/example_images/tokyo_query.jpg \
--second_im_path=patchnetvlad/example_images/tokyo_db.png
修改之后的指令可参考下述语句
python match_two.py \
--config_path patchnetvlad/configs/speed.ini \
--first_im_path=patchnetvlad/example_images/office1.png \
--second_im_path=patchnetvlad/example_images/office2.png
Note:
①上述脚本使用的是两个示例图片,实际使用时可以替换为任意两个图片
②该脚本将打印一个分数值作为输出,其中较大的分数表示更相似的图像,较低的分数表示不相似的图像。该函数还输出一个匹配图,显示两个图像之间的对应关系(RANSAC之后),该图保存在results/patchMatchings.png中.
4.4 训练Training
1、创建保存缓存文件的文件夹
用于保存训练过程中产生的中间结果和缓存文件的文件夹。
理论上是创建的哪里都可以,只需要创建完成后在运行脚本中修改成对应的地址即可。
这里创建在Patch_NetVLAD/patchnetvlad
文件下,命名为cache
,因此其相对地址为Patch_NetVLAD/patchnetvlad/cache
。
2、创建保存checkpoint的文件夹
用于保存checkpoint文件的文件夹。
同理,这里创建在Patch_NetVLAD/patchnetvlad
文件下,命名为save_checkpoints
,因此其相对地址为Patch_NetVLAD/patchnetvlad/save_checkpoints
。
3、修改下面的脚本后运行训练程序
python train.py \
--config_path patchnetvlad/configs/train.ini \
--cache_path=/path/to/your/desired/cache/folder \
--save_path=/path/to/your/desired/checkpoint/save/folder \
--dataset_root_dir=/path/to/your/mapillary/dataset
这里修改完成后为:
python train.py \
--config_path patchnetvlad/configs/train.ini \
--cache_path ~/Code/SceneRecognition/Patch_NetVLAD/patchnetvlad/cache \
--save_path ~/Code/SceneRecognition/Patch_NetVLAD/patchnetvlad/save_checkpoints \
--dataset_root_dir ~/Code/SceneRecognition/Patch_NetVLAD/patchnetvlad/dataset/mapillary
4.5 减少训练数据集
由于源代码是训练了21个城市的数据,这样数据太大了,训练的时间也过长。因此我们可以通过将msls.py中的数据集定义进行修改,以减少训练的数据集。
msls.py中原定义为:
default_cities = {
'train': ["trondheim", "london", "boston", "melbourne", "amsterdam", "helsinki",
"tokyo", "toronto", "saopaulo", "moscow", "zurich", "paris", "bangkok",
"budapest", "austin", "berlin", "ottawa", "phoenix", "goa", "amman", "nairobi", "manila"],
'val': ["cph", "sf"],
'test': ["miami", "athens", "buenosaires", "stockholm", "bengaluru", "kampala"]
}
修改后为:
default_cities = {
'train': ["trondheim"],
'val': ["cph"],
'test': ["miami"]
}
4.6 使用PCA降维
训练模型后,可以使用 add_pca.py 添加 PCA。
在/Patch_NetVLAD目录下打开终端,修改并输入下述指令
python add_pca.py \
--config_path patchnetvlad/configs/train.ini \
--resume_path=full/path/with/extension/to/your/saved/checkpoint \
--dataset_root_dir=/path/to/your/mapillary/dataset
其中
①改写resume_path
。所给的示例是让我们填写保存checkpoint的地址。
②改写dataset_root_dir
。存放mapliiary数据集的地址
修改后的指令参考如下:
python add_pca.py \
--config_path patchnetvlad/configs/train.ini \
--resume_path=~/Code/SceneRecognition/Patch_NetVLAD/patchnetvlad/save_checkpoints \
--dataset_root_dir=~/Code/SceneRecognition/Patch_NetVLAD/patchnetvlad/dataset/mapillary
5 监测模型训练效果
1、查看运行内存
watch -n 0.1 nvidia-smi
结果:
7443MiB(模型训练)
2.165GB(两张图片匹配)
2、模型大小
可以使用工具"Disk Usage Analyzer"查看所占内存,首先运行下列指令安装此工具。
sudo apt install baobab
安装完成后在应用程序菜单中搜索"Disk Usage Analyzer"。
可以看到:
初始下载:20.3MB
相关配置后(不算datasets):2.2G
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KVbEgfE8-1691119674410)(patchnetvlad模型大小.png)]
3、推理速度——计算推理两张图片相似度的时间
在match_two.py脚本中加入以下代码:
import time
start_time = time.time() # 记录开始时间
# 在这里插入你要执行的代码段
end_time = time.time() # 记录结束时间
execution_time = end_time - start_time
print(f"代码执行时间: {execution_time:.5f} 秒")`
结果:
9.08951 秒
4、测试自己数据集的相似度分数
在代码所在文件夹下打开终端,进入patchnetvlad虚拟环境,输入以下指令
python match_two.py \
--config_path patchnetvlad/configs/performance.ini \
--first_im_path=patchnetvlad/example_images/1.png \
--second_im_path=patchnetvlad/example_images/2.png
6 一些修改
1、将train.py line85的训练轮数由30修改为10
2、将train.ini batchsize由4修改为2
3、将match_two.py文件中的171行的opt = parser.parse_args()修改为opt = parser.parse_args(args=[])
7 模型单步调试
(1)设置调试配置文件
首先在VScode窗口最左侧栏选择“运行和调试”功能,点击菜单中的“创建配置文件”按钮,选择“Python”作为调试配置文件。
在生成的launch.json文件中,写入下列内容。
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/train.py",
"console": "integratedTerminal",
"justMyCode": true ,
"args": [
"--config_path",
"patchnetvlad/configs/train.ini",
"--cache_path",
"~/Code/SceneRecognition/Patch_NetVLAD/patchnetvlad/cache",
"--save_path",
"~/Code/SceneRecognition/Patch_NetVLAD/patchnetvlad/save_checkpoints",
"--dataset_root_dir",
"~/Code/SceneRecognition/Patch_NetVLAD/patchnetvlad/dataset/mapillary"
],
}
]
}
(2)单步调试match_two.py
代码跳转流程:match_two.py>>models_generic(通用模型).get_backend()>> 训练网络
match_two>>models_generic(通用模型).get_model()>> 获取网络
match_two>>patchnetvlad>>
使用patchnetvlad模块
models_generic.if append>>models_generic.L2norm>>
match_two>>datasets.py>>
local_matcher