??從上圖可以看出,ControlNet的基本結(jié)構(gòu)由一個(gè)對(duì)應(yīng)的原先網(wǎng)絡(luò)的神經(jīng)網(wǎng)絡(luò)模塊和兩個(gè)”零卷積“層組成。在訓(xùn)練過(guò)程中,會(huì)”鎖死“原先網(wǎng)絡(luò)的權(quán)重,只更新ControlNet基本結(jié)構(gòu)中的網(wǎng)絡(luò)”副本“和零卷積層的權(quán)重。這些可訓(xùn)練的網(wǎng)絡(luò)”副本“將學(xué)會(huì)如何讓模型按照新的控制條件來(lái)生成結(jié)果,而被”鎖死“的網(wǎng)絡(luò)會(huì)保留原先網(wǎng)絡(luò)已經(jīng)學(xué)會(huì)的所有知識(shí)。零卷積層是一些權(quán)重和偏置被初始化為0的1X1卷積層。訓(xùn)練剛開(kāi)始的時(shí)候,無(wú)論新添加的控制條件是什么,這些零卷積層都只輸出0,ControlNet不會(huì)對(duì)擴(kuò)散模型的生成結(jié)果造成任何影響。隨著訓(xùn)練過(guò)程的深入,ControlNet將逐漸調(diào)整擴(kuò)展模型原先的生成過(guò)程,使得生成的圖像逐漸向新添加的控制條件靠近。

二、ControlNet訓(xùn)練

? ? ? 將上面描述的ControlNet block堆疊14次就得到完整的ControlNet,如下圖所示:

 訓(xùn)練一個(gè)附加到某個(gè)Stable Diffusion模型上的ControlNet的過(guò)程大致如下所示:

  1. 收集想要對(duì)其附加控制條件的數(shù)據(jù)集和對(duì)應(yīng)的Prompt。假如想訓(xùn)練一個(gè)通過(guò)人體關(guān)鍵點(diǎn)來(lái)對(duì)擴(kuò)散模型的人體進(jìn)行姿態(tài)控制的ControlNet,則首先需要收集一批人物圖片,并標(biāo)注好這批人物圖片的Prompt以及對(duì)應(yīng)的人體關(guān)鍵點(diǎn)的位置;
  2. 將Prompt輸入被”鎖死“的Stable Diffusion模型,并將標(biāo)注好的圖像控制條件(如人體關(guān)鍵點(diǎn)的標(biāo)注結(jié)果)輸入ControlNet,然后按照Stable Diffusion模型的訓(xùn)練過(guò)程迭代ControlNet block權(quán)重;
  3. 在訓(xùn)練過(guò)程中,隨機(jī)將50%的文本Prompt替換為空白字符串,這樣做的目的是”強(qiáng)制“網(wǎng)絡(luò)從圖像控制條件中學(xué)習(xí)更多的語(yǔ)義信息;
  4. 訓(xùn)練結(jié)束后,便可以使用ControlNet對(duì)應(yīng)的圖像控制條件(如輸入的人體關(guān)鍵點(diǎn))來(lái)控制擴(kuò)散模型生成符合條件的圖像

三、ControlNet示例

    本小節(jié)將介紹一些已經(jīng)訓(xùn)練好的ControlNet示例,都來(lái)自Huggingface。

3.1 ControlNet與Canny Edge

? ? ? ?Canny Edege是一種多階段的邊緣檢測(cè)算法,該算法可以從不同的視覺(jué)對(duì)象中提取有用的結(jié)構(gòu)信息,從而顯著降低圖像處理過(guò)程中的數(shù)據(jù)處理量,ControlNet與Canny Edge結(jié)合使用的效果如下圖所示:

3.2 ControlNet與M-LSD Lines

? ? ? ?M-LSD Lines是另一種輕量化的邊緣檢測(cè)算法,擅長(zhǎng)提取圖像中的直線線條。訓(xùn)練在M-LSD Lines上的ControlNet適合室內(nèi)環(huán)境方面的圖片。ControlNet與M-LSD Lines結(jié)合使用的效果,如下圖所示:

3.3 ControlNet與HED Boundary

? ? ? ?HED?Boundary可以保持輸入圖像更多信息,訓(xùn)練在HED Boundary上的ControlNet適合用來(lái)重新上色和進(jìn)行風(fēng)格重構(gòu)。ControlNet與HED Boundary結(jié)合使用的效果,如下圖所示:

 四、ControlNet實(shí)戰(zhàn)

    下面以Canny Edge為例,展示如何在Diffusers中使用StableDiffusionControlNetPipeline生成圖像。

安裝需要使用的庫(kù)

!pip install -q diffusers==0.14.0 transformers xformers git+https://
github.com/huggingface/accelerate.git

為了對(duì)應(yīng)選擇ControlNet,需要安裝兩個(gè)依賴庫(kù)對(duì)圖像進(jìn)行處理,以提取不同的圖像控制條件

!pip install -q opencv-contrib-python
!pip install -q controlnet_aux

