大家好我是AIGC阿道夫
假设有一个不太懂电脑的朋友请求你编辑一张照片。照片上是他靠近一只猫的情景,他希望你把猫替换成一条龙。选择使用Photoshop编辑这张图片要花费几个小时甚至几天时间,但是使用Stable Diffusion模型在几分钟内就可以完成。
Stable Diffusion作为一种强大的深度学习模型,被广泛应用于图像生成、修复和增强等领域。**我们可以用文字提示Stable Diffusion模型来生成图像,也可以使用图像和遮罩进行更具体的提示。**此外,调整一些超参数如引导强度和推理步数也有助于更好地控制扩散过程,生成更符合需求的图像。
- 在使用文字提示时,可以描述你希望生成的图像的具体细节,比如颜色、构图、风格等。
- **在使用图像和遮罩提示时,**可以在已有的图像基础上,通过遮罩指定哪些部分需要改变或者保持不变,这样可以得到更精准的结果。
- **超参数可以使用*引导强度和**推理步数***。****引导强度(Guidance Scale)**这个参数决定了生成图像时对提示文本的依赖程度。较高的引导强度会使生成的图像更符合提示文本,但可能会牺牲一定的多样性。**推理步数(Inference Steps)**这个参数决定了生成图像的迭代次数。更多的推理步数通常会带来更高的图像质量,但生成时间也会相应增加。
通过调整这些参数,可以在质量、速度和多样性之间找到一个平衡点,从而生成最符合需求的图像。
此外,**Stable Diffusion模型还支持inpainting技术,可以对图像的特定部分进行编辑。**Inpaint是一种基于Stable Diffusion的图片修复技术,主要用于去除图片中的水印、划痕、污渍等。**其工作原理分为两步:**首先,用户提供待修复的图像,并在图像上绘制遮罩(mask),标示需要修复的区域;然后,Stable Diffusion根据该图像和遮罩生成一个新图像,对瑕疵区域进行修复或重绘。
**现在,我们来看看如何在代码中实现上面说的这些功能。**我们将在Jupyter Notebook中运行下面的代码示例。
1. 安装所需的包。
!pip install -q accelerate torch diffusers transformers comet_ml
2. 从Comet下载我们的遮罩和图像
import comet_ml
comet_ml.init(anonymous=True, project_name="4: Diffusion Prompting")
# Create the Comet Experiment for loggingexp = comet_ml.Experiment()
logged_artifact = exp.get_artifact("L4-data", "anmorgan24")local_artifact = logged_artifact.download("./")
3. 加载图像
from PIL import Image
image=Image.open("L4_data/boy-with-kitten.jpg").resize((256, 256))image_mask=Image.open("L4_data/cat_binary_mask.png").resize((256, 256))
加载原始图像
import matplotlib.pyplot as plt
# Print the imageplt.imshow(image)
显示遮罩图像
# Print the maskplt.imshow(image_mask)
4. 导入并准备模型
下载模型
stable-diffusion-2-inpainting
git clone https://huggingface.co/stabilityai/stable-diffusion-2-inpainting
然后加载模型
import torchdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")
from diffusers import StableDiffusionInpaintPipeline
sd_pipe = StableDiffusionInpaintPipeline.from_pretrained( "./models/stabilityai/stable-diffusion-2-inpainting", torch_dtype=torch.float16 if torch.cuda.is_available() else torch.bfloat16, low_cpu_mem_usage=False if torch.cuda.is_available() else True,).to(device)
# Set the value of seed manually for reproducibility of the resultsseed = 66733generator = torch.Generator(device).manual_seed(seed)
prompt = "a realistic green dragon"
注意!硬件要求:
要生成本实验中演示的图像,至少需要一台具有 8 GB CPU 的机器,在大约 3 分钟内得到 3 次推理步骤的结果。但是,对于涉及 10 步骤的任务,使用 CPU 可能需要大约 10 分钟。而涉及 100 步骤的任务,使用 CPU 需要更长的时间。或者,可以考虑使用 GPU 以加快处理速度。使用 GPU,例如本地 GPU ,所有三个步骤都可以在 1 秒内完成。
5. 创建新的 Comet 实验。
首先,我们启动一个新的Comet实验来记录图像、元数据和参数。然后,将这些参数传递给Stable Diffusion流水线以生成输出图像。接着,我们提取图像,并把图像、提示、种子和推理步数记录到Comet中。最后,结束实验并进行结果分析。
exp = comet_ml.Experiment()
output = sd_pipe( image=image, mask_image=image_mask, prompt=prompt, generator=generator, num_inference_steps=3,)
generated_image = output.images[0]
exp.log_image( generated_image, name=f"{prompt}", metadata={ "prompt": prompt, "seed": seed, "num_inference_steps": 3 })
exp.end()
6. 查看执行”a realistic green dragon”Prompt后的结果
import io
reference_experiment = comet_ml.APIExperiment( workspace="ckaiser", project_name="4-diffusion-prompting", previous_experiment="b1b9e80bb0054b52a8914beec97d36a6")
reference_image = reference_experiment.get_asset_by_name(f"{prompt}")
plt.imshow(Image.open(io.BytesIO(reference_image)))
7. 设置*推理步数(Inference Steps)*
更多的推理步数通常会带来更高的图像质量,但生成时间也会相应增加。
我们将推理步骤数设置成100。
exp = comet_ml.Experiment()
prompt = "a realistic green dragon"
exp.log_parameters({ "seed": seed, "num_inference_steps": 100})
output = sd_pipe( image=image, mask_image=image_mask, prompt=prompt, generator=generator, num_inference_steps=100,)
generated_image = output.images[0]
exp.log_image( generated_image, name=f"{prompt}", metadata={ "prompt": prompt, "seed": seed, "num_inference_steps": 100 })
exp.end()
看看生成的效果,生成的龙更加逼真。
reference_experiment = comet_ml.APIExperiment( workspace="ckaiser", project_name="4-diffusion-prompting", previous_experiment="948c8e6cfd23420c86a0de5f65719955")
reference_image = reference_experiment.get_asset_by_name(f"{prompt}")
plt.imshow(Image.open(io.BytesIO(reference_image)))
8. 设置*引导强度(Guidance Scale)*
较高的引导强度“Guidance Scale”会使生成的图像更符合提示文本,但可能会牺牲一定的多样性。
首先创建一个包含不同Guidance Scale的numpy数组,并在流水线中使用这些值。通过调用display并传递tab=images参数,可以在Comet应用程序中看到图像仪表板,显示所有图像的元数据和不同输出。
import numpy as np
guidance_scale_values = [x for x in np.arange(0, 21, 10)]
exp = comet_ml.Experiment()
prompt = "a realistic green dragon"
num_inference_steps = 100 #if torch.cuda.is_available() else 10
exp.log_parameters({ "seed": seed,})
for guidance_scale in guidance_scale_values:
output = sd_pipe( image=image, mask_image=image_mask, prompt=prompt, generator=generator, num_inference_steps=num_inference_steps, guidance_scale=guidance_scale )
generated_image = output.images[0]
exp.log_image( generated_image, name=f"{prompt}", metadata={ "prompt": prompt, "seed": seed, "num_inference_steps": num_inference_steps, "guidance_scale": guidance_scale } )
exp.end()
reference_experiment = comet_ml.APIExperiment( workspace="ckaiser", project_name="4-diffusion-prompting", previous_experiment="b34b94f94c594802b7090b6f2f1224f2")
reference_experiment.display(tab="images")
两张最佳图像的Guidance Scale分别是10和20,这表明最佳输出出现在Guidance Scale为10到20之间。我们将继续在此范围内寻找更多的Guidance Scale值,以找到最优值。
9. 设置另一个超参数:“强度”
我们现在尝试另一个独特于图像应用的扩散模型超参数——强度超参数。在使用扩散模型进行inpainting时,我们需要添加噪声来删除要替换的部分。添加噪声量决定了移除的信息量,少量噪声使图像与原图非常相似,大量噪声则完全移除替换部分。强度参数决定了添加噪声的多少。
strength_values = [x for x in np.arange(0.1, 1.1, 0.2)]
exp = comet_ml.Experiment()
prompt = "a realistic green dragon"
num_inference_steps = 200 if torch.cuda.is_available() else 10
exp.log_parameters({ "seed": seed,})
for strength in strength_values:
output = sd_pipe( image=image, mask_image=image_mask, prompt=prompt, generator=generator, num_inference_steps=num_inference_steps, strength=strength )
generated_image = output.images[0]
exp.log_image( generated_image, name=f"{prompt}", metadata={ "prompt": prompt, "seed": seed, "num_inference_steps": num_inference_steps, "strength": strength } )
exp.end()
reference_experiment = comet_ml.APIExperiment( workspace="ckaiser", project_name="4-diffusion-prompting", previous_experiment="2964615a382d46f09c3a36c50c74deef")
reference_experiment.display(tab="images")
结果显示,当强度很低时,猫几乎没有变化。随着强度增加,越来越多的猫被移除,但改变强度并没有改善图像。
10. 负面提示
负面提示很直观,它告诉模型你不希望图像看起来像什么。因此,当我们使用 “a realistic green dragon” 作为提示时,可以给出”cartoon”这样的负面提示,以增强输出的现实感
exp = comet_ml.Experiment()
prompt = "a realistic green dragon"negative_prompt = "cartoon"
num_inference_steps = 100 if torch.cuda.is_available() else 10
exp.log_parameters({ "seed": seed,})
output = sd_pipe( image=image, mask_image=image_mask, prompt=prompt, negative_prompt=negative_prompt, generator=generator, num_inference_steps=num_inference_steps, guidance_scale=10)
generated_image = output.images[0]
exp.log_image( generated_image, name=f"{prompt}", metadata={ "prompt": prompt, "seed": seed, "num_inference_steps": num_inference_steps, "guidance_scale": 10 })
exp.end()
reference_experiment = comet_ml.APIExperiment( workspace="ckaiser", project_name="4-diffusion-prompting", previous_experiment="f05b04ac203a4f9aa606ea6cf9417fa3")
reference_image = reference_experiment.get_asset_by_name(f"{prompt}")
plt.imshow(Image.open(io.BytesIO(reference_image)))
结果显示,我们优化了龙的图像,去掉了一些不喜欢的特征,同时增强了好的特质。
通过这篇文章的知识和学习 AI 绘画系列的其他文章内容,我们应该能够构建一个流水线,从图像生成遮罩,使用inpainting进行编辑,并流畅完成这一切,就像一个由Stable Diffusion驱动的Photoshop。
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
评论(0)