生成对抗网络项目:1~5(2)

简介: 生成对抗网络项目:1~5(2)

生成对抗网络项目:1~5(1)https://developer.aliyun.com/article/1426892

3D-GAN 的 Keras 实现

在本节中,我们将在 Keras 框架中实现生成器网络和判别器网络。 我们需要创建两个 Keras 模型。 这两个网络都有各自独立的权重值。 让我们从生成器网络开始。

生成器网络

为了实现生成器网络,我们需要创建 Keras 模型并添加神经网络层。 实现生成器网络所需的步骤如下:

  1. 首先为不同的超参数指定值:
z_size = 200 gen_filters = [512, 256, 128, 64, 1]
gen_kernel_sizes = [4, 4, 4, 4, 4]
gen_strides = [1, 2, 2, 2, 2]
gen_input_shape = (1, 1, 1, z_size)
gen_activations = ['relu', 'relu', 'relu', 'relu', 'sigmoid']
gen_convolutional_blocks = 5
  1. 接下来,创建一个输入层,以允许网络进行输入。 生成器网络的输入是从概率潜在空间中采样的向量:
input_layer = Input(shape=gen_input_shape)
  1. 然后,添加第一个 3D 转置卷积(或 3D 解卷积)块,如以下代码所示:
# First 3D transpose convolution( or 3D deconvolution) block a = Deconv3D(filters=gen_filters[0],  
 kernel_size=gen_kernel_sizes[0],
             strides=gen_strides[0])(input_layer)
a = BatchNormalization()(a, training=True)
a = Activation(activation=gen_activations[0])(a)
  1. 接下来,再添加四个 3D 转置卷积(或 3D 解卷积)块,如下所示:
# Next 4 3D transpose convolution( or 3D deconvolution) blocks for i in range(gen_convolutional_blocks - 1):
    a = Deconv3D(filters=gen_filters[i + 1], 
 kernel_size=gen_kernel_sizes[i + 1],
                 strides=gen_strides[i + 1], padding='same')(a)
    a = BatchNormalization()(a, training=True)
    a = Activation(activation=gen_activations[i + 1])(a)
  1. 然后,创建 Keras 模型并指定生成器网络的输入和输出:
model = Model(inputs=input_layer, outputs=a)
  1. 将生成器网络的整个代码包装在一个名为build_generator()的函数内:
def build_generator():
 """
 Create a Generator Model with hyperparameters values defined as follows  :return: Generator network
 """  z_size = 200
  gen_filters = [512, 256, 128, 64, 1]
 gen_kernel_sizes = [4, 4, 4, 4, 4]
 gen_strides = [1, 2, 2, 2, 2]
 gen_input_shape = (1, 1, 1, z_size)
 gen_activations = ['relu', 'relu', 'relu', 'relu', 'sigmoid']
 gen_convolutional_blocks = 5    input_layer = Input(shape=gen_input_shape)
 # First 3D transpose convolution(or 3D deconvolution) block
  a = Deconv3D(filters=gen_filters[0], 
 kernel_size=gen_kernel_sizes[0],
 strides=gen_strides[0])(input_layer)
 a = BatchNormalization()(a, training=True)
 a = Activation(activation='relu')(a)
 # Next 4 3D transpose convolution(or 3D deconvolution) blocks
  for i in range(gen_convolutional_blocks - 1):
 a = Deconv3D(filters=gen_filters[i + 1], 
 kernel_size=gen_kernel_sizes[i + 1],
 strides=gen_strides[i + 1], padding='same')(a)
 a = BatchNormalization()(a, training=True)
 a = Activation(activation=gen_activations[i + 1])(a)
 gen_model = Model(inputs=input_layer, outputs=a)
 gen_model.summary()
 return gen_model

我们已经成功地为生成器网络创建了 Keras 模型。 接下来,为判别器网络创建 Keras 模型。

判别器网络

同样,要实现判别器网络,我们需要创建 Keras 模型并向其中添加神经网络层。 实现判别器网络所需的步骤如下:

  1. 首先为不同的超参数指定值:
dis_input_shape = (64, 64, 64, 1)
dis_filters = [64, 128, 256, 512, 1]
dis_kernel_sizes = [4, 4, 4, 4, 4]
dis_strides = [2, 2, 2, 2, 1]
dis_paddings = ['same', 'same', 'same', 'same', 'valid']
dis_alphas = [0.2, 0.2, 0.2, 0.2, 0.2]
dis_activations = ['leaky_relu', 'leaky_relu', 'leaky_relu', 'leaky_relu', 'sigmoid']
dis_convolutional_blocks = 5
  1. 接下来,创建一个输入层,以允许网络进行输入。 判别器网络的输入是形状为 64x64x64x1的 3D 图像:
dis_input_layer = Input(shape=dis_input_shape)
  1. 然后,添加第一个 3D 卷积块,如下所示:
# The first 3D Convolution block a = Conv3D(filters=dis_filters[0],
           kernel_size=dis_kernel_sizes[0],
           strides=dis_strides[0],
           padding=dis_paddings[0])(dis_input_layer)
