Code前端首页关于Code前端联系我们

稳定的diffus离子企业级教程:揭秘Inpainting工作的秘密!

terry 2年前 (2023-09-23) 阅读数 62 #AI人工智能

来说一下理论设计内容。总的来说,我们想谈谈基于SD实现的不同功能的组合方法。

比如在基本的文生图应用中,我们知道文本信息和图像信息是通过跨attention结合起来的,可以是几层transformer。那么如何创建qkv呢?对于图像制作工作,输入的图像组合如何影响最终的图像制作?说到绘画,为什么要有单独的绘画模型呢?原模型如何进行喷漆?

接下来,让我们深入代码,看看文本和图像如何在 SD 中神奇地结合在一起。

2。 TextToImage

stable diffusion企业级教程:图生图Inpainting功能大揭秘!

这张图相信大家都认识。diffus吉恩潜在原理示意图取自《High-Resolution Image Synthesis with Latent Diffusion Models》。也正是基于这个原则,稳定的diffus才能训练成功,和大家见面。

论文称文本向量和图像向量是通过“跨attention”结合在一起的。 “跨attention”源自字母“attention就是你所需要的”。虽然文中没有明确说明,但“编码器-解码器attention”已经具备了“跨attention”的身份——即QKV的来源不同。 stable diffusion企业级教程:图生图Inpainting功能大揭秘!

在原自attention中,QKV是通过将原始和不同的矩阵进行积分来计算的,而在“跨attention”中,“X”首先来自不同的来源,产生基于不同来源的QKV,然后在attention的下一次计算中,来自不同来源的“X”被组合起来。 stable diffusion企业级教程:图生图Inpainting功能大揭秘!

在SD中,X有两个来源:文本和图像。从信中我们知道,sd中的交叉attention发生在不存在的部分。通过启用pokemon.yaml中的unet部分,我们可以看到ldm/modules/diffus ionmodules/openaimodel.py UNetModelUNet 。

在这个类中,我们通过配置文件将use_spatial_transformer设置为True,因此在创建attention模块时,类SpatialTransformer的使用方式有所不同。 › stable diffusion企业级教程:图生图Inpainting功能大揭秘!

类中SpatialTransformer我们看到它对图像数据进行拉伸,将(b,c,h,w)转换为(b,(hw),张量c)就是将图像数据转换成数组长度为 hw,尺寸为 c。 stable diffusion企业级教程:图生图Inpainting功能大揭秘!

在下面的类ldm/modules/attention.py/CrossAttention中,我们生成图像变化序列的查询,并使用数据生成attention十字的键和值。 stable diffusion企业级教程:图生图Inpainting功能大揭秘!

其实更容易理解,因为在SD的训练过程中,文本编码器部分是固定的,不更新,所以很自然地让相机和文本编码更接近,很自然地用文本编码作为value,利用Self-attention机制生成新的条件图像信息。

那么接下来的finetune,比如中文编码器的训练,我们是否可以考虑把这里的关系反过来,用文本字符替换q,用图形字符替换k和v,让中文编码器直接添加到训练好的unet中?靠近点。这是一个值得考虑的指南~

3。 ImageToImage

stable diffusion企业级教程:图生图Inpainting功能大揭秘!

使用webui的同学应该对这个页面很熟悉。我们可以使用此页面来创建快速视线图。即在创建 SD 时以图像和文本作为参考来指导最终图像的创建。

除了页面之外,在我们的项目中,您可以通过scripts/img2img.py体验相关功能。那么使用 img2img 函数,如何添加图像来生成最终图像呢?

这里需要讲一下SD的基本原理。如果您想以任何方式获取它,您可以查看下面的链接。我在这里简单解释一下推理过程。图解稳定扩散​jalammar.github.io/illusterated-stable-diffus ion/

在SD模型推理过程中,我们通过采样得到了一张图像random,它是随机噪声。 ;根据当前处理步骤数和当前图像 A,我们可以使用diffus离子模型计算图像 B。模型认为,当我们从图片A中取出图片B时,剩下的图片会更接近,我们想要的结果是A_new = A-B。然后不断重复“猜B、减B”的过程,最后剩下的就是我们最终的猜测图像

当用于SD预测的文本和迭代次数一定时,唯一能影响最终结果的就是第一张随机图像。因此,一方面可以认为,当其他内容确定后,最终的图像结果将由初始噪声决定。

回到留声机问题,要让输入图像来指导图像的创建,利用输入图像来产生这种噪声是一个非常直观的想法。具体步骤可以参考diffus离子原理中给原图添加K步声音的过程,这里不再赘述。代码中主要体现在下图中标注的两个地方。

位置1)是把原始图像转换成VQGAN的隐藏空间向量,因为diffus的离子过程就是在这个空间完成的;

位置2)是给隐藏空间向量添加噪声,使其成为随机噪声。 stable diffusion企业级教程:图生图Inpainting功能大揭秘!

