万物皆可GAN之3D-GAN(keras框架)

前言

这几天看了一篇比较有意思的文章,这里给你们分享一下。
论文地址:https://arxiv.org/abs/1610.07584
以下就用keras来对这个3D-GAN来进行分析;目前我还在看这篇文章的potorch代码,如果看懂了后续会将他给也分享出来。
分享出来主要是当作自己的学习笔记,然后也可以供大家学习参考。有兴趣的话,可以点击关注收藏。
下面主要从这几个方面来进行分析

  • 3D-GAN 基础知识简介
  • 建立项目
  • 准备数据
  • 3D-GAN 的 Keras 实现
  • 训练 3D-GAN
  • 超参数优化
  • 3D-GAN 的实际应用

3D-GAN 简介

3D 生成对抗网络(3D-GAN)是 GAN 的变体,就像 StackGAN,CycleGAN 和超分辨率生成对抗网络(SRGAN)一样 。 与朴素 GAN 相似,它具有生成器和判别器模型。 这两个网络都使用 3D 卷积层,而不是使用 2D 卷积。 如果提供足够的数据,它可以学习生成具有良好视觉质量的 3D 形状。
在仔细查看 3D-GAN 网络之前,让我们了解 3D 卷积。

3D 卷积

简而言之,3D 卷积操作沿x,y和z这三个方向对输入数据应用 3D 过滤器。 此操作将创建 3D 特征映射的堆叠列表。 输出的形状类似于立方体或长方体的形状。
下图说明了 3D 卷积操作。 左立方体的突出显示部分是输入数据。 内核位于中间,形状为(3, 3, 3)。 右侧的块是卷积运算的输出:
在这里插入图片描述

3D-GAN 的架构

3D-GAN 中的两个网络都是深度卷积神经网络。 生成器网络通常是一个上采样网络。 它对噪声向量(来自概率潜在空间的向量)进行上采样,以生成形状为的 3D 图像,该形状的长度,宽度,高度和通道与输入图像相似。 判别器网络是下采样网络。 使用一系列 3D 卷积运算和密集层,它可以识别提供给它的输入数据是真实的还是伪造的。

生成器网络的架构

生成器网络包含五个体积完全卷积的层,具有以下配置:

  • 卷积层:5
  • 过滤器: 512,256,128 和 64,1
  • 核大小:4 x 4 x 4, 4 x 4 x 4, 4 x 4 x 4, 4 x 4 x 4, 4 x 4 x 4
  • 步幅:1、2、2、2、2 或(1, 1), (2, 2), (2, 2), (2, 2), (2, 2)
  • 批量规范化:是,是,是,是,否
  • 激活:ReLU, ReLU, ReLU, ReLU,Sigmoid
  • 池化层:否,否,否,否,否
  • 线性层:否,否,否,否,否

网络的输入和输出如下:
输入:从概率潜在空间中采样的 200 维向量
输出:形状为64x64x64的 3D 图像
下图显示了生成器的架构:
在这里插入图片描述
下图显示了判别器网络中张量的流动以及每个层的张量的输入和输出形状。 这将使您对网络有更好的了解:
在这里插入图片描述
完全卷积网络是在网络末端没有完全连接的密集层的网络。 相反,它仅由卷积层组成,并且可以进行端到端训练,就像具有完全连接的层的卷积网络一样。 生成器网络中没有池化层。

判别器网络的架构

判别器网络包含五个具有以下配置的体积卷积层:

  • 3D 卷积层:5 通道:64、128、256、512、1
  • 核大小:4、4、4、4、4、4 步幅:2、2、2、2、1
  • 激活:LReLU,LReLU,LReLU,LReLU,Sigmoid
  • 批量规范化:是,是,是,是,无
  • 池化层:否,否,否,否,否
  • 线性层:否,否,否,否,否

网络的输入和输出如下:
输入:形状为(64, 64, 64)的 3D 图像
输出:输入数据属于真实或假类的概率

下图显示了判别器网络中每一层的张量流以及张量的输入和输出形状。 这将使您对判别器网络有更好的了解:
在这里插入图片描述
判别器网络主要镜像生成器网络。 一个重要的区别是它使用中的 LeakyReLU 代替了 ReLU 作为激活函数。 而且,网络末端的 Sigmoid 层用于二分类,并预测所提供的图像是真实的还是伪造的。 最后一层没有规范化层,但是其他层使用批量规范化输入。

目标函数

目标函数是训练 3D-GAN 的主要方法。 它提供损失值,这些损失值用于计算梯度,然后更新权重值。 3D-GAN 的对抗损失函数如下:
在这里插入图片描述
在这里, log(D(X))是二进制交叉熵损失或分类损失,log(1 - D(G(Z)))是对抗损失,z是来自概率空间p(Z)的潜向量, D(X)是判别器网络的输出, G(Z)是生成器网络的输出。

