7.5.3 基于扩散模型(Diffusion Model)合成数据
AI图像生成是2022年以来AIGC(Artificial Intelligence Generated Content:人工智能创作内容)最热门的话题之一。一般以自然语言描述为输入,输出与该描述相匹配的图像。这种模型的开发始于2010年代中期,伴随深度神经网络技术的发展而进步。2022年,最先进的文生图模型,例如OpenAI的DALL-E 2、Google的Imagen、StabilityAI的稳定扩散(Stable Diffusion),以及Midjourney公司的Midjourney V5,其品质开始接近真实照片或是人类所绘艺术作品。
举个简单例子,图7-8是由Stable Diffusion生成的图片,我们只需输入文字“a photograph of an astronaut riding a horse”(骑着一匹马的宇航员照片),即可由AI一键生成超逼真图片!
图7-9则是由Midjourney v5在提示词“A pair of young Chinese lovers, wearing jackets and jeans, sitting on the roof, the background is Beijing in the1990s, and the opposite building can be seen.”(“一对年轻的中国情侣,穿着夹克和牛仔裤,坐在屋顶上,背景是20世纪90年代的北京,可以看到对面的建筑”),生成的照片。
图7-8 由stable diffusion生成的照片
图7-9 由Midjourney v5 生成的照片
以上AI图像生成软件均是基于扩散模型(Diffusion Model)来实现的。扩散模型是一类生成式模型,自2021年因其生成高质量图像的能力而越来越受欢迎。简单来说,扩散模型的工作方式首先是向训练集中的图像添加一定量的随机噪声。然后,反向整个过程,即在训练过程中,模型学习去除噪声以重构图像。目前比较流行的扩散模型,包括:来自Stability AI的Stable Diffusion以及基于Stable Diffusion的ControlNet,还有来自OpenAI的DALL-E2,Google的Imagen等。
7.5.3.1 Stable Diffusion基本原理
下面我们简单了解下Stable Diffusion的基本原理。
Stable Diffusion
Stable diffusion是一种基于潜在扩散模型(Latent Diffusion Models)的文本到图像生成模型,能够根据任意文本输入生成高质量、高分辨率、高逼真的图像。
下面介绍下stable diffusion的主要模块,如图7-10所示:
(1)文本编码器(Text Encoder)
这个文本编码器是一个特殊的Transformer语言模型(多模态的文本编码器),它接收文本做输入,然后输出数组表示每个词/表征(每个表征都是一个向量)。
输入:“paradise(天堂)、cosmic(广袤的)、beach(海滩)”
输出:77个表征向量(token embeddings),每个有768维度。
(2)图片信息生成器(Image Information Creator)
这个组件分多次迭代来生成图像信息,迭代大约要重复30~50次,低维空间变量(潜在空间)在迭代过程中从纯噪声不断变成包含丰富语义信息的向量,这一组件由UNet和调度算法(Scheduler)组成。
输入:文本表征向量(token embeddings) 和 起始随机图片信息张量(Random Image information sensor)由噪声组成。
输出:处理后的图片信息张量(Processed image information tensor)
(3) 图片解码器(Image Decoder)
图像解码器通过前置的图片信息生成器得到的信息来生成图像。它只在最后的运行一次来生成最终的像素图像。
输入:处理过的信息数组(Processed image information tensor)
输出:结果图像(Generated Image)
图7-10 Stable Diffusion的基本原理图
7.5.3.2 基于Stable Diffusion生成数据
我们将介绍一种基于huggingface上的Diffusers的实现方案。Diffusers 是一个包含多种预训练扩散模型的模型库,用于生成图像、音频甚至分子的 3D 结构,详细介绍可参考其网址https://huggingface.co/docs/diffusers/quicktour。
下面我们看下如何基于Stable Diffusion生成样本数据,主要步骤如下:
首先安装必要的Python包。
%%sh
pip install -q --upgrade pip
pip install -q --upgrade diffusers transformers scipy ftfy huggingface_hub
Python Notebook代码如代码段7-2所示:
代码段7-2:基于Stable Diffusion模型的文生图模型生成测试样本代码
import torch
from diffusers import StableDiffusionPipeline
from huggingface_hub import notebook_login
# 需要登录huggingface获取stable diffusion模型
notebook_login()
generator = StableDiffusionPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16, revision="fp16"
)
generator = generator.to("cuda")
image = generator("a young Asia man's face").images[0] #生成一个亚洲青年人脸
image #display it.
通过指定要生成的图片的提示词(prompt),循环调用generator,就可以生成一批我们想要的样本数据了,图7-11是上述代码生成的几个典型的亚洲青年人脸。
图7-11 基于Stable Diffusion模型生成的测试样本
除了基于文生图外,我们还可以利用StableDiffusion的图生图(Img2Img)能力来生成相似的测试样本,代码示例如代码段7-3所示。
代码段7-3:基于Stable Diffusion模型的图生图模型生成测试样本代码
import torch
import requests
from PIL import Image
from io import BytesIO
from diffusers import StableDiffusionImg2ImgPipeline
device = "cuda"
model_id_or_path = "runwayml/stable-diffusion-v1-5"
pipe = StableDiffusionImg2ImgPipeline.from_pretrained(model_id_or_path, torch_dtype=torch.float16).to(
device
)
pic = "dog.png"
init_image = Image.open(pic).convert("RGB")
init_image.thumbnail((768, 768))
init_image #展示原图
prompt = "A dog with the same pose but with different color" #相同姿势不同颜色的小狗
generator = torch.Generator(device=device)
image = pipe(prompt=prompt, image=init_image, strength=0.75, guidance_scale=7.5, generator=generator).images[0]
image #展示生成图
通过指定要生成的图片的提示词,循环调用generator,就可以生成一批我们想要的样本数据了,图7-12是上述代码生成的几个典型的相似姿势的小狗样本。
图7-12 基于原图小狗(左图)生成的一系列相似姿势的小狗样本
7.5.3.3 基于ControlNet生成数据
ControlNet使用了一种称为"Conditional Generative Adversarial Networks"(条件生成对抗网络)的技术来生成图像。传统的生成对抗网络就像黑盒子一样,我们很难能够控制生成的图片,而ControlNet 允许用户对生成的图像进行精细的控制。ControlNet可以与扩散模型结合使用,以实现条件输入,例如边缘检测(Canny edge detection),姿态检测(OpenPose),深度信息估算(Depth)等,能够更精准控制 AI 图像的生成,以获得更好的视觉效果。
下面我们将演示如何基于边缘检测和姿态检测生成相似AI样本数据。
1. 基于Canny边缘检测生成样本数据
Canny边缘检测是一种常用的边缘检测算法,它可以在图像中找到明显的边缘,并将其提取出来。通过从提取出边缘轮廓,我们可以控制生成的图片和原图保持轮廓一致。
代码段7-4显示了如何借助opencv2从原图中提取出边缘轮廓,图7-13是原图及其对应的边缘轮廓图。
代码段7-4:生成原图的边缘轮廓代码
#ControlNet
from diffusers import StableDiffusionControlNetPipeline
from diffusers.utils import load_image
image = load_image("dog.png")
import cv2
from PIL import Image
import numpy as np
image = np.array(image)
low_threshold = 100
high_threshold = 200
image = cv2.Canny(image, low_threshold, high_threshold)
image = image[:, :, None]
image = np.concatenate([image, image, image], axis=2)
canny_image = Image.fromarray(image)
图7-13 原图及其边缘轮廓图
有了边缘轮廓图后,我们可以将其作为ControlNet的输入,然后我们指定提示词("a dog under the sunlight"),生成有相似轮廓图的样本数据,参见代码段7-5。
代码7-5 基于Canny生成相似轮廓的样本代码
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
import torch
controlnet = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-canny", torch_dtype=torch.float16)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5", controlnet=controlnet, torch_dtype=torch.float16
)
pipe = pipe.to("cuda")
generator = torch.manual_seed(0)
prompt = "a dog under the sunlight" #阳光下的小狗
out_image = pipe(
prompt=prompt, num_inference_steps=20, generator=generator, image=canny_image
).images[0]
通过循环执行上面的代码,我们就可以生成一批我们想要的样本数据了,图7-14是上述代码生成的几个典型的相似轮廓的小狗样本。和基于Stable Diffusion生成的图7-12相比,显然基于ControlNet生成的图片和原图更加的相似,包括小狗的耳朵、姿态以及地面等细节。
图7-14 基于原图小狗(左图)生成的一系列相似轮廓的小狗样本
2. 基于OpenPose生成样本数据
ControlNet的OpenPose可以根据我们指定的人体图片中提取姿态信息,然后就可以生成相同姿态的人体的样本数据。
代码段7-6显示如何从原图中提取出姿态信息,图7-15是原图及其对应的姿态图。
代码段7-6 加载原图及生成对应的姿态图代码
from controlnet_aux import OpenposeDetector
from diffusers.utils import load_image
openpose = OpenposeDetector.from_pretrained("lllyasviel/ControlNet")
origin_image = load_image("man.png")
openpose_image = openpose(origin_image)
openpose_image
图图7-15 原图及其姿态图
有了姿态图后,我们可以将其作为ControlNet的输入,然后我们指定提示词("a man standing in a bright room with a clear face”),生成有相同姿态的样本数据,参见代码段7-7。
代码段7-7 基于OpenPose生成相同姿态的样本代码
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, UniPCMultistepScheduler
import torch
controlnet = [
ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-openpose", torch_dtype=torch.float16),
]
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5", controlnet=controlnet, torch_dtype=torch.float16
)
pipe = pipe.to("cuda")
generator = torch.Generator(device="cuda").manual_seed(1)
prompt = "a man standing in a bright room with a clear face"
images = [openpose_image]
image = pipe(
prompt,
images,
num_inference_steps=50,
generator=generator,
negative_prompt=negative_prompt,
controlnet_conditioning_scale=[0.75],
).images[0]
通过循环执行代码段7-7,我们就可以生成一批我们想要的样本数据了,图7-16是上述代码生成的几个典型的姿势相同的样本。
图7-16 基于原图(左图)生成的一系列相同姿势的人体样本图
ControlNet还有更多模型可以更精准地控制生成的图片,这里不再陈述,感兴趣的读者前往https://huggingface.co/docs/diffusers/v0.17.1/en/api/pipelines/controlnet 及https://github.com/lllyasviel/ControlNet 做进一步的了解。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有