如果有兴趣,可以仔细看看decode方法,你会发现z_enc需要替换这里的噪声变量。几代人中随机生成的。

通过在制作过程中添加介绍性图片和文字指南,我们可以更好地控制生成的输出。例如下图中,我希望创建一个建筑物(building),主导图像是百度大厦。从最终结果中可以看出,生成的建筑物在声音和角度方面与指南的地图相似。 stable diffusion企业级教程:图生图Inpainting功能大揭秘!

还要注意,这里控制的是输出图像和输入图像的相似程度,它由两个参数定义:1)采样步长; 2)降噪强度。 stable diffusion企业级教程:图生图Inpainting功能大揭秘!

乘以2就是去噪过程中的最后一个数字。上图为采样步长为20、降噪强度为0.8的结果;下图为采样步数为50、降噪强度为0.8的结果和采样步数为50、降噪强度为0.2的结果stable diffusion企业级教程:图生图Inpainting功能大揭秘!

== ==== =20230613 补充===== == =

这段时间我在Imagen中应用了绘图工作,发现有很多东西可以讲。这个绘图工作并不像我们想象的那么简单。 。

首先,我们可以在配置文件中看到,训练时使用了1000个时间步,这说明了两点:

1。我在原始图像上添加了 1000 次噪声,将其变成纯噪声。 ;

2。我对噪声图像进行了1000次过滤,并将其转换为原始图像;

这里注意,纯噪声和原始图像是这个轴的最后两个点,只有时间过程负责这部分,时间步长只是表示这部分是如何切割的。这并不意味着时间步长越大,添加的噪声就越多或者图像越好。因此,当timesteps=1000时,添加噪声500次,当timesteps=100时,添加噪声50次,噪声图的结果几乎相同。

我谈论这个过程是为了更好地理解下一代过程。生成时,我们选择生成步长为20,那么根据训练时设置的timestep=1000,会选择20个数字来覆盖这1000步。一种简单的方法是选择[0,50,100,150,…,1000]作为20个点进行去噪。这也部分解释了为什么当随机数固定时,不同去噪步骤的结果是相同的。

那么涂胜涂会怎么样呢?前面提到的第一个噪声的定义不是很清楚。具体操作如下。以去噪步长为 20 为例,我们在这里选择 power = 0.2,因此我们期望最终图像更接近原始图像。对于20步,对应的噪声步强度为[0,50,100…1000],1000代表纯噪声。因此,对于原始图像我们选择idx = 20 * 0.2 = 4,对应的噪声级别为150,去除原始图像得到原始噪声。由于这个噪声对应的是150,所以很明显,噪声不能从1000开始降低,而是需要从150开始降低。降噪强度分别为150、100、50、0,得到原始图像。这也解释了为什么,在绘制过程中,当选择power时,迭代步长是sampling_steps * power。

成像相当于在某个部位对应的图像上添加噪声,然后将其抵消,之前从扩散过程的中间,到原始图像。

4。着色

stable diffusion企业级教程:图生图Inpainting功能大揭秘!

绘画是一项有趣且有用的活动。这允许我们更改所选区域而不影响图像的其他区域。

上图是webui提供的着色功能。但是当你使用这个功能的时候,你是否对WebUI是如何利用底层SD模型来实现着色功能感兴趣呢?

无论是runwayml、compvis还是stable,他们似乎都选择使用新模型来提供涂装工作。这和基于原sd的inpaint有什么区别? https://github.com/runwayml/stable-diffus ion/​github.com/runwayml/stable-diffus ion/https://github.com/CompVis/stable-diffus ion​github.com/CompVis /stable- diffus ionGitHub - Stability-AI/stablediffus ion:使用潜在扩散模型进行高分辨率图像合成​github.com/Stability-AI/stablediffus ionstable diffusion企业级教程:图生图Inpainting功能大揭秘!

4.1 使用新模型进行绘画♷He❀ 参见,尤其是绘画作品中使用的模型是如何应用这项技能的?

首先我们要知道我们画画的时候有哪些数据。除了主要文本内容之外,我们还会有原始图像、蒙版图像和容易被忽视的蒙版图像。我个人的理解是,与其让模型根据图像和掩模生成掩模图像,不如手动提供,这样可以减少模型的计算压力。stable diffusion企业级教程:图生图Inpainting功能大揭秘!

其次我们看一下修复模型的配置文件configs\stable-diffus ion\inpaint\v1-finetune-for-inpainting-laion-iaesthe.yaml,但是主要区别在于两点,一方面,主模型从LatentDiffusion变为LatentInpaintDiffusion;另外,更重要的是在unet部分(即diffus离子模型部分),图像输入的维度从4变为9。 stable diffusion企业级教程:图生图Inpainting功能大揭秘!

