DeepSDF是一篇比较老的文章,点开它的开源网站可以看到上一次修改已经是六年前的事情。前面写的这篇文章
DeepSDF论文复现1—数据集生成1—官方代码运行_deepsdf源码运行怎么运行-CSDN博客
充分展示了时代久远的文章如果没有给出数据集的话,要生成其数据集就需要花一定的功夫。不过好消息是,网络实现部分即便用当前最新的Pytorch2.0+版本也没有太大的问题,顶多就报点警告。
现在假定我们已经获得了数据集(如果还没有且着实不想自己搞,可以去这里下),来看看具体代码该怎么运行起来。
下载源代码
注意,之前生成数据集的时候下载过的就不用下了。
git clone https://github.com/facebookresearch/DeepSDF.git
环境安装
同样,如果已经按照这篇文章所说的方法生成了数据集,环境是可以直接用的,不需要再安装。然而,如果显卡太新,用老的版本似乎会报错(RTX 4090运行报错,不知道是不是个例),因此本人在完成数据集生成之后重新搞了个环境。。。
conda create -n DeepSDF python=3.11
conda activate DeepSDF
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
pip install plyfile
pip install scikit-image
pip install trimesh
这个环境因为用了比较新的pytorch版本,因此有些函数已经被声明为弃用,会有警告,不过无所谓,就不管了。
运行训练
修改examples文件夹中关于数据集位置的描述。比如想训练planes这个分类,就进入到planes文件夹中修改其specs.json文件,给其指定数据集路径:
//"DataSource" : "data",
"DataSource" : "G:/DeepSDFData/SDFdata_train",
然后修改训练的批数量,4090原版有24g内存,可以支持36左右的批大小(默认64,不愧是谷歌团队。。。有老哥买了魔改的48g 4090或者5090可以往大了改,比如5090可以改到48:
//"ScenesPerBatch" : 64,
"ScenesPerBatch" : 36,
注意,如果用的是Windows平台,批大小最好设置小一点,不然因为Win上其他应用本身会占比较多的显存,开太大可能会用到虚拟显存,导致速度下降非常夸张(而且不报错,没往这里想的时候可能会以为训练本来就这么慢)。当然,使用Win平台进行训练本身就比较坑,可能是因为io的关系,同一份代码放在相同位置,Linux上训练一轮30s,Windows上要53s。可见Win平台只适合用来做调试,真的跑训练还是能免则免)。
另外,因为python版本改了,需要将train_deep_sdf.py的第257行稍加修改:
#logging.info("Experiment description: \n" + specs["Description"])
logging.info("Experiment description: \n" + " ".join(specs["Description"]))
然后直接运行训练代码即可:
python train_deep_sdf.py -e ./examples/planes
训练需要的时间比较长,以planes这个子集为例,本人在AMD9950X3D+RTX4090的平台上训练一个轮次大概需要30s左右。训练轮次官方代码写的是2000轮,因此要30*2000大约17个小时。另外,因为数据集中不同类别的数量不一样,因此训练的时间也会有所差异。数据集类别个数具体如下:
类别代号 | 类别 | Train采样个数 | Test采样个数 | 总个数 |
---|---|---|---|---|
02691156 | 飞机 | 1780 | 456 | 4045 |
03001627 | 椅子 | 3281 | 832 | 6778 |
03636649 | 灯 | 897 | 213 | 2318 |
04256520 | 沙发 | 1628 | 411 | 3173 |
04379243 | 桌子 | 4859 | 1216 | 8436 |
总数 | 12445 | 3128 | 24750 |
出于好奇,我还在AutoDL上租了一台RTX5090的主机跑planes类别的训练,意外发现要43s左右才能训练完一轮,原因不明,可能是除显卡之外的其他配置的差异造成的。按这个速度算,训练一轮DeepSDF需要花72块左右,肉疼。。。
训练过程可视化
开源代码将训练过程都记录了下来(每10轮存一次),保存在examples/xxx/Logs.pth这个文件中,同时提供了可视化工具。要可视化只需要安装matplotlib:
pip install matplotlib
然后就可以直接查看。
loss
python plot_log.py -e ./examples/planes -t loss
time
python plot_log.py -e ./examples/planes -t time
训练结果三维可视化
模型在训练的时候每10轮会在/examples/planes/ModelParameters文件夹中保存一次权重(这个权重会被新的覆盖掉),在100、500、1000和2000轮的时候则以次数命名保存一次出来,这些就是我们花了七八十块最终要得到的东西。
开源代码给出了使用模型进行三维重建的完整实现,不过因为版本问题,需要将mesh.py中如下的语句进行修改:
#verts, faces, normals, values = skimage.measure.marching_cubes_lewiner(numpy_3d_sdf_tensor, level=0.0, spacing=[voxel_size] * 3)
verts, faces, normals, values = skimage.measure.marching_cubes(numpy_3d_sdf_tensor, level=0.0, spacing=[voxel_size] * 3)
随后运行如下代码即可对之前没学习过的测试集数据进行三维重建,重建后的数据放在\examples\planes\Reconstructions\2000路径中:
python reconstruct.py -e examples/planes -c 2000 --split examples/splits/sv2_planes_test.json -d G:\DeepSDFData\SDFdata_test--skip
下面是模型fff513f407e00e85a9ced22d91ad7027
在100、500、1000和2000轮训练权重下的预测结果:
可以看到随着训练轮数的增加,模型在细节上在慢慢向原本模型靠拢。
不过,即便是到了2000轮,拉进了看还是可以发现很多模型上的问题,比如连续性差,细节丢失严重,表面不够平滑等等。
甚至直接拿训练集中的数据来预测这个问题也同样比较严重:
当然,这个是好事,有助于后来者改进并水文章哈哈哈。
总结
到此我们就完成了官方代码的复现已经可视化工作。总的来说,谷歌团队的工作还是非常靠谱的,虽然已经过去了六年,出现了些版本兼容方面问题,但只需要稍微修改一下就能顺利跑起来,可视化等方面做的也比较到位。
下篇文章将结合代码具体分析文章的原理和三维重建部分,有兴趣的老哥可以关注一下。