【机器学习】机器学习的重要技术——生成对抗网络:理论、算法与实践

引言

生成对抗网络(Generative Adversarial Networks, GANs)由Ian Goodfellow等人在2014年提出,通过生成器和判别器两个神经网络的对抗训练,成功实现了高质量数据的生成。GANs在图像生成、数据增强、风格迁移等领域取得了显著成果,成为深度学习的重要分支。本文将深入探讨GANs的基本原理、核心算法及其在实际中的应用,并提供代码示例以帮助读者更好地理解和掌握这一技术。
在这里插入图片描述

第一章 GANs的基本概念

1.1 什么是生成对抗网络

生成对抗网络由两个相互对抗的神经网络组成:生成器(Generator)和判别器(Discriminator)。生成器负责生成与真实数据相似的假数据,判别器负责区分真实数据和生成数据。生成器和判别器通过对抗训练,最终生成器能够生成逼真的数据,判别器难以区分其真伪。

1.2 GANs的基本结构
  • 生成器(Generator):接受随机噪声作为输入,生成与真实数据分布相似的样本。
  • 判别器(Discriminator):接受真实数据和生成数据作为输入,输出区分它们的概率。

GANs的目标是通过对抗训练,使得生成器生成的数据与真实数据无法区分,从而实现高质量的数据生成。

1.3 GANs的训练过程

GANs的训练过程可以概括为以下步骤:

  1. 初始化:随机初始化生成器和判别器的参数。
  2. 判别器训练:固定生成器的参数,更新判别器的参数,使其能够更好地区分真实数据和生成数据。
  3. 生成器训练:固定判别器的参数,更新生成器的参数,使其生成的数据能够欺骗判别器。
  4. 迭代:重复步骤2和3,直到生成器生成的数据与真实数据难以区分。

第二章 GANs的核心算法

2.1 标准GANs

标准GANs的损失函数由生成器和判别器的对抗损失组成。判别器的目标是最大化正确分类的概率,生成器的目标是最小化生成数据被判别器识别为假的概率。

import tensorflow as tf
from tensorflow.keras import layers# 生成器模型
def build_generator():model = tf.keras.Sequential()model.add(layers.Dense(256, activation='relu', input_dim=100))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(512, activation='relu'))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(1024, activation='relu'))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(28 * 28 * 1, activation='tanh'))model.add(layers.Reshape((28, 28, 1)))return model# 判别器模型
def build_discriminator():model = tf.keras.Sequential()model.add(layers.Flatten(input_shape=(28, 28, 1)))model.add(layers.Dense(512, activation='relu'))model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(256, activation='relu'))model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(1, activation='sigmoid'))return model# 编译模型
generator = build_generator()
discriminator = build_discriminator()
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])# GAN模型
discriminator.trainable = False
gan_input = layers.Input(shape=(100,))
generated_image = generator(gan_input)
gan_output = discriminator(generated_image)
gan = tf.keras.models.Model(gan_input, gan_output)
gan.compile(optimizer='adam', loss='binary_crossentropy')# 加载MNIST数据集
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype('float32') - 127.5) / 127.5
x_train = np.expand_dims(x_train, axis=3)# 训练GANs
batch_size = 128
epochs = 10000
half_batch = int(batch_size / 2)for epoch in range(epochs):# 训练判别器idx = np.random.randint(0, x_train.shape[0], half_batch)real_images = x_train[idx]noise = np.random.normal(0, 1, (half_batch, 100))generated_images = generator.predict(noise)d_loss_real = discriminator.train_on_batch(real_images, np.ones((half_batch, 1)))d_loss_fake = discriminator.train_on_batch(generated_images, np.zeros((half_batch, 1)))d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)# 训练生成器noise = np.random.normal(0, 1, (batch_size, 100))valid_y = np.array([1] * batch_size)g_loss = gan.train_on_batch(noise, valid_y)if epoch % 1000 == 0:print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]")
2.2 深度卷积生成对抗网络(DCGAN)

DCGAN通过在生成器和判别器中引入卷积层,显著提高了图像生成的质量。以下是一个基于DCGAN的示例。

