type
status
date
slug
summary
tags
category
icon
password
URL
October 3, 2022 • 11 min read
by Simon Meng, mp.weixin.qq.com • See original
几天前,微博大V,@Simon_阿文 公开点名让我回答最新的文字生成三维模型人工智能算法——DreamFusion(下图)的技术原理(这不是把我这个编程菜鸟往火坑了推么?!),我肝了大半天之后终于理出来了一点头绪,作了一个不专业的科普,随便和我前段时间发布的Dreamfields3D工具的原理做了一个比较,欢迎各位大佬指正哈!
先说结论:
DreamFusion和Dreamfields3D用的底层技术——Dream fileds(看起来名字很类似是不是? 没错,这两篇论文有好几个共同作者)的原理类似,都是基于NeRF来构建三维物体。 区别是早先的Dream Fields是用CLIP对NeRF(神经辐射场)做引导,但是由于CLIP并不是图像生成模型,而只能判定图片和文字的相似度,所以用CLIP引导图像生成还差点意思; 于是,在DreamFusion中,引导NeRF的模型换成了早些时候Google发布的,号称超越Dalle2实现了text2image任务SOTA的diffusion扩散模型,Imagen。 凭借Imagen的出色的图片生成能力,再加入一些微调和增强,DreamFusion就实现了更好的三维生成效果。 但是,因为Imagen至今没有开源,那么使用了Imagen的DreamFusion啥时候能开源,也成为了未知数…(目前还没看到开源计划; 此外,感觉上也可以使用stable diffusion去替换Imagen,可能效果更好还说不定,这个可以是后续的一个尝试方向 )。
然后,如果大家还想彻底了解DreamFusion的原理,那么就要做好收藏本文慢慢阅读的准备,因为需要给大家讲4部分内容: NeRF,Dream fields(Nerf+Clip),扩散模型 (diffusion Model),DreamFusion。
先说NeRF:
NeRF(神经辐射场): 以体渲染(Volume Rendering)为基础,大家可以简单理解为,三维空间矩阵中有很多点,每个点有不同的不透明度(密度)数值,全透明的点将被忽略,即空白部分; 而有一定不透明度(全不透明或者部分不透明)的点会组成一个三维场(field),这个三维场在不同的角度下观察会呈现不同的颜色,就可以用来表征不同的三维物体。 同时,这些点的密度和颜色是使用一个多层MLP神经网络编码的,也就是可以被训练的,即只要我们能够“告诉”NeRF,它现在渲染的图像是与我们想要的是更接近了还是更跑偏了,NeRF就可以不断往我们希望的输出靠近。
那么,在传统的NeRF中,如何让一个NeRF表征我们希望的物体呢? 最直接的做法是,拍摄真实存在的,或者已经手工建模完毕的某个物体在不同角度的图片(如上图中显示的挖掘机玩具和架子鼓),然后把这些图片与拍摄时相机的位姿(xyz坐标点和水平垂直旋转角,也可以理解为机位)一起输入神经网络; 神经网络就可以根据给定的相机位姿渲染出对应的图片,然后和这个机位对应的真实图片比较,不断迭代学习,最后预测出尽量与已经存在的物体尽量相似的场景。
再说Dreamfields:
看到这里大家也发现了,传统NeRF其实只能做到复原,因为需要有已存在的物体(包或真实物体或数字三维模型)作为参照。那么,能不能不需要图片,例如只用文字无中生有呢?这时候就要借助大家熟悉的CLIP预训练模型(连接文字和图片的跨模态模型),也就是Dream fIelds(下图)的做法。
其实Dream Fields的原理很简单,就是让用户输入一段描述文字,然后把这段文字输入CLIP,然后在每个相机位姿输出图片,再将这个图片也输入到CLIP,然后让CLIP判断现在生成的图片是和用户输入的文字越来越接近了,还是差异更大了,以此来迭代和调校NeRF,从而让NeRF生成的物体逐渐接近CLIP理解的文字描述的场景。
在Dream Fields基础上,DreamFusion用能够通过文字生成图像的Imagen模型(扩散模型的一种),替换了CLIP。 直观上来说,DreamFusion运行方式应该是,我们输入一段文字,然后让Imagen生成对应的图像,然后把这个图像和NeRF在某个相机位姿渲染出来的图像做对比,看看是否相似就行。 但事实上是不能这么操作的。 因为我们在使用各种扩散模型(如stable diffusion等)的过程中,我们发现即便两次输入的text prompt(文字引导)完全一致,由于seed(对应不同的随机高斯噪声)的存在,得到的图片可能是完全不一样的。 所以,由于我们不能在不同的视角使用同一张图片作为“标准答案”,Imagen也不能够在不同的视角提供角度恰好的,几何特征连续的同类型不同图片(有这本事Imagen自己就能生成三维模型了),所以这里需要借鉴扩散模型中一些更“高级"的方法,这也是本文最难以理解的地方。
关于扩散模型(diffusion model):
要解释这个部分,我们要稍微解释一下扩散模型(diffusion model)的基本原理,这里我们只需要知道两件事。
首先,扩散模型训练的过程中先把一张真实图片X0逐步地添加高斯噪声(从0次到t次;给原图增加噪声是可以通过公式直接计算的,不需要AI),直到得到一张噪声图Xt(正向过程);然后训练再从噪声图Xt出发,让AI模型预测这张图变得如此模糊之前,被添加了什么样的噪声,然后再把这些被预测出来的噪声从当前的Xt图片中逐步去掉,直到回到清晰的图X0(反向过程)。
那么,这里AI模型需要学习的,也是决定整个扩散模型运行得好不好的关键是,AI“看”到噪声图Xt时,预测的此前被添加的(即一会要消除的)噪声εθ(xt,t),是否和被添加的真实噪声ε一致。这里如何根据加噪的过程学习去噪的数学推导比较复杂,我们暂且不提(其实我也没完全看懂,但是你可以大概类比一下,如果我们观察一幅画的拆解过程,例如将一幅古典名画逐步去掉高光、阴影、笔触、色块、描边、底色,直到还原成一张有很多纹理的帆布,我们是能够学习到一点这张图是如何被绘制出来的过程的)。我们需要记住的点是,AI需要优化的目标是,将 || εθ(xt,t) - ε || 最小化(εθ(xt,t)指的是扩散模型在看到被加噪到t步的噪声图片xt时,预测出的被加入的噪声;ε则是x0在变成Xt之前,被加入的真实噪声)。如果这两者的差异越小,即他们相减的绝对值越接近0,则AI减噪得到的图片X0^越接近真实的原始图片X0。
最后回到DreamFusion:
那么如果理解了这部分(如果没理解就再读两遍,这是我能写出来的最简单的方式了; 如果两遍后再不理解,你有两个选择: 1去补相关数学和AI知识; 2去干点别的吧不要看了,世界很大,人生还很长,我们可以回到DreamFusion的说明了。
DreamFusion基本借鉴了上述扩散模型中的模型优化方式(即让 || εθ(xt,t) - ε || 最小化那一步),来确保NeRF根据一段文字生成的三维物体在各个机位渲染得到的图像的分布,和Imagen模型根据同样文字生成的图像的分布一致(注意,这里是两组图像的分布一致,而不是一模一样,分布是数学上的一个概念,在这里你可以大致理解为两组图像的语义或者特征一致)。 上边是DreamFusion的流程图(图中信息比较多,建议放大查看),大概的步骤在图上我都用文字注明了,在这里再大概说明一下。
先用NeRF在预定的机位渲染图片,然后将这张图片和高斯分布ε~Ν(0,Ι)混合,就得到了一张加噪图片Zt 。 然后,将这张加噪图片和文字信息y(图中案例是“a DSLR photo of a peacock on a surfboard”,即冲浪板上的孔雀)一起,输入到已经训练好的imagn模型中,得到去噪后的图片X^θ(Zt|y;t)。 此时,这张X^θ并非直接使用,而是和前面的加噪图片Zt做比较,就可以得到,Imagen在生成X^θ的过程中,从前面的加噪图Zt上去掉的预测噪声ε^θ(Zt|y;t)。
这时,因为我们前面增加的噪声是已知的,即ε,那么我们就可以将预测的噪声和实际增加的噪声做比较。 这里一个主要推论是,如果NeRF生成的图像的分布,和Imagen根据文字输入生成的图像的分布是完全一致的,那么我们增加的噪声和Imagn在去噪时候将被去除的预测噪声ε^θ(Zt|y;t),也应该完全一致。
于是,我们就可以以最小化 || ε^θ(Zt|y;t) - ε || 为目标,在冻结Imagen模型参数的情况下,去迭代训练NeRF的参数,让其生成的图像越来越符合Imagne根据文字预测的图像分布。 除此之外,DreamFusion中还用了对NeRF渲染的图片做各种增强的方法,这里暂且不表。
以上为编程菜鸟的不专业科普,欢迎大家指正,拍砖请轻拍哈~!
参考文献:
diffusion扩散模型讲解: https://zhuanlan.zhihu.com/p/449284962
Dream Fields: https://ajayj.com/dreamfields
DreamFusion: https://dreamfusion3d.github.io
- 作者:Simon阿蒙
- 链接:https://shengyu.me//article/3DGEN-2022
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章