当前位置: 首页 > news >正文

[Day 44] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

生成对抗网络(Generative Adversarial Networks,GANs)是一种由Ian Goodfellow等人在2014年提出的深度学习模型,广泛用于图像生成、图像超分辨率、图像修复等领域。GAN由一个生成器(Generator)和一个判别器(Discriminator)组成,二者通过对抗训练相互提升性能。以下是关于GAN的详细介绍和代码实现示例。

一、生成对抗网络的原理

1.1 生成器(Generator)

生成器的目标是生成逼真的样本,使得判别器无法区分生成样本和真实样本。生成器接收一个随机噪声向量(通常为高斯分布或均匀分布),通过一系列的神经网络层转换成逼真的数据样本。

1.2 判别器(Discriminator)

判别器的目标是将真实样本和生成样本区分开来。判别器是一个二分类模型,输入为样本数据,输出为分类概率,表示输入样本是“真实”还是“生成”的概率。

1.3 对抗训练

生成器和判别器通过对抗训练来提升彼此的能力。生成器试图欺骗判别器,而判别器不断提升自己的判别能力。二者的目标函数如下:

  • 生成器的损失函数:使得生成样本被判别器判断为真实样本的概率最大。
  • 判别器的损失函数:最大化判别真实样本和生成样本的能力。

具体的数学表达式如下:

min_{G} max_{D}V(D,G)E_{x\sim p_{data}(x)}[logD(x)]+E_{x\sim p_{z}(z)}[log(1 - D(G((z)))]

二、代码实现

我们将以MNIST数据集为例,使用Keras实现一个简单的GAN模型。

2.1 导入必要的库

import numpy as np
import matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.models import Sequential, Model
from keras.layers import Dense, LeakyReLU, BatchNormalization, Reshape, Flatten, Input
from keras.optimizers import Adam

2.2 数据预处理

加载并预处理MNIST数据集,使其适用于GAN的输入。

# 加载MNIST数据集
(X_train, _), (_, _) = mnist.load_data()# 归一化并reshape数据
X_train = X_train / 127.5 - 1.0
X_train = np.expand_dims(X_train, axis=3)# 输入维度
img_shape = X_train.shape[1:]
z_dim = 100  # 噪声向量维度

2.3 构建生成器

生成器将噪声向量转换为逼真的图像。我们使用全连接层和转置卷积层实现这一过程。

def build_generator(z_dim):model = Sequential()model.add(Dense(256, input_dim=z_dim))model.add(LeakyReLU(alpha=0.01))model.add(BatchNormalization(momentum=0.8))model.add(Dense(512))model.add(LeakyReLU(alpha=0.01))model.add(BatchNormalization(momentum=0.8))model.add(Dense(1024))model.add(LeakyReLU(alpha=0.01))model.add(BatchNormalization(momentum=0.8))model.add(Dense(np.prod(img_shape), activation='tanh'))model.add(Reshape(img_shape))return modelgenerator = build_generator(z_dim)
generator.summary()

2.4 构建判别器

判别器将输入图像分类为真实或生成的。我们使用卷积层和全连接层实现这一过程。

def build_discriminator(img_shape):model = Sequential()model.add(Flatten(input_shape=img_shape))model.add(Dense(512))model.add(LeakyReLU(alpha=0.01))model.add(Dense(256))model.add(LeakyReLU(alpha=0.01))model.add(Dense(1, activation='sigmoid'))return modeldiscriminator = build_discriminator(img_shape)
discriminator.summary()

2.5 编译模型

我们为生成器和判别器选择优化器,并编译判别器。

# 优化器
optimizer = Adam(0.0002, 0.5)# 编译判别器
discriminator.compile(loss='binary_crossentropy',optimizer=optimizer,metrics=['accuracy'])

2.6 构建GAN模型

我们将生成器和判别器结合起来,构建完整的GAN模型,并编译生成器。

# 构建生成器
z = Input(shape=(z_dim,))
img = generator(z)# 将判别器设置为不可训练,仅训练生成器
discriminator.trainable = False# 判别器预测生成图像
validity = discriminator(img)# 构建GAN模型
gan = Model(z, validity)
gan.compile(loss='binary_crossentropy', optimizer=optimizer)gan.summary()

2.7 训练模型

我们定义训练过程,包括生成器和判别器的训练步骤。

def train(epochs, batch_size=128, sample_interval=100):# 加载数据(X_train, _), (_, _) = mnist.load_data()X_train = X_train / 127.5 - 1.0X_train = np.expand_dims(X_train, axis=3)# 真实标签real = np.ones((batch_size, 1))fake = np.zeros((batch_size, 1))for epoch in range(epochs):# ---------------------# 训练判别器# ---------------------# 随机选择真实图像idx = np.random.randint(0, X_train.shape[0], batch_size)imgs = X_train[idx]# 生成噪声并生成假图像z = np.random.normal(0, 1, (batch_size, z_dim))gen_imgs = generator.predict(z)# 训练判别器d_loss_real = discriminator.train_on_batch(imgs, real)d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)# ---------------------# 训练生成器# ---------------------z = np.random.normal(0, 1, (batch_size, z_dim))g_loss = gan.train_on_batch(z, real)# 打印进度print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]")# 每隔sample_interval保存生成的图像样本if epoch % sample_interval == 0:sample_images(epoch)def sample_images(epoch, image_grid_rows=4, image_grid_columns=4):z = np.random.normal(0, 1, (image_grid_rows * image_grid_columns, z_dim))gen_imgs = generator.predict(z)gen_imgs = 0.5 * gen_imgs + 0.5fig, axs = plt.subplots(image_grid_rows, image_grid_columns, figsize=(4, 4), sharey=True, sharex=True)cnt = 0for i in range(image_grid_rows):for j in range(image_grid_columns):axs[i, j].imshow(gen_imgs[cnt, :, :, 0], cmap='gray')axs[i, j].axis('off')cnt += 1plt.show()

2.8 开始训练

我们设置训练参数并开始训练GAN模型。

epochs = 10000
batch_size = 64
sample_interval = 1000train(epochs, batch_size, sample_interval)

2.9 详细解释代码

导入库

我们导入了Keras和其他必要的库,用于构建和训练我们的GAN模型。

import numpy as np
import matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.models import Sequential, Model
from keras.layers import Dense, LeakyReLU, BatchNormalization, Reshape, Flatten, Input
from keras.optimizers import Adam
数据预处理

我们加载MNIST数据集,并对图像进行归一化处理,将其范围调整到[-1, 1],以便于GAN的训练。

(X_train, _), (_, _) = mnist.load_data()
X_train = X_train / 127.5 - 1.0
X_train = np.expand_dims(X_train, axis=3)
img_shape = X_train.shape[1:]
z_dim = 100
构建生成器

生成器将噪声向量转换为逼真的图像。我们使用了全连接层、LeakyReLU激活函数和批归一化层来实现这一过程。

def build_generator(z_dim):model = Sequential()model.add(Dense(256, input_dim=z_dim))model.add(LeakyReLU(alpha=0.01))model.add(BatchNormalization(momentum=0.8))model.add(Dense(512))model.add(LeakyReLU(alpha=0.01))model.add(BatchNormalization(momentum=0.8))model.add(Dense(1024))model.add(LeakyReLU(alpha=0.01))model.add(BatchNormalization(momentum=0.8))model.add(Dense(np.prod(img_shape), activation='tanh'))model.add(Reshape(img_shape))return model
构建判别器

判别器将输入图像分类为真实或生成的。我们使用了卷积层、LeakyReLU激活函数和全连接层来实现这一过程。

def build_discriminator(img_shape):model = Sequential()model.add(Flatten(input_shape=img_shape))model.add(Dense(512))model.add(LeakyReLU(alpha=0.01))model.add(Dense(256))model.add(LeakyReLU(alpha=0.01))model.add(Dense(1, activation='sigmoid'))return model
编译模型

我们为生成器和判别器选择优化器,并编译判别器。

optimizer = Adam(0.0002, 0.5)
discriminator.compile(loss='binary_crossentropy',optimizer=optimizer,metrics=['accuracy'])
构建GAN模型

我们将生成器和判别器结合起来,构建完整的GAN模型,并编译生成器。

z = Input(shape=(z_dim,))
img = generator(z)
discriminator.trainable = False
validity = discriminator(img)
gan = Model(z, validity)
gan.compile(loss='binary_crossentropy', optimizer=optimizer)
训练模型

我们定义训练过程,包括生成器和判别器的训练步骤。

def train(epochs, batch_size=128, sample_interval=100):(X_train, _), (_, _) = mnist.load_data()X_train = X_train / 127.5 - 1.0X_train = np.expand_dims(X_train, axis=3)real = np.ones((batch_size, 1))fake = np.zeros((batch_size, 1))for epoch in range(epochs):idx = np.random.randint(0, X_train.shape[0], batch_size)imgs = X_train[idx]z = np.random.normal(0, 1, (batch_size, z_dim))gen_imgs = generator.predict(z)d_loss_real = discriminator.train_on_batch(imgs, real)d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)z = np.random.normal(0, 1, (batch_size, z_dim))g_loss = gan.train_on_batch(z, real)print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]")if epoch % sample_interval == 0:sample_images(epoch)def sample_images(epoch, image_grid_rows=4, image_grid_columns=4):z = np.random.normal(0, 1, (image_grid_rows * image_grid_columns, z_dim))gen_imgs = generator.predict(z)gen_imgs = 0.5 * gen_imgs + 0.5fig, axs = plt.subplots(image_grid_rows, image_grid_columns, figsize=(4, 4), sharey=True, sharex=True)cnt = 0for i in range(image_grid_rows):for j in range(image_grid_columns):axs[i, j].imshow(gen_imgs[cnt, :, :, 0], cmap='gray')axs[i, j].axis('off')cnt += 1plt.show()
开始训练