a = BatchNormalization()(a, training=True)
a = LeakyReLU(alphas[0])(a)
  1. 之后,再添加四个 3D 卷积块,如下所示:
# The next 4 3D Convolutional Blocks for i in range(dis_convolutional_blocks - 1):
    a = Conv3D(filters=dis_filters[i + 1],
               kernel_size=dis_kernel_sizes[i + 1],
               strides=dis_strides[i + 1],
               padding=dis_paddings[i + 1])(a)
    a = BatchNormalization()(a, training=True)
    if dis_activations[i + 1] == 'leaky_relu':
        a = LeakyReLU(dis_alphas[i + 1])(a)
    elif dis_activations[i + 1] == 'sigmoid':
        a = Activation(activation='sigmoid')(a)
  1. 接下来,创建一个 Keras 模型,并为判别器网络指定输入和输出:
dis_model = Model(inputs=dis_input_layer, outputs=a)
  1. 将判别器网络的完整代码包装在一个函数中,如下所示:
def build_discriminator():
    """
 Create a Discriminator Model using hyperparameters values defined as follows  :return: Discriminator network
 """    dis_input_shape = (64, 64, 64, 1)
    dis_filters = [64, 128, 256, 512, 1]
    dis_kernel_sizes = [4, 4, 4, 4, 4]
    dis_strides = [2, 2, 2, 2, 1]
    dis_paddings = ['same', 'same', 'same', 'same', 'valid']
    dis_alphas = [0.2, 0.2, 0.2, 0.2, 0.2]
    dis_activations = ['leaky_relu', 'leaky_relu', 'leaky_relu', 
 'leaky_relu', 'sigmoid']
    dis_convolutional_blocks = 5    dis_input_layer = Input(shape=dis_input_shape)
    # The first 3D Convolutional block
  a = Conv3D(filters=dis_filters[0],
               kernel_size=dis_kernel_sizes[0],
               strides=dis_strides[0],
               padding=dis_paddings[0])(dis_input_layer)
    a = BatchNormalization()(a, training=True)
    a = LeakyReLU(dis_alphas[0])(a)
    # Next 4 3D Convolutional Blocks
  for i in range(dis_convolutional_blocks - 1):
        a = Conv3D(filters=dis_filters[i + 1],
                   kernel_size=dis_kernel_sizes[i + 1],
                   strides=dis_strides[i + 1],
                   padding=dis_paddings[i + 1])(a)
        a = BatchNormalization()(a, training=True)
        if dis_activations[i + 1] == 'leaky_relu':
            a = LeakyReLU(dis_alphas[i + 1])(a)
        elif dis_activations[i + 1] == 'sigmoid':
            a = Activation(activation='sigmoid')(a)
    dis_model = Model(inputs=dis_input_layer, outputs=a)
    print(dis_model.summary())
 return dis_model

在本节中,我们为判别器网络创建了 Keras 模型。 我们现在准备训练 3D-GAN。

训练 3D-GAN

训练 3D-GAN 类似于训练朴素 GAN。 我们首先在生成的图像和真实图像上训练判别器网络,但是冻结生成器网络。 然后,我们训练生成器网络,但冻结判别器网络。 我们对指定的周期数重复此过程。 在一次迭代中,我们按顺序训练两个网络。 训练 3D-GAN 是一个端到端的训练过程。 让我们一步一步地进行这些步骤。

训练网络

要训练 3D-GAN,请执行以下步骤:

  1. 首先指定训练所需的不同超参数的值,如下所示:
gen_learning_rate = 0.0025 dis_learning_rate = 0.00001
beta = 0.5
batch_size = 32
z_size = 200
DIR_PATH = 'Path to the 3DShapenets dataset directory'
generated_volumes_dir = 'generated_volumes'
log_dir = 'logs'
  1. 接下来,创建并编译两个网络,如下所示:
# Create instances
generator = build_generator()
discriminator = build_discriminator()
# Specify optimizer 
gen_optimizer = Adam(lr=gen_learning_rate, beta_1=beta)
dis_optimizer = Adam(lr=dis_learning_rate, beta_1=0.9)
# Compile networks
generator.compile(loss="binary_crossentropy", optimizer="adam")
discriminator.compile(loss='binary_crossentropy', optimizer=dis_optimizer)

我们正在使用Adam优化器作为优化算法,并使用binary_crossentropy作为损失函数。 在第一步中指定Adam优化器的超参数值。

  1. 然后,创建并编译对抗模型:
discriminator.trainable = False adversarial_model = Sequential()
adversarial_model.add(generator)
adversarial_model.add(discriminator)  adversarial_model.compile(loss="binary_crossentropy", optimizer=Adam(lr=gen_learning_rate, beta_1=beta))
  1. 之后,提取并加载所有airplane图像以进行训练:
def getVoxelsFromMat(path, cube_len=64):
    voxels = io.loadmat(path)['instance']   voxels = np.pad(voxels, (1, 1), 'constant', constant_values=(0, 0))   if cube_len != 32 and cube_len == 64:
        voxels = nd.zoom(voxels, (2, 2, 2), mode='constant', order=0)   return voxels
 def get3ImagesForACategory(obj='airplane', train=True, cube_len=64, obj_ratio=1.0):
    obj_path = DIR_PATH + obj + '/30/'
  obj_path += 'train/' if train else 'test/'
  fileList = [f for f in os.listdir(obj_path) if f.endswith('.mat')]
    fileList = fileList[0:int(obj_ratio * len(fileList))]
    volumeBatch = np.asarray([getVoxelsFromMat(obj_path + f, cube_len) for f in fileList], dtype=np.bool)
    return volumeBatch
volumes = get3ImagesForACategory(obj='airplane', train=True, obj_ratio=1.0)
volumes = volumes[..., np.newaxis].astype(np.float)
  1. 接下来,添加TensorBoard回调并添加generatordiscriminator网络:
tensorboard = TensorBoard(log_dir="{}/{}".format(log_dir, time.time()))
tensorboard.set_model(generator)
tensorboard.set_model(discriminator)
  1. 添加一个循环,该循环将运行指定的周期数:
for epoch in range(epochs):
    print("Epoch:", epoch)
    # Create two lists to store losses
    gen_losses = []
    dis_losses = []
  1. 在第一个循环中添加另一个循环以运行指定的批量数量:
number_of_batches = int(volumes.shape[0] / batch_size)
    print("Number of batches:", number_of_batches)
    for index in range(number_of_batches):
        print("Batch:", index + 1)
  1. 接下来,从一组真实图像中采样一批图像,并从高斯正态分布中采样一批噪声向量。 噪声向量的形状应为(1, 1, 1, 200)
z_sample = np.random.normal(0, 0.33, size=[batch_size, 1, 1, 1, 
                            z_size]).astype(np.float32)
volumes_batch = volumes[index * batch_size:(index + 1) * batch_size, 
                        :, :, :]
  1. 使用生成器网络生成伪造图像。 向其传递z_sample的一批噪声向量,并生成一批假图像:
gen_volumes = generator.predict(z_sample,verbose=3)
  1. 接下来,在由生成器生成的伪图像和一组真实图像中的一批真实图像上训练判别器网络。 另外,使判别器易于训练:
# Make the discriminator network trainable discriminator.trainable = True
# Create fake and real labels
labels_real = np.reshape([1] * batch_size, (-1, 1, 1, 1, 1))
labels_fake = np.reshape([0] * batch_size, (-1, 1, 1, 1, 1))
# Train the discriminator network
loss_real = discriminator.train_on_batch(volumes_batch, 
                                         labels_real)
loss_fake = discriminator.train_on_batch(gen_volumes, 
                                         labels_fake)
# Calculate total discriminator loss
d_loss = 0.5 * (loss_real + loss_fake)

前面的代码训练了判别器网络并计算了总的判别器损失。

  1. 训练同时包含generatordiscriminator网络的对抗模型:
z = np.random.normal(0, 0.33, size=[batch_size, 1, 1, 1, z_size]).astype(np.float32)
 # Train the adversarial model        g_loss = adversarial_model.train_on_batch(z, np.reshape([1] * batch_size, (-1, 1, 1, 1, 1)))

另外,将损失添加到其各自的列表中,如下所示:

gen_losses.append(g_loss)
        dis_losses.append(d_loss)
  1. 每隔一个周期生成并保存 3D 图像:
if index % 10 == 0:
            z_sample2 = np.random.normal(0, 0.33, size=[batch_size, 1, 1, 1, z_size]).astype(np.float32)
            generated_volumes = generator.predict(z_sample2, verbose=3)
            for i, generated_volume in enumerate(generated_volumes[:5]):
                voxels = np.squeeze(generated_volume)
                voxels[voxels < 0.5] = 0.
  voxels[voxels >= 0.5] = 1.
  saveFromVoxels(voxels, "results/img_{}_{}_{}".format(epoch, index, i))
  1. 在每个周期之后,将平均损失保存到tensorboard
# Save losses to Tensorboard write_log(tensorboard, 'g_loss', np.mean(gen_losses), epoch)
write_log(tensorboard, 'd_loss', np.mean(dis_losses), epoch)

我的建议是将其训练 100 个周期,以查找代码中的问题。 解决了这些问题后,您就可以在 100,000 个周期内训练网络。

保存模型

训练完成后,通过添加以下代码来保存生成器和判别器模型的学习权重:

""" Save models """ generator.save_weights(os.path.join(generated_volumes_dir, "generator_weights.h5"))
discriminator.save_weights(os.path.join(generated_volumes_dir, "discriminator_weights.h5"))

测试模型

要测试网络,请创建generatordiscriminator网络。 然后,加载学习的权重。 最后,使用predict()方法生成预测:

# Create models generator = build_generator()
discriminator = build_discriminator()
# Load model weights generator.load_weights(os.path.join(generated_volumes_dir, "generator_weights.h5"), True)
discriminator.load_weights(os.path.join(generated_volumes_dir, "discriminator_weights.h5"), True)
# Generate 3D images z_sample = np.random.normal(0, 0.33, size=[batch_size, 1, 1, 1, z_size]).astype(np.float32)
generated_volumes = generator.predict(z_sample, verbose=3)

在本节中,我们成功地训练了 3D-GAN 的生成器和识别器。 在下一节中,我们将探讨超参数调整和各种超参数优化选项。

可视化损失

要可视化训练的损失,请按如下所示启动tensorboard服务器。

tensorboard --logdir=logs

现在,在浏览器中打开 localhost:6006 。 TensorBoard 的标量部分包含两种损失的图表:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r8BSrgMU-1681652801317)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/gan-proj/img/b67a8b95-a1fe-4c06-be44-cec497dd35bf.png)]

生成器网络的损失图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ak0QeZM6-1681652801318)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/gan-proj/img/7937c970-9e91-4f47-bc05-2b230ae1b0c6.png)]

判别器网络的损失图

这些图将帮助您决定是继续还是停止训练。 如果损失不再减少,您就可以停止训练,因为没有改善的机会。 如果损失持续增加,则必须停止训练。 尝试使用超参数,然后选择一组您认为可能会提供更好结果的超参数。 如果损失逐渐减少,请继续训练模型。

可视化图

TensorBoard 的GRAPHS部分包含两个网络的图 。 如果网络表现不佳,这些图可以帮助您调试网络。 它们还显示了每个图中的张量流和不同的运算:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ik0IBSFg-1681652801318)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/gan-proj/img/411f5f33-a51c-4f61-a795-4fb06231ea00.png)]

超参数优化

我们训练的模型可能不是一个完美的模型,但是我们可以优化超参数来改进它。 3D-GAN 中有许多可以优化的超参数。 其中包括:

  • 批量大小:尝试使用 8、16、32、54 或 128 的批量大小值。
  • 周期数:尝试 100 个周期,并将其逐渐增加到 1,000-5,000。
  • 学习率:这是最重要的超参数。 用 0.1、0.001、0.0001 和其他较小的学习率进行实验。
  • 生成器和判别器网络的不同层中的激活函数:使用 Sigmoid,tanh,ReLU,LeakyReLU,ELU,SeLU 和其他激活函数进行实验。
  • 优化算法:尝试使用 Adam,SGD,Adadelta,RMSProp 和 Keras 框架中可用的其他优化器。
  • 损失函数:二进制交叉熵是最适合 3D-GAN 的损失函数。
  • 两个网络中的层数:根据可用的训练数据量,在网络中尝试不同的层数。 如果您有足够的可用数据来进行训练,则可以使网络更深。

我们还可以通过使用 HyperoptHyperas 选择最佳的超参数集。

3D-GAN 的实际应用

3D-GAN 可以广泛用于各种行业,如下所示:

  • 制造业:3D-GAN 可以是帮助快速创建原型的创新工具。 他们可以提出创意,并可以帮助模拟和可视化 3D 模型。
  • 3D 打印:3D-GAN 生成的 3D 图像可用于在 3D 打印中打印对象。 创建 3D 模型的手动过程非常漫长。
  • 设计过程:3D 生成的模型可以很好地估计特定过程的最终结果。 他们可以向我们展示将要构建的内容。
  • 新样本:与其他 GAN 相似,3D-GAN 可以生成图像来训练监督模型。

总结

在本章中,我们探讨了 3D-GAN。 我们首先介绍了 3D-GAN,并介绍了架构以及生成器和判别器的配置。 然后,我们经历了建立项目所需的不同步骤。 我们还研究了如何准备数据集。 最后,我们在 Keras 框架中实现了 3D-GAN,并在我们的数据集中对其进行了训练。 我们还探讨了不同的超参数选项。 我们通过探索 3D-GAN 的实际应用来结束本章。

在下一章中,我们将学习如何使用条件生成对抗网络cGAN)执行人脸老化。

三、使用条件 GAN 进行人脸老化

条件 GANcGAN)是 GAN 模型的扩展。 它们允许生成具有特定条件或属性的图像,因此被证明比朴素 GAN 更好。 在本章中,我们将实现一个 cGAN,该 cGAN 一旦经过训练,就可以执行自动人脸老化。 Grigory Antipov,Moez Baccouche 和 Jean-Luc Dugelay 在其名为《使用条件生成对抗网络的人脸老化》的论文中,首先介绍了我们将要实现的 cGAN 网络。 可以在以下链接中找到

在本章中,我们将介绍以下主题:

  • 介绍用于人脸老化的 cGAN
  • 建立项目
  • 准备数据
  • cGAN 的 Keras 实现
  • 训练 cGAN
  • 评估和超参数调整
  • 人脸老化的实际应用

介绍用于人脸老化的 cGAN

