论文题目: Diffusion Probabilistic Models for 3D Point Cloud Generation
论文地址:https://arxiv.org/pdf/2103.01458.pdf
代码地址:https://github.com/luost26/diffusion-point-cloud/tree/main
Diffusion Probabilistic Models(扩散概率模型)是一种生成模型。我们知道,最典型的生成模型是GAN,VAE和flow。扩散模型是一种新的生成模型。它在paper with code上,取得了很高的性能。被作者鼓吹是一种可以替代GAN的模型(注:我持怀疑态度。因为DPM模型太复杂了。且测试的时候需要迭代太多次,不优雅)。
扩散模型是什么意思呢?我们知道,东西在空气中,追随熵增大原理,会扩散变无序。例如,我们有一个椅子,如果放在空气中,长达数百年。这个椅子就会腐蚀成一个高斯噪声了。如果我们能学习到腐蚀的过程。那么,我们逆回去。就可以把一个高斯噪声变成一个椅子。这就是利用扩散模型进行点云(或图像)的生成过程。
和condition gan一样,这个文章也想用condition。它先对某个shape提了一个shape latent作为条件(注:这个条件是指类别条件还是点云条件?如果是前者,那么,例如我只需要提一个飞机类别,就可以生成一个飞机的点云。如果是后者,我需要输入一个飞机的点云,然后输出是这个输入的点云的一个风格变换后的点云。读完后文,我发现这个条件十分不优雅,甚至有点鸡生蛋和蛋生鸡的矛盾。)
相关文献
点云的生成。由于我重点想关注本文的方法而非点云生成本身。关于点云生成的参考文献我直接略过。
扩散概率模型。我前面已经讲了,扩散模型就是,如果我们有一个点云,我t0时刻是点云本身,t1时刻它扩散了一上,t2时刻进一步扩散。走到tn时刻变成高斯噪声。这整个过程可以看成是一个马尔科夫过程。我们只要逆回去,就可以用一个高斯噪声生成一个点云。本文评论到,现有的扩散模型多用于无条件生成,就随便用一个噪声,就可以生成一个目标。而本文首次做了condiction 扩散模型。(注:这就是是GAN到condiction GAN的改进吗?读完后文,我发现这个条件十分不优雅,甚至有点鸡生蛋和蛋生鸡的矛盾。)
方法
以下要讲述本文的方法了。在开始讲之前,请大家先了解一件事:王广聪博士曾经说过,大家在学习VAE之前,先不要看论文里面的formulation(或者VAE的formulation定义),而是先读训练和测试算法框图或者代码。这句话真是让我受用终身。原因是什么呢?就是VAE的数学formulation太优雅了,以至于你读算法或才代码的时候会发现,定义中的formulation和真正的实现根本就是两个东西。如果只看算法,就会发现VAE是一个无比庸俗简单的东西,却被formulate成高深莫测的东西。并且,formuation之后还会多一段话,说"To make the training simpler and more efficient, following [11], instead of evaluating the expectation of the whole summation over all the time steps in Eq. (9), we balabalabala...”,后面就开始说真正的实现和formulation不一致的地方。我有时候对这种过度formulation不太喜欢。而扩散模型正是和VAE一样,存在过度formulation现象。
本文的扩散模型是一个条件扩散模型(注:这个条件用的不是很优雅)。首先请看下面的示意:
(x_T, x_0 -> z) -> … -> (x_t, z) -> (x_{t-1}, z) -> … -> x_0
(x_0, z -> x_0) -> … -> (x_{t-1}, z) -> (x_t, z) -> … -> (x_T, z)
为了利于理解,先讲inference阶段。在此阶段,我们输入的是一个高斯噪声x_T+一个条件z。这里有点不太合理的是,我们需要先将一个图输入到encode中得到这个条件z。这就好比说,为了生成飞机的点云。我们先要将一个飞机点云x_0输入到一个encode中,得到条件z。然后这个z和x_T一块,迭代T次,最终生成飞机的点云x_0。这就有一个鸡生蛋和蛋生鸡的矛盾了。如果我事先有一个飞机的点云了,我还要再生一个做什么?当然,这是符合条件生成器的定义的。有时候我们输入一个低分辨率的点云,想生成一个高分辨率的点云。或者我们需要做image-to-image tranlation或者风格转换。输入高斯噪声x_T+条件z,我们输入一个net中,预测一个e_theta,然后用这个e_theta采样(相乘),得到x_{T-1}(注:见代码e_theta = self. net(x_t, beta=beta, context=context); x_next = c0 * (x_t - c1 * e_theta) + sigma * z)。然后反复迭代,得到x_{t}, 继续得到x_{t-1},最终得到x_0,这就是我们的输出。具体参见此行代码:https://github.com/luost26/diffusion-point-cloud/blob/cde2e501855dea31496ddffad16f40aa588e3af8/models/diffusion.py#L137
接下来向大家介绍训练阶段。在训练阶段,我们也是先用x_0输入encoder得到z,然后用x_0采样噪声(即扩散)得到x_1,x_1得到x_1,如此,最终得到x_T,即x_0 -> x_1 -> x_2 -> x_3 … -> x_T(注:在本文的训练代码中,实现并非迭代采样。只x_0可直接采样x_t。只要得到一个恰当的采样就可以一步到位。因为高斯采样有叠加性质)。但是,在训练的时候,需要保证测试的时候扩散能逆回去。即保证:x_T -> x_{T-1} -> … -> x_2 -> x_1。由于 e_theta = self. net(x_t, beta=beta, context=context); x_next = c0 * (x_t - c1 * e_theta) + sigma * z)。我们只需要保证e_theta为标准高斯分布即可。因此,训练时,随机采样一个时间 t \in [0, T],使得e_theta = self. net(x_t, beta=beta, context=z) 与标准高斯分布的mse loss最小化。这就是训练过程。具体参见此行代码:https://github.com/luost26/diffusion-point-cloud/blob/cde2e501855dea31496ddffad16f40aa588e3af8/models/diffusion.py#L118。至于说,为什么e_theta = self. net(x_t, beta=beta, context=z) 与标准高斯分布的mse loss最小化可以保证可逆,这也许是DDPM的性质之一。这就好比为什么kld loss能使VAE的code落在N(0,1)分布一样。
对于Test VAE来说,还是需要输入一个点云,才能生成一个点云的(注:即所谓的条件生成器)。请见:https://github.com/luost26/diffusion-point-cloud/blob/cde2e501855dea31496ddffad16f40aa588e3af8/test_ae.py#L61
所以,对于本文的方法来说,实在是一个包装。要从噪声来生成一个点云,本文的扩散模型根本做不到。为了生成点去,它需要借助于传统的VAE模型(或者说需要借助kld loss)或Flow模型(或者说flow的loss)。请参见:
对VAE的需要见:https://github.com/luost26/diffusion-point-cloud/blob/cde2e501855dea31496ddffad16f40aa588e3af8/train_gen.py#L104 和https://github.com/luost26/diffusion-point-cloud/blob/cde2e501855dea31496ddffad16f40aa588e3af8/models/vae_gaussian.py#L39;
对Flow的需要见:https://github.com/luost26/diffusion-point-cloud/blob/cde2e501855dea31496ddffad16f40aa588e3af8/train_gen.py#L106和https://github.com/luost26/diffusion-point-cloud/blob/cde2e501855dea31496ddffad16f40aa588e3af8/models/vae_flow.py#L52。
综上。本文虽然提出来用扩散概率模型来生成点云。实际上生不出来。它需要加VAE的kld loss或者Flow模型某些loss。与VAE不同之处在于,VAE的decoder是仅访问一次decoding net一次的,在DDPM变成一个多次迭代访问一个net了。
-----------------------------------
大家好,我来自fast lab。我开始不定时公开写作。这些写作主要通过两个渠道公布:一是FAST LAB官方网站;一是印象识堂(微信可访问)。欢迎大家订阅。谢谢!
FAST Lab的官方网址为:https://wanggrun.github.io/projects/fast
除此外,还可以关注我的小伙伴王广润:https://wanggrun.github.io/
王广聪: https://wanggcong.github.io/
石阳:https://www.linkedin.com/in/%E9%98%B3-%E7%9F%B3-381b521a4/
有时候这些网站打不开,请耐心多点几次。
多谢大家关注。