LatentInpaintDiffusion在数据处理上有影响。这里我们会添加额外的处理逻辑,帮助我们使用字典来组织需要进行不同处理的条件的信息(比如“crossattn”中的字符,而在“concat”下我们放入一些需要组合的条件);而unet部分新增的5个通道对应了上面提到的两个mask相关数据:mask(通道1)和图像mask(通道4)。

关键是如何重复使用这两个新条件,达到“只是改变遮罩区域并与原始图像匹配良好”的目标。

新模型非常简单。预处理后,我们将掩模和掩模图像转换为VQGAN空间中的张量,每次返回时,通过等待将这两个张量分开。将带噪声的输入向量concat,输入待预测的diffus离子模型,得到相关的预测结果。

具体编码过程参见这些文件和方法:

  • 1)原始数据处理:scripts/inpaint_sd.py⇒ ⓙ VQ GAN 张量图: ldm/model s /嚚明ION/ddpm.pyLatentInpaintDiffusion.get_input()
  • 3) 和噪声张量模型:明ION/ddpm。 py
DiffusionWrapper.forward

这样的“懒惰”行为实际上会让模型不仅需要学习如何处理额外的数据,还需要调整已经掌握的绘画技巧。因此,在 runwayml 存储库中,它显示 sd-v1-5-inpaint.ckpt 是基于获得的 sd-v1-5.ckpt 440K 过程进行训练的。您应该知道 sd-v1-5.ckpt,因为基础模型经过了 595K 步骤的训练。

4.2 使用basemodel进行绘画

ok,接下来就看看webui如何神奇的使用basemodel来实现这个任务。

注意着色功能有两个条件:

  • 1)只改变遮罩区域,不改变遮罩区域以外的内容
  • 2)输出一致,其他区域也可以做到;

这里参考代码是这个,大家都知道~ https://github.com/AUTOMATIC1111/stable-diffus ion-webui​github.com/AUTOMATIC1111/stable-diffus ion-webui 这里是我们讨论DDIM-Sampler下webui上inpaint的实现。同样,它有原始图像 img_org、掩码和文本。其着色过程如下:

  • 1)将img_org映射到VQGAN潜在空间,得到init_latent
  • 2)初始化随机噪声

  • 3)对于每一次迭代(per步骤),执行:
    • 基于步骤t,生成init_latent数据并添加相应的噪声♷t♸,此时我们有两个噪声,一个是在上一步的基础上去噪得到的张量x_dec ,另一个是根据原始图像 img_noise_t ❀ 得到的张量。现在我们将两者与mask结合起来,x_dec_new = mask * img_noise_t + (1-mask) * x_dec即原始图像的未掩模区域和噪声图像的掩模区域。融合完成得到一张新地图。
    • 被发送到下一个diffus离子网络进行去噪。
    • 重复到最后。
  • 具体基于DDIM-Sampler的视线可以参考webui中的这个方法。 modules/sd_samplers_compvis.pystable diffusion企业级教程:图生图Inpainting功能大揭秘!

    4.3着色附加说明

    上面介绍了webui中着色的方法,这里也详细讨论了它的配置的几个事情。

    • 1)遮蔽:这个很容易理解,就是需要重复遮蔽的区域或者未遮盖的区域。应用时,除了根据输入反转掩码之外什么也没有。
    stable diffusion企业级教程:图生图Inpainting功能大揭秘!
    • 2) mask/mask content:这对应于webui代码中的modules/processing.pyStableDiffusionProcessingImg››本身。 npainting_fill变量成员。需要明确的是,该选项控制如何根据初始图像生成 init_latent(也在 4.2 中进行了描述)。
      • 填充空白:用于填充原始图像的模糊数据
      • 原始图像:直接填充原始图像
      • 包络噪声:随机噪声♿空:3)inpaint/重绘区域:对应webui代码中的modules/processing.pyStableDiffusionProcessingImg2Img
    类。 成员变量。一个简单的理解是定义我应该发送给模型的第一个图像区域,可以是整个图像,也可以是掩模附近的区域。
    • 整个图像:上传整个图像,然后将原始图像和蒙版调整为指定尺寸
    • 仅蒙版:裁剪蒙版周围,然后将剪切的图像调整为指定尺寸。重新绘制,重置完成后链接到原图。
    stable diffusion企业级教程:图生图Inpainting功能大揭秘!

    5。总结

    本文主要是理论总结,整理SD模型以及基于SD模型的webui,如何理解文生圣像、绘画作品。

    提到的模型融合是一项非常关键的技能,可能是深度学习皇冠上的下一颗钻石(笑)。另外,你需要对diffus离子模型有特别的了解,不是数学层面的,而是模型系统层面的。有需要的朋友可以看参考文献“diffus稳定离子带图片”中的第四个链接。

    版权声明

    本文仅代表作者观点,不代表Code前端网立场。
    本文系作者Code前端网发表,如需转载,请注明页面地址。

    发表评论:

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    热门