def build_generator():model = tf.keras.Sequential()model.add(layers.Dense(7 * 7 * 256, use_bias=False, input_shape=(100,)))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Reshape((7, 7, 256)))model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))return modeldef build_discriminator():model = tf.keras.Sequential()model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1]))model.add(layers.LeakyReLU())model.add(layers.Dropout(0.3))model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))model.add(layers.LeakyReLU())model.add(layers.Dropout(0.3))model.add(layers.Flatten())model.add(layers.Dense(1))return modelgenerator = build_generator()
discriminator = build_discriminator()# 编译判别器
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])# 编译GAN模型
discriminator.trainable = False
gan_input = layers.Input(shape=(100,))
generated_image = generator(gan_input)
gan_output = discriminator(generated_image)
gan = tf.keras.models.Model(gan_input, gan_output)
gan.compile(optimizer='adam', loss='binary_crossentropy')# 加载MNIST数据集
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype('float32') - 127.5) / 127.5
x_train = np.expand_dims(x_train, axis=3)# 训练DCGAN
batch_size = 128
epochs = 10000
half_batch = int(batch_size / 2)for epoch in range(epochs):# 训练判别器idx = np.random.randint(0, x_train.shape[0], half_batch)real_images = x_train[idx]noise = np.random.normal(0, 1, (half_batch, 100))generated_images = generator.predict(noise)d_loss_real = discriminator.train_on_batch(real_images, np.ones((half_batch, 1)))d_loss_fake = discriminator.train_on_batch(generated_images, np.zeros((half_batch, 1)))d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)# 训练生成器noise = np.random.normal(0, 1, (batch_size, 100))valid_y = np.array([1] * batch_size)g_loss = gan.train_on_batch(noise, valid_y)if epoch % 1000 == 0:print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]")
2.3 条件生成对抗网络(Conditional GAN)

条件生成对抗网络(Conditional GAN, cGAN)通过在生成器和判别器中引入条件变量,使生成的数据能够满足特定条件。

def build_generator():model = tf.keras.Sequential()model.add(layers.Dense(7 * 7 * 256, use_bias=False, input_shape=(110,)))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Reshape((7, 7, 256)))model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))return modeldef build_discriminator():model = tf.keras.Sequential()model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 11]))model.add(layers.LeakyReLU())model.add(layers.Dropout(0.3))model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))model.add(layers.LeakyReLU())model.add(layers.Dropout(0.3))model.add(layers.Flatten())model.add(layers.Dense(1))return modelgenerator = build_generator()
discriminator = build_discriminator()# 编译判别器
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])# 编译cGAN模型
discriminator.trainable = False
noise_input = layers.Input(shape=(100,))
label_input = layers.Input(shape=(10,))
gan_input = layers.Concatenate()([noise_input, label_input])
generated_image = generator(gan_input)
label_image = layers.Concatenate()([generated_image, label_input])
gan_output = discriminator(label_image)
cgan = tf.keras.models.Model([noise_input, label_input], gan_output)
cgan.compile(optimizer='adam', loss='binary_crossentropy')# 加载MNIST数据集
(x_train, y_train), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype('float32') - 127.5) / 127.5
x_train = np.expand_dims(x_train, axis=3)
y_train = tf.keras.utils.to_categorical(y_train, 10)# 训练cGAN
batch_size = 128
epochs = 10000
half_batch = int(batch_size / 2)for epoch in range(epochs):# 训练判别器idx = np.random.randint(0, x_train.shape[0], half_batch)real_images = x_train[idx]real_labels = y_train[idx]noise = np.random.normal(0, 1, (half_batch, 100))generated_labels = np.random.randint(0, 10, half_batch)generated_labels = tf.keras.utils.to_categorical(generated_labels, 10)generated_images = generator.predict([noise, generated_labels])real_images_with_labels = np.concatenate([real_images, real_labels], axis=3)generated_images_with_labels = np.concatenate([generated_images, generated_labels], axis=3)d_loss_real = discriminator.train_on_batch(real_images_with_labels, np.ones((half_batch, 1)))d_loss_fake = discriminator.train_on_batch(generated_images_with_labels, np.zeros((half_batch, 1)))d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)# 训练生成器noise = np.random.normal(0, 1, (batch_size, 100))valid_y = np.array([1] * batch_size)labels = np.random.randint(0, 10, batch_size)labels = tf.keras.utils.to_categorical(labels, 10)g_loss = cgan.train_on_batch([noise, labels], valid_y)if epoch % 1000 == 0:print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]")

