图像生成:Pytorch实现一个简单的对抗生成网络模型

图像生成:Pytorch实现一个简单的对抗生成网络模型

  • 前言
  • 相关介绍
  • 具体步骤
    • 准备并读取数据集
    • 定义生成器
    • 定义判别器
    • 定义损失函数
    • 定义优化器
    • 开始训练
    • 完整代码
  • 训练生成的图片

前言

  • 由于本人水平有限,难免出现错漏,敬请批评改正。
  • 更多精彩内容,可点击进入人工智能知识点专栏、Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏或我的个人主页查看
  • 基于DETR的人脸伪装检测
  • YOLOv7训练自己的数据集(口罩检测)
  • YOLOv8训练自己的数据集(足球检测)
  • YOLOv5:TensorRT加速YOLOv5模型推理
  • YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
  • 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
  • YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
  • YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
  • Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
  • YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
  • 使用Kaggle GPU资源免费体验Stable Diffusion开源项目

相关介绍

对抗生成网络(Adversarial Generative Networks,简称GANs)是由伊恩·古德费洛(Ian Goodfellow)等人在2014年提出的深度学习框架,主要用于无监督学习中的数据生成任务。GAN的设计灵感来源于博弈论中的极小极大游戏,在机器学习领域开辟了一种全新的生成模型方法。

GAN包含两个主要组成部分:

  1. 生成器(Generator, G)

    • 生成器G是一个神经网络,它的功能是从随机噪声向量(通常来自高斯分布或其他先验分布)出发,通过一系列变换来生成新的数据样本,这些样本应该尽可能接近于训练数据的真实分布。
    • G的目标是尽可能地“欺骗”判别器,使其无法区分生成的数据和真实数据。
  2. 判别器(Discriminator, D)

    • 判别器D也是一个神经网络,它的作用是接收输入的样本,并将其分类为“真”(来自真实数据分布)或“假”(来自生成器产生的分布)。
    • D的目标是准确地区分真实数据和伪造数据,从而提高自身鉴别能力。

训练过程中,GAN采用了极小极大博弈策略,具体步骤如下:

  • 先固定判别器参数,更新生成器参数以使得生成的数据更有可能被判别器误认为真实数据;
  • 再固定生成器参数,更新判别器参数以更好地区分真实数据和生成器生成的伪数据。

这种交替优化的方式促使两个网络性能不断提升,直到达到纳什均衡,此时生成器能够生成非常逼真的新样本,而判别器再也无法有效区分真实数据和生成数据。

GAN在图像生成、图像到图像转换、视频生成、音频合成等多个领域都取得了显著成果,并且随着研究的深入,衍生出了许多改进版本和变体,比如条件GAN(Conditional GANs)、 Wasserstein GAN(WGAN)、CycleGAN等,进一步提高了生成效果并拓展了应用范围。
在这里插入图片描述

具体步骤

准备并读取数据集

以mnist数据集为例。

# Configure data loader
os.makedirs("./data/mnist", exist_ok=True)
dataloader = torch.utils.data.DataLoader(
    datasets.MNIST(
        "./data/mnist",
        train=True,
        download=True,
        transform=transforms.Compose(
            [transforms.Resize(opt.img_size), transforms.ToTensor(), transforms.Normalize([0.5], [0.5])]
        ),
    ),
    batch_size=opt.batch_size,
    shuffle=True,
)

定义生成器