训练 3D-GAN

训练 3D-GAN 类似于训练朴素 GAN。 训练 3D-GAN 涉及的步骤如下:

  1. 从高斯(正态)分布中采样 200 维噪声向量。
  2. 使用生成器模型生成伪图像。
  3. 在真实图像(从真实数据中采样)和生成器网络生成的伪图像上训练生成器网络。
  4. 使用对抗模型训练生成器模型。 不要训练判别器模型。
  5. 对指定的周期数重复这些步骤。

准备数据

我们将使用 3D ShapeNets 数据集,该数据集可从这个页面获得。 它由 Wu 和 Song 等人发行。 并包含 40 个对象类别的正确标注的 3D 形状。 我们将使用目录中可用的体积数据, 在接下来的工作中,我们将下载,提取和浏览数据集。

下载并提取数据集

运行以下命令以下载并提取数据集:

首先使用以下链接下载3DShapeNets:
wget http://3dshapenets.cs.princeton.edu/3DShapeNetsCode.zip

下载文件后,运行以下命令将文件提取到适当的目录中:
unzip 3DShapeNetsCode.zip

现在,我们已经成功下载并提取了数据集。 它包含.mat(MATLAB)格式的图像。 每隔一张图像是 3D 图像。

探索数据集

要了解数据集,我们需要可视化 3D 图像。我们将首先更详细地了解什么是体素。 然后,我们将加载并可视化 3D 图像。

什么是体素?

体像素或体素是三维空间中的一个点。 体素在x,y和z方向上定义了具有三个坐标的位置。 体素是表示 3D 图像的基本单位。 它们主要用于 CAT 扫描,X 射线和 MRI 中,以创建人体和其他 3D 对象的准确 3D 模型。 要处理 3D 图像,了解体素非常重要,因为这些是 3D 图像的组成。 包含下图,以使您了解 3D 图像中的体素是什么样的:
在这里插入图片描述
在 3D 图像中的一系列体素。 阴影区域是单个体素。
前面的图像是体素的堆叠表示。 灰色长方体代表一个体素。 现在,您了解了什么是体素,让我们在下一部分中加载和可视化 3D 图像。

加载和可视化 3D 图像

3D ShapeNets 数据集包含.mat文件格式。 我们将这些.mat文件转换为 NumPy N 维数组。 我们还将可视化 3D 图像,以直观了解数据集。
执行以下代码以从.mat文件加载 3D 图像:
1、使用scipy中的loadmat()函数检索voxels。 代码如下:`

import scipy.io as io
voxels = io.loadmat("path to .mat file")['instance']

2、加载的 3D 图像的形状为30x30x30。 我们的网络需要形状为64x64x64的图像。 我们将使用 NumPy 的 pad()方法将 3D 图像的大小增加到32x32x32:

import numpy as np
voxels = np.pad(voxels, (1, 1), 'constant', constant_values=(0, 0))

pad()方法采用四个参数,它们是实际体素的 N 维数组,需要填充到每个轴边缘的值的数量,模式值(constant)和constant_values 被填充。
3、然后,使用scipy.ndimage模块中的zoom()函数将 3D 图像转换为大小为64x64x64的 3D 图像。

import scipy.ndimage as nd
voxels = nd.zoom(voxels, (2, 2, 2), mode='constant', order=0)

我们的网络要求图像的形状为64x64x64,这就是为什么我们将 3D 图像转换为这种形状的原因。

可视化 3D 图像

让我们使用 matplotlib 可视化 3D 图像,如以下代码所示:
1、首先创建一个 matplotlib 图并向其中添加一个子图:

fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect('equal')

2、接下来,将voxels添加到绘图中:

ax.voxels(voxels, edgecolor="red")

3、接下来,显示该图并将其另存为图像,以便稍后我们可以对其进行可视化和理解:

plt.show() plt.savefig(file_path)

第一个屏幕截图表示 3D 飞机上的飞机:
在这里插入图片描述
第二张屏幕截图表示 3D 平面中的表格:

在这里插入图片描述

第三个屏幕截图表示 3D 平面中的椅子:

在这里插入图片描述
我们已经成功下载,提取和浏览了数据集。 我们还研究了如何使用体素。 接下来,我们将在 Keras 框架中实现 3D-GAN。

3D-GAN 的 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

2、接下来,创建一个输入层,以允许网络进行输入。 生成器网络的输入是从概率潜在空间中采样的向量:

input_layer = Input(shape=gen_input_shape)

3、然后,添加第一个 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)

4、接下来,再添加四个 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)

5、然后,创建 Keras 模型并指定生成器网络的输入和输出:

model = Model(inputs=input_layer, outputs=a)

6、将生成器网络的整个代码包装在一个名为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, 
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啊菜来了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值