深度学习(18):nerf、nerf-pytorch代码运行与学习

时间:2022-10-11 18:52:57

0 前言

NeRF代码基于tensorflow1写的,我电脑是RTX3070只能使用tensorflow2,而且我也懒得(没那个能力)再去代码里修改tensorflow1和tensorflow2的区别了,于是先放弃复现。
nerf-pytorch项目是 NeRF 的忠实 PyTorch 实现,它在运行速度提高 1.3 倍的同时重现结果;下面就演示了nerf-pytorch代码的运行。
二者在github上都是几千个star的项目,都很不错。

一 NeRF代码运行–放弃复现

NeRF论文代码:github: https://github.com/bmild/nerf

1.1 下载代码

git clone https://github.com/bmild/nerf.git
cd  nerf

1.2 配置环境

执行下面配置环境:
conda env create -f environment.yml
环境配置如下:

深度学习(18):nerf、nerf-pytorch代码运行与学习

如果看到下面报错
报错如下,应该是conda自身的问题:

Solving environment: failed
InvalidVersionSpecError: Invalid version spec: =2.7

这里尝试升级conda(网上有其他解决方案,我正好升级conda解决了):
conda update conda
这个命令会升级conda的默认环境下的包并安装一些新包。
接下来执行conda env create -f environment.yml就不受影响了。

1.3 下载示例数据

conda activate nerf
bash download_example_data.sh

会下载得到"tiny_nerf_data.npz"文件和一个data数据集,data文件夹里面包括:合成Lego数据集和 LLFF Fern 数据集。

1.4 运行demo

优化低分辨率 Fern NeRF:
python run_nerf.py --config config_fern.txt
报错:
tensorflow.python.framework.errors_impl.InternalError: Blas GEMM launch failed : a.shape=(65536, 63), b.shape=(63, 256), m=65536, n=256, k=63 [Op:MatMul]
应该是tensorflow架构的问题,上面environment.yml安装的是tensorflow-gpu==1.15;可能不适配自己当前的显卡。

深度学习(18):nerf、nerf-pytorch代码运行与学习

尝试替换环境中的tensorflow1为显卡适配的tensorflow2运行,发现代码中的一部分函数运行不了(tensorflow1和tensorflow2的区别),先放弃tensorflow实现

1.5 删除虚拟环境–可要可不要

conda remove -n your_env_name(虚拟环境名称) --all
conda remove -n nerf --all

二 nerf-pytorch–复现成功

nerf-pytorch项目是 NeRF 的忠实 PyTorch 实现,它在运行速度提高 1.3 倍的同时重现结果。
github地址: https://github.com/yenchenlin/nerf-pytorch

2.1 环境搭建

2.1.1 github参考步骤搭建的环境–弃用

(1)搭建环境

创建虚拟环境:
conda create -n nerfpy37 python=3.7
conda activate nerfpy37

安装:

git clone https://github.com/yenchenlin/nerf-pytorch.git
cd nerf-pytorch
pip install -r requirements.txt

(2) 运行demo

下载数据集 lego和 fern :
bash download_example_data.sh
训练一个低分辨率的 lego NeRF:
python run_nerf.py --config configs/lego.txt
报错如下NVIDIA GeForce RTX 3070 with CUDA capability sm_86 is not compatible with the current PyTorch installation.
,是显卡和pytorch不兼容。这里可以尝试仅仅替换当前虚拟环境中的torch版本为适合自己硬件的,应该是可行的方案,我在复现giraffe时就仅仅替换torch就成功了,我这里就先不尝试了。

深度学习(18):nerf、nerf-pytorch代码运行与学习

2.1.2 使用之前yolov5的虚拟环境–使用