class Generator(nn.Module):
    def __init__(self):
        super(Generator, 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 layers

        self.model = nn.Sequential(
            *block(opt.latent_dim, 128, normalize=False),
            *block(128, 256),
            *block(256, 512),
            *block(512, 1024),
            nn.Linear(1024, int(np.prod(img_shape))),
            nn.Tanh()
        )

    def forward(self, z):
        img = self.model(z)
        img = img.view(img.size(0), *img_shape)
        return img

定义判别器

class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()

        self.model = nn.Sequential(
            nn.Linear(int(np.prod(img_shape)), 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

定义损失函数

# Loss function
adversarial_loss = torch.nn.BCELoss()

定义优化器

# Optimizers
optimizer_G = torch.optim.Adam(generator.parameters(), lr=opt.lr, betas=(opt.b1, opt.b2))
optimizer_D = torch.optim.Adam(discriminator.parameters(), lr=opt.lr, betas=(opt.b1, opt.b2))

开始训练

# ----------
#  Training
# ----------

for epoch in range(opt.n_epochs):
    for i, (imgs, _) in enumerate(dataloader):

        # Adversarial ground truths
        valid = Variable(Tensor(imgs.size(0), 1).fill_(1.0), requires_grad=False)
        fake = Variable(Tensor(imgs.size(0), 1).fill_(0.0), requires_grad=False)

        # Configure input
        real_imgs = Variable(imgs.type(Tensor))

        # -----------------
        #  Train Generator
        # -----------------

        optimizer_G.zero_grad()

        # Sample noise as generator input
        z = Variable(Tensor(np.random.normal(0, 1, (imgs.shape[0], opt.latent_dim))))

        # Generate a batch of images
        gen_imgs = generator(z)

        # Loss measures generator's ability to fool the discriminator
        # 生成器损失,目的是生成的图像,逼近真是图像,是判别器认为是真
        g_loss = adversarial_loss(discriminator(gen_imgs), valid)

        g_loss.backward()
        optimizer_G.step()

        # ---------------------
        #  Train Discriminator
        # ---------------------

        optimizer_D.zero_grad()

        # Measure discriminator's ability to classify real from generated samples
        # 真实图像在判别器的目标函数损失,即判别器应该判为真
        real_loss = adversarial_loss(discriminator(real_imgs), valid)
        # 生成器生成出来的图像在判别器的目标函数损失,即判别器应该判为假
        fake_loss = adversarial_loss(discriminator(gen_imgs.detach()), fake)
        # 判别器损失,目的是判别生成的图像是假
        d_loss = (real_loss + fake_loss) / 2

        d_loss.backward()
        optimizer_D.step()

        print(
            "[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f]"
            % (epoch, opt.n_epochs, i, len(dataloader), d_loss.item(), g_loss.item())
        )

完整代码

import argparse
import os
import numpy as np
import math

import torchvision.transforms as transforms
from torchvision.utils import save_image

from torch.utils.data import DataLoader
from torchvision import datasets
from torch.autograd import Variable

import torch.nn as nn
import torch.nn.functional as F
import torch

os.makedirs("images", exist_ok=True)

parser = argparse.ArgumentParser()
parser.add_argument("--n_epochs", type=int, default=100, help="number of epochs of training")
parser.add_argument("--batch_size", type=int, default=128, help="size of the batches")
parser.add_argument("--lr", type=float, default=0.0002, help="adam: learning rate")
parser.add_argument("--b1", type=float, default=0.5, help="adam: decay of first order momentum of gradient")
parser.add_argument("--b2", type=float, default=0.999, help="adam: decay of first order momentum of gradient")
parser.add_argument("--n_cpu", type=int, default=8, help="number of cpu threads to use during batch generation")
parser.add_argument("--latent_dim", type=int, default=100, help="dimensionality of the latent space")
parser.add_argument("--img_size", type=int, default=28, help="size of each image dimension")
parser.add_argument("--channels", type=int, default=1, help="number of image channels")
parser.add_argument("--sample_interval", type=int, default=400, help="interval betwen image samples")
opt = parser.parse_args()
print(opt)

img_shape = (opt.channels, opt.img_size, opt.img_size)

cuda = True if torch.cuda.is_available() else False


class Generator(nn.Module):
    def __init__(self):
        super(Generator, 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 layers

        self.model = nn.Sequential(
            *block(opt.latent_dim, 128, normalize=False),
            *block(128, 256),
            *block(256, 512),
            *block(512, 1024),
            nn.Linear(1024, int(np.prod(img_shape))),
            nn.Tanh()
        )

    def forward(self, z):
        img = self.model(z)
        img = img.view(img.size(0), *img_shape)
        return img


class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()

        self.model = nn.Sequential(
            nn.Linear(int(np.prod(img_shape)), 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


# Loss function
adversarial_loss = torch.nn.BCELoss()

# Initialize generator and discriminator
generator = Generator()
discriminator = Discriminator()

if cuda:
    generator.cuda()
    discriminator.cuda()
    adversarial_loss.cuda()

# Configure data loader
os.makedirs("./data/mnist", exist_ok=True)
dataloader = torch.utils.data.DataLoader(
    datasets.MNIST(
        "./data/mnist",
        train=True,
        download=True,
        transform=transforms.Compose(
            [transforms.Resize(opt.img_size), transforms.ToTensor(), transforms.Normalize([0.5], [0.5])]
        ),
    ),
    batch_size=opt.batch_size,
    shuffle=True,
)

# Optimizers
optimizer_G = torch.optim.Adam(generator.parameters(), lr=opt.lr, betas=(opt.b1, opt.b2))
optimizer_D = torch.optim.Adam(discriminator.parameters(), lr=opt.lr, betas=(opt.b1, opt.b2))


Tensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor

# ----------
#  Training
# ----------

for epoch in range(opt.n_epochs):
    for i, (imgs, _) in enumerate(dataloader):

        # Adversarial ground truths
        valid = Variable(Tensor(imgs.size(0), 1).fill_(1.0), requires_grad=False)
        fake = Variable(Tensor(imgs.size(0), 1).fill_(0.0), requires_grad=False)

        # Configure input
        real_imgs = Variable(imgs.type(Tensor))

        # -----------------
        #  Train Generator
        # -----------------

        optimizer_G.zero_grad()

        # Sample noise as generator input
        z = Variable(Tensor(np.random.normal(0, 1, (imgs.shape[0], opt.latent_dim))))

        # Generate a batch of images
        gen_imgs = generator(z)

        # Loss measures generator's ability to fool the discriminator
        g_loss = adversarial_loss(discriminator(gen_imgs), valid)

        g_loss.backward()
        optimizer_G.step()

        # ---------------------
        #  Train Discriminator
        # ---------------------

        optimizer_D.zero_grad()

        # Measure discriminator's ability to classify real from generated samples
        real_loss = adversarial_loss(discriminator(real_imgs), valid)
        fake_loss = adversarial_loss(discriminator(gen_imgs.detach()), fake)
        d_loss = (real_loss + fake_loss) / 2

        d_loss.backward()
        optimizer_D.step()

        print(
            "[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f]"
            % (epoch, opt.n_epochs, i, len(dataloader), d_loss.item(), g_loss.item())
        )

        batches_done = epoch * len(dataloader) + i
        if batches_done % opt.sample_interval == 0:
            save_image(gen_imgs.data[:25], "images/%d.png" % batches_done, nrow=5, normalize=True)

在这里插入图片描述

训练生成的图片

在这里插入图片描述

  • 由于本人水平有限,难免出现错漏,敬请批评改正。
  • 更多精彩内容,可点击进入人工智能知识点专栏、Python日常小操作专栏、OpenCV-Python小应用专栏、YOLO系列专栏、自然语言处理专栏或我的个人主页查看
  • 基于DETR的人脸伪装检测
  • YOLOv7训练自己的数据集(口罩检测)
  • YOLOv8训练自己的数据集(足球检测)
  • YOLOv5:TensorRT加速YOLOv5模型推理
  • YOLOv5:IoU、GIoU、DIoU、CIoU、EIoU
  • 玩转Jetson Nano(五):TensorRT加速YOLOv5目标检测
  • YOLOv5:添加SE、CBAM、CoordAtt、ECA注意力机制
  • YOLOv5:yolov5s.yaml配置文件解读、增加小目标检测层
  • Python将COCO格式实例分割数据集转换为YOLO格式实例分割数据集
  • YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)
  • 使用Kaggle GPU资源免费体验Stable Diffusion开源项目

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【网站项目】校园失物招领小程序

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

java数据结构与算法刷题-----LeetCode210. 课程表 II

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 深度优先遍历但不进行逆拓扑排序(不用栈)…

三年Android开发经验面试经历分享

最近,参加了多家公司的面试,下面是我所经历的一些面试问题及自己的回答思路。 一、京东面试 一面: 项目内容:主要讲述了在实习期间参与的项目,以及在项目中负责的工作和取得的成果。MVP模式:解释了MVP模…

特征融合篇 | YOLOv8改进之将Neck网络更换为多级特征融合金字塔HS-FPN | 助力小目标检测

前言:Hello大家好,我是小哥谈。HS-FPN(Hierarchical Scale Feature Pyramid Network)是一种用于目标检测任务的网络结构。它是在传统的Feature Pyramid Network(FPN)基础上进行改进的。HS-FPN的主要目标是解决目标检测中存在的多尺度问题。在传统的FPN中,通过在不同层级…

机器学习实训 Day1

线性回归练习 Day1 手搓线性回归 随机初始数据 import numpy as np x np.array([56, 72, 69, 88, 102, 86, 76, 79, 94, 74]) y np.array([92, 102, 86, 110, 130, 99, 96, 102, 105, 92])from matplotlib import pyplot as plt # 内嵌显示 %matplotlib inlineplt.scatter…

Android自定义控件ScrollView实现上下滑动功能

本文实例为大家分享了Android ScrollView实现上下滑动功能的具体代码,供大家参考,具体内容如下 package com.example.zhuang; import android.content.Context; import android.util.AttributeSet; import android.util.DisplayMetrics; import android…

什么是生成式AI?有哪些特征类型

生成式AI是人类一种人工智能技术,可以生成各种类型的内容,包括文本、图像、音频和合成数据。那么什么是人工智能?人工智能和机器学习之间的区别是什么?有哪些技术特征? 人工智能是一门学科,是计算机科学的一…

日志监控思路分享,只监控日志内容,不存储

有一个这样的需求,就是实时监控日志文件的内容,不需要存储,仅当某行日志内容触发某个规则时调用一段业务逻辑就行了。比如用户触发限流规则,就将其封禁并发送钉钉通知到运维群。 看到这个需求首先想到的就是日志采集工具&#xff…

【ARM 裸机】汇编 led 驱动之原理分析

1、我们为什么要学习汇编??? 之前我们或许接触过 STM32 以及其他的 32 位的 MCU ,都是基于 C 语言环境进行编程的,都没怎么注意汇编,是因为 ST 公司早已将启动文件写好了,新建一个 STM32 工程的时候&#…

网站HTTP升级成为HTTPS的方法

将网站从HTTP免费升级为HTTPS,您可以按照以下步骤操作: 1. 选择证书颁发机构(CA): - 为了免费升级,您可以选择使用JoySSL这样的公益项目。JoySSL提供免费、自动化的SSL/TLS证书颁发服务,适用于各…

HAL STM32F4内部温度读取+ADC阻塞式读取

HAL STM32F4内部温度读取ADC阻塞式读取 📍相关篇《STM32F103VET6基于STM32CubeMX 配置非DMA方式获取内部温度》 🔖对于大多数stm32型号,基本上内部都集成了温度传感器。 ⛳不同型号的STM32单片机,计算温度的公式差异 &#x1f33f…

Vue2和Vue3组件通信:父子与兄弟间的桥梁

🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…

网盘——登录跳转

在界面设计这块,当登录界面上输入的账号和密码都正确的情况下,直接跳转到好友界面,否则不跳转 1、在opewidget.h里面定义一个单例模式 static OpeWidget &getInstance(); 2、添加定义 产生一个静态的操作界面的对象。操作界面这个对象他…

《零秒思考》像麦肯锡精英一样思考 - 三余书屋 3ysw.net

零秒思考:像麦肯锡精英一样思考 大家好,今天我们要深入探讨的著作是《零秒思考》。在领导提出问题时,我们常常会陷入沉思,却依然难以有所进展,仿佛原地踏步,但是身边的同事却能够立即给出清晰的回答。这种…

Rust面试宝典第1题:爬楼梯

题目 小乐爬楼梯,一次只能上1级或者2级台阶。楼梯一共有n级台阶,请问总共有多少种方法可以爬上楼? 解析 这道题虽然是一道编程题,但实际上更是一道数学题,着重考察应聘者的逻辑思维能力和分析解决问题的能力。 当楼梯只…

Web路径专题

文章目录 1.资源定位1.前置条件上下文路径设置 2.上下文路径介绍重点说明 3.资源定位方式资源路径 上下文路径 资源位置a.html定位C.java定位 4.浏览器和服务器解析的区别1.浏览器解析/(地址变化)2.服务器解析/(地址不变) 5.带/…

华为ensp中PPP(点对点协议)中的CHAP认证 原理和配置命令

作者主页:点击! ENSP专栏:点击! 创作时间:2024年4月11日6点00分 PPP协议(Point-to-Point Protocol)是点到点协议,是一种常用的串行链路层协议,用于在两个节点之间建立点…

结合 tensorflow.js 、opencv.js 与 Ant Design 创建美观且高性能的人脸动捕组件并发布到InsCode

系列文章目录 如何在前端项目中使用opencv.js | opencv.js入门如何使用tensorflow.js实现面部特征点检测tensorflow.js 如何从 public 路径加载人脸特征点检测模型tensorflow.js 如何使用opencv.js通过面部特征点估算脸部姿态并绘制示意图tensorflow.js 使用 opencv.js 将人脸…

PTA 2813:画家问题(熄灯问题)

有一个正方形的墙,由NN个正方形的砖组成,其中一些砖是白色的,另外一些砖是黄色的。Bob是个画家,想把全部的砖都涂成黄色。但他的画笔不好使。当他用画笔涂画第(i,j)个位置的砖时, 位置(i−1,j)、 (i1,j)、(i,j−1)、(i…

HJ13 句子逆序(句子反序,再把单词反序)

句子反序,再把单词反序 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别String s sc.n…