【Week-G1】调用官方GAN实现MNIST数字识别,Pytorch框架

文章目录

  • 1. 准备数据
    • 1.1 配置超参数
    • 1.2 下载数据
    • 1.3 配置数据
  • 2. 创建模型
    • 2.1 定义鉴别器
    • 2.2 定义生成器
  • 3. 训练模型
    • 3.1 创建实例
    • 3.2 开始训练
    • 3.3 保存模型
  • 4. 什么是GAN(对抗生成网络)?

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊 | 接辅导、项目定制

说明:
(1)使用CPU时,屏蔽.cuda(),否则报错:
在这里插入图片描述

1. 准备数据

系统环境:
语言:Python3.7.8
编译器:VSCode
深度学习框架:torch 1.13.1

1.1 配置超参数

print("***********1.1 配置超参数*****************")
import argparse
import os
import numpy as np
import torchvision.transforms as transforms
from torchvision.utils import save_image
from torchvision import datasets
from torch.utils.data import DataLoader
from torch.autograd import Variable
import torch.nn as nn
import torch
## 创建文件夹
# 程序在路径 D:\jupyter notebook\DL-100-days\下运行,也就是下方的 ./
os.makedirs("./GAN/G1/images/", exist_ok=True)  # 记录训练过程的图片效果
os.makedirs("./GAN/G1/save/", exist_ok=True)    # 训练完成时,模型的保存位置
os.makedirs("./GAN/G1/mnist/", exist_ok=True)   # 下载数据集存放的位置
## 超参数配置
n_epochs  = 50
batch_size = 64
lr  = 0.0002
b1 = 0.5
b2 = 0.999
n_cpu = 2
latent_dim = 100
img_size = 28
channels = 1
sample_interval = 500
#图像的尺寸(1, 28, 28),和图像的像素面积(784)
img_shape = (channels, img_size, img_size)
img_area = np.prod(img_shape)
#设置cuda: (cuda:0)
cuda = True if torch.cuda.is_available() else False
print("CUDA: ", cuda)
print("\n")

文件路径如下图:
在这里插入图片描述
使用CPU版本,所以打印的CUDA结果为FALSE;
在这里插入图片描述

1.2 下载数据

print("***********2. 下载数据*****************")
mnist = datasets.MNIST(root='./datasets/', train=True, download=True, transform=transforms.Compose([transforms.Resize(img_size), transforms.ToTensor(), transforms.Normalize([0.5], [0.5])]),
)
print("\n")

在这里插入图片描述

1.3 配置数据

print("***********1.3 配置数据*****************")
dataloader = DataLoader(mnist,batch_size=batch_size,shuffle=True
)
print("\n")

2. 创建模型

2.1 定义鉴别器

print("***********2. 创建模型********************")
print("***********2.1 定义鉴别器*****************")
class Discriminator(nn.Module):def __init__(self):super(Discriminator, self).__init__()self.model = nn.Sequential(nn.Linear(img_area, 512),nn.LeakyReLU(0.2, inplace=True),nn.Linear(512, 256),nn.LeakyReLU(0.2, inplace=True),nn.Linear(256, 1),nn.Sigmoid(),)def forward(self, img):img_flat = img.view(img.size(0), -1)validity = self.model(img_flat)return validity
print("\n")

2.2 定义生成器

print("***********2.2 定义生成器*****************")
class Generate(nn.Module):def __init__(self):super(Generate, self).__init__()def block(in_feat, out_feat, normalize=True):layers = [nn.Linear(in_feat, out_feat)]if normalize:layers.append(nn.BatchNorm1d(out_feat, 0.8))layers.append(nn.LeakyReLU(0.2, inplace=True))return layersself.model = nn.Sequential(*block(latent_dim, 128, normalize=False),*block(128, 256),*block(256, 512),*block(512, 1024),nn.Linear(1024, img_area),nn.Tanh())def forward(self, z):imgs = self.model(z)imgs = imgs.view(imgs.size(0), *img_shape)return imgs
print("\n")

3. 训练模型

3.1 创建实例

print("***********3. 训练模型*****************")
print("***********3.1 创建实例****************")
generator = Generate()
discriminator = Discriminator()criterion = torch.nn.BCELoss()optimizer_G = torch.optim.Adam(generator.parameters(), lr=lr, betas=(b1, b2))
optimizer_D = torch.optim.Adam(discriminator.parameters(), lr=lr, betas=(b1, b2))if torch.cuda.is_available():generator = generator.cuda()discriminator = discriminator#.cuda()criterion = criterion.cuda()
print("\n")