在这里插入图片描述

第三章 GANs的应用实例

3.1 图像生成

GANs在图像生成任务中表现出色,可以生成高质量的图像。以下是一个使用DCGAN生成手写数字图像的示例。

import matplotlib.pyplot as plt# 生成手写数字图像
noise = np.random.normal(0, 1, (25, 100))
generated_images = generator.predict(noise)# 绘制生成的图像
plt.figure(figsize=(10, 10))
for i in range(generated_images.shape[0]):plt.subplot(5, 5, i + 1)plt.imshow(generated_images[i, :, :, 0], cmap='gray')plt.axis('off')
plt.tight_layout()
plt.show()
3.2 数据增强

GANs可以用于数据增强,通过生成新的样本扩展训练数据集,从而提高模型的泛化能力。以下是一个使用cGAN生成带标签的手写数字图像的示例。

# 生成带标签的手写数字图像
noise = np.random.normal(0, 1, (25, 100))
labels = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9] * 2 + [0, 1, 2, 3, 4])
labels = tf.keras.utils.to_categorical(labels, 10)
generated_images = generator.predict([noise, labels])# 绘制生成的图像
plt.figure(figsize=(10, 10))
for i in range(generated_images.shape[0]):plt.subplot(5, 5, i + 1)plt.imshow(generated_images[i, :, :, 0], cmap='gray')plt.axis('off')
plt.tight_layout()
plt.show()
3.3 风格迁移

GANs可以用于风格迁移,通过将一种图像的内容与另一种图像的风格结合,生成具有新风格的图像。以下是一个使用CycleGAN进行图像风格迁移的示例。

