目录

在Notebook中设置基础

数据集创建和拆分

创建和训练自动编码器

在Keras中交换编码器和解码器


  • 下载项目文件 - 75.5 MB

深度伪造——使用深度学习在视频中将一个人的脸换成另一个人的脸——是当今使用人工智能的最有趣最可怕的方式之一。

虽然深度伪造可用于合法目的,但它们也可用于虚假信息。能够轻松地将某人的脸换成任何视频,我们真的可以相信我们的眼睛告诉我们的吗?政治家或演员做或说令人震惊的事情的真实视频可能根本不是真实的。

在本系列文章中,我们将展示深度伪造的工作原理,并展示如何从头开始实现它们。然后我们将看看DeepFaceLab,它是一种多合一的Tensorflow驱动的工具,通常用于创建令人信服的深度伪造。

在上一篇文章中,我们通过将四个视频转换为两个面集来预处理我们的数据。在本文中,我们将构建将使用人脸集合的自动编码器。对于我来说,我从一开始就在开发Kaggle Notebook,所以我将使用之前的Notebook的输出作为我现在要使用的这个的输入。我将使用此Notebook来调整模型的超参数,但实际的繁重训练将在下一个主题中运行,我们将使用Docker容器在Google AI 平台上训练我们的模型。

如果您不知道如何使用以前的notebook的输出作为新notebook的输入,只需创建一个新notebook,然后单击右上角的“添加数据”按钮:

单击“Notebook输出文件”,然后单击“您的数据集”:

最后,单击要导入的输出文件旁边的“添加”:

如果您在本地运行此项目,您将使用保存在results_1results_2文件夹中的图像。导入所需的数据后,让我们进入实际代码!

在Notebook中设置基础

让我们从导入所需的库开始:

import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
import cv2
from tensorflow.keras.models import load_model
from sklearn.model_selection import train_test_split
import keras
from keras import layers
from tensorflow.keras.callbacks import ModelCheckpoint
import tensorflow as tf

现在让我们加载我们将要使用的人脸集合并拆分它们以开始训练。

数据集创建和拆分

让我们创建一个函数,以我们的模型可以理解的形状加载数据。为此,我将创建一个函数来帮助我们完成此任务:

def create_dataset(path):images = []for dirname, _, filenames in os.walk(path):for filename in filenames:image = cv2.imread(os.path.join(dirname, filename))image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)image = image.astype('float32')image /= 255.0images.append(image)images = np.array(images)
return images

本质上,此函数将相应文件夹中的每个图像作为整数数组读取,将颜色通道从BGR校正为RGB,将数组数据类型转换为浮点数,并将其标准化以将值置于0和1之间的范围内,而不是0和255。这将有助于我们未来的模型更容易收敛。

要调用该函数并开始加载数据,请运行:

faces_1 = create_dataset('/kaggle/input/presidentsfacesdataset/trump/')
faces_2 = create_dataset('/kaggle/input/presidentsfacesdataset/biden/')

现在终于准备好拆分我们的数据集了:

X_train_a, X_test_a, y_train_a, y_test_a = train_test_split(faces_1, faces_1, test_size=0.20, random_state=0)
X_train_b, X_test_b, y_train_b, y_test_b = train_test_split(faces_2, faces_2, test_size=0.15, random_state=0)

创建和训练自动编码器

我们已经到了这个系列的核心!您可能还记得,我们需要创建和训练两个自动编码器,然后交换它们的元素以获得将为我们进行面部变换的结果模型。我们将使用Keras Functional API来构建我们的模型。

发出以下命令来创建编码器结构:

input_img = layers.Input(shape=(120, 120, 3))
x = layers.Conv2D(256,kernel_size=5, strides=2, padding='same',activation='relu')(input_img)
x = layers.MaxPooling2D((2, 2), padding='same')(x)
x = layers.Conv2D(512,kernel_size=5, strides=2, padding='same',activation='relu')(x)
x = layers.MaxPooling2D((2, 2), padding='same')(x)
x = layers.Conv2D(1024,kernel_size=5, strides=2, padding='same',activation='relu')(x)
x = layers.MaxPooling2D((2, 2), padding='same')(x)
x = layers.Flatten()(x)
x = layers.Dense(9216)(x)
encoded = layers.Reshape((3,3,1024))(x)
encoder = keras.Model(input_img, encoded,name="encoder")

