JoJoGAN: One Shot Face Stylization. 只用一张人脸图片,就能学习其风格,然后迁移到其他图片。训练时长只用 1~2 min 即可。

效果:

主流程:

本文分享了个人在本地环境(非 colab)实践 JoJoGAN 的整个过程。你也可以依照本文上手训练自己喜欢的风格。

准备环境

安装:

conda create -n torch python=3.9 -y
conda activate torch conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch -y

检查:

$ python - <<EOF
import torch, torchvision
print(torch.__version__, torch.cuda.is_available())
EOF
1.10.1 True

准备代码

git clone https://github.com/mchong6/JoJoGAN.git
cd JoJoGAN pip install tqdm gdown matplotlib scipy opencv-python dlib lpips wandb # Ninja is required to load C++ extensions
wget https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-linux.zip
sudo unzip ninja-linux.zip -d /usr/local/bin/
sudo update-alternatives --install /usr/bin/ninja ninja /usr/local/bin/ninja 1 --force

然后,将本文提供的几个 *.py 放进 JoJoGAN 目录,从这里获取: https://github.com/ikuokuo/start-deep-learning/tree/master/practice/JoJoGAN

  • download_models.py: 获取模型
  • generate_faces.py: 生成人脸
  • stylize.py: 风格化
  • train.py: 训练

之后,于训练流程一节,会结合代码,讲述下 JoJoGAN 的工作流程。其他些 *.py 只提下用法,实现就不多说了。

获取模型

python download_models.py 获取模型,如下:

models/
├── arcane_caitlyn_preserve_color.pt
├── arcane_caitlyn.pt
├── arcane_jinx_preserve_color.pt
├── arcane_jinx.pt
├── arcane_multi_preserve_color.pt
├── arcane_multi.pt
├── art.pt
├── disney_preserve_color.pt
├── disney.pt
├── dlibshape_predictor_68_face_landmarks.dat
├── e4e_ffhq_encode.pt
├── jojo_preserve_color.pt
├── jojo.pt
├── jojo_yasuho_preserve_color.pt
├── jojo_yasuho.pt
├── restyle_psp_ffhq_encode.pt
├── stylegan2-ffhq-config-f.pt
├── supergirl_preserve_color.pt
└── supergirl.pt

生成人脸

用 StyleGAN2 预训练模型随机生成人脸,用于测试:

python generate_faces.py -n 5 -s 2000 -o input

使用预训练风格

JoJoGAN 给了 8 个预训练模型,可以一并体验,与文首的效果图一样:

# 预览 JoJoGAN 所有预训练模型 风格化某图片(test_input/iu.jpeg)的效果
python stylize.py -i test_input/iu.jpeg -s all --save-all --show-all # 使用 JoJoGAN 所有预训练模型 风格化所有生成的测试人脸(input/*)
find ./input -type f -print0 | xargs -0 -i python stylize.py -i {} -s all --save-all

训练自己的风格

首先,准备一张风格图:

之后,开始训练:

python train.py -n yinshi -i style_images/yinshi.jpeg --alpha 1.0 --num_iter 500 --latent_dim 512 --use_wandb --log_interval 50

--use_wandb 时,可查看训练日志:

最后,测试效果:

python stylize.py -i input/girl.jpeg --save-all --show-all --test_style yinshi --test_ckpt output/yinshi.pt --test_ref output/yinshi/style_images_aligned/yinshi.png

训练工作流程

准备风格图片,转为训练数据

将风格图片里的人脸裁减对齐:

# dlib 预测人脸特征点,再裁减对齐
from util import align_face
style_aligned = align_face(img_path)

将风格图片 GAN Inversion 逆映射回预训练模型的隐向量空间(Latent Space):

name, _ = os.path.splitext(os.path.basename(img_path))
style_code_path = os.path.join(latent_dir, f'{name}.pt') # e4e FFHQ encoder (pSp) > GAN inversion,得到 latent
from e4e_projection import projection
latent = projection(style_aligned, style_code_path, device)

载入 StyleGAN2 模型,训练微调

载入预训练模型:

latent_dim = 512

# 加载预训练模型
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) # 准备微调的模型
generator = deepcopy(original_generator)

训练可调参数:

# 控制风格强度 [0, 1]
alpha = 1.0
alpha = 1-alpha # 是否保留原图像色彩
preserve_color = True # 训练迭代次数(最好 500,Adam 学习率是基于 500 次迭代调优的)
num_iter = 500 # 风格图片 targets 及 latents
targets = ..
latents = ..

进行训练,拟合隐空间。最后保存:

# 准备 LPIPS 计算 loss
lpips_fn = lpips.LPIPS(net='vgg').to(device) # 准备优化器
g_optim = torch.optim.Adam(generator.parameters(), lr=2e-3, betas=(0, 0.99)) # 哪些层用于交换,用于生成风格化图片
if preserve_color:
id_swap = [7,9,11,15,16,17]
else:
id_swap = list(range(7, generator.n_latent)) # 训练迭代
for idx in tqdm(range(num_iter)):
# 交换层混合风格,并加噪声
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] # 以 latent 风格化图片,与目标风格对比
img = generator(in_latent, input_is_latent=True)
loss = lpips_fn(F.interpolate(img, size=(256,256), mode='area'),
F.interpolate(targets, size=(256,256), mode='area')).mean() # 优化
g_optim.zero_grad()
loss.backward()
g_optim.step() # 保存权重,完成
torch.save({"g": generator.state_dict()}, save_path)

