PyTorch深度学习实战(38)——StyleGAN详解与实现

PyTorch深度学习实战(38)——StyleGAN详解与实现

    • 0. 前言
    • 1. StyleGAN
      • 1.1 模型介绍
      • 1.2 模型策略分析
    • 2. 实现 StyleGAN
      • 2.1 生成图像
      • 2.2 风格迁移
    • 小结
    • 系列链接

0. 前言

StyleGAN (Style-Generative Adversarial Networks) 是生成对抗网络 (Generative Adversarial Networks, GAN) 的变体,是一种无监督学习模型,用于生成逼真且高分辨率的图像。与传统 GAN 不同,StyleGAN 引入了两个关键概念:样式迁移和逐渐增强。样式迁移允许生成网络控制图像的风格和外观,从而生成具有不同特征的图像。逐渐增强则是指生成网络逐层地生成图像,先生成粗略的细节,然后逐渐添加更多细节和结构,从而获得更加逼真的图像。本节中,将利用预训练的 StyleGAN2 模型执行风格迁移。

1. StyleGAN

1.1 模型介绍

相比于传统生成对抗网络 (Generative Adversarial Networks, GAN),StyleGAN 的主要优点在于其能够生成高分辨率的逼真图像,同时可以控制所生成图像的风格。StyleGAN 使用自适应实例规范化 (Adaptive Instance Normalization, AdaIN),可以从输入的噪声向量中学习多个层次的风格信息,并且可以通过调整生成网络的输入来控制所生成图像的风格。
StyleGAN 之前,GAN 面临的最大问题是生成的图像分辨率通常较小(通常为 64 x 64),尝试生成更大尺寸图像会导致生成网络或判别网络陷入局部最小值。ProGAN (Progressive GAN) 通过渐进式逐层增强的方式来生成高分辨率、逼真的图像,从而克服了传统 GAN 在高分辨率图像生成时面临的困难,为高质量图像生成奠定了基础。
具体来说,ProGAN 采用了分层的生成网络结构,每一层都包含一个生成网络和一个判别网络,同时每一层的输出分辨率也相应地增加。在训练过程中,逐渐增加图像的分辨率,直到达到所需的分辨率。这种逐渐增加分辨率的方法,可以使得模型在从低分辨率图像逐渐生成高分辨率图像的过程中逐渐学习更多的图像特征,从而生成更加逼真的图像。通过这种方式,ProGAN 已经能够成功地生成高达 1024x1024 像素的图像,其生成质量和逼真度已经接近甚至超越了人眼的识别限制:

ProGAN 架构
尽管 ProGAN 成功地提高了生成图像的质量,但仍然难以控制生成图像的属性,例如性别和年龄等,主要是因为网络只有一个输入,为了解决这一问题,Tero Karras 等人提出了 StyleGAN
StyleGAN 使用与 ProGAN 类似的训练方案,逐步生成图像,但每次网络增加时都会添加一组新的潜在输入,即网络在获得所需尺寸的图像前会接受多个潜在向量。在生成阶段给出的每个潜在向量都决定了在该网络阶段将生成的特征(图像风格):

StyleGAN 架构
在上图中,我们可以看到传统的图像生成方式与基于风格的生成网络之间的差别。在传统的生成网络中,只有一个输入;但基于风格的生成网络中采用以下机制:

  • 创建一个大小为 1 x 512 的随机噪声向量 z z z
  • 将其输入到风格网络(或映射网络)的辅助网络中,该网络创建大小为 18 x 512 的张量 w w w
  • 生成(合成)网络包含 18 个卷积层,每一层都将接受以下内容作为输入:
    • w ( A ) w(A) w(A) 的对应行
    • 随机噪声向量 ( B ) (B) (B)
    • 上一层的输出

其中,噪声 ( B ) (B) (B) 仅用于正则化。

以上三个组合将创建一个管道,该管道接收一个 1 x 512 向量并创建一个 1024 x 1024 图像。映射网络能够生成 18 x 512 向量,其中每个 1 x 512 向量(共 18 个)都能够图像的生成作出贡献。输入合成网络前几层的 1 x 512 向量(负责生成 4 x 48 x 8 的图像)有助于得到图像的整体姿态和大尺度特征(如姿势、面部形状等),并且会在后面几层得到增强;添加到中间层的向量(负责生成 16 x 1632 x 3264 x 64 图像)对应于小尺度特征,例如发型、睁眼或闭眼等;添加到最后几层的向量对应于图像的颜色方案和其他微观结构,在最后几层时,图像结构被保留,面部特征也被保留,只有图像级别的细节,例如光照条件等会发生变化。