3.2 开始训练

print("***********3.2 开始训练*****************")
for epoch in range(n_epochs):  # epoch:50for i, (imgs, _) in enumerate(dataloader):## =============================训练判别器==================## view(): 相当于numpy中的reshape,重新定义矩阵的形状, 相当于reshape(128,784)  原来是(128, 1, 28, 28)imgs = imgs.view(imgs.size(0), -1)  # 将图片展开为28*28=784  imgs:(64, 784)real_img = Variable(imgs).cuda()  # 将tensor变成Variable放入计算图中,tensor变成variable之后才能进行反向传播求梯度real_label = Variable(torch.ones(imgs.size(0), 1))#.cuda()  ## 定义真实的图片label为1fake_label = Variable(torch.zeros(imgs.size(0), 1))#.cuda()  ## 定义假的图片的label为0## ---------------------##  Train Discriminator## 分为两部分:1、真的图像判别为真;2、假的图像判别为假## ---------------------## 计算真实图片的损失real_out = discriminator(real_img)  # 将真实图片放入判别器中loss_real_D = criterion(real_out, real_label)  # 得到真实图片的lossreal_scores = real_out  # 得到真实图片的判别值,输出的值越接近1越好## 计算假的图片的损失## detach(): 从当前计算图中分离下来避免梯度传到G,因为G不用更新z = Variable(torch.randn(imgs.size(0), latent_dim))#.cuda()  ## 随机生成一些噪声, 大小为(128, 100)fake_img = generator(z).detach()  ## 随机噪声放入生成网络中,生成一张假的图片。fake_out = discriminator(fake_img)  ## 判别器判断假的图片loss_fake_D = criterion(fake_out, fake_label)  ## 得到假的图片的lossfake_scores = fake_out  ## 得到假图片的判别值,对于判别器来说,假图片的损失越接近0越好## 损失函数和优化loss_D = loss_real_D + loss_fake_D  # 损失包括判真损失和判假损失optimizer_D.zero_grad()  # 在反向传播之前,先将梯度归0loss_D.backward()  # 将误差反向传播optimizer_D.step()  # 更新参数## -----------------##  Train Generator## 原理:目的是希望生成的假的图片被判别器判断为真的图片,## 在此过程中,将判别器固定,将假的图片传入判别器的结果与真实的label对应,## 反向传播更新的参数是生成网络里面的参数,## 这样可以通过更新生成网络里面的参数,来训练网络,使得生成的图片让判别器以为是真的, 这样就达到了对抗的目的## -----------------z = Variable(torch.randn(imgs.size(0), latent_dim))#.cuda()  ## 得到随机噪声fake_img = generator(z)  ## 随机噪声输入到生成器中,得到一副假的图片output = discriminator(fake_img)  ## 经过判别器得到的结果## 损失函数和优化loss_G = criterion(output, real_label)  ## 得到的假的图片与真实的图片的label的lossoptimizer_G.zero_grad()  ## 梯度归0loss_G.backward()  ## 进行反向传播optimizer_G.step()  ## step()一般用在反向传播后面,用于更新生成网络的参数## 打印训练过程中的日志## item():取出单元素张量的元素值并返回该值,保持原元素类型不变if (i + 1) % 300 == 0:print("[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f] [D real: %f] [D fake: %f]"% (epoch, n_epochs, i, len(dataloader), loss_D.item(), loss_G.item(), real_scores.data.mean(),fake_scores.data.mean()))## 保存训练过程中的图像batches_done = epoch * len(dataloader) + iif batches_done % sample_interval == 0:save_image(fake_img.data[:25], "./GAN/G1/images/%d.png" % batches_done, nrow=5, normalize=True)
print("\n")

训练结果:

***********3.2 开始训练*****************
[Epoch 0/50] [Batch 299/938] [D loss: 1.363185] [G loss: 1.811396] [D real: 0.922554] [D fake: 0.692913]
[Epoch 0/50] [Batch 599/938] [D loss: 0.753042] [G loss: 2.229975] [D real: 0.815112] [D fake: 0.410212]
[Epoch 0/50] [Batch 899/938] [D loss: 1.049122] [G loss: 1.940738] [D real: 0.789812] [D fake: 0.548839]
... ... ...
[Epoch 48/50] [Batch 299/938] [D loss: 0.956054] [G loss: 1.398938] [D real: 0.661061] [D fake: 0.327662]
[Epoch 48/50] [Batch 599/938] [D loss: 1.070262] [G loss: 0.950201] [D real: 0.538358] [D fake: 0.234096]
[Epoch 48/50] [Batch 899/938] [D loss: 1.012980] [G loss: 1.247620] [D real: 0.650552] [D fake: 0.319423]
[Epoch 49/50] [Batch 299/938] [D loss: 1.254801] [G loss: 1.048441] [D real: 0.522079] [D fake: 0.313869]
[Epoch 49/50] [Batch 599/938] [D loss: 0.884523] [G loss: 1.709880] [D real: 0.767361] [D fake: 0.402201]
[Epoch 49/50] [Batch 899/938] [D loss: 1.019181] [G loss: 1.608823] [D real: 0.739194] [D fake: 0.421154]

./GAN/G1/images/下的缩略图如下:
在这里插入图片描述
部分详细图如下:
在这里插入图片描述

3.3 保存模型

print("***********3.3 保存模型*****************")
torch.save(generator.state_dict(), "./GAN/G1/save/generator.pth")
torch.save(discriminator.state_dict(). "./GAN/G1/save/discriminator.pth")
print("\n")

保存的模型文件如下:
在这里插入图片描述

4. 什么是GAN(对抗生成网络)?

【详解1】
【详解2】

机器学习的模型大体分为两类:判别模型(Discriminative Model)和生成模型(Generative Model)。

  • 判别模型:输入变量,使用模型进行预测
  • 生成模型:给出目标的隐含信息,随机产生观测数据。比如:给出一系列猫的图片,来生成一张新的猫的图片。重要点在于“生成”二字。

GAN:适用于无监督学习,该网络的框架由(至少)两个模块构成,即判别模型(Discriminative Model)和生成模型(Generative Model),通过二者的互相博弈学习来产生相当好的输出。

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

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

相关文章

【BES2500x系列 -- RTX5操作系统】深入探索CMSIS-RTOS RTX -- 同步与通信篇 -- 信号量和互斥锁 --(三)

💌 所属专栏:【BES2500x系列】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &#x1f49…

帕金森患者吞咽困难?如何让饮食更顺畅!

在帕金森病患者的日常生活中,吞咽困难是一个常见而又棘手的问题。它不仅影响了患者的饮食质量,还可能导致营养不良、吸入性肺炎等严重并发症。那么,面对帕金森综合症导致的吞咽困难,我们该如何应对呢? 一、了解帕金森综…

一个去掉PDF背景水印的思路

起因 昨天测试 使用“https://github.com/VikParuchuri/marker” 将 pdf 转 Markdown的过程中,发现转换后的文件中会保护一些背景图片,是转换过程中,程序把背景图识别为了内容。于是想着怎么把背景图片去掉。 背景水印图片的特征 我这里拿…

GPT-5的到来~

IT之家6月22日消息,在美国达特茅斯工程学院周四公布的采访中,OpenAI首席技术官米拉穆拉蒂被问及GPT-5是否会在明年发布,给出了肯定答案并表示将在一年半后发布。此外,穆拉蒂在采访中还把GPT-4到GPT-5的飞跃描述为高中生到博士生的成长。“像 GPT-4 这样的系统则更像是聪明的…

openGuass数据库极简版安装和远程连接实战(阿里云服务器操作)