我们设置训练参数并开始训练GAN模型。

epochs = 10000
batch_size = 64
sample_interval = 1000train(epochs, batch_size, sample_interval)

三、总结

通过以上代码和详细解释,我们实现了一个简单的生成对抗网络模型,并通过训练使生成器能够生成逼真的MNIST手写数字图像。GANs在许多领域有着广泛的应用,本文只是一个起步,读者可以进一步探索其在图像超分辨率、图像修复、文本生成等方面的应用。

相关文章:

  • Mendix 创客访谈录|Mendix 如何化解工业企业数字化转型的复杂性
  • 【人工智能基础四】循环神经网络(RNN)与长短时记忆网络(LSTM)
  • fabricjs 实现图像的二值化功能
  • 计算机网络基础 - 计算机网络和因特网(2)
  • ARM/Linux嵌入式面经(二十):地平线嵌入式开发
  • SQL进阶技巧:数据预处理如何对数据进行分桶【分箱】?
  • SD8223LC 首鼎SHOUDING单键电容式触摸IC SOT23-6
  • 面试经典算法150题系列-h指数
  • Jenkins参数化构建
  • C# 使用 NLog 输出日志到文件夹
  • springboot新农村综合展示平台-计算机毕业设计源码41793
  • 震惊!一男子深夜燥热难耐,竟然偷偷起身打开电脑并开始 学习c++入门基础(下)
  • 一个很变态却非常实用的发论文的新方向,【Transformer+目标检测】
  • 为什么有的地方笔记本经常连不上wifi,而手机可以?
  • Linux学习第56天:RGB转HDMI
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • Asm.js的简单介绍
  • Bootstrap JS插件Alert源码分析
  • CSS实用技巧干货
  • echarts花样作死的坑
  • Github访问慢解决办法
  • go语言学习初探(一)
  • leetcode-27. Remove Element
  • mockjs让前端开发独立于后端
  • spring security oauth2 password授权模式
  • Vue ES6 Jade Scss Webpack Gulp
  • VUE es6技巧写法(持续更新中~~~)
  • vue.js框架原理浅析
  • 成为一名优秀的Developer的书单
  • 多线程事务回滚
  • 基于组件的设计工作流与界面抽象
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 少走弯路,给Java 1~5 年程序员的建议
  • 协程
  • 在weex里面使用chart图表
  • elasticsearch-head插件安装
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #70结构体案例1(导师,学生,成绩)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (八十八)VFL语言初步 - 实现布局
  • (补)B+树一些思想
  • (理论篇)httpmoudle和httphandler一览
  • (十三)Maven插件解析运行机制
  • (数据结构)顺序表的定义
  • (一) springboot详细介绍
  • (一)RocketMQ初步认识
  • (转)Sublime Text3配置Lua运行环境
  • .gitignore不生效的解决方案
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET 5种线程安全集合
  • .net core使用EPPlus设置Excel的页眉和页脚
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .NET业务框架的构建