到目前为止,我们已经针对不同的用例实现了不同的 GAN 网络。 条件 GAN 扩展了普通 GAN 的概念,并允许我们控制生成器网络的输出。 人脸老化就是在不更改身份的情况下更改一个人的人脸年龄。 在大多数其他模型(包括 GAN)中,由于不考虑人脸表情和人脸配件(例如太阳镜或胡须),因此会使人的外观或身份损失 50%。 Age-cGAN 会考虑所有这些属性。 在本节中,我们将探索用于人脸老化的 cGAN。

了解 cGAN

cGAN 是 GAN 的一种,它取决于一些额外的信息。 我们将额外的y信息作为额外的输入层提供给生成器。 在朴素 GAN 中,无法控制所生成图像的类别。 当我们向生成器添加条件y时,我们可以使用y生成特定类别的图像,该图像可以是任何类型的数据,例如类标签或整数数据 。朴素 GAN 只能学习一个类别,而为多个类别构造 GAN 则非常困难。 但是,可以使用 cGAN 生成针对不同类别具有不同条件的多模式模型。

下图显示了 cGAN 的架构:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yPtm31WZ-1681652801318)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/gan-proj/img/7b4b89cd-9b42-4609-84e2-94086b34ac3a.png)]

cGAN 的训练目标函数可以表示为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TKtYz0Os-1681652801318)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/gan-proj/img/115b5d5f-6623-46dc-bed1-e99a6aa5910c.png)]

此处,G是生成器网络,D是判别器网络。 判别器的损失为log D(x|y), 生成器的损失为log(1 - D(G(z|y)))。 我们可以说G(z|y)在给定zy情况下建模我们数据的分布。 在此,z是从正态分布得出的大小为 100 的先验噪声分布。

Age-cGAN 的架构

用于人脸老化的 cGAN 的架构稍微复杂一些。 Age-cGan 由四个网络组成:编码器,FaceNet,生成器网络和判别器网络。 使用编码器,我们可以利用潜在的向量z[0]来学习输入人脸图像和年龄条件的逆映射。 FaceNet 是人脸识别网络,用于学习输入图像x与重构的图像x_tide之间的差异。 我们有一个生成器网络,该网络使用由人脸图像和条件向量组成的隐藏表示并生成图像。 判别器网络将区分真实图像和伪图像。

cGAN 的问题在于它们无法学习将属性y的输入图像x逆映射到潜向量z的任务。解决此问题的方法是使用编码器网络。 我们可以训练一个编码器网络来近似输入图像x的逆映射。 在本节中,我们将探讨 Age-cGAN 涉及的网络。

编码器网络

编码器网络的主要目标是生成所提供图像的潜向量。 基本上,它会拍摄大小为(64, 64, 3)的图像,并将其转换为 100 维向量。 编码器网络是一个深度卷积神经网络。 网络包含四个卷积块和两个密集层。 每个卷积块包含一个卷积层,一个批标准化层和一个激活函数。 在每个卷积块中,每个卷积层后面都有一个批量归一化层,但第一个卷积层除外。 Age-cGAN 部分的 “Keras 实现”将介绍编码器网络的配置。

生成器网络

生成器的主要目标是生成大小为(64, 64, 3)的图像。 它需要一个 100 维的潜向量和一些额外的信息y和尝试生成逼真的图像。 生成器网络也是一个深层卷积神经网络。 它由密集,上采样和卷积层组成。 它采用两个输入值:噪声向量和条件值。 条件值是提供给网络的附加信息。 对于 Age-cGAN,这就是年龄。 生成器网络的配置将在 Age-cGAN 部分的“Keras 实现”中进行介绍。

判别器网络

判别器网络的主要目标是识别所提供的图像是伪造的还是真实的。 它通过使图像经过一系列下采样层和一些分类层来实现。 换句话说,它可以预测图像是真实的还是伪造的。 像其他网络一样,判别器网络是另一个深度卷积网络。 它包含几个卷积块。 每个卷积块都包含一个卷积层,一个批量归一化层和一个激活函数,除了第一个卷积块之外,它没有批量归一化层。 判别器网络的配置将在 Age-cGAN 部分的“Keras 实现”中进行介绍。

人脸识别网络

人脸识别网络的主要目标是在给定图像中识别人的身份。 对于我们的任务,我们将使用没有完全连接的层的预训练的 Inception-ResNet-2 模型。 Keras 有一个很好的预训练模型库。 出于实验目的,您也可以使用其他网络,例如 Inception 或 ResNet-50。 要了解有关 Inception-ResNet-2 的更多信息,请访问链接。 一旦提供了图像,经过预训练的 Inception-ResNet-2 网络将返回相应的嵌入。 可以通过计算嵌入的欧几里德距离来计算针对真实图像和重建图像的提取的嵌入。 关于年龄识别网络的更多信息将在 Age-cGAN 部分的“Keras 实现”中进行介绍。

Age-cGAN 的阶段