openGauss部署之后,在服务器上提供了在命令行下运行的数据库连接工具gsql。此工具除了具备操作数据库的基本功能,还提供了若干高级特性,便于用户使用。但图形化工具除了官方的Data Studio外,还可以使用SQLynx进行连接(…

Taro + vue3 中微信小程序中实现拉起支付

在前端开发中 H5 的拉起支付和微信小程序的拉起支付 是不太一样的 现在分享一下微信小程序中的拉起支付 逻辑都在后端 我是用的Taro 框架 其实就是一个Api Taro 文档

酷开系统丨开启家庭智能教育让学习成为一种乐趣

在数字化时代,孩子们接触的信息日益增多,而酷开系统洞察到了家长对孩子成长环境的关切。酷开系统,作为家庭娱乐与教育的融合平台,不仅注重提供丰富的教育资源,更致力于创造一个健康、有益的学习和娱乐环境。 在酷开系…

【数据同步】什么是ETL增量抽取?

目录 一、什么是ETL增量抽取 二、企业如何应用ETL增量抽取 三、如何进行ETL增量抽取 1.基于时间戳的增量抽取 2.基于主键的增量抽取 在当今信息化时代,数据的快速增长和多样化使得企业面临着巨大的数据管理挑战。为了高效地处理和利用数据,ETL&#xff0…

BeanFactoryPostProcessor源码分析

BeanFactoryPostProcessor是Spring框架中的一个重要接口,它允许开发者在容器实例化和属性赋值完成后,初始化Bean之前,执行一些自定义逻辑。BeanFactoryPostProcessor接口定义了一个方法: public interface BeanFactoryPostProces…

地球地图:快速进行先进土地监测和气候评估的新工具Earth Map

地球地图:快速进行先进土地监测和气候评估的新工具 这个工具是居于GEE 开发的多功能的一个APP应用,主要进行土地监测和气候评估 Earth Map 什么是地球地图? 地球地图是联合国粮食及农业组织(粮农组织)在粮农组织与谷歌合作框架内开发的一个创新、免费和开放源码的工具。…

NC65[Cloud]用户密码SQL实现

--NC65用户密码加密方式为:U_U--V MD5(用户的CUSERID字段值密码明文)SELECT U_U--VSTUFF(master.dbo.fn_varbintohexstr(HASHBYTES(MD5,CONVERT(VARCHAR(50), cuserid密码))),1,2,) AS NC65 FROM sm_user --NC Cloud用户密码加密方式为:S_S Base64编码(SHA256(用户的CUSERID…

EasyExcel动态表头多sheet录入,单元格操作样式,自动修改单元格格式

EasyExcel动态表头多sheet录入,单元格操作样式,自动修改单元格格式 说明 EasyExcel是一款开源的Java库,用于读取、写入和操作Excel文件。它是阿里巴巴集团开发的一款高效、功能丰富且易于使用的Excel操作工具。 EasyExcel提供了简洁的API,使得读写Excel…

定个小目标之刷LeetCode热题(31)

238. 除自身以外数组的乘积 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。请 不要使用除法&#…

安装docker版redis集群

本文介绍在docker中搭建一个redis集群,之前讲过 一文搞定Redis主从复制,哨兵集群,Cluster集群搭建与测试,还有 安装docker版redis并挂载配置文件redis.conf,结合这两篇文章,也可以搭建redis集群,需要的朋友可以回顾一以下~ 一、环境准备 这次的redis集群将搭建在一台…

零知识证明基础:对称加密与非对称加密

1、绪论 在密码学体系中,对称加密、非对称加密、单向散列函数、消息认证码、数字签名和伪随机数生成器被统称为密码学家的工具箱。其中,对称加密和非对称加密主要是用来保证机密性;单向散列函数用来保证消息的完整性;消息认证码的…

权限 chmod

参考: Linux chmod 命令 | 菜鸟教程 (runoob.com) Linux chmod(英文全拼:change mode)命令是控制用户对文件的权限的命令 Linux/Unix 的文件调用权限分为三级 : 文件所有者(Owner Users)用户组&#xff08…

Arduino - MG996R

Arduino - MG996R In this tutorial, we are going to learn how to use the MG996R high-torque servo motor with Arduino. 在本教程中,我们将学习如何将MG996R高扭矩伺服电机与Arduino一起使用。 Hardware Required 所需硬件 1Arduino UNO or Genuino UNO Ard…

windows系统如何快速查看显卡详情信息

winR,输入dxdiag 打开DirectX诊断工具,可以看到显卡的详细硬件信息

面试经典sql题

假设有两张表,表1为份额表,表2为行业表。份额表与行业表依靠产品id相关联。现在需要查询表2中行业分类字段为1的所有行业的占比变动情况,占比变动计算公式为:最后一天(假设为20240531)的行业占比减去第一天…

小抄 20240625

1 先照顾好自己,有余力,再去帮助别人,否则,帮了别人,自己落得个生活不能自理,整体并没有变得更好。 2 如果几十年的沉默没有给你带来任何好处,一定要试着去表达,去主动暴露自己&am…