使用JojoGAN創(chuàng)建風格化的面部圖
介紹
風格遷移是神經網絡的一個發(fā)展領域,它是一個非常有用的功能,可以集成到社交媒體和人工智能應用程序中。幾個神經網絡可以根據訓練數據將圖像樣式映射和傳輸到輸入圖像。在本文中,我們將研究 JojoGAN,以及僅使用一種參考樣式來訓練和生成具有該樣式的任何圖像的過程。
JoJoGAN:One Shot Face Stylization
One Shot Face Stylization(一次性面部風格化)可用于 AI 應用程序、社交媒體過濾器、有趣的應用程序和業(yè)務用例。隨著 AI 生成的圖像和視頻濾鏡的日益普及,以及它們在社交媒體和短視頻、圖像中的使用,一次性面部風格化是一個有用的功能,應用程序和社交媒體公司可以將其集成到最終產品中。
因此,讓我們來看看用于一次性生成人臉樣式的流行 GAN 架構——JojoGAN。
JojoGAN 架構
JojoGAN 是一種風格遷移程序,可讓將人臉圖像的風格遷移為另一種風格。它通過GAN將參考風格圖像反轉為近似的配對訓練數據,根據風格化代碼生成真實的人臉圖像,并與參考風格圖像相匹配。然后將該數據集用于微調 StyleGAN,并且可以使用新的輸入圖像,JojoGAN 將根據 GAN 反轉(inversion)將其轉換為該特定樣式。
JojoGAN 架構和工作流程
JojoGAN 只需一種參考風格即可在很短的時間內(不到 1 分鐘)進行訓練,并生成高質量的風格化圖像。
JojoGan 的一些例子
JojoGAN 生成的風格化圖像的一些示例:
風格化的圖像可以在各種不同的輸入風格上生成并且可以修改。
JojoGan 代碼深潛
讓我們看看 JojoGAN 生成風格化人像的實現。有幾個預訓練模型可用,它們可以在我們的風格圖像上進行訓練,或者可以修改模型以在幾分鐘內更改風格。
JojoGAN 的設置和導入
克隆 JojoGAN 存儲庫并導入必要的庫。在 Google Colab 存儲中創(chuàng)建一些文件夾,用于存儲反轉代碼、樣式圖像和模型。
!git clone https://github.com/mchong6/JoJoGAN.git
%cd JoJoGAN
!pip install tqdm gdown scikit-learn==0.22 scipy lpips dlib opencv-python wandb
!wget https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-linux.zip
!sudo unzip ninja-linux.zip -d /usr/local/bin/
import torch
torch.backends.cudnn.benchmark = True
from torchvision import transforms, utils
from util import *
from PIL import Image
import math
import random
import os
import numpy
from torch import nn, autograd, optim
from torch.nn import functional
from tqdm import tqdm
import wandb
from model import *
from e4e_projection import projection
from google.colab import files
from copy import deepcopy
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials
模型文件
使用 Pydrive 下載模型文件。一組驅動器 ID 可用于預訓練模型。這些預訓練模型可用于隨時隨地生成風格化圖像,并具有不同的準確度。之后,可以訓練用戶創(chuàng)建的模型。
#Download models
#optionally enable downloads with pydrive in order to authenticate and avoid drive download limits.
download_with_pydrive = True
device = 'cuda' #['cuda', 'cpu']
!wget http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
!bzip2 -dk shape_predictor_68_face_landmarks.dat.bz2
!mv shape_predictor_68_face_landmarks.dat models/dlibshape_predictor_68_face_landmarks.dat
%matplotlib inline
drive_ids = {
"stylegan2-ffhq-config-f.pt": "1Yr7KuD959btpmcKGAUsbAk5rPjX2MytK",
"e4e_ffhq_encode.pt": "1o6ijA3PkcewZvwJJ73dJ0fxhndn0nnh7",
"restyle_psp_ffhq_encode.pt": "1nbxCIVw9H3YnQsoIPykNEFwWJnHVHlVd",
"arcane_caitlyn.pt": "1gOsDTiTPcENiFOrhmkkxJcTURykW1dRc",
"arcane_caitlyn_preserve_color.pt": "1cUTyjU-q98P75a8THCaO545RTwpVV-aH",
"arcane_jinx_preserve_color.pt": "1jElwHxaYPod5Itdy18izJk49K1nl4ney",
"arcane_jinx.pt": "1quQ8vPjYpUiXM4k1_KIwP4EccOefPpG_",
"arcane_multi_preserve_color.pt": "1enJgrC08NpWpx2XGBmLt1laimjpGCyfl",
"arcane_multi.pt": "15V9s09sgaw-zhKp116VHigf5FowAy43f",
"sketch_multi.pt": "1GdaeHGBGjBAFsWipTL0y-ssUiAqk8AxD",
"disney.pt": "1zbE2upakFUAx8ximYnLofFwfT8MilqJA",
"disney_preserve_color.pt": "1Bnh02DjfvN_Wm8c4JdOiNV4q9J7Z_tsi",
"jojo.pt": "13cR2xjIBj8Ga5jMO7gtxzIJj2PDsBYK4",
"jojo_preserve_color.pt": "1ZRwYLRytCEKi__eT2Zxv1IlV6BGVQ_K2",
"jojo_yasuho.pt": "1grZT3Gz1DLzFoJchAmoj3LoM9ew9ROX_",
"jojo_yasuho_preserve_color.pt": "1SKBu1h0iRNyeKBnya_3BBmLr4pkPeg_L",
"art.pt": "1a0QDEHwXQ6hE_FcYEyNMuv5r5UnRQLKT",
}
# from StyelGAN-NADA
class Downloader(object):
def __init__(self, use_pydrive):
self.use_pydrive = use_pydrive
if self.use_pydrive:
self.authenticate()
def authenticate(self):
auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
self.drive = GoogleDrive(gauth)
def download_file(self, file_name):
file_dst = os.path.join('models', file_name)
file_id = drive_ids[file_name]
if not os.path.exists(file_dst):
print(f'Downloading {file_name}')
if self.use_pydrive:
downloaded = self.drive.CreateFile({'id':file_id})
downloaded.FetchMetadata(fetch_all=True)
downloaded.GetContentFile(file_dst)
else:
!gdown --id $file_id -O $file_dst
downloader = Downloader(download_with_pydrive)
downloader.download_file('stylegan2-ffhq-config-f.pt')
downloader.download_file('e4e_ffhq_encode.pt')
加載生成器
加載原始和微調生成器。設置用于調整圖像大小和規(guī)范化圖像的 transforms。
latent_dim = 512
# Load original generator
original_generator = Generator(1024, latent_dim, 8, 2).to(device)
ckpt = torch.load('models/stylegan2-ffhq-config-f.pt', map_location=lambda storage, loc: storage)
original_generator.load_state_dict(ckpt["g_ema"], strict=False)
mean_latent = original_generator.mean_latent(10000)
# to be finetuned generator
generator = deepcopy(original_generator)
transform = transforms.Compose(
[
transforms.Resize((1024, 1024)),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
]
)
輸入圖像
設置輸入圖像位置。對齊和裁剪面并重新設置映射的樣式。
#image to the test_input directory and put the name here
filename = 'face.jpeg' #@param {type:"string"}
filepath = f'test_input/{filename}'
name = strip_path_extension(filepath)+'.pt'
# aligns and crops face
aligned_face = align_face(filepath)
# my_w = restyle_projection(aligned_face, name, device, n_iters=1).unsqueeze(0)
my_w = projection(aligned_face, name, device).unsqueeze(0)
預訓練圖
選擇預訓練好的圖類型,選擇不保留顏色的檢查點,效果更好。
plt.rcParams['figure.dpi'] = 150
pretrained = 'sketch_multi' #['art', 'arcane_multi', 'sketch_multi', 'arcane_jinx', 'arcane_caitlyn', 'jojo_yasuho', 'jojo', 'disney']
#Preserve color tries to preserve color of original image by limiting family of allowable transformations.
if preserve_color:
ckpt = f'{pretrained}_preserve_color.pt'
else:
ckpt = f'{pretrained}.pt'
生成結果
加載檢查點和生成器并設置種子值,然后開始生成風格化圖像。用于 Elon Musk 的輸入圖像將根據圖類型進行風格化。
#Generate results
n_sample = 5#{type:"number"}
seed = 3000 #{type:"number"}
torch.manual_seed(seed)
with torch.no_grad():
generator.eval()
z = torch.randn(n_sample, latent_dim, device=device)
original_sample = original_generator([z], truncation=0.7, truncation_latent=mean_latent)
sample = generator([z], truncation=0.7, truncation_latent=mean_latent)
original_my_sample = original_generator(my_w, input_is_latent=True)
my_sample = generator(my_w, input_is_latent=True)
# display reference images
if pretrained == 'arcane_multi':
style_path = f'style_images_aligned/arcane_jinx.png'
elif pretrained == 'sketch_multi':
style_path = f'style_images_aligned/sketch.png'
else:
style_path = f'style_images_aligned/{pretrained}.png'
style_image = transform(Image.open(style_path)).unsqueeze(0).to(device)
face = transform(aligned_face).unsqueeze(0).to(device)
my_output = torch.cat([style_image, face, my_sample], 0)
生成的結果
結果生成為預先訓練的類型“Jojo”,看起來相當準確。
現在讓我們看一下在自創(chuàng)樣式上訓練 GAN。
使用你的風格圖像進行訓練
選擇一些面部圖,甚至創(chuàng)建一些自己的面部圖并加載這些圖像以訓練 GAN,并設置路徑。裁剪和對齊人臉并執(zhí)行 GAN 反轉。
names = ['1.jpg', '2.jpg', '3.jpg']
targets = []
latents = []
for name in names:
style_path = os.path.join('style_images', name)
assert os.path.exists(style_path), f"{style_path} does not exist!"
name = strip_path_extension(name)
# crop and align the face
style_aligned_path = os.path.join('style_images_aligned', f'{name}.png')
if not os.path.exists(style_aligned_path):
style_aligned = align_face(style_path)
style_aligned.save(style_aligned_path)
else:
style_aligned = Image.open(style_aligned_path).convert('RGB')
# GAN invert
style_code_path = os.path.join('inversion_codes', f'{name}.pt')
if not os.path.exists(style_code_path):
latent = projection(style_aligned, style_code_path, device)
else:
latent = torch.load(style_code_path)['latent']
latents.append(latent.to(device))
targets = torch.stack(targets, 0)
latents = torch.stack(latents, 0)
微調 StyleGAN
通過調整 alpha、顏色保留和設置迭代次數來微調 StyleGAN。加載感知損失的鑒別器并重置生成器。
#Finetune StyleGAN
#alpha controls the strength of the style
alpha = 1.0 # min:0, max:1, step:0.1
alpha = 1-alpha
#preserve color of original image by limiting family of allowable transformations
preserve_color = False
#Number of finetuning steps.
num_iter = 300
#Log training on wandb and interval for image logging
use_wandb = False
log_interval = 50
if use_wandb:
wandb.init(project="JoJoGAN")
config = wandb.config
config.num_iter = num_iter
config.preserve_color = preserve_color
wandb.log(
{"Style reference": [wandb.Image(transforms.ToPILImage()(target_im))]},
step=0)
# load discriminator for perceptual loss
discriminator = Discriminator(1024, 2).eval().to(device)
ckpt = torch.load('models/stylegan2-ffhq-config-f.pt', map_location=lambda storage, loc: storage)
discriminator.load_state_dict(ckpt["d"], strict=False)
# reset generator
del generator
generator = deepcopy(original_generator)
g_optim = optim.Adam(generator.parameters(), lr=2e-3, betas=(0, 0.99))
訓練生成器從潛在空間生成圖像,并優(yōu)化損失。
if preserve_color:
id_swap = [9,11,15,16,17]
z = range(numiter)
for idx in tqdm( z):
mean_w = generator.get_latent(torch.randn([latents.size(0), latent_dim]).to(device)).unsqueeze(1).repeat(1, generator.n_latent, 1)
in_latent = latents.clone()
in_latent[:, id_swap] = alpha*latents[:, id_swap] + (1-alpha*mean_w[:, id_swap]
img = generator(in_latent, input_is_latent=True)
with torch.no_grad():
real_feat = discriminator(targets)
fake_feat = discriminator(img)
loss = sum([functional.l1_loss(a, b) for a, b in zip(fake_feat, real_feat)])/len(fake_feat)
if use_wandb:
wandb.log({"loss": loss}, step=idx)
if idx % log_interval == 0:
generator.eval()
my_sample = generator(my_w, input_is_latent=True)
generator.train()
wandb.log(
{"Current stylization": [wandb.Image(my_sample)]},
step=idx)
g_optim.zero_grad()
loss.backward()
g_optim.step()
使用 JojoGAN 生成結果
現在生成結果。下面已經為原始圖像和示例圖像生成了結果以進行比較。
#Generate resultsn_sample = 5
seed = 3000
torch.manual_seed(seed)
with torch.no_grad():
generator.eval()
z = torch.randn(n_sample, latent_dim, device=device)
original_sample = original_generator([z], truncation=0.7, truncation_latent=mean_latent)
sample = generator([z], truncation=0.7, truncation_latent=mean_latent)
original_my_sample = original_generator(my_w, input_is_latent=True)
my_sample = generator(my_w, input_is_latent=True)
# display reference images
style_images = []
for name in names:
style_path = f'style_images_aligned/{strip_path_extension(name)}.png'
style_image = transform(Image.open(style_path))
style_images.append(style_image)
face = transform(aligned_face).to(device).unsqueeze(0)
style_images = torch.stack(style_images, 0).to(device)
my_output = torch.cat([face, my_sample], 0)
output = torch.cat([original_sample, sample], 0)
生成的結果
現在,你可以使用 JojoGAN 生成你自己風格的圖像。結果令人印象深刻,但可以通過調整訓練方法和訓練圖像中的更多特征來進一步改進。
結論
JojoGAN 能夠以快速有效的方式準確地映射和遷移用戶定義的樣式。關鍵要點是:
· JojoGAN 可以只用一種風格進行訓練,以輕松映射并創(chuàng)建任何面部的風格化圖
· JojoGAN 非?焖儆行,可以在不到一分鐘的時間內完成訓練
· 結果非常準確,類似于逼真的肖像
· JojoGAN 可以輕松微調和修改,使其適用于 AI 應用程序
因此,無論風格類型、形狀和顏色如何,JojoGAN 都是用于風格轉移的理想神經網絡,因此可以成為各種社交媒體應用程序和 AI 應用程序中非常有用的功能。
原文標題 : 使用JojoGAN創(chuàng)建風格化的面部圖

請輸入評論內容...
請輸入評論/評論長度6~500個字
最新活動更多
-
7月8日立即報名>> 【在線會議】英飛凌新一代智能照明方案賦能綠色建筑與工業(yè)互聯
-
7月22-29日立即報名>> 【線下論壇】第三屆安富利汽車生態(tài)圈峰會
-
7.30-8.1火熱報名中>> 全數會2025(第六屆)機器人及智能工廠展
-
7月31日免費預約>> OFweek 2025具身智能機器人產業(yè)技術創(chuàng)新應用論壇
-
免費參會立即報名>> 7月30日- 8月1日 2025全數會工業(yè)芯片與傳感儀表展
-
即日-2025.8.1立即下載>> 《2024智能制造產業(yè)高端化、智能化、綠色化發(fā)展藍皮書》
推薦專題