从零开始 - 在Python中构建和训练生成对抗网络(GAN)模型
生成对抗网络(GANs)是一种强大的生成模型,可以合成新的逼真图像。通过完整的实现过程,读者将对GANs在幕后的工作原理有深刻的理解。本教程首先导入必要的库并加载将用于训练GAN的Fashion-MNIST数据集。然后,提供了构建GAN核心组件(生成器和判别器模型)的代码示例。接下来的部分解释了如何构建一个组合模型,该模型训练生成器以欺骗判别器,以及如何设计一个训练函数来优化对抗过程。
目录:
1. 导入库和下载数据集
2. 构建生成器模型
3. 构建判别器模型
4. 构建组合模型
5. 构建训练函数
6. 训练和观察结果
导入库和下载数据集
让我们首先导入本文中将使用的重要库:
from __future__ import print_function, division
from keras.datasets import fashion_mnist
from keras.layers import Input, Dense, Reshape, Flatten, Dropout
from keras.layers import BatchNormalization, Activation, ZeroPadding2D
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.convolutional import UpSampling2D, Conv2D
from keras.models import Sequential, Model
from keras.optimizers import Adam
import numpy as np
import matplotlib.pyplot as plt
在本文中,您将在Fashion-MNIST数据集上训练DCGAN。Fashion-MNIST包含60,000个用于训练的灰度图像和一个包含10,000个图像的测试集。每个28×28的灰度图像与10个类别中的一个标签相关联。Fashion-MNIST旨在作为原始MNIST数据集的直接替代品,用于对比机器学习算法的性能。与三通道的彩色图像相比,灰度图像在一通道上训练卷积网络时需要更少的计算能力,这使您更容易在没有GPU的个人计算机上进行训练。
数据集分为10个时尚类别。类别标签如下:
您可以使用以下代码加载数据集:
(training_data, _), (_, _) = fashion_mnist.load_data()
X_train = training_data / 127.5 - 1.
X_train = np.expand_dims(X_train, axis=3)
要可视化数据集中的图像,可以使用以下代码:
def visualize_input(img, ax):ax.imshow(img, cmap='gray')width, height = img.shapethresh = img.max()/2.5for x in range(width):for y in range(height):ax.annotate(str(round(img[x][y],2)), xy=(y,x),horizontalalignment='center',verticalalignment='center',color='white' if img[x][y]<thresh else="" 'black')="" =""
fig = plt.figure(figsize = (12,12))
ax = fig.add_subplot(111)
visualize_input(training_data[3343], ax)We also use batch normalization and a ReLU activation.
For each of these layers, the general scheme is convolution ⇒ batch normalization
⇒ ReLU. We keep stacking up layers like this until we get the final transposed
convolution layer with shape 28 × 28 × 1:
2. 构建生成器模型
正如我们在前面的文章中所探讨的,GANs由两个主要组件组成,即生成器和判别器。在这一部分中,我们将构建生成器模型,其输入将是一个噪声向量(z)。生成器的架构如下图所示。
第一层是一个全连接层,然后被重新塑造成深而窄的层,在原始的DCGAN论文中,作者将输入重新塑造为4×4×1024。在这里,我们将使用7×7×128。然后,我们使用上采样层将特征映射的维度从7×7加倍到14×14,然后再次加倍到28×28。在这个网络中,我们使用了三个卷积层。我们还将使用批归一化和ReLU激活。
对于每个层,通用方案是卷积 ⇒ 批归一化 ⇒ ReLU。我们不断地堆叠这样的层,直到得到最终的转置卷积层,形状为28×28×1。
以下是构建上述生成器模型的Keras代码:
def build_generator():generator = Sequential()generator.add(Dense(6272, activation="relu", input_dim=100)) # Add dense layergenerator.add(Reshape((7, 7, 128))) # reshape the imagegenerator.add(UpSampling2D()) # Upsampling layer to double the size of the imagegenerator.add(Conv2D(128, kernel_size=3, padding="same", activation="relu"))generator.add(BatchNormalization(momentum=0.8))generator.add(UpSampling2D())# convolutional + batch normalization layersgenerator.add(Conv2D(64, kernel_size=3, padding="same", activation="relu"))generator.add(BatchNormalization(momentum=0.8))# convolutional layer with filters = 1generator.add(Conv2D(1, kernel_size=3, padding="same", activation="relu"))generator.summary() # prints the model summary"""We don't add upsampling here because the image size of 28 × 28 is equal to the image size in the MNIST dataset. You can adjust this for your own problem."""noise = Input(shape=(100,))fake_image = generator(noise)# Returns a model that takes the noise vector as an input and outputs the fake imagereturn Model(inputs=noise, outputs=fake_image)
3. 构建判别器模型
GANs的第二个主要组件是判别器。判别器只是一个传统的卷积分类器。判别器的输入是28×28×1的图像。我们希望有一些卷积层,然后是输出的全连接层。
与之前一样,我们希望得到一个Sigmoid输出,并且我们需要返回logits。对于卷积层的深度,我们可以从第一层开始使用32或64个过滤器,然后在添加层时将深度加倍。在这个实现中,我们将从64层开始,然后是128,然后是256。对于降采样,我们不使用池化层。相反,我们只使用步幅卷积层进行降采样,类似于Radford等人的实现。
我们还使用批归一化和dropout来优化训练。对于四个卷积层的每一层,通用方案是卷积 ⇒ 批归一化 ⇒ 泄漏的ReLU。
现在,让我们构建build_discriminator函数:
def build_discriminator():discriminator = Sequential()discriminator.add(Conv2D(32, kernel_size=3, strides=2, input_shape=(28,28,1), padding="same"))discriminator.add(LeakyReLU(alpha=0.2))discriminator.add(Dropout(0.25))discriminator.add(Conv2D(64, kernel_size=3, strides=2,padding="same"))discriminator.add(ZeroPadding2D(padding=((0,1),(0,1))))discriminator.add(BatchNormalization(momentum=0.8))discriminator.add(LeakyReLU(alpha=0.2))discriminator.add(Dropout(0.25))discriminator.add(Conv2D(128, kernel_size=3, strides=2, padding="same"))discriminator.add(BatchNormalization(momentum=0.8))discriminator.add(LeakyReLU(alpha=0.2))discriminator.add(Dropout(0.25))discriminator.add(Conv2D(256, kernel_size=3, strides=1, padding="same"))discriminator.add(BatchNormalization(momentum=0.8))discriminator.add(LeakyReLU(alpha=0.2))discriminator.add(Dropout(0.25))discriminator.add(Flatten())discriminator.add(Dense(1, activation='sigmoid'))img = Input(shape=(28,28,1))probability = discriminator(img)return Model(inputs=img, outputs=probability)
4. 构建组合模型
正如本系列的第二篇文章中所解释的,为了训练生成器,我们需要构建一个包含生成器和判别器的组合网络。组合模型以噪声信号(z)作为输入,并将判别器的预测输出作为虚假或真实输出。
重要的是要记住,我们希望在组合模型中禁用判别器的训练,正如本系列的第二篇文章中所解释的那样。在训练生成器时,我们不希望判别器更新权重,但我们仍然希望将判别器模型包含在生成器训练中。因此,我们创建一个包含两个模型的组合网络,但在组合网络中冻结判别器模型的权重:
optimizer = Adam(learning_rate=0.0002, beta_1=0.5)
discriminator = build_discriminator()
discriminator.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
discriminator.trainable = False# Build the generator
generator = build_generator()
z = Input(shape=(100,))
img = generator(z)
valid = discriminator(img)
combined = Model(inputs=z, outputs=valid)
combined.compile(loss='binary_crossentropy', optimizer=optimizer)
5. 构建训练函数
为了训练GAN模型,我们训练两个网络:判别器和我们在前面部分创建的组合网络。让我们构建train函数,该函数接受以下参数:
epoch
batch size 大小
save_interval,以指定多久保存一次结果
def train(epochs, batch_size=128, save_interval=50):valid = np.ones((batch_size, 1))fake = np.zeros((batch_size, 1))for epoch in range(epochs): # Train Discriminator networkidx = np.random.randint(0, X_train.shape[0], batch_size)imgs = X_train[idx]noise = np.random.normal(0, 1, (batch_size, 100))gen_imgs = generator.predict(noise)d_loss_real = discriminator.train_on_batch(imgs, valid)d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)g_loss = combined.train_on_batch(noise, valid)# printing progressprint("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" %(epoch, d_loss[0], 100*d_loss[1], g_loss))if epoch % save_interval == 0:plot_generated_images(epoch, generator)
我们还将创建另一个函数`plot_generated_images()` 来绘制生成的图像。
def plot_generated_images(epoch, generator, examples=100, dim=(10, 10),figsize=(10, 10)):noise = np.random.normal(0, 1, size=[examples, latent_dim])generated_images = generator.predict(noise)generated_images = generated_images.reshape(examples, 28, 28)plt.figure(figsize=figsize)for i in range(generated_images.shape[0]):plt.subplot(dim[0], dim[1], i+1)plt.imshow(generated_images[i], interpolation='nearest', cmap='gray_r')plt.axis('off')plt.tight_layout()plt.savefig('gan_generated_image_epoch_%d.png' % epoch
最后,让我们为训练GAN模型定义重要的变量和参数:
# Input shape
img_shape = (28,28,1)
channels = 1
latent_dim = 100
optimizer = Adam(0.0002, 0.5)# Build and compile the discriminator
discriminator = build_discriminator()
discriminator.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
# Build the generator
generator = build_generator()
# The generator takes noise as input and generates imgs
z = Input(shape=(latent_dim,))
img = generator(z)
# For the combined model we will only train the generator
discriminator.trainable = False
# The discriminator takes generated images as input and determines validity
valid = discriminator(img)
# The combined model (stacked generator and discriminator)
# Trains the generator to fool the discriminator
combined = Model(z, valid)
combined.compile(loss='binary_crossentropy', optimizer=optimizer)
6. 训练和观察结果
此时,代码实现已经完成,我们准备开始DCGAN的训练。要训练模型,请运行以下代码行:
train(epochs=1000, batch_size=32, save_interval=50)
这将在1,000个epochs上运行训练,并每50个epochs保存一次图像。当运行`train()` 函数时,训练进度将如下所示:
如下图所示,在epoch = 0时,图像只是随机噪声,没有明确的模式或有意义的数据。到了第50个epoch,图案已经开始形成。
在训练过程的后期,到了第1,000个epoch,您可以看到清晰的形状,可能能够猜测输入到GAN模型的训练数据的类型。
再快进到第10,000个epoch,您会发现生成器已经非常擅长重新创建训练数据集中不存在的新图像。
· END ·
HAPPY LIFE
本文仅供学习交流使用,如有侵权请联系作者删除
相关文章:
从零开始 - 在Python中构建和训练生成对抗网络(GAN)模型
生成对抗网络(GANs)是一种强大的生成模型,可以合成新的逼真图像。通过完整的实现过程,读者将对GANs在幕后的工作原理有深刻的理解。本教程首先导入必要的库并加载将用于训练GAN的Fashion-MNIST数据集。然后,提供了构建…...
OfficeWeb365 Indexs 任意文件读取漏洞复现
0x01 产品简介 OfficeWeb365 是专注于 Office 文档在线预览及PDF文档在线预览云服务,包括 Microsoft Word 文档在线预览、Excel 表格在线预览、Powerpoint 演示文档在线预览,WPS 文字处理、WPS 表格、WPS 演示及 Adobe PDF 文档在线预览。 0x02 漏洞概述 OfficeWeb365 /Pi…...
Crypto的简单应用-前后端加密传输
最近遇到一个数据脱敏处理的需求,想要用一种轻量级的技术实现,必须足够简单并且适用于所有场合如前后端加密传输、路由加密、数据脱敏等。抽时间研究了一下Crypto加密库的一些API,发现完全符合上述需求,扩展也比较容易。 1、前端加…...
Vue3-32-路由-重定向路由
什么是重定向 路由的重定向 :将匹配到的路由 【替换】 为另一个路由。 redirect : 重定向的关键字。 重定向的特点 1、重定向是路由的直接替换,路由的地址是直接改变的; 2、在没有子路由配置的情况下,重定向的路由可以省略 component 属性的配…...
如何用js动态修改字体大小
在项目中,我们常常会遇到使用v-html渲染文本的情况。 如果需要点击大中小三个字号按钮,需要修改字体的大小。那我们应该怎么做呢 function fontSize(element, type) {let size {big: 22,middle: 16,small: 12};var result element.innerHTML.replac…...
【BIG_FG_CSDN】C++ 数组与指针 (个人向——学习笔记)
一维数组 在内存占用连续存储单元的相同类型数据序列的存储。 数组是静态存储器的块;在编译时确定大小后才能使用; 其声明格式如下: 元素类型 数组名[常量];元素类型:数组中元素的数据类型; 常量&#…...
桌面天气预报软件 Weather Widget free mac特点介绍
Weather Widget free for Mac多种吸引人的小部件设计可供选择,可以随时了解天气!还可以在Dock和菜单栏中为您提供简短的天气预报或当前状况的概述。 Weather Widget free for Mac软件介绍 始终在桌面上使用时尚的天气小部件来随时了解天气!多…...
HarmonyOS应用开发-搭建开发环境
本文介绍如何搭建 HarmonyOS 应用的开发环境,介绍下载安装 DevEco Studio 开发工具和 SDK 的详细流程。华为鸿蒙 DevEco Studio 是面向全场景的一站式集成开发环境,面向全场景多设备,提供一站式的分布式应用开发平台,支持分布式多…...
<JavaEE> TCP 的通信机制(五) -- 延时应答、捎带应答、面向字节流
目录 TCP的通信机制的核心特性 七、延时应答 1)什么是延时应答? 2)延时应答的作用 八、捎带应答 1)什么是捎带应答? 2)捎带应答的作用 九、面向字节流 1)沾包问题 2)“沾包…...
电脑怎么设置代理IP上网?如何隐藏自己电脑的真实IP?
在现代互联网中,代理IP已成为许多用户保护隐私和上网安全的重要手段。通过设置代理IP,用户可以隐藏自己的真实IP地址,提高上网的安全性,同时保护个人信息不被泄露。本文将详细介绍如何设置代理IP上网以及如何隐藏电脑的真实IP地址…...
Django信号机制源码分析(观察者模式)
Django信号的实现原理本质是设计模式中的观察者模式,浅谈Python设计模式 -- 观察者模式,也可以叫做发布-订阅模式,信号对象维护一个订阅者列表,当信号被触发时,它会遍历订阅者,依次通知它们。 先来回顾一下…...
MyBatis-config.xml配置文件
1、基本介绍: mybatis的核心配置文件(mybatis-config.xml),比如配置jdbc连接信息,注册mapper等等,我们需要对这个配置文件有详细的了解。 官网地址有详细介绍 mybatis – MyBatis 3 | 配置 2、properties属性 在通常的情况下&am…...
【Spring实战】17 REST服务介绍
文章目录 1. 为什么出现2. 拥有哪些优势3. Spring中的应用4. spring-boot-starter-data-rest总结 REST(Representational State Transfer)是一种软件架构风格,通常用于设计网络应用程序的服务接口。RESTful 服务是基于 REST 原则构建的网络服…...
java struts2教务管理系统Myeclipse开发mysql数据库struts2结构java编程计算机网页项目
一、源码特点 java struts2 教务管理系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助 struts2 框架开发,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境 为TOMCAT7.0,Myeclipse8.5开发,数据库…...
跟着cherno手搓游戏引擎【3】事件系统和预编译头文件
不多说了直接上代码,课程中的架构讲的比较宽泛,而且有些方法写完之后并未测试。所以先把代码写完。理解其原理,未来使用时候会再此完善此博客。 文件架构: Event.h:核心基类 #pragma once #include"../Core.h" #inclu…...
排序算法之快速排序
快速排序是一种高效的排序算法,它的基本思想是采用分治策略,将一个无序数组分割成两个子数组,分别对子数组进行排序,然后将两个排序好的子数组合并成一个有序数组。快速排序的性能优于归并排序,尤其在处理大规模数据时…...
Docker 从入门到实践:Docker介绍
前言 在当今的软件开发和部署领域,Docker已经成为了一个不可或缺的工具。Docker以其轻量级、可移植性和标准化等特点,使得应用程序的部署和管理变得前所未有的简单。无论您是一名开发者、系统管理员,还是IT架构师,理解并掌握Dock…...
用IDEA创建/同步到gitee(码云)远程仓库(保姆级详细)
前言: 笔者最近在学习java,最开始在用很笨的方法:先克隆远程仓库到本地,再把自己练习的代码从本地仓库上传到远程仓库,很是繁琐。后发现可以IDEA只需要做些操作可以直接把代码上传到远程仓库,也在网上搜了些…...
【Linux】进程控制深度了解
> 作者简介:დ旧言~,目前大二,现在学习Java,c,c,Python等 > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:熟练掌握Linux下的进程控制 > 毒鸡汤ÿ…...
kbdnso.dll文件缺失,软件或游戏报错的快速修复方法
很多小伙伴遇到电脑报错,提示“kbdnso.dll文件缺失,程序无法启动执行”时,不知道应该怎样处理,还以为是程序出现了问题,想卸载重装。 首先,先要了解“kbdnso.dll文件”是什么? kbdnso.dll是Win…...
Spring技术内幕笔记之IOC的实现
IOC容器的实现 依赖反转: 依赖对象的获得被反转了,于是依赖反转更名为:依赖注入。许多应用都是由两个或者多个类通过彼此的合作来实现业务逻辑的,这使得每个对象都需要与其合作的对象的引用,如果这个获取过程需要自身…...
kotlin foreach 循环
java中的foreach循环也使用于kotlin ,先回顾下java里面的foreach循环 java foreach循环格式 for(元素类型t 元素变量x : 遍历对象obj){引用了x的语句;} 例如: int[] intary {1,2,3,4};for (int a: intary) {Log.d("intary", String.value…...
分享相关知识
直接使用海龟图进行创作移动动态的游戏 这段代码是一个简单的turtle模块实现的小游戏,主要功能包括: 窗口和无人机初始化: 创建了一个turtle窗口,设置了窗口的背景颜色和标题。创建了一个表示无人机的turtle,形状为正…...
RabbitMQ(七)ACK 消息确认机制
目录 一、简介1.1 背景1.2 定义1.3 如何查看确认/未确认的消息数? 二、消息确认机制的分类2.1 消息发送确认1)ConfirmCallback方法2)ReturnCallback方法3)代码实现方式一:统一配置a.配置类a.生产者c.消费者d.测试结果 …...
ubuntu 编译内核报错
Ubuntu 编译 Linux 内核经常会遇到如下错误: 如果报错 canonical-certs.pem: 如下: make[1]: *** No rule to make target ‘debian/canonical-certs.pem’, needed by ‘certs/x509_certificate_list’. Stop. make: *** [Makefile:1868: …...
Python之自然语言处理库snowNLP
一、介绍 SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的,由于现在大部分的自然语言处理库基本都是针对英文的,于是写了一个方便处理中文的类库,并且和TextBlob不同的是&…...
C# 语法进阶 委托
1.委托 委托是一个引用类型,其实他是一个类,保存方法的指针 (指针:保存一个变量的地址)他指向一个方法,当我们调用委托的时候这个方法就立即被执行 关键字:delegate 运行结果: 思…...
开源可观测性平台Signoz(四)【链路监控及数据库中间件监控篇】
转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 前文链接: 开源可观测性平台Signoz系列(一)【开篇】 开源可观测性平台Signoz&…...
【嵌入式开发 Linux 常用命令系列 4.2 -- git .gitignore 使用详细介绍】
文章目录 .gitignore 使用详细介绍.gitignore 文件的位置.gitignore 语法规则使用示例注意事项 .gitignore 使用详细介绍 .gitignore 文件是一个特殊的文本文件,它告诉 Git 哪些文件或目录是可以被忽略的,即不应该被纳入版本控制系统。这主要用于避免一…...
【熔断限流组件resilience4j和hystrix】
文章目录 🔊博主介绍🥤本文内容起因resilience4j落地实现pom.xml依赖application.yml配置接口使用 hystrix 落地实现pom.xml依赖启动类上添加注解接口上使用 📢文章总结📥博主目标 🔊博主介绍 🌟我是廖志伟…...
深圳网站建设公司报价单/虎门今日头条新闻
API 现在无处不在。因此,现代开发人员需要一种高效的查询语言 GraphQL 如果您不熟悉 API(应用程序接口),它是 2 个应用程序相互交互的一种方式。例如,如果您单击 Facebook 上的“上传您的照片”按钮,API 将允许您将您的照片上传到 Facebook。有成千上万的 API 可供程序员…...
搜狗站长工具/长沙seo优化首选
对于二进制文件的编辑,windows下有一款很优秀的软件winhex,会让你的生活非常简单。但是到了linux 下面似乎没有专门的二进制编辑器,但是大家不要忘了vim虽然vim并不是针对二进制编辑而设计,但是通过技巧也可让vim成为很好用的二进…...
做年报的网站/搜索引擎推广是什么意思
Linux命令--du 目录 一、用途 二、命令格式: 三、命令参数 四、实例 一、用途 Linux du命令是查看当前指定文件或目录(会递归显示子目录)占用磁盘空间大小 二、命令格式: du [选项][文件] 三、命令参数 -a或-all 显示目录中个别文件的大小。…...
福州建设注册中心网站/关键词查询网
DateTime.Now;//当前时间 DateTime.AddDays(1);//明天时间 eg: DateTime str DateTime.Now; DateTime str2 str.AddDays(1);...
如何查询网站空间商/手游推广代理平台有哪些
今天介绍一下lamp环境的配置。 服务器用的是阿里云的服务器。 L:centos、A:apache、M:mysql、P:php (一)安装apache 我们这里安装的是httpd (1)安装httpd # yum install httpd…...
wordpress用户中心授权码/营业推广策略
阅读本文前,请您先点击上面的蓝色字体,再点击“关注”,这样您就可以继续免费收到最新文章了。每天都有分享。完全是免费订阅,请放心关注。 …...