以知名畫(huà)作《戴珍珠耳環(huán)的少女》為例進(jìn)行展示ControlNet效果

from diffusers import StableDiffusionControlNetPipeline
from diffusers.utils import load_image
 
image = load_image(
"https://hf.co/datasets/huggingface/documentation-images/
resolve/main/diffusers/input_image_vermeer.png"
)
image

首先將這張圖片交給Canny?Edge邊緣提取器進(jìn)行預(yù)處理

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)
canny_image

邊緣提取效果,如下圖所示:

可以看到Canny Edge能夠識(shí)別出圖像中物體的邊緣線條。接下來(lái),需要導(dǎo)入runwaylml/stable-diffusion-v1-5模型以及能夠處理Canny Edge的ControlNet模型。為了加快推理速度,采用半精度(float16)。

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
)

使用當(dāng)前速度最快的擴(kuò)散模型調(diào)度器-UniPCMultistepScheduler,迭代20次就可以達(dá)到之前默認(rèn)調(diào)度器50次迭代的效果。

from diffusers import UniPCMultistepScheduler
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.
config)

使用Canny Edge來(lái)控制所生成圖像中物體的確切位置和邊緣輪廓。下面代碼旨在生成一些人物的肖像,這些人物鈞擺出與《戴珍珠耳環(huán)的少女》相同的姿勢(shì)。在ControlNet和Canny Edge下,我們只需要在Prompt中提到這些人的姓名就可以了,代碼如下:

def image_grid(imgs, rows, cols):
assert len(imgs) == rows * cols
 
w, h = imgs[0].size
grid = Image.new("RGB", size=(cols * w, rows * h))
grid_w, grid_h = grid.size
 
for i, img in enumerate(imgs):
grid.paste(img, box=(i % cols * w, i // cols * h))
return grid
 
prompt = ", best quality, extremely detailed"
prompt = [t + prompt for t in ["Sandra Oh", "Kim Kardashian",
"rihanna", "taylor swift"]]
generator = [torch.Generator(device="cpu").manual_seed(2) for i
in range(len(prompt))]
 
output = pipe(
prompt,
canny_image,
negative_prompt=["monochrome, lowres, bad anatomy, worst
quality, low quality"] * len (prompt),
generator=generator,
num_inference_steps=20,
)
 
image_grid(output.images, 2, 2)

? 生成的人物肖像,如下圖所示:

?? ?還可以從一張圖片中提取身體姿態(tài),然后用它生成具有完全相同的身體姿態(tài)的另一張圖片,代碼如下:

urls = "yoga1.jpeg", "yoga2.jpeg", "yoga3.jpeg", "yoga4.jpeg"
imgs = [
load_image("https://hf.co/datasets/YiYiXu/controlnet-testing/
resolve/main/" + url)
for url in urls
]
 
image_grid(imgs, 2, 2)

?? ?原始圖片如下圖所示:

提取瑜伽的身體姿態(tài),代碼如下:

from controlnet_aux import OpenposeDetector
 
model = OpenposeDetector.from_pretrained("lllyasviel/ControlNet")
 
poses = [model(img) for img in imgs]
image_grid(poses, 2, 2)

提取效果,如下圖所示:

使用Open Pose ControlNet生成一些正在做瑜伽的超級(jí)英雄圖片,代碼如下:

controlnet = ControlNetModel.from_pretrained(
"fusing/stable-diffusion-v1-5-controlnet-openpose",
torch_dtype=torch.float16
)
 
model_id = "runwayml/stable-diffusion-v1-5"
pipe = StableDiffusionControlNetPipeline.from_pretrained(
model_id,
controlnet=controlnet,
torch_dtype=torch.float16,
)
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.
config)
pipe.enable_model_cpu_of f load()
pipe.enable_xformers_memory_efficient_attention()
 
generator = [torch.Generator(device="cpu").manual_seed(2) for i
in range(4)]
prompt = "super-hero character, best quality, extremely detailed"
output = pipe(
[prompt] * 4,
poses,
negative_prompt=["monochrome, lowres, bad anatomy, worst
quality, low quality"] * 4,
generator=generator,
num_inference_steps=20,
)
image_grid(output.images, 2, 2)

生成的效果,如下圖所示:

關(guān)于ControlNet更多的使用方法,可以參考如下:

lllyasviel/sd-controlnet-depth

lllyasviel/sd-controlnet-hed

lllyasviel/sd-controlnet-normal

lllyasviel/sd-controlnet-scribbl

lllyasviel/sd-controlnet-seg

lllyasviel/sd-controlnet-openpose

lllyasviel/sd-controlnet-mlsd

文章轉(zhuǎn)自微信公眾號(hào)@ArronAI

上一篇:

擴(kuò)散模型實(shí)戰(zhàn)(十二):使用調(diào)度器DDIM反轉(zhuǎn)來(lái)優(yōu)化圖像編輯

下一篇:

擴(kuò)散模型實(shí)戰(zhàn)(十四):擴(kuò)散模型生成音頻
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門(mén)場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)