结语

JoJoGAN 实践下来效果不错。使用本文给到的代码,更容易上手训练自己喜欢的风格,值得试试。

JoJoGAN 实践的更多相关文章

  1. webp图片实践之路

    最近,我们在项目中实践了webp图片,并且抽离出了工具模块,整合到了项目的基础模板中.传闻IOS10也将要支持webp,那么使用webp带来的性能提升将更加明显.估计在不久的将来,webp会成为标配. ...

  2. Hangfire项目实践分享

    Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(De ...

  3. TDD在Unity3D游戏项目开发中的实践

    0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...

  4. Logstash实践: 分布式系统的日志监控

    文/赵杰 2015.11.04 1. 前言 服务端日志你有多重视? 我们没有日志 有日志,但基本不去控制需要输出的内容 经常微调日志,只输出我们想看和有用的 经常监控日志,一方面帮助日志微调,一方面及 ...

  5. 【大型网站技术实践】初级篇:借助Nginx搭建反向代理服务器

    一.反向代理:Web服务器的“经纪人” 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从 ...

  6. Windows平台分布式架构实践 - 负载均衡

    概述 最近.NET的世界开始闹腾了,微软官方终于加入到了对.NET跨平台的支持,并且在不久的将来,我们在VS里面写的代码可能就可以通过Mono直接在Linux和Mac上运行.那么大家(开发者和企业)为 ...

  7. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  8. Mysql事务探索及其在Django中的实践(一)

    前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...

  9. netty5 HTTP协议栈浅析与实践

      一.说在前面的话 前段时间,工作上需要做一个针对视频质量的统计分析系统,各端(PC端.移动端和 WEB端)将视频质量数据放在一个 HTTP 请求中上报到服务器,服务器对数据进行解析.分拣后从不同的 ...

随机推荐

  1. 第四十九个知识点:描述在IPsec和TLS后的基本想法

    第四十九个知识点:描述在IPsec和TLS后的基本想法 网络安全协议(Internet Protocol Security,IPsec)和安全传输层协议(Transport Layer Securit ...

  2. 第三十五个知识点:给针对ECDLP问题的Pollard rho,Pollard "Kangaroo",parallel Pollard rho攻击的一个粗略的描述

    第三十五个知识点:给针对ECDLP问题的Pollard rho,Pollard "Kangaroo",parallel Pollard rho攻击的一个粗略的描述 我们的目标是对任 ...

  3. The Hessian Penalty: A Weak Prior for Unsupervised Disentanglement

    目录 概 主要内容 标量情况 向量情况 处于实际(计算量)的考量 应用到生成模型中 代码 Pebbles W., Pebbles J., Zhu J., Efros A., Torralba A. T ...

  4. CS5211替代CH7511B|设计DP转LVDS转接板|替代CH7511B

    CH7511B是一款DP转lvds屏转换芯片CH7511B是一款eDP转LVDS转换芯片.CH7511B将嵌入式DisplayPort信号转换为LVDS(低压差分信号).通过CH7511B的高级解码/ ...

  5. 查看电脑内存是ddr3还是ddr4

    内存不够用了 要加个内存 但是不想拆机 怎么知道自己电脑是第几代内存呢? 怎么知道频率呢? 1.运行cmd 2.输入wmic回车 3.输入memorychip回车 4.往右拉找到Speed Statu ...

  6. vue3+TypeScript+vue-router使用

    简单使用 创建项目 vue-cli创建 $npm install -g @vue/cli $vue --version @vue/cli 4.5.15 $vue create my-project 然 ...

  7. GitForWindows工具集(GitBash命令行)

    1.Git For Windows工具集 Git For Windows专注于提供一套轻量级的本地工具集, 它将Git SCM的完整功能集引入Windows, 同时为Git用户提供适当的用户界面, 方 ...

  8. Microsoft HoloLens 开发(3): 全息图交互方式 - Gaze

    Gaze(凝视) 是 HoloLens 交互输入的第一种形式,告诉你 用户 在世界上的位置,并让你确定他们的意图. 1.Gaze的用途 作为一个 Mixed Reality 开发者,Gaze 可以做很 ...

  9. linux tomcat【9.0.12】 使用 ssl证书 配置 https 的具体操作 【使用 域名 】

    1.前言 根据上一个随笔,已经可以正式在 阿里云服务器发布 工程了 ,但是用的协议默认是 http ,端口80 但是 http不安全 ,容易被拦截抓包 ,于是出来了个 https tomcat发布 对 ...

  10. linux VI命令快捷键

    ctrl+f  下一页 ctrl+b 上一页 ctrl+u 上半页 ctrl+d 下半页 数字+空格键 根据当前光标移动多少个字母 0键 光标移动到第一个字母,是当前行的 $键 光标移动到最后一个字母 ...