yolov5环境配置(https://blog.csdn.net/BIT_HXZ/article/details/123444769)
修改 xx/nerf-pytorch/requirements.txt 如下,补充安装除了torch之外的包:

# torch==1.11.0
# torchvision>=0.9.1
imageio
imageio-ffmpeg
matplotlib
configargparse
tensorboard>=2.0
tqdm
opencv-python

安装包:pip install -r requirements.txt

深度学习(18):nerf、nerf-pytorch代码运行与学习

2.2 训练fern

注:测试参考2.4.3
训练:python run_nerf.py --config configs/fern.txt
configs/fern.txt如下:

expname = fern_test
basedir = ./logs
datadir = ./data/nerf_llff_data/fern
dataset_type = llff

factor = 8
llffhold = 8

N_rand = 1024
N_samples = 64
N_importance = 64

use_viewdirs = True
raw_noise_std = 1e0

训练过程终端截图:
深度学习(18):nerf、nerf-pytorch代码运行与学习

深度学习(18):nerf、nerf-pytorch代码运行与学习
深度学习(18):nerf、nerf-pytorch代码运行与学习

训练开始打印输出:

(yolov5py37) meng@meng:~/subject/NeRF/nerf-pytorch$ python run_nerf.py --config configs/fern.txt
Loaded image data (378, 504, 3, 20) [378.         504.         407.56579161]
Loaded ./data/nerf_llff_data/fern 16.985296178676084 80.00209740336334
recentered (3, 5)
[[ 1.0000000e+00  0.0000000e+00  0.0000000e+00  1.4901161e-09]
 [ 0.0000000e+00  1.0000000e+00 -1.8730975e-09 -9.6857544e-09]
 [-0.0000000e+00  1.8730975e-09  1.0000000e+00  0.0000000e+00]]
Data:
(20, 3, 5) (20, 378, 504, 3) (20, 2)
HOLDOUT view is 12
Loaded llff (20, 378, 504, 3) (120, 3, 5) [378.     504.     407.5658] ./data/nerf_llff_data/fern
Auto LLFF holdout, 8
DEFINING BOUNDS
NEAR FAR 0.0 1.0
Found ckpts []
get rays
done, concats
shuffle rays
done
Begin
TRAIN views are [ 1  2  3  4  5  6  7  9 10 11 12 13 14 15 17 18 19]
TEST views are [ 0  8 16]
VAL views are [ 0  8 16]
[TRAIN] Iter: 100 Loss: 0.04988392814993858  PSNR: 16.008405685424805           
[TRAIN] Iter: 200 Loss: 0.041811756789684296  PSNR: 16.925973892211914          
[TRAIN] Iter: 300 Loss: 0.03342441841959953  PSNR: 17.929391860961914           
[TRAIN] Iter: 400 Loss: 0.02886515110731125  PSNR: 18.603059768676758           
[TRAIN] Iter: 500 Loss: 0.02745005488395691  PSNR: 18.930387496948242           
[TRAIN] Iter: 600 Loss: 0.026994995772838593  PSNR: 18.70709800720215           
[TRAIN] Iter: 700 Loss: 0.025570739060640335  PSNR: 18.959453582763672          
[TRAIN] Iter: 800 Loss: 0.0206332728266716  PSNR: 20.038761138916016     

训练中间出现的warning,这个应该只造成速度损失(speed loss),对效果影响不大:

IMAGEIO FFMPEG_WRITER WARNING: input image is not divisible by macro_block_size=16, resizing from (504, 378) to (512, 384) to ensure video compatibility with most codecs and players. To prevent resizing, make your input image divisible by the macro_block_size or set the macro_block_size to 1 (risking incompatibility).
[swscaler @ 0x676d380] Warning: data is not aligned! This can lead to a speed loss

最终最后一行的结果:

[TRAIN] Iter: 200000 Loss: 0.0034459223970770836  PSNR: 28.529253005981445

在训练了 200k 次迭代(单次 2080 Ti 约 8 小时,我的RTX3070也大概是8小时)后,可以在 logs/fern_test/fern_test_spiral_200000_rgb.mp4(名称中的200000应该指的是200k次迭代) 和 logs/fern_test/fern_test_spiral_200000_disp.mp4 找到以下视频,如下图所示

训练结果存放目录:

深度学习(18):nerf、nerf-pytorch代码运行与学习

可以看出除了200k迭代对应的视频,还有50k、100k、150k次迭代的视频,不过我直接看不出这四个迭代次数视频的区别,需要视频的可以留言,不过视频和官方github和其他博主分享的没区别好像。
四个未压缩的文件夹是对应迭代次数的单视角测试效果:

深度学习(18):nerf、nerf-pytorch代码运行与学习

2.3 训练lego

注:测试参考2.4.3
训练:python run_nerf.py --config configs/lego.txt
configs/lego.txt如下:

expname = blender_paper_lego
basedir = ./logs
datadir = ./data/nerf_synthetic/lego
dataset_type = blender

no_batching = True

use_viewdirs = True
white_bkgd = True
lrate_decay = 500

N_samples = 64
N_importance = 128
N_rand = 1024

precrop_iters = 500
precrop_frac = 0.5

half_res = True

在训练 100k 次迭代(单个 2080 Ti 上约 4 小时,我的RTX3070也约4小时–记不清楚了)后,可以在 logs/lego_test/下分别找到50k和100k的视频(blender_paper_lego_spiral_050000_rgb.mp4等)和对应的测试图片(testset_050000等)
训练结果目录:
深度学习(18):nerf、nerf-pytorch代码运行与学习

对应的测试图片:
深度学习(18):nerf、nerf-pytorch代码运行与学习

2.4 更多数据集

2.4.1下载

https://drive.google.com/drive/folders/128yBriW1IG_3NJ5Rp7APSTZsJqdJdfc1
先下载这两个:

深度学习(18):nerf、nerf-pytorch代码运行与学习

下载后按照文件夹名称将对应文件放到对应目录下即可,相同文件夹如fern和lego可直接跳过,目录如下:
深度学习(18):nerf、nerf-pytorch代码运行与学习
深度学习(18):nerf、nerf-pytorch代码运行与学习
深度学习(18):nerf、nerf-pytorch代码运行与学习

深度学习(18):nerf、nerf-pytorch代码运行与学习

2.4.2训练

python run_nerf.py --config configs/{DATASET}.txt
替换 {DATASET} 用 trex | horns | flower | fortress | lego | etc.

以flower数据集为例:
python run_nerf.py --config configs/flower.txt
configs/flower.txt如下:(llff 注明对应数据集)

expname = flower_test
basedir = ./logs
datadir = ./data/nerf_llff_data/flower
dataset_type = llff

factor = 8
llffhold = 8

N_rand = 1024
N_samples = 64
N_importance = 64

use_viewdirs = True
raw_noise_std = 1e0

深度学习(18):nerf、nerf-pytorch代码运行与学习

训练大概用了10个小时,我12点前离开电脑的:

深度学习(18):nerf、nerf-pytorch代码运行与学习

训练结果目录:

深度学习(18):nerf、nerf-pytorch代码运行与学习
深度学习(18):nerf、nerf-pytorch代码运行与学习

2.4.3测试

python run_nerf.py --config configs/{DATASET}.txt --render_only
替换 {DATASET} 用 trex | horns | flower | fortress | lego | etc.

测试flower数据集:(其他数据集可类似测试)
python run_nerf.py --config configs/flower.txt --render_only
测试终端打印如下,箭头所指位置应该是上一步训练得到的内容或者是预训练模型的内容,测试的时间比训练时间短多了。

深度学习(18):nerf、nerf-pytorch代码运行与学习
![在这里插入图片描述](https://img-blog.csdnimg.cn/4b2a140f8a9e4d57a0e25728bda6d428.png#pic_center)

测试完成:

深度学习(18):nerf、nerf-pytorch代码运行与学习

测试结果在下面这个目录中,测试在不同视角下的渲染效果

深度学习(18):nerf、nerf-pytorch代码运行与学习

2.5 使用预训练模型进行

预训练模型下载地址:https://drive.google.com/drive/folders/1jIr8dkvefrQmv737fFm2isiT6tqpbTbv,全部下载即可

深度学习(18):nerf、nerf-pytorch代码运行与学习

将下载的目录放在 ./logs 中(注:如果前面训练过程在./logs下产生相同名称文件夹,先不要替换对应目录,可以将自己训练的结果进行压缩备份),以便稍后进行测试。请参见以下目录结构:

深度学习(18):nerf、nerf-pytorch代码运行与学习

然后运行下面命令即可测试:
python run_nerf.py --config configs/{DATASET}.txt --render_only
替换 {DATASET} 用 trex | horns | flower | fortress | lego | etc.
注:测试参考2.4.3

3 代码阅读

3.0 参考

https://blog.csdn.net/YuhsiHu/article/details/124676445
https://blog.csdn.net/weixin_44292547/article/details/126249933