################################################################### 条件控制之DreamBooth ################################################################### 本章我们讨论谷歌团队发表的 `DreamBooth` :footcite:`ruiz2023dreambooth` , `DreamBooth` 也是一种控制图像生成内容的方法,但它的思想和场景与 `ControlNet` 是截然不同的。 `DreamBooth` 针对的使用场景是,期望生成同一个主体的多张不同图像, 就像照相馆一样,可以为同一个人或者物体照多张不同背景、不同姿态、不同服装的照片。 `DreamBooth` 就类似照相馆,可以通过文本 Prompt 控制每次都生成同一个主体的不同背景、姿态、服装的图像, 这个主体可以是人、动物、物体等等。 我们用一个例子说明。 假设你养了一条小狗,你非常喜爱它,你想为它生成各种可爱的照片,把它打造成一个网红。 然而每次用照相机拍照成本太高,很多场景也布置不出来, 这时候就可以用 `DreamBooth` + `Stable Diffusion` 批量生成多彩多姿的图片。 只需要提前准备好 3~5 张小狗的图片,给它起个名字吗,然后使用 `DreamBooth` 方法微调一下预训练的 `Stable Diffusion` 模型,生成图像时,在提示词里加入小狗的名字,就能生成以你的小狗为主体的各式各样的图片, 如 :numref:`fig_dreambooth_001` 所示。 .. _fig_dreambooth_001: .. figure:: pictures/dreambooth_dog.jpg 为同一只小狗生成不同场景的图像(图片来自 `DreamBooth project`_ ) DreamBooth 技术 ######################################################## `DreamBooth` 并不是一个独立的图像生成模型,它是一种微调技术,通过对现有的预训练好的图像生成模型进行微调, 进而实现能通过文本 Prompt 控制生成同一个主体的不同场景的图像。 与 `ControlNet` 不同的是, `DreamBooth` 要简单很多,它并没有修改 `Unet` 的网络结构,也没有增加额外的网络。 `DreamBooth` 仅仅是在文本 `Prompt` 动了手脚,不需要对扩算模型做任何改动。 首先,需要准备3~5张的目标主题的照片,可以是你的自拍美照,也可以是宠物的照片,任何特定实体的多张照片。 最好是不同角度的照片,但要突出你先要的实体。 然后,给这个实体起一个名字,这个名字最好是比较罕见的词汇,尽量不要用常见词,必然会产生歧义。 这个名字作为这个主体的 **唯一标识符** ,接下来的目的是要让模型学习到 (唯一标识符,特定主体)这个关系。 接下来,就要为每一张照片设置一段文本提示语,这个文本提示语的格式为"一个[标识符][类名词]" 其中 `[标识符]` 是主体的唯一标识符, `[类名词]` 是主体的粗略类描述符(例如,猫、狗、手表、小姐姐等) ,类描述符可以由用户提供或通过分类器获得,类描述符指明了这个主体是什么,是非常重要的信息。 它相当于一种先验知识,把我们的主体和这个类别联系起来, 论文中提到,**使用错误的类描述符或没有类描述符会增加训练时间和语言漂移,同时降低性能**。 从本质上讲, 我们试图利用模型对特定类别的先验,并将其与我们主体的独特标识符的嵌入联系起来, 这样我们就可以利用视觉先验来生成主体在不同语境中的新姿势和表述。 唯一标识符的选择也很重要,模型需要把这个标识符和照片中的主体联系起来, 如果是一个本身就很常见的单词或者词汇,在仅有少量样本的情况下, 模型是很难学习到的。如果样本太多或者学习轮次太多,又容易造成过拟合现象, 此时模型就会忘记这个词汇原本的含义,这就造成了 **语言迁移** 现象。 这就促使需要一个在语言模型和扩散模型中都具有弱先验的标识符。 一个危险的方法是选择英语中的随机字符,并将它们连接起来,生成一个罕见的标识符(例如 "xy5syt00")。 在现实中, `tokenizer` 可能会对每个字母分别进行分割,而扩散模型的先验对这些字母是很强的。 我们经常发现,这些字母 `tokens` 会招致与使用普通英语单词类似的弱点。 解决的方法是,首先在文本模型的在词汇表(vocabulary)中寻找出罕见的 `tokens` , 把这些稀有 `tokens` 作为候选集合,从这些稀有的 `tokens` 中选出 :math:`k=\{1,\dots,3\}` 个出来组成文本作为主体的唯一描述符。 论文中介绍,对于 `Imagen` ,使用 `T5-XXL` 的 `tokenizer` 生成的编号为 :math:`\{5000, \dots, 10000\}` 范围内的 `tokens` 作为候选集, 从中随机抽取3个罕见 `tokens` 或者更少一点的 Unicode字符(不含空格),效果很不错。 根据论文作者的经验,通过对模型的所有层进行微调, 可以获得最大的主体保真度的最佳结果。 这包括对文本编码器进行微调,但是这就产生了 **语言漂移** 的问题。 语言漂移是语言模型中观察到的一个问题, 即一个在大型文本语料库中预训练的模型,后来为一个特定的任务进行了微调, 逐渐失去了语言的句法和语义知识。 这会影响扩散模型,模型慢慢地忘记了如何生成与目标主体 **相同类别** 的主体。 **另一个问题是可能会减少图像生成的多样性**。 文本到图像的扩散模型自然拥有大量的输出多样性, 在对一小部分图像进行微调时,我们希望能够以新的视角、姿势和衔接方式生成主体。 然而,有一种风险是主体的姿势和视角可能会变得单一。 这种情况经常发生,特别是当模型训练时间过长时。 1. 准备3~5张,特定的主题的照片,并设定好图片的描述文本:"一个[标识符][类名词]",作为微调训练样本 A. 2. 用预训练的扩散模型以 "一个[类名词]" 作为提示语生成一批相同类别的图片样本,作为微调训练样本 B. 3. 合并练样本 A 和 B,对扩散模型进行微调训练。 `DreamBooth` 方法可以为同一个主体生成不同的图像,这是非常常见的场景,所以 `DreamBooth` 技术其实非常有价值。 而且它和 `ControlNet` 并不冲突,可以和 `ControlNet` 一同使用,生成更加随心所欲的图片。 `DreamBooth` 的训练方法并不复杂,简单实用。 huggingface 提供了详细的训练教程和例子,地址在: https://huggingface.co/docs/diffusers/training/dreambooth ,可以参考一下。 参考文献 ######################################################## .. footbibliography:: .. _DreamBooth project: https://dreambooth.github.io/ .. meta:: :description lang=zh_CN: 扩散模型 :keywords: 变分自编码器,Variational Autoencoder,VAE,扩散模型,Diffusion Model,生成模型,图像生成,DreamBooth