仔细看上面的代码。解码器的第一个Conv2D层需要具有与其最后一个输入深度相同数量的过滤器,因此我们强制该模型输出形状为(3,3,1024)的张量。这样,解码器可以从第一个Conv2D层中的1024个过滤器开始。这个模型的最后一个MaxPooling层输出一个多维张量,所以我们用Flatten使它变平,最后用Dense和Reshape层强制它成为形状(3,3,1024)。在最后一行中,我们定义了这个模型的输入和输出,并为其命名。让我们创建解码器结构:

decoder_input= layers.Input(shape=((3,3,1024)))
x = layers.Conv2D(1024,kernel_size=5, strides=2, padding='same',activation='relu')(decoder_input)
x = layers.UpSampling2D((2, 2))(x)
x = layers.Conv2D(512,kernel_size=5, strides=2, padding='same',activation='relu')(x)
x = layers.UpSampling2D((2, 2))(x)
x = layers.Conv2D(256,kernel_size=5, strides=2, padding='same',activation='relu')(x)
x = layers.Flatten()(x)
x = layers.Dense(np.prod((120, 120, 3)))(x)
decoded = layers.Reshape((120, 120, 3))(x)
decoder = keras.Model(decoder_input, decoded,name="decoder")

在这段代码中,有一个不寻常的层:UpSampling2D。如果在编码器中我们想降低输入图像的维数并使用MaxPooling2D层来获取其潜在表示,我们将需要一种方法来恢复此维数以在解码器的末尾获取输入图像。

为了实现这一点,我们实现了一个UpSampling层来为我们完成这项任务。本质上,它以最简单的方式进行上采样:将每一行和每一列加倍。例如,如果我们将数组[[1,2],[3,4]]传递给这一层,那么输出将是[[1,1,2,2],[1,1,2,2] ,[3,3,4,4],[3,3,4,4]]。如果你算一下,解码器的输入形状是(3,3,1024),输出是(120,120,3),这是原始输入图像的维度。

最后,要编译带有两个元素的自动编码器,请发出以下命令:

auto_input = layers.Input(shape=(120,120,3))
encoded = encoder(auto_input)
decoded = decoder(encoded)autoencoder = keras.Model(auto_input, decoded,name="autoencoder")
autoencoder.compile(optimizer=keras.optimizers.Adam(lr=5e-5, beta_1=0.5, beta_2=0.999), loss='mae')
autoencoder.summary()
Model: "autoencoder"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_3 (InputLayer)         [(None, 120, 120, 3)]     0
_________________________________________________________________
encoder (Functional)         (None, 3, 3, 1024)        54162944
_________________________________________________________________
decoder (Functional)         (None, 120, 120, 3)       86880192
=================================================================
Total params: 141,043,136
Trainable params: 141,043,136
Non-trainable params: 0
_________________________________________________________________

请注意,我们有大量模型参数需要从头开始训练,这意味着此过程肯定需要数小时甚至数天,因此请准备好等待。我使用Adam作为优化器,使用MAE(平均误差)作为要减少的损失(因为这个任务可以建模为回归)。

模型创建已完成。是时候开始训练srcdst自动编码器了。为此,您可以像训练常规深度学习模型一样使用fit方法。在这种特殊情况下,我会用ModelCheckpoint实现从Keras保存在训练中取得的最好模式。要开始src训练,请发出以下命令:

checkpoint1 = ModelCheckpoint("/kaggle/working/autoencoder_a.hdf5", monitor='val_loss', verbose=1,save_best_only=True, mode='auto', period=1)
history1 = autoencoder.fit(X_train_a, X_train_a, epochs=2700, batch_size=512, shuffle=True, validation_data=(X_test_a, X_test_a), callbacks=[checkpoint1])

我在这个notebook中训练了2700个epochs,但是为了获得可接受的结果,你应该训练这个模型至少20000次迭代。在过程结束时,模型获得0.01926的损失, 如果您训练更长的时间,损失可能会更低。为了让您了解所实现的指标有多好,让我们绘制一个参考及其各自的重建图:

%matplotlib inline
plt.figure()
plt.imshow(X_test_a[30])
plt.show()