import tensorflow as tf
import tensorflow_addons as tfa
from tensorflow.keras import layersdef residual_block(x, filters, kernel_size=3):fx = layers.Conv2D(filters, kernel_size, padding='same')(x)fx = tfa.layers.InstanceNormalization()(fx)fx = layers.ReLU()(fx)fx = layers.Conv2D(filters, kernel_size, padding='same')(fx)fx = tfa.layers.InstanceNormalization()(fx)x = layers.Add()([x, fx])return xdef build_generator():inputs = layers.Input(shape=[256, 256, 3])x = layers.Conv2D(64, 7, padding='same')(inputs)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)x = layers.Conv2D(128, 3, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)x = layers.Conv2D(256, 3, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)for _ in range(9):x = residual_block(x, 256)x = layers.Conv2DTranspose(128, 3, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)x = layers.Conv2DTranspose(64, 3, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)x = layers.Conv2D(3, 7, padding='same')(x)x = layers.Activation('tanh')(x)return tf.keras.Model(inputs, x)def build_discriminator():inputs = layers.Input(shape=[256, 256, 3])x = layers.Conv2D(64, 4, strides=2, padding='same')(inputs)x = layers.LeakyReLU(alpha=0.2)(x)x = layers.Conv2D(128, 4, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.LeakyReLU(alpha=0.2)(x)x = layers.Conv2D(256, 4, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.LeakyReLU(alpha=0.2)(x)x = layers.Conv2D(512, 4, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.LeakyReLU(alpha=0.2)(x)x = layers.Conv2D(1, 4, padding='same')(x)return tf.keras.Model(inputs, x)# 构建CycleGAN模型
generator_g = build_generator()
generator_f = build_generator()
discriminator_x = build_discriminator()
discriminator_y = build_discriminator()# 编译模型
generator_g.compile(optimizer='adam', loss='mse')
generator_f.compile(optimizer='adam', loss='mse')
discriminator_x.compile(optimizer='adam', loss='mse')
discriminator_y.compile(optimizer='adam', loss='mse')# 训练CycleGAN
# 训练数据准备和训练代码略# 使用CycleGAN进行风格迁移
def generate_images(model, test_input):prediction = model(test_input)plt.figure(figsize=(12, 12))display_list = [test_input[0], prediction[0]]title = ['Input Image', 'Predicted Image']for i in range(2):plt.subplot(1, 2, i + 1)plt.title(title[i])plt.imshow(display_list[i] * 0.5 + 0.5)plt.axis('off')plt.show()# 测试图像
test_image = tf.expand_dims(tf.image.resize(test_image, (256, 256)), axis=0) / 127.5 - 1
generate_images(generator_g, test_image)

在这里插入图片描述

第四章 GANs的未来发展与挑战

4.1 训练稳定性

GANs的训练过程容易出现不稳定性,如模式崩溃(mode collapse)和梯度消失等问题。研究如何提高GANs训练的稳定性是一个重要的方向。

4.2 模型评价

如何有效评估GANs生成数据的质量和多样性是一个挑战。研究方向包括开发更好的评价指标,如Frechet Inception Distance(FID)和Inception Score(IS)等。

4.3 应用扩展

GANs的应用范围不断扩大,研究如何在更多领域和任务中应用GANs,如文本生成、音频生成和科学模拟等,是一个重要的方向。

结论

生成对抗网络作为一种强大的生成模型,通过生成器和判别器的对抗训练,实现了高质量的数据生成和多种应用。本文详细介绍了GANs的基本概念、核心算法及其在实际中的应用,并提供了具体的代码示例,帮助读者深入理解和掌握这一技术。希望本文能够为您进一步探索和应用生成对抗网络提供有价值的参考。

在这里插入图片描述

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

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

相关文章

详细分析Springmvc中的@ModelAttribute基本知识(附Demo)

目录 前言1. 注解用法1.1 方法参数1.2 方法1.3 类 2. 注解场景2.1 表单参数2.2 AJAX请求2.3 文件上传 3. 实战4. 总结 前言 将请求参数绑定到模型对象上,或者在请求处理之前添加模型属性 可以在方法参数、方法或者类上使用 一般适用这几种场景: 表单…

ros笔记01--初次体验ros2

ros笔记01--初次体验ros2 介绍安装ros2测试验证ros2说明 介绍 机器人操作系统(ROS)是一组用于构建机器人应用程序的软件库和工具。从驱动程序和最先进的算法到强大的开发者工具,ROS拥有我们下一个机器人项目所需的开源工具。 当前ros已经应用到各类机器人项目开发中…

【Matlab 六自由度机器人】机器人动力学之推导拉格朗日方程(附MATLAB机器人动力学拉格朗日方程推导代码)

【Matlab 六自由度机器人】机器人动力学概述 近期更新前言正文一、拉格朗日方程的推导1. 单自由度系统2. 单连杆机械臂系统3. 双连杆机械臂系统 二、MATLAB实例推导1. 机器人模型的建立2. 动力学代码 总结参考文献 近期更新 【汇总】 【Matlab 六自由度机器人】系列文章汇总 …

Elasticsearch 第四期:搜索和过滤

序 2024年4月,小组计算建设标签平台,使用ES等工具建了一个demo,由于领导变动关系,项目基本夭折。其实这两年也陆陆续续接触和使用过ES,两年前也看过ES的官网,当时刚毕业半年多,由于历史局限性导…

大数据开发如何管理项目

在面试的时候总是 会问起项目,那在大数据开发的实际工作中,如何做好一个项目呢? 目录 1. 需求分析与项目规划1.1 需求收集与梳理1.2 可行性分析1.3 项目章程与计划 2. 数据准备与处理2.1 数据源接入2.2 数据仓库建设2.3 数据质量管理 3. 系统…

ARCGIS添加在线地图

地图服务地址:http://map.geoq.cn/ArcGIS/rest/services 具体方法: 结果展示:

Python逻辑控制语句 之 循环语句--for循环

1.for 的介绍 for 循环 也称为是 for 遍历, 也可以做指定次数的循环遍历: 是从容器中将数据逐个取出的过程.容器: 字符串/列表/元组/字典 2.for 的语法 (1)for 循环遍历字符串 for 变量 in 字符串: 重复执⾏的代码 字符串中存在多少个字符, 代码就执行…

flink的窗口

目录 窗口分类 1.按照驱动类型分类 1. 时间窗口(Time window) 2.计数窗口(Count window) 2.按照窗口分配数据的规则分类 窗口API分类 API调用 窗口分配器器: 窗口函数 增量聚合函数: 全窗口函数…

网络编程常见问题

1、TCP状态迁移图 2、TCP三次握手过程 2.1、握手流程 1、TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态; 2、TCP客户进程也是先创建传输控制块TCB&#xff…

Echarts地图实现:杭州市困难人数分布【动画滚动播放】

Echarts地图实现:杭州市困难人数分布 实现功能 杭州市地区以及散点图分布结合的形式数据展示动画轮播可进去杭州市下级地区可返回杭州市地图展示 效果预览 实现思路 使用ECharts的地图和散点图功能结合实现地区分布通过动画轮播展示数据变化实现下级地区数据的展…

搜索引擎的原理与相关知识

搜索引擎是一种网络服务,它通过互联网帮助用户找到所需的信息。搜索引擎的工作原理主要包括以下几个步骤: 网络爬虫(Web Crawler):搜索引擎使用网络爬虫(也称为蜘蛛或机器人)来遍历互联网&#…

Hugging Face Accelerate 两个后端的故事:FSDP 与 DeepSpeed

社区中有两个流行的零冗余优化器 (Zero Redundancy Optimizer,ZeRO)算法实现,一个来自DeepSpeed,另一个来自PyTorch。Hugging FaceAccelerate对这两者都进行了集成并通过接口暴露出来,以供最终用户在训练/微调模型时自主选择其中之…

flask-socket的实践

1.长连接和短连接的由来 1)TCP在真正的读写操作之前,server与client之间必须建立一个连接, 当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接, 连接的建立通过三次握手,释放则需要四次握手…

java基于ssm+jsp 二手车交易网站

1用户功能模块 定金支付管理,在定金支付管理页面可以填写订单编号、车型、品牌、分类、车身颜色、售价、订金金额、付款日期、备注、用户名、姓名、联系方式、是否支付等信息,进行详情、修改,如图1所示。 图1定金支付管理界面图 预约到店管…

“论大数据处理架构及其应用”写作框架,软考高级,系统架构设计师

论文真题 大数据处理架构是专门用于处理和分析巨量复杂数据集的软件架构。它通常包括数据收集、存储、处理、分析和可视化等多个层面,旨在从海量、多样化的数据中提取有价值的信息。Lambda架构是大数据平台里最成熟、最稳定的架构,它是一种将批处理和流…

kicad第三方插件安装问题

在使用KICAD时想安装扩展内容,但是遇到下载失败,因为SSL connect error。 因为是公司网络,我也不是很懂,只能另寻他法。找到如下方法可以曲线救国。 第三方插件包目录 打开存放第三方插件存放目录,用于存放下载插件包…

通俗范畴论4 范畴的定义

注:由于CSDN无法显示本文章源文件的公式,因此部分下标、字母花体、箭头表示可能会不正常,请读者谅解 范畴的正式定义 上一节我们在没有引入范畴这个数学概念的情况下,直接体验了一个“苹果1”范畴,建立了一个对范畴的直观。本节我们正式学习范畴的定义和基本性质。 一个…

【WPF】Windows系统桌面应用程序编程开发新手入门-打造自己的小工具

电脑Windows系统上的桌面程序通常是用Visual Studio 开发工具编写出来的,有两种开发方式供选择,一种是WindowForm,简称WinForm,另一种是Windows Presentation Foundation,简称WPF,这里将学习WPF项目。 文章…

收银系统源码-千呼新零售【全场景收银】

千呼新零售2.0系统是零售行业连锁店一体化收银系统,包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体,线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

云计算-期末复习题-框架设计/选择/填空/简答(2)

目录 框架设计 1.负载分布架构 2.动态可扩展架构 3.弹性资源容量架构 4.服务负载均衡架构 5.云爆发结构 6.弹性磁盘供给结构 7.负载均衡的虚拟服务器实例架构 填空题/简答题 单选题 多选题 云计算期末复习部分练习题,包括最后的部分框架设计大题(只是部分…