代码网址:DIF-Net
论文网址:Arxiv - Deformed Implicit Field: Modeling 3D Shapes with Learned Dense Correspondence
一、论文理解
本小节仅记录一些个人对这篇论文的理解。
我认为这篇论文的核心主要有以下三点:
- 论文在DeepSDF(应该是最早提出的Auto-Decoder的训练方式,通过建模连续的SDF进行物体表面建模)上做了改进。
DeepSDF中的shape latent code和point coordinates简单的进行concat后输入进网络中,求出该point coordinates到最近shape表面的Signed Distance Value。
在这篇论文中,将shape latent code和point coordinates进行了分解,将这两个独立的信息用各自独立的网络进行处理,效果自然而然会有改善。 - 通过所提出的网络在Unsupervised的条件下(现有的数据集很少会提供Dense Correspondence,大部分是Part Correspondence或Patch Correspondence,故不太适合有监督的学习)建立了Dense Correspondence
- 将相同category的所有object的common semantic information和common structure提取到Template Field中,将该category下的所有object的表面建模描述为将点经过Deformation+Correction变换到Template Field上进行SDF预测的结果
其次就是对网络流程的一些解释:
- α α α为shape latent code,将这个 k k k维的向量输入Hyper-Net中获得的结果是Deform-Net的网络参数。为什么要预测Deform-Net的参数呢?因为shape latent code是instance级的,每一个instance的shape latent code都不一样,想要变换到Template Field下所需要做的Deformation也是不一致的。所以给定一个shape latent code,我们预测它Deform-Net的参数,以判断点应该做一个怎样的变形
- 将点 p p p输入到Deform-Net中,获得这个点的Deformation流 v v v(在 x , y , z x,y,z x,y,z三个方向上做的变换),还有一个Correction Field校正域,用于弥补最后得到的predict sdf和ground truth sdf之间的插值。这个Correction Field的好处在于可以生成一些模板域中不具备的结构,例如椅子的侧拉伸器等(这一点在论文中有提及和证明,提及看Deformation Field and Coorection Field部分,证明看提及部分的图或者实验部分的图都可以),从而提高了Shape representation ability
- 将点 p + v p+v p+v后得到的点 p ′ p' p′输入到Template Field中,这里实际上就是将原始的点经变换并align到Template Field中来,通过Template Field输出该点的predict sdf。这里Template Field是一个category共享同一个Template Field
- Template Field的存在对于有结构差异的对象会学的更好,因为也有使用mesh作为模板的表达形式,但是基于mesh的模板仅在其表面有意义,学的没那么好(摘自文章中的话)
二、代码复现
第一步: 这篇文章的代码复现不算特别复杂,只需要根据它说的做就行了,通过以下操作克隆仓库并配置环境,这一步我都没有出现任何问题:
git clone https://github.com/microsoft/DIF-Net.git --recursive
cd DIF-Net
conda env create -f environment.yml
source activate dif
第二步: 不知道为什么,它引用的pytorch-meta库我没有成功的克隆下来,所以我在本文件夹下通过命令删除了pytorch-meta文件夹,并重新克隆了一个pytorch-meta
rm -rf pytorch-meta
git clone https://github.com/tristandeleu/pytorch-meta.git
第三步: 根据代码主页给定的操作去进行torch-meta库的安装(据我的了解这是一个元学习库,但是我并没有特地了解过什么是元学习)
cd pytorch-meta
python setup.py install
第四步: 执行到这一步运行generate的代码应该没什么问题(我很久以前运行的generate,好像不安装pytorch-meta也能运行,记不清了,如果这一步还是运行不了,就把下面的步骤做完,再重新运行),下载好项目主页提供的训练模型并放置到models/对应类别的文件夹下,generate的代码就是以下的部分,category.yml的category调整成指定类别的就可以了
# generate 3D shapes of certain subjects in certain category
python generate.py --config=configs/generate/<category>.yml --subject_idx=0,1,2
2023.05.09补充如下,我刚刚重新下载了这个code并执行generate任务,出现了一点小问题:
Traceback (most recent call last):
File "generate.py", line 17, in <module>
import modules, utils
File "/mnt/d/sdc/liutong/codes/DIF/modules.py", line 6, in <module>
from torchmeta.modules import (MetaModule, MetaSequential)
File "/home/liutong/anaconda3/envs/dif/lib/python3.6/site-packages/torchmeta-1.4.0-py3.6.egg/torchmeta/__init__.py", line 1, in <module>
from torchmeta import datasets
File "/home/liutong/anaconda3/envs/dif/lib/python3.6/site-packages/torchmeta-1.4.0-py3.6.egg/torchmeta/datasets/__init__.py", line 1, in <module>
from torchmeta.datasets.triplemnist import TripleMNIST
File "/home/liutong/anaconda3/envs/dif/lib/python3.6/site-packages/torchmeta-1.4.0-py3.6.egg/torchmeta/datasets/triplemnist.py", line 11, in <module>
from torchmeta.datasets.utils import get_asset
File "/home/liutong/anaconda3/envs/dif/lib/python3.6/site-packages/torchmeta-1.4.0-py3.6.egg/torchmeta/datasets/utils.py", line 3, in <module>
from torchvision.datasets.utils import makedir_exist_ok, check_integrity
ImportError: cannot import name 'makedir_exist_ok'
分析报错的位置,是torchmeta/datasets/utils.py下的问题,直接溯源dif文件夹下的pytorch-meta/torchmeta/datasets/utils.py,发现确实一开始有import makedir_exist_ok
,而makedir_exist_ok
在utils代码里面并未被使用,所以我们直接将源代码中的
from torchvision.datasets.utils import makedir_exist_ok, check_integrity
改成:
from torchvision.datasets.utils import check_integrity
就可以了,改完后保存,我pip uninstall pytorch-meta
后再次在pytorch-meta下执行python setup.py install
,报错即可解决
第五步: 运行训练代码,我下载了chair类的数据,所以我使用以下的代码进行训练
# train dif-net of certain category
python train.py --config=configs/train/chair.yml
但是在训练过程中遇到了一个报错:
ModuleNotFoundError: No module named 'torchmeta.modules.utils'
按图索骥一下,实际上就是找不到torchmeta.modules.utils
,那我们就去torchmeta文件夹下看一看就行了,进入DIF-Net/pytorch-meta/torchmeta/modules
文件夹,发现确实没有utils.py
文件,再去看一下原始的pytorch-meta github的对应部分:torchmeta/modules/utils.py,确实有这么一个utils.py
文件,既然没有,就在modules文件夹下新建utils.py
文件,将github上的代码复制进去就行:
cd pytorch-meta/torchmeta/modules
vim utils.py
按a
进入编辑模式后粘贴以下代码:
import re
from collections import OrderedDict
def get_subdict(dictionary, key=None):
if dictionary is None:
return None
if (key is None) or (key == ''):
return dictionary
key_re = re.compile(r'^{0}\.(.+)'.format(re.escape(key)))
return OrderedDict((key_re.sub(r'\1', k), value) for (k, value)
in dictionary.items() if key_re.match(k) is not None)
接着按ESC
键,输入:wq!
返回,再回到pytorch-meta
文件夹下,执行:
cd pytorch-meta
python setup.py install
接着就可以进行训练了,如下图所示,不会再提示原来的错误了,可以打印出训练信息。这里我只是缺少了具体的训练数据,所以会报错。
第六步: 如果下载的是github链接里提供的数据的话,那些数据是是eval集的数据,所以要用作者给定的数据做训练的话,就要将split/train下的chair.txt文件用split/eval下的chair.txt文件替换掉。也就是:
cp split/eval/chair.txt split/train/
覆盖掉就可以正常训练了
第七步: 在train.py文件里面使用了多显卡并发式训练
所以在训练之前记得查看一下服务器上的哪些显卡被使用了,然后调整一下要使用的显卡序号(在train.py文件的开头),在下边这个位置进行调整:
第八步: 如果报类似于下边这种错误
就调整一下config/train
下的对应类别的yml文件配置,把里面的batch_size
大小调小一点,我这里是调整成64
就能训练起来了,显卡是NVIDIA TITAN XP的:
三、generate复现结果
以下是chair类别的的Template
以下是chair类别的train objcet:
以下是Reference阶段的一些evaluation结果:
因为chair类别的objects之间的differences本身就是比较大的,所以得到这样的效果应该可以说算是不错的了。
之后若是对于train的复现过程还会出现什么问题的话,再补充。