Age-cGAN 具有多个训练阶段。 如上一节所述,Age-cGAN 具有四个网络,并经过三个阶段的训练。 Age-cGAN 的训练包括三个阶段:

  1. 条件 GAN 训练:在此阶段,我们训练生成器网络和判别器网络。
  2. 初始潜在向量近似:在此阶段,我们训练编码器网络。
  3. 潜在向量优化:在此阶段,我们同时优化编码器和生成器网络。

以下屏幕截图显示了 Age-cGAN 的各个阶段:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VneaMWyP-1681652801318)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/gan-proj/img/3019472f-d08b-4fa2-9ea1-071be37bc6bd.png)]

Age-cGAN 的各个阶段,资料来源:使用条件生成对抗网络进行人脸老化

我们将在以下部分介绍 Age- cGAN 的所有阶段。

条件 GAN 的训练

在这个阶段,我们训练生成器网络和判别器网络。 经过训练后,生成器网络可以生成人脸的模糊图像。 此阶段类似于训练朴素 GAN,其中我们同时训练两个网络。

训练目标函数

用于训练 cGAN 的训练目标函数可以表示为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9kUVMlic-1681652801319)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/gan-proj/img/0e7b1187-382e-4584-9c8b-b39c1db1fd91.png)]

训练 cGAN 网络涉及优化函数,ν(θ[G], θ[D])。 训练 cGAN 可以看作是 minimax 游戏,其中同时对生成器和判别器进行训练。 在上式中, θ[G}代表生成器网络的参数,θ[D]代表GD的参数 , log D(x, y)是判别器模型的损失,log(1 - D(G(z|y_tide), y_tide))是生成器模型的损失, P(data)是所有可能的图像的分布。

初始潜在向量近似

初始潜在向量近似是一种近似潜在向量以优化人脸图像重建的方法。 为了近似一个潜在向量,我们有一个编码器网络。 我们在生成的图像和真实图像上训练编码器网络。 训练后,编码器网络将开始从学习到的分布中生成潜在向量。 用于训练编码器网络的训练目标函数是欧几里得距离损失。

潜在向量优化

在潜在向量优化过程中,我们同时优化了编码器网络和生成器网络。 我们用于潜在向量优化的方程式如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JtkLbpdA-1681652801319)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/gan-proj/img/98bda784-ced5-4608-8c1d-38477d40cb8f.png)]

FR是人脸识别网络。 该方程式表明,真实图像和重建图像之间的欧几里得距离应最小。 在此阶段,我们尝试最小化距离以最大程度地保留身份。

设置项目

如果尚未使用所有章节的完整代码克隆存储库,请立即克隆存储库。 克隆的存储库有一个名为Chapter03的目录,其中包含本章的全部代码。 执行以下命令来设置项目:

  1. 首先,导航到父目录,如下所示:
cd Generative-Adversarial-Networks-Projects
  1. 现在,将目录从当前目录更改为 Chapter03
cd Chapter03
  1. 接下来,为该项目创建一个 Python 虚拟环境:
virtualenv venv
virtualenv venv -p python3 # Create a virtual environment using python3 interpreter
virtualenv venv -p python2 # Create a virtual environment using python2 interpreter

我们将为此项目使用此新创建的虚拟环境。 每章都有其自己单独的虚拟环境。

  1. 接下来,激活新创建的虚拟环境:
source venv/bin/activate

激活虚拟环境后,所有其他命令将在此虚拟环境中执行。

  1. 接下来,通过执行以下命令,安装requirements.txt 文件中提供的所有库:
pip install -r requirements.txt

您可以参考 README.md 文件,以获取有关如何设置项目的更多说明。 开发人员经常会遇到依赖关系不匹配的问题。 为每个项目创建一个单独的虚拟环境将解决此问题。

在本节中,我们已成功设置项目并安装了所需的依赖项。 在下一部分中,我们将处理数据集。

准备数据

在本章中,我们将使用Wiki-Cropped数据集,其中包含 64 张以上 328 张不同人脸的图像。 作者还提供了数据集 ,该数据集仅包含已裁剪的人脸,因此我们无需裁剪人脸。

论文《没有人脸标志的单张图像的真实年龄和外表年龄的深度期望》,可在以下网址获得。作者从维基百科抓取了这些图片,并将其用于学术目的。 如果您打算将数据集用于商业目的,请通过以下方式与作者联系:rrothe@vision.ee.ethz.ch

您可以从以下链接手动下载数据集,并将所有压缩文件放置在 Age-cGAN 项目内的目录中。

执行以下步骤以下载和提取数据集。

下载数据集

要下载仅包含裁剪的面的数据集,请执行以下命令:

# Before download the dataset move to data directory
cd data
# Wikipedia : Download faces only
wget https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/static/wiki_crop.tar

提取数据集

下载数据集后,手动将文件提取到数据文件夹中,或执行以下命令来提取文件:

# Move to data directory
cd data
# Extract wiki_crop.tar
tar -xvf wiki_crop.tar

wiki_crop.tar文件包含 62,328 张图像和一个包含所有标签的wiki.mat文件。 scipy.io库有一个称为loadmat的方法,这是在 Python 中加载.mat文件的非常方便的方法。 使用以下代码加载提取的.mat文件:

def load_data(wiki_dir, dataset='wiki'):
    # Load the wiki.mat file
  meta = loadmat(os.path.join(wiki_dir, "{}.mat".format(dataset)))
    # Load the list of all files
  full_path = meta[dataset][0, 0]["full_path"][0]
    # List of Matlab serial date numbers
  dob = meta[dataset][0, 0]["dob"][0]
    # List of years when photo was taken
  photo_taken = meta[dataset][0, 0]["photo_taken"][0]  # year   # Calculate age for all dobs  age = [calculate_age(photo_taken[i], dob[i]) for i in range(len(dob))]
    # Create a list of tuples containing a pair of an image path and age
  images = []
    age_list = []
    for index, image_path in enumerate(full_path):
        images.append(image_path[0])
        age_list.append(age[index])
    # Return a list of all images and respective age
  return images, age_list

photo_taken变量是年份列表,dob是 Matlab 列表中相应照片的序列号。 我们可以根据序列号和照片拍摄的年份来计算该人的年龄。 使用以下代码来计算年龄:

def calculate_age(taken, dob):
    birth = datetime.fromordinal(max(int(dob) - 366, 1))
    # assume the photo was taken in the middle of the year
  if birth.month < 7:
        return taken - birth.year
    else:
        return taken - birth.year - 1

现在,我们已经成功下载并提取了数据集。 在下一节中,让我们研究 Age-cGAN 的 Keras 实现。

Age-cGAN 的 Keras 实现

像普通 GAN 一样,cGAN 的实现非常简单。 Keras 提供了足够的灵活性来编码复杂的生成对抗网络。 在本节中,我们将实现 cGAN 中使用的生成器网络,判别器网络和编码器网络。 让我们从实现编码器网络开始。

在开始编写实现之前,创建一个名为 main.py 的 Python 文件,并导入基本模块,如下所示:

import math
import os
import time
from datetime import datetime
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from keras import Input, Model
from keras.applications import InceptionResNetV2
from keras.callbacks import TensorBoard
from keras.layers import Conv2D, Flatten, Dense, BatchNormalization, Reshape, concatenate, LeakyReLU, Lambda, \
    K, Conv2DTranspose, Activation, UpSampling2D, Dropout
from keras.optimizers import Adam
from keras.utils import to_categorical
from keras_preprocessing import image
from scipy.io import loadmat

编码器网络

编码器网络是卷积神经网络CNN),可将图像(x)编码为潜向量(z)或潜在的向量表示。 让我们从在 Keras 框架中实现编码器网络开始。

执行以下步骤来实现编码器网络:

  1. 首先创建一个输入层:
input_layer = Input(shape=(64, 64, 3))
  1. 接下来,添加第一个卷积块,其中包含具有激活函数的 2D 卷积层,具有以下配置:
  • 过滤器32
  • 核大小5
  • 步幅2
  • 填充same
  • 激活LeakyReLU,其中alpha等于0.2
# 1st Convolutional Block enc = Conv2D(filters=32, kernel_size=5, strides=2, padding='same')(input_layer)  enc = LeakyReLU(alpha=0.2)(enc)
  1. 接下来,再添加三个卷积块,其中每个都包含一个 2D 卷积层,然后是一个批量归一化层和一个激活函数,具有以下配置:
  • 过滤器64128256
  • 核大小555
  • 步幅222
  • 填充samesamesame
  • 批量规范化:每个卷积层后面都有一个批量规范化层
  • 激活LealyReLULeakyReLULeakyReLU,其中alpha等于0.2
# 2nd Convolutional Block enc = Conv2D(filters=64, kernel_size=5, strides=2, padding='same')(enc)
enc = BatchNormalization()(enc)
enc = LeakyReLU(alpha=0.2)(enc)
# 3rd Convolutional Block enc = Conv2D(filters=128, kernel_size=5, strides=2, padding='same')(enc)
enc = BatchNormalization()(enc)
enc = LeakyReLU(alpha=0.2)(enc)
# 4th Convolutional Block enc = Conv2D(filters=256, kernel_size=5, strides=2, padding='same')(enc)
enc = BatchNormalization()(enc)
enc = LeakyReLU(alpha=0.2)(enc)
  1. 接下来,将最后一个卷积块的输出展开,如下所示:
# Flatten layer enc = Flatten()(enc)

n维张量转换为一维张量(数组)称为“扁平化”。

  1. 接下来,添加具有以下配置的密集(完全连接)层,批量规范化层和激活函数:
  • 单元(节点):2,096
  • 批量规范化:是
  • 激活LeakyReLU,其中alpha等于0.2
# 1st Fully Connected Layer enc = Dense(4096)(enc)
enc = BatchNormalization()(enc)
enc = LeakyReLU(alpha=0.2)(enc)
  1. 接下来,使用以下配置添加第二个密集(完全连接)层:
  • 单元(节点)100
  • 激活:无:
# Second Fully Connected Layer enc = Dense(100)(enc)
  1. 最后,创建 Keras 模型并指定编码器网络的输入和输出:
# Create a model model = Model(inputs=[input_layer], outputs=[enc])

编码器网络的完整代码如下所示:

def build_encoder():
    """
 Encoder Network   :return: Encoder model
 """  input_layer = Input(shape=(64, 64, 3))
    # 1st Convolutional Block
  enc = Conv2D(filters=32, kernel_size=5, strides=2, padding='same')(input_layer)   enc = LeakyReLU(alpha=0.2)(enc)
    # 2nd Convolutional Block
  enc = Conv2D(filters=64, kernel_size=5, strides=2, padding='same')(enc)
    enc = BatchNormalization()(enc)
    enc = LeakyReLU(alpha=0.2)(enc)
    # 3rd Convolutional Block
  enc = Conv2D(filters=128, kernel_size=5, strides=2, padding='same')(enc)
    enc = BatchNormalization()(enc)
    enc = LeakyReLU(alpha=0.2)(enc)
    # 4th Convolutional Block
  enc = Conv2D(filters=256, kernel_size=5, strides=2, padding='same')(enc)
    enc = BatchNormalization()(enc)
    enc = LeakyReLU(alpha=0.2)(enc)
    # Flatten layer
  enc = Flatten()(enc)
    # 1st Fully Connected Layer
  enc = Dense(4096)(enc)
    enc = BatchNormalization()(enc)
    enc = LeakyReLU(alpha=0.2)(enc)
    # Second Fully Connected Layer
  enc = Dense(100)(enc)
    # Create a model
  model = Model(inputs=[input_layer], outputs=[enc])
    return model

我们现在已经成功地为编码器网络创建了 Keras 模型。 接下来,为生成器网络创建 Keras 模型。

生成对抗网络项目:1~5(3)https://developer.aliyun.com/article/1426894

相关文章
|
2月前
|
机器学习/深度学习 算法 TensorFlow
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
动物识别系统。本项目以Python作为主要编程语言,并基于TensorFlow搭建ResNet50卷积神经网络算法模型,通过收集4种常见的动物图像数据集(猫、狗、鸡、马)然后进行模型训练,得到一个识别精度较高的模型文件,然后保存为本地格式的H5格式文件。再基于Django开发Web网页端操作界面,实现用户上传一张动物图片,识别其名称。
82 1
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
|
2月前
|
机器学习/深度学习 人工智能 算法
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
植物病害识别系统。本系统使用Python作为主要编程语言,通过收集水稻常见的四种叶片病害图片('细菌性叶枯病', '稻瘟病', '褐斑病', '稻瘟条纹病毒病')作为后面模型训练用到的数据集。然后使用TensorFlow搭建卷积神经网络算法模型,并进行多轮迭代训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地模型文件。再使用Django搭建Web网页平台操作界面,实现用户上传一张测试图片识别其名称。
107 22
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
|
16天前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
38 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
2月前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
86 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
2月前
|
机器学习/深度学习 人工智能 算法
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
文本分类识别系统。本系统使用Python作为主要开发语言,首先收集了10种中文文本数据集("体育类", "财经类", "房产类", "家居类", "教育类", "科技类", "时尚类", "时政类", "游戏类", "娱乐类"),然后基于TensorFlow搭建CNN卷积神经网络算法模型。通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型,并保存为本地的h5格式。然后使用Django开发Web网页端操作界面,实现用户上传一段文本识别其所属的类别。
79 1
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
2月前
|
机器学习/深度学习 人工智能 算法
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台。果蔬识别系统,本系统使用Python作为主要开发语言,通过收集了12种常见的水果和蔬菜('土豆', '圣女果', '大白菜', '大葱', '梨', '胡萝卜', '芒果', '苹果', '西红柿', '韭菜', '香蕉', '黄瓜'),然后基于TensorFlow库搭建CNN卷积神经网络算法模型,然后对数据集进行训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地文件方便后期调用。再使用Django框架搭建Web网页平台操作界面,实现用户上传一张果蔬图片识别其名称。
49 0
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
3月前
|
计算机视觉
在yolov5项目中如何使用自带摄像机不用网络摄像机进行实时检测?
这篇文章讨论了在yolov5项目中,如何避免使用网络摄像机而改用自带的本地摄像机进行实时目标检测,并提供了解决摄像头打开错误的具体步骤和代码示例。
在yolov5项目中如何使用自带摄像机不用网络摄像机进行实时检测?
|
3月前
|
数据采集 资源调度 JavaScript
Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
【8月更文挑战第4天】Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
55 5
|
3月前
|
Java Android开发 Kotlin
Android项目架构设计问题之要在Glide库中加载网络图片到ImageView如何解决
Android项目架构设计问题之要在Glide库中加载网络图片到ImageView如何解决
31 0
|
3月前
|
Java Android开发 开发者
Android项目架构设计问题之使用Retrofit2作为网络库如何解决
Android项目架构设计问题之使用Retrofit2作为网络库如何解决
59 0