1.2 模型策略分析

在本节中,我们将利用预训练的 StyleGAN2 模型执行风格迁移,以生成具有不同风格的图像,模型策略原理如下所示:

  • 假设 w 1 w_1 w1 风格向量用于生成 face-1,而 w 2 w_2 w2 风格向量用于生成 face-2,样式向量的形状都为 18 x 512
  • w 2 w_2 w2 中的前几个向量(负责生成从 4 x 48 x 8 分辨率的图像)被替换为来自 w 1 w_1 w1 的相应向量,这样我们就可以将低级特征(如面部姿态)从 face-1 迁移到 face-2
  • 如果 w 2 w_2 w2 的中间的风格向量(比如第 315——负责生成 64 x 64256 x 256 分辨率的图像)被替换为 w 1 w_1 w1 中的风格向量,则可以迁移例如眼睛、鼻子等其他中级特征
  • 如果最后几个风格向量(负责生成 512 x 5121024 x 1024 分辨率的图像)被替换,则肤色和背景等精细特征将会(不会显着影响面部整体特征)被迁移

了解了风格迁移的策略后,现在让我们了解如何使用 StyleGAN2 在自定义图像上执行风格迁移:

  • 获取图像
  • 对齐图像,以便存储图像中的面部区域
  • 获取对齐图像的潜在向量
  • 通过将随机潜在向量 (1 x 512) 传递到映射网络生成图像

通过以上过程,得到两个图像:对齐图像和 StyleGAN2 网络生成的图像,然后将对齐图像的一些特征迁移到 StyleGAN2 网络生成的图像中。

2. 实现 StyleGAN

接下来,我们使用 PyTorch 实现以上策略,为了节省训练时间,从 gitcode 中获取预训练网络,下载后解压缩。

2.1 生成图像

(1) 获取预训练网络权重:

from pytorch_stylegan_encoder.InterFaceGAN.models.stylegan_generator import StyleGANGenerator
from pytorch_stylegan_encoder.models.latent_optimizer import PostSynthesisProcessing
import torch
import numpy as np
from matplotlib import pyplot as plt
from glob import glob
import cv2synthesizer = StyleGANGenerator("stylegan_ffhq").model.synthesis
mapper = StyleGANGenerator("stylegan_ffhq").model.mapping
trunc = StyleGANGenerator("stylegan_ffhq").model.truncation

(2) 加载预训练的生成网络、合成网络和映射网络的权重:

post_processing = PostSynthesisProcessing()
post_process = lambda image: post_processing(image).detach().cpu().numpy().astype(np.uint8)[0]

(3) 定义函数根据随机向量生成图像:

def latent2image(latent):img = post_process(synthesizer(latent))img = img.transpose(1,2,0)return img

(4) 生成随机向量:

rand_latents = torch.randn(1,512).cuda()

在以上代码中,通过映射网络传递随机的 1 x 512 维向量以生成 1 x 18 x 512 维向量,生成的 18 x 512 维向量决定了生成图像的风格。

(5) 根据随机向量生成图像:

plt.imshow(latent2image(trunc(mapper(rand_latents))))
plt.show()

生成图像

2.2 风格迁移

接下来,我们将学习如何在以上生成图像和其他选择图像之间执行风格迁移,首先从 gitcode 中获取用于人脸对齐的程序并解压缩。

(1) 获取测试图像 (MyImage.jpg) 并将其对齐,对齐对于生成合适的潜在向量非常重要,因为 StyleGAN 生成的所有图像都以人脸为中心且特征明显,在 shell 中执行以下命令对齐测试图像:

$ mkdir -p stylegan-encoder/raw_images
$ mkdir -p stylegan-encoder/aligned_images
$ mv MyImage.jpg stylegan-encoder/raw_images
$ python stylegan-encoder/align_images.py stylegan-encoder/raw_images/ stylegan-encoder/aligned_images/
$ mv stylegan-encoder/aligned_images/* ./MyImage.jpg

(2) 查看对齐后的测试图像

from PIL import Image
img = Image.open('MyImage.jpg')plt.imshow(np.array(img))
plt.title('original')
plt.show()

查看测试图像

(3) 使用对齐图像生成潜在向量,这是一个识别潜在向量组合的过程,该组合使对齐图像与根据潜在向量生成的图像之间的差异最小化。

首先,在 shell 中执行以下命令:

$ python encode_image.py MyImage.jpg pred_dlatents_image.npy --use_latent_finder true --image_to_latent_path ../trained_models/image_to_latent.pt

encode_image.py 程序执行以下操作:

  • 在潜在空间中创建一个随机向量 w w w
  • 使用随机向量 w w w 生成图像
  • 使用 VGG 感知损失(与神经风格迁移中的损失相同)将生成图像与原始输入图像进行比较
  • 对随机向量 w w w 执行反向传播,减少损失
  • 优化后的 w w w 向量将生成一张 VGG 特征与输入图像几乎相同的图像,因此合成图像看起来与输入图像相似。

然后,继续编写代码:

pred_dlatents = np.load('pred_dlatents_image.npy')
pred_dlatent = torch.from_numpy(pred_dlatents).float().cuda()
pred_image = latent2image(pred_dlatent)
plt.imshow(pred_image)
plt.title('synthesized')
plt.show()

风格迁移结果

得到了与感兴趣图像相对应的潜在向量后,执行图像风格迁移。

(4) 执行风格迁移。

风格迁移的核心逻辑实际上是风格张量的部分迁移,即 18 x 512 风格张量中的 18 个子集。接下来,我们分别传输前两行、 3-15 行、15-18 行;由于每组向量负责生成图像的不同方面,因此每组交换的向量会交换图像中的不同特征:

idxs_to_swap = slice(0,3)
my_latents = torch.Tensor(np.load('pred_dlatents_image.npy', allow_pickle=True))A, B = latent2image(my_latents.cuda()), latent2image(trunc(mapper(rand_latents)))
generated_image_latents = trunc(mapper(rand_latents))x = my_latents.clone()
x[:,idxs_to_swap] = generated_image_latents[:,idxs_to_swap]
a = latent2image(x.float().cuda())x = generated_image_latents.clone()
x[:,idxs_to_swap] = my_latents[:,idxs_to_swap]
b = latent2image(x.float().cuda())
plt.subplot(221)
plt.imshow(A)
plt.subplot(222)
plt.imshow(a)
plt.subplot(223)
plt.imshow(B)
plt.subplot(224)
plt.imshow(b)
plt.suptitle('Transfer high level features')
plt.show()

请添加图片描述

idxs_to_swap 分别作为 slice(4,15)slice (15,18) 的输出如下:

slice(4,15)

slice (15,18)

(5) 接下来,我们需要推导一组风格向量,新向量仅改变测试图像的笑脸。为此,需要计算沿潜在向量z移动的正确方向。我们可以通过首先创建大量伪造图像来实现这一点,然后训练 SVM 分类器判断图像中的人物是否微笑,该 SVM 将创建一个超平面,划分笑脸与非笑脸,潜在向量 z z z 所需的移动方向将垂直于这个超平面,在 shell 中执行以下命令:

python InterFaceGAN/edit.py -m stylegan_ffhq -o results_new_smile -b InterFaceGAN/boundaries/stylegan_ffhq_smile_w_boundary.npy -i pred_dlatents_image.npy -s WP --steps 20

可视化生成图像:

generated_faces = glob('results_new_smile/*.jpg')cols = len(generated_faces)
ix = 1
for im in sorted(generated_faces):plt.subplot(1, cols, ix)plt.imshow(cv2.cvtColor(cv2.imread(im,1), cv2.COLOR_BGR2RGB))ix += 1
plt.show()

小结

StyleGAN 能够生成非常高分辨率人脸图像的关键在于,在增加分辨率的步骤中逐步增加生成网络和判别网络的复杂性,以便在每一步中,两个模型都可以很好地完成任务。我们学习了如何通过确保每个分辨率的特征由一个独立的输入(称为风格向量)来控制,从而操纵生成图像的风格,以及如何通过将图像之间的风格进行交换来操作不同图像的风格。

系列链接

PyTorch深度学习实战(1)——神经网络与模型训练过程详解
PyTorch深度学习实战(2)——PyTorch基础
PyTorch深度学习实战(3)——使用PyTorch构建神经网络
PyTorch深度学习实战(4)——常用激活函数和损失函数详解
PyTorch深度学习实战(5)——计算机视觉基础
PyTorch深度学习实战(6)——神经网络性能优化技术
PyTorch深度学习实战(7)——批大小对神经网络训练的影响
PyTorch深度学习实战(8)——批归一化
PyTorch深度学习实战(9)——学习率优化
PyTorch深度学习实战(10)——过拟合及其解决方法
PyTorch深度学习实战(11)——卷积神经网络
PyTorch深度学习实战(12)——数据增强
PyTorch深度学习实战(13)——可视化神经网络中间层输出
PyTorch深度学习实战(14)——类激活图
PyTorch深度学习实战(15)——迁移学习
PyTorch深度学习实战(16)——面部关键点检测
PyTorch深度学习实战(17)——多任务学习
PyTorch深度学习实战(18)——目标检测基础
PyTorch深度学习实战(19)——从零开始实现R-CNN目标检测
PyTorch深度学习实战(20)——从零开始实现Fast R-CNN目标检测
PyTorch深度学习实战(21)——从零开始实现Faster R-CNN目标检测
PyTorch深度学习实战(22)——从零开始实现YOLO目标检测
PyTorch深度学习实战(23)——从零开始实现SSD目标检测
PyTorch深度学习实战(24)——使用U-Net架构进行图像分割
PyTorch深度学习实战(25)——从零开始实现Mask R-CNN实例分割
PyTorch深度学习实战(26)——多对象实例分割
PyTorch深度学习实战(27)——自编码器(Autoencoder)
PyTorch深度学习实战(28)——卷积自编码器(Convolutional Autoencoder)
PyTorch深度学习实战(29)——变分自编码器(Variational Autoencoder, VAE)
PyTorch深度学习实战(30)——对抗攻击(Adversarial Attack)
PyTorch深度学习实战(31)——神经风格迁移
PyTorch深度学习实战(32)——Deepfakes
PyTorch深度学习实战(33)——生成对抗网络(Generative Adversarial Network, GAN)
PyTorch深度学习实战(34)——DCGAN详解与实现
PyTorch深度学习实战(35)——条件生成对抗网络(Conditional Generative Adversarial Network, CGAN)
PyTorch深度学习实战(36)——Pix2Pix详解与实现
PyTorch深度学习实战(37)——CycleGAN详解与实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/721190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手搓反激电源 | 五、反激高频变压器的设计与计算

手搓反激电源 | 五、反激高频变压器的设计与计算 先上干货,变压器设计规格书 千里之行,积于跬步,万里之船,成于罗盘 A journey of thousands of miles accumulates in steps, and the ship of thousands of miles becomes a compass 反激式变换操作 反激式变换器的…

基于springboot的教师工作量管理系统论文

教师工作量管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了教师工作量管理系统的开发全过程。通过分析教师工作量管理系统管理的不足,创建了一个计算机管理教师工作量管理系统的方案。文章…

Ambari动态给YARN分配计算节点

1.前言 YARN可用的计算节点数量并不总是等于 Hadoop集群节点数量,可以根据业务需求分配 YARN计算节点数量。 这里首先介绍一些前置知识: YARN中 ResourceManager 和 NodeManager是两个核心组件,其中 ResourceManager负责集群资源的统一管理…

C++模拟揭秘刘谦魔术,领略数学的魅力

新的一年又开始了,大家新年好呀~。在这我想问大家一个问题,有没有同学看了联欢晚会上刘谦的魔术呢? 这个节目还挺有意思的,它最出彩的不是魔术本身,而是小尼老师“念错咒语”而导致他手里的排没有拼在一起,…

BUUCTF------[HCTF 2018]WarmUp

开局一个表情&#xff0c;源代码发现source.php <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["source">"source.php","hint">"hint.php"];if (! isset($page) |…

06_netdev网卡设备内核模块

01_basicLinux内核模块-CSDN博客文章浏览阅读315次&#xff0c;点赞3次&#xff0c;收藏3次。环境IDubuntuMakefilemodules:clean:basic.creturn 0;运行效果。https://blog.csdn.net/m0_37132481/article/details/136157384my_netdev.c #include <linux/kernel.h> #incl…

基于springboot的大学生就业招聘系统的设计与实现论文

大学生就业招聘系统的设计与实现 摘要 随着信息互联网信息的飞速发展&#xff0c;大学生就业成为一个难题&#xff0c;好多公司都舍不得培养人才&#xff0c;只想要一专多能之人才&#xff0c;不愿是承担社会的责任&#xff0c;针对这个问题开发一个专门适应大学生就业招聘的网…

大部分人只有在工作几年后才知道什么是程序员

在大学 大学时期的我们&#xff0c;有几个从大一就开始好好学习&#xff0c;立志考研的&#xff1f;大多数人都只是在“享受大学生活”&#xff0c;就连选择计算机专业都是别人推荐的&#xff0c;根本不知道将来毕业会干啥。在我们的印象中&#xff0c;程序员就是一个模糊的名…

QT----写完的程序打包为APK在自己的手机上运行

目录 1、qt安装android组件2、打开qt配置Android 环境3、手机打开开发者模式&#xff0c;打开usb调试&#xff0c;连接电脑4、运行代码 1、qt安装android组件 qtcreater–工具-QTMaintenaceTool-startMaintenaceTool—登陆—添加或修改组件—找到android&#xff0c;安装 若是…

深入探讨 AutoGPT:彻底改变游戏的自主 AI

原文地址&#xff1a;Deep Dive into AutoGPT: The Autonomous AI Revolutionizing the Game 2023 年 4 月 24 日 AutoGPT 是一个功能强大的工具&#xff0c;它通过 API 使用 GPT-4 和 GPT-3.5&#xff0c;通过将项目分解为子任务并在自动循环中使用互联网和其他工具来创建完…

Python高光谱遥感数据处理与机器学习

通过高光谱矿物识别&#xff0c;木材含水量提取、土壤有机碳评估等案例&#xff0c;提供可借鉴的高光谱应用领域的技术服务方案&#xff0c;结合Python科学计算、可视化、数据处理与机器学习等开源开发库&#xff0c;深入介绍高光谱技术的应用功能开发。 高光谱遥感信息对于我…

C++11线程同步之条件变量

C11线程同步之条件变量 condition_variable成员函数生产者和消费者模型 condition_variable_any成员函数生产者和消费者模型 条件变量是C11提供的另外一种用于 等待的同步机制&#xff0c;它能阻塞一个或多个线程&#xff0c;直到收到另外一个线程发出的通知或者超时时&#x…

springboot+xjar加密打包部署教程

需求背景 为了跟上时代的步伐&#xff0c;为了更好的生存。开个玩笑&#xff0c;就是心血来潮&#xff0c;使用xjar加密部署jar包&#xff0c;于是就测试一下。 xjar教程 1-maven配置文件修改 首先找到自己ideal配置的maven文件夹&#xff0c;然后找到apache-maven-3.9.3\co…

vue修改打包后静态资源路径的修改

不得不说&#xff0c;ai是真的强大&#xff0c;直接自己生成。

消息队列-Kafka-基础架构

基础架构 官网地址 上面这张图类比RocketMQ 相当于对一个主题进行了分区&#xff08;类似于RockeMQ 消息队列&#xff09;&#xff0c;每个分区存储到不同的Broker。在发送消息的时候都是发送到主分区。如果一台Broker由于其它节点备份了挂掉节点的数据&#xff0c;所以可以…

世界的本质是旋转(6)-在复平面上借助软件无线电SDR解调BPSK波形

在上一篇文章中&#xff0c;已经完成了BPSK波形的发射。 相对于BPSK波形的生成总共就4行代码&#xff0c;接收要略微复杂一些&#xff0c;算上各种同步、锁相环&#xff0c;约80行。完整版参考Git仓库。 设备连接&#xff1a; #mermaid-svg-aMmvYQSgMzU6Gepf {font-family:&q…

探索Python编程世界:从入门到精通

一.Python 从入门到精通 随着计算机科学的发展&#xff0c;编程已经成为了一种必备的技能。而 Python 作为一种简单易学、功能强大的编程语言&#xff0c;越来越受到人们的喜爱。本文将为初学者介绍 Python 编程的基础知识&#xff0c;帮助他们踏入 Python 编程的大门&#xf…

Linux 驱动 中断(二)

中断下半部 在 Linux 内核中&#xff0c;中断下半部&#xff08;也称为中断下半场&#xff09;是指在中断服务程序&#xff08;Top Half&#xff09;执行完毕后&#xff0c;在上下文之外延迟执行的一些操作。中断下半部通常用于处理那些不适合在中断上下文中立即执行的任务&am…

O2OA(翱途)移动端如何查看系统日志?

O2OA(翱途)移动端如何查看系统日志&#xff1f; 一、进入APP移动端应用&#xff0c;点击右下角“设置” 二、点击“系统日志”&#xff0c;如下图所示 点开日志列表即可查看。

关于 CTF 中 php 考点与绕过那些事的总结

关于 CTF 中常见 php 绕过的总结可以参考我之前的博客&#xff1a; CTF之PHP特性与绕过 PHP特性之CTF中常见的PHP绕过-CSDN博客 其中主要介绍了 md5()、sha1()、strcmp、switch、intval、$_SERVER 函数、三元运算符、strpos() 、数组、非法参数名传参等相关的绕过。 在此基础上…