加载训练期间获得的最佳模型并绘制相应的图像重建:

autoencoder_a = load_model("/kaggle/working/autoencoder_a.hdf5")
output_image = autoencoder_a.predict(np.array([X_test_a[30]]))
plt.figure()
plt.imshow(output_image[0])
plt.show()

还不错吧?这是一张随机选择的图像,尽管看起来不错,但损失仍然很高。这意味着这次重建的高质量是幸运的。当损失很高时,我们通常不会期望如此好的结果,我们不应该指望它。话虽如此,让我们开始dst训练:

checkpoint2 = ModelCheckpoint("/kaggle/working/autoencoder_b.hdf5", monitor='val_loss', verbose=1,save_best_only=True, mode='auto', period=1)
history2 = autoencoder.fit(X_train_b, X_train_b,epochs=2700,batch_size=512,shuffle=True,validation_data=(X_test_b, X_test_b),callbacks=[checkpoint2])

在训练结束时,最好的自动编码器模型获得了0.02634的损失,略高于src的损失。请记住,尽管此人脸集合较小。为了让我们了解它重建图像的效果,让我们运行:

plt.figure()
plt.imshow(X_test_b[0])
plt.show()

autoencoder_b = load_model("/kaggle/working/autoencoder_b.hdf5")
output_image = autoencoder_b.predict(np.array([X_test_b[0]]))
plt.figure()
plt.imshow(output_image[0])
plt.show()

正如我在之前的自动编码器中所说的,仅仅因为这种重建看起来不错并不意味着它们都会这样。实际上,由于此损失更高,因此此自动编码器的性能比前一个更差。如果我们需要减少损失,一个好的方法是用更多的帧来增加这人脸集合,使用数据增强或训练更多的epochs。

在Keras中交换编码器和解码器

现在我们已经训练了我们的自动编码器,是时候交换它们的部分了。如果我们想获得带有src面部手势的dst脸,那么我们需要将src编码器和dst解码器放在一起。如果我们需要相反的情况,那么我们需要将dst编码器与src解码器结合起来。让我们来看看代码:

# TO LOAD ONLY THE ENCODER A
encoder_a = keras.Model(autoencoder_a.layers[1].input, autoencoder_a.layers[1].output)
# TO LOAD ONLY THE DECODER A
decoder_a = keras.Model(autoencoder_a.layers[2].input, autoencoder_a.layers[2].output)
# TO LOAD ONLY THE ENCODER B
encoder_b = keras.Model(autoencoder_b.layers[1].input, autoencoder_b.layers[1].output)
# TO LOAD ONLY THE DECODER B
decoder_b = keras.Model(autoencoder_b.layers[2].input, autoencoder_b.layers[2].output)# TO TRANSFORM SRC IMAGES
input_test = encoder_a.predict(np.array([X_test_a[30]]))
output_test = decoder_b.predict(input_test)# TO TRANSFORM DST IMAGES
input_test = encoder_b.predict(np.array([X_test_b[30]]))
output_test = decoder_a.predict(input_test)

output_test 是转换后的图像。

有了这个,你刚刚完成了最困难的部分。看你的下一篇文章中,我将在其中跳跃到如何在谷歌AI平台训练你的模型之前,提供关于Docker容器的简要介绍。

https://www.codeproject.com/Articles/5298025/Building-and-Training-Deep-Fake-Autoencoders

(五)构建和训练深度伪造自动编码器相关推荐

  1. (七)准备在云中训练深度伪造模型

    目录 检查先决条件 在本地计算机上设置所有内容 创建提交训练作业所需的局部变量 创建项目所需的Bucket 下载项目文件 - 75.5 MB 深度伪造--使用深度学习在视频中将一个人的脸换成另一个人的 ...

  2. 【火炉炼AI】深度学习003-构建并训练深度神经网络模型

    [火炉炼AI]深度学习003-构建并训练深度神经网络模型 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotl ...

  3. (三)使用自动编码器进行深度伪造

    目录 应用于深度伪造的卷积自编码器 下载项目文件 - 75.5 MB 深度伪造--使用深度学习在视频中将一个人的脸换成另一个人的脸--是当今使用人工智能的最有趣和最可怕的方式之一. 虽然深度伪造可用于 ...

  4. pytorch深度学习和入门实战(四)神经网络的构建和训练

    目录 1.前言 2.神经网络概述 2.1 核心组件包括: 2.2 核心过程 3.构建神经网络模型 3.1构建网络层(Layer ➨ Model) 3.2 torch.nn.Sequential的3大使 ...

  5. 【金融】【pytorch】使用深度学习预测期货收盘价涨跌——全连接神经网络模型构建与训练

    [金融][pytorch]使用深度学习预测期货收盘价涨跌--全连接神经网络模型构建与训练 模型构建与训练 模型构建与训练 def get_accuracy(SR,GT,threshold=0.5):S ...

  6. 【金融】【pytorch】使用深度学习预测期货收盘价涨跌——LSTM模型构建与训练

    [金融][pytorch]使用深度学习预测期货收盘价涨跌--LSTM模型构建与训练 LSTM 创建模型 模型训练 查看指标 LSTM 创建模型 指标函数参考<如何用keras/tf/pytorc ...

  7. (十)DeepFaceLab:预包装的DIY深度伪造替代品

    目录 准备输入数据和设置笔记本 初始化Notebook并安装依赖项 数据集导入 从原始视频中提取和去噪帧 人脸检测 可选:排序和增强Facesets 模型训练 合并结果帧 获取结果视频:深度伪造 下载 ...

  8. (四)为深度伪造预处理数据集

    目录 在Notebook上设置基础 提取视频帧 人脸检测和提取 下载项目文件 - 75.5 MB 深度伪造--使用深度学习在视频中将一个人的脸换成另一个人的脸--是当今使用人工智能的最有趣和最可怕的方 ...

  9. (二)生成深度伪造的方法

    目录 自编码器概述 DeepFaceLab概述 换脸概述 下载项目文件 - 75.5 MB 深度伪造--使用深度学习在视频中将一个人的脸换成另一个人的脸--是当今使用人工智能的最有趣和最可怕的方式之一 ...

最新文章

  1. vs2015 python 调试dll
  2. android学习日记16--GridView(网格视图)
  3. [CTF][Web][PHP][JavaScript]弱类型问题
  4. 【牛客 - 370E】Rinne Loves Gift(Bellman_Ford判负环,二分,分数规划)
  5. [转]链接中 href='#' 和 href='###' 的区别以及优缺点
  6. 5)Thymeleaf 模板布局 th:fragment、th:replace、th:insert、th:remove
  7. 【粉丝福利】Logo评选投票,礼品赠送!
  8. Eclipse代码自动生成
  9. HTML5基础网页设计(加代码CSS)
  10. libiec61850探究【1】-第一个MMS通讯实例
  11. idea回到上一个光标位置
  12. web端 小米商城网站总结
  13. 如何利用今日头条推荐规则, 打造阅读量100万+的爆款文章?
  14. L3级自动驾驶接管实验测试平台及其应用研究
  15. Centos7安装网易云播放器
  16. 【java类型转换】
  17. 阿里巴巴的零知识证明
  18. Who wann invitation of gmail, wallop, orkut?
  19. 接盘恒大、清债,自救的华远地产能度过地产寒冬吗?
  20. 绝望而沉重的爱·《致我们终将逝去的青春》

热门文章

  1. python语言pos_Python自然语言处理(二)--NLTK调用Stanford_NLP_Tools完成NLP任务
  2. c语言 信号函数,C语言中进程信号集的相关操作函数详解
  3. php教程 二叉树,PHP ClassObject -- PHP 自排序二叉树的深入解析
  4. 无限极业绩_2019中国保健品行业典型企业分析——无限极、康宝莱、汤臣倍健...
  5. 规划系统_智慧水务规划系统思维的设计思考
  6. u盘在磁盘管理可以显示 但是电脑中找不到_关于U盘你不知道的一些知识
  7. 国潮中国风工作学习总结学习PPT模板
  8. 智慧城市发展未来PSD分层海报模板|科技突破你的想象!
  9. 电商促销类插画素材,适合各种活动banner设计
  10. sonar覆盖率怎么统计的_实战|Java 测试覆盖率 Jacoco插桩的不同形式总结和踩坑记录(上)...