生成1010格式规律的数据的判别器模型构建

释放双眼,带上耳机,听听看~!
本文介绍了如何构建用于判断输入数据是真实的1010格式规律数据还是生成的数据的判别器模型,以支持生成对抗神经网络(GAN)的实训项目。

实训手册:生成1010格式规律

引言

1.1 项目概述

本实训项目旨在通过生成1010格式规律的数据,训练生成对抗神经网络(GAN)。GAN是由生成器和判别器组成的对抗模型,通过交替训练生成器和判别器,使生成器能够生成逼真的1010格式规律数据,而判别器能够准确区分生成的数据和真实的1010格式规律数据。

1.2 实训目标

  • 了解生成对抗神经网络(GAN)的基本原理和工作机制。
  • 学习构建判别器模型和生成器模型,并定义损失函数和优化器。
  • 掌握训练GAN的方法和技巧,以及评估生成器和判别器的性能。
  • 实现生成1010格式规律的数据,并进行实验讨论和结果分析。

准备工作

2.1 环境设置

在开始实训之前,需要进行环境设置,包括安装Python、PyTorch和其他必要的库,并配置GPU(如果可用)。以下是环境设置的步骤:

  1. 安装Python:根据操作系统下载并安装Python的最新版本。
  2. 安装PyTorch:使用pip命令或Anaconda安装PyTorch库。
  3. 安装其他库:根据需要安装其他所需的Python库,如torchvision、matplotlib等。
  4. 配置GPU(可选):如果使用GPU进行训练加速,确保正确安装GPU驱动程序并配置PyTorch以使用GPU。

2.2 数据集准备

生成1010格式规律的数据集是实训的基础。数据集应包含真实的1010格式规律数据和随机生成的非规律数据。以下是数据集准备的步骤:

  1. 定义数据生成函数:编写函数generate_real()和generate_random(),用于生成真实的1010格式规律数据和随机生成的非规律数据。
  2. 导入必要的库:导入torch和其他需要使用的库。
  3. 实现数据生成函数:根据生成规则和需求,实现generate_real()和generate_random()函数。

示例代码

import random
import torch
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

def ganerate_real():
    real_data=torch.FloatTensor(
        [
            random.uniform(0.8,1.0),
            random.uniform(0.0,0.2),
            random.uniform(0.8,1.0),
            random.uniform(0.0,0.2)
        ]
    )
    return real_data.to(device)

def generate_random(size):
    return torch.rand(size).to(device)

if __name__ =='__main__':
    x=generate_random(4)
    print(x)

构建判别器模型

3.1 定义判别器模型结构

判别器模型用于判断输入数据是真实的1010格式规律数据还是生成的数据。判别器模型应具有足够的复杂度来区分生成器生成的数据。将按照以下步骤来构建判别器模型:

  1. 导入必要的库:导入pandastorchtorch.nn库以支持数据处理、深度学习模型的构建和训练。
  2. 定义判别器类:创建一个判别器类,并继承自torch.nn.Module,以实现自定义的判别器模型。
  3. 定义判别器模型结构:在判别器类的构造函数中,定义判别器模型的结构。这个模型由两个线性层和两个Sigmoid激活函数组成。
  4. 实现前向传播方法:在判别器类中实现forward()方法,定义数据在模型中的前向传播路径。输入数据通过模型的线性层和激活函数得到输出结果。
  5. 实现训练方法:在判别器类中实现train()方法,用于训练判别器模型。传入输入数据和相应的标签,计算模型输出和标签之间的损失,并更新模型参数以最小化损失。
  6. 实现损失绘制方法:在判别器类中实现plot_progress()方法,用于绘制训练过程中损失值的变化曲线。
  7. 实现模型保存和加载方法:在判别器类中实现save()load()方法,用于保存和加载判别器模型的参数。
  8. 初始化判别器对象:创建一个判别器对象的实例,用于后续的模型训练和测试。

示例代码:

import pandas as pd
import torch
import torch.nn as nn
import matplotlib.pyplot as plt

class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()
        self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        self.model = nn.Sequential(
            nn.Linear(4, 3),  # 输入层到隐藏层的线性变换
            nn.Sigmoid(),  # 隐藏层的激活函数
            nn.Linear(3, 1),  # 隐藏层到输出层的线性变换
            nn.Sigmoid()  # 输出层的激活函数
        )
        self.criterion=nn.MSELoss().to(self.device)  # 使用均方误差作为损失函数
        self.optimiser=torch.optim.SGD(self.parameters(), lr=0.01)  # 使用随机梯度下降法作为优化算法

        self.counter=0  # 记录训练步数
        self.loss_ls=[]  # 记录损失值的变化


    def forward(self, inputs):
        inputs=inputs.to(self.device)
        return self.model(inputs)
    
    def train(self, inputs, label):
        inputs, label = inputs.to(self.device), label.to(self.device)

        y_pred = self.forward(inputs)  # 鉴别器的前向传播,计算输出结果
        loss = self.criterion(y_pred, label)  # 计算鉴别器的损失值

        self.counter += 1
        if self.counter % 10 == 0:
            self.loss_ls.append(loss.item())  # 记录损失值

        if self.counter % 10000 == 0:
            print('counter=', self.counter, 'loss=', loss.item())  # 每训练10000步打印一次损失值

        self.optimiser.zero_grad()  # 清空梯度
        loss.backward()  # 反向传播,计算梯度
        self.optimiser.step()  # 更新模型参数

    def plot_progress(self):
        df = pd.DataFrame(self.loss_ls, columns=['loss'])
        df.plot(ylim=(0, 1), figsize=(16, 8), alpha=0.1, marker='.', grid=True, yticks=(0, 0.25, 0.5))
        plt.show()  # 绘制损失值的变化曲线

    def save(self, model_path):
        torch.save(self.state_dict(), model_path)  # 保存模型参数到指定路径

    def load(self, model_path):
        state_dict = torch.load(model_path)  # 加载模型参数
        self.load_state_dict(state_dict)  # 更新模型的参数

3.2 测试判别器模型

在训练完判别器模型后,可以对其进行测试以评估其性能。测试判别器模型的过程与训练过程类似,但不需要进行反向传播和参数更新。以下是测试判别器模型的步骤:

  1. 导入必要的库:导入torchtorch.nnrandompandas库,以支持模型加载、数据生成和结果展示。
  2. 导入数据生成函数和判别器类:从相应的模块中导入generate_real函数和Discriminator类,以生成真实数据和加载判别器模型。
  3. 创建判别器对象:创建一个判别器对象的实例。
  4. 加载判别器模型:使用load()方法加载预训练的判别器模型参数。
  5. 设置设备:根据可用的GPU资源情况,将判别器模型移动到相应的设备上(GPU或CPU)。
  6. 进行测试:使用forward()方法将随机生成的输入数据传递给判别器模型,得到相应的输出结果。
  7. 展示结果:打印输出结果,观察判别器对于输入数据的判断。

示例代码:

import torch
import torch.nn as nn
import random
import pandas as pd
from data_1010 import generate_real,generate_random
from discriminator import Discriminator

# D = Discriminator()
# device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
# D.to(device)
#
# for i in range(10000):
#     D.train(generate_real(), torch.FloatTensor([1.0]))
#     D.train(generate_random(4), torch.FloatTensor([0.0]))
# D.plot_progress()
# D.save('model/Discriminator.pth')

D = Discriminator()
D.load('model/Discriminator.pth')
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
D.to(device)

for i in range(10):
    inputs = generate_random(4)
    y = D.forward(inputs)
    print(y)

打印结果

生成1010格式规律的数据的判别器模型构建
如上图所示,损失值一开始接近0.25,随着训练次数增加,损失值逐渐接近0。

    tensor([0.0582], device='cuda:0', grad_fn=<SigmoidBackward0>)
    tensor([0.0448], device='cuda:0', grad_fn=<SigmoidBackward0>)
    tensor([0.8794], device='cuda:0', grad_fn=<SigmoidBackward0>)
    tensor([0.0350], device='cuda:0', grad_fn=<SigmoidBackward0>)
    tensor([0.0608], device='cuda:0', grad_fn=<SigmoidBackward0>)
    tensor([0.0420], device='cuda:0', grad_fn=<SigmoidBackward0>)
    tensor([0.0958], device='cuda:0', grad_fn=<SigmoidBackward0>)
    tensor([0.0539], device='cuda:0', grad_fn=<SigmoidBackward0>)
    tensor([0.0745], device='cuda:0', grad_fn=<SigmoidBackward0>)
    tensor([0.0496], device='cuda:0', grad_fn=<SigmoidBackward0>)
    

打印出的结果是判别器对于随机生成的输入数据进行判断的输出结果。每个输出是一个介于0和1之间的值,表示对应输入数据为真实数据的概率估计。这个值越接近1,表示判别器认为输入数据越接近真实数据;而值越接近0,表示判别器认为输入数据越接近随机生成的数据。

由于判别器是在已经训练好的模型上进行测试,输出结果可以用来评估判别器的性能。通常情况下,我们希望判别器能够准确地将真实数据和随机数据区分开来,即对于真实数据的输出接近1,对于随机数据的输出接近0。

构建生成器模型

4.1 定义生成器模型结构

生成器模型用于生成1010格式规律的数据。生成器模型应具有足够的复杂度来学习生成逼真的1010格式规律数据的规律。以下是定义生成器模型结构的步骤:

  1. 导入必要的库:导入torch和torch.nn库。

  2. 定义生成器类:创建一个生成器类,并继承自torch.nn.Module。

  3. 定义生成器模型结构:在生成器类中,构建生成器模型的结构,包括线性层、激活函数等。

  4. 实现前向传播方法:在生成器类中,实现forward()方法,定义数据在模型中的前向传播路径。

    示例代码:

    class generator(nn.Module):
        def __init__(self):
            super(generator, self).__init__()
            self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
            self.model = nn.Sequential(
                nn.Linear(1, 3),#
                nn.Sigmoid(),
                nn.Linear(3, 4),#
                nn.Sigmoid()
            )
            # self.criterion=nn.MSELoss().to(self.device)
            self.optimiser=torch.optim.SGD(self.parameters(), lr=0.01)
    
            self.counter=0
            self.loss_ls=[]
    
    
        def forward(self, inputs):
            inputs=inputs.to(self.device)
            return self.model(inputs)
    

4.2 训练生成器模型

在训练生成器模型时,同样需要加载数据集,并进行迭代训练。训练过程包括前向传播、计算损失、反向传播和更新参数等步骤。以下是训练生成器模型的步骤:

  1. 加载数据集:使用generate_real()函数生成真实数据作为训练数据。
  2. 将数据转换为Tensor:将数据转换为PyTorch的Tensor格式,并根据需要将其移动到GPU上(如果可用)。
  3. 清零梯度:在每个训练迭代之前,使用optimizer.zero_grad()清零梯度。
  4. 前向传播:将数据输入到生成器模型中,进行前向传播计算。
  5. 计算损失:根据生成器模型的输出和真实数据,计算生成器的损失值。
  6. 反向传播:通过调用loss.backward()方法,计算梯度并进行反向传播。
  7. 更新参数:根据优化器的选择,使用optimizer.step()方法更新生成器模型的参数。

示例代码:

import pandas as pd
import torch
import torch.nn as nn
import matplotlib.pyplot as plt

class generator(nn.Module):
    def __init__(self):
        super(generator, self).__init__()
        self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        self.model = nn.Sequential(
            nn.Linear(1, 3),  # 输入层到隐藏层的线性变换
            nn.Sigmoid(),  # 隐藏层的激活函数
            nn.Linear(3, 4),  # 隐藏层到输出层的线性变换
            nn.Sigmoid()  # 输出层的激活函数
        )
        # self.criterion=nn.MSELoss().to(self.device)
        self.optimiser = torch.optim.SGD(self.parameters(), lr=0.01)  # 优化器选择随机梯度下降(SGD)

        self.counter = 0  # 计数器,用于记录训练步数
        self.loss_ls = []  # 存储损失值的列表

    def forward(self, inputs):
        inputs = inputs.to(self.device)
        return self.model(inputs)  # 前向传播,计算生成器的输出

    def train(self, D, inputs, label):
        inputs, label = inputs.to(self.device), label.to(self.device)

        g_output = self.forward(inputs)  # 生成器生成输出
        d_output = D.forward(g_output)  # 鉴别器判断生成器输出的真实性
        loss = D.criterion(d_output, label)  # 计算生成器的损失值

        self.counter += 1  # 计数器加1
        if self.counter % 10 == 0:
            self.loss_ls.append(loss.item())  # 每10步记录一次损失值
        # if self.counter % 10000 == 0:
        #     print('counter=', self.counter, 'loss=', loss.item())

        self.optimiser.zero_grad()  # 梯度清零
        loss.backward()  # 反向传播,计算梯度
        self.optimiser.step()  # 更新生成器的参数

    def plot_progress(self):
        df = pd.DataFrame(self.loss_ls, columns=['loss'])
        df.plot(ylim=(0, 1), figsize=(16, 8), alpha=0.1, marker='.', grid=True, yticks=(0, 0.25, 0.5))
        plt.show()  # 绘制损失值的变化曲线

    def save(self, model_path):
        torch.save(self.state_dict(), model_path)  # 保存生成器模型的参数到指定路径

    def load(self, model_path):
        state_dict = torch.load(model_path)  # 加载生成器模型的参数
        self.load_state_dict(state_dict)  # 将参数加载到生成器模型中

4.3定义损失函数

对于生成器来说,它的目标是生成尽可能逼真的数据样本,使得判别器难以区分生成的数据与真实数据。生成器的训练是通过判别器的反馈来进行的,因此生成器的损失函数通常不会单独定义。

在训练过程中,生成器的损失函数可以通过判别器的输出来计算。生成器的目标是使得判别器对生成的数据输出的概率尽可能接近1,因此可以将判别器输出的概率与目标值(通常为1)之间的差异作为生成器的损失。这样,通过最小化生成器的损失,生成器能够逐渐提高生成的数据的逼真程度。

在代码中,生成器的训练函数中的损失计算部分体现了这一思想。首先,生成器根据输入数据生成数据样本,然后将生成的数据样本输入判别器得到判别器的输出。生成器的损失函数即为判别器输出与目标值(在训练中通常为1,表示生成数据被判别为真实数据)之间的差异,即使用判别器的损失函数计算生成器的损失。通过优化生成器的损失,生成器能够逐步提高生成数据的质量。

总结起来,生成器的损失函数是通过判别器的输出来计算的,目标是使生成器生成的数据样本能够欺骗判别器,被判别为真实数据。

4.4 检查生成器输出

在训练完生成器模型后,可以检查其输出结果以评估其性能。生成器的输出应该接近真实的1010格式规律数据。以下是检查生成器输出的步骤:

  1. 加载生成器模型:使用torch.load()方法加载生成器模型。
  2. 生成数据:使用生成器模型生成数据。
  3. 输出数据:将生成的数据输出,以便查看生成器的输出结果。

示例代码:

import torch
from generator import generator

G = generator()
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
G.to(device)

X = torch.FloatTensor([0.5])
y_pred = G.forward(X)
print(y_pred)

结果分析

   tensor([0.4898, 0.4256, 0.5960, 0.3457], device='cuda:0',
         grad_fn=<SigmoidBackward0>)

生成器生成的结果用于生成模型的输出或者生成新的数据样本。在生成对抗网络 (GAN) 中,生成器负责生成与真实数据样本相似的合成数据。而此时的生成器并不是很符合1010规律

5训练GAN

训练GAN的过程包括交替训练鉴别器和生成器。首先,通过将真实数据和生成数据输入鉴别器模型,计算损失并更新鉴别器的参数。然后,生成器使用噪声作为输入生成数据,并将生成数据输入鉴别器,计算损失并更新生成器的参数。通过反复迭代训练过程,逐步提升鉴别器和生成器的性能。

import torch
from data_1010 import ganerate_real, generate_random
import numpy as np
import matplotlib.pyplot as plt
from discriminator import Discriminator
from generator import generator

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')  # 检查是否支持CUDA加速,并选择设备
D = Discriminator().to(device)  # 创建鉴别器对象并移动到相应设备上
G = generator().to(device)  # 创建生成器对象并移动到相应设备上

image_ls = []  # 用于存储生成器生成的图像结果
for i in range(10000):
    D.train(ganerate_real(), torch.FloatTensor([1.0]).to(device))  # 训练鉴别器,使用真实数据
    g_data = G.forward(torch.FloatTensor([0.5])).detach()  # 生成器生成数据
    D.train(g_data, torch.FloatTensor([0.0]).to(device))  # 训练鉴别器,使用生成的数据
    G.train(D, torch.FloatTensor([0.5]).to(device), torch.FloatTensor([1.0]).to(device))  # 训练生成器
    if i % 1000 == 0:
        image_ls.append(G.forward(torch.FloatTensor([0.5])).detach().cpu().numpy())  # 保存生成器生成的图像结果

D.plot_progress()  # 绘制鉴别器的训练进展
G.plot_progress()  # 绘制生成器的训练进展

plt.Figure(figsize=(16, 8))
plt.imshow(np.array(image_ls).T, interpolation='none', cmap='Blues')  # 将生成的图像结果可视化
plt.show()

5.1生成器的损失函数

生成1010格式规律的数据的判别器模型构建
生成器的损失图,与鉴别器损失是互补的

5.2辨别器的损失函数

生成1010格式规律的数据的判别器模型构建
损失值最终保持在0.25附近。这说明鉴别器无法判断数据是真实的还是伪造的,于是输出0.5,由于我们损失函数使用的是均方误差,所以损失值是0.5的平方,即0.25。

5.3生成器训练规律

生成1010格式规律的数据的判别器模型构建

在实训过程中,可以通过观察判别器和生成器的损失值、生成器的输出结果等指标来评估模型的性能。如果判别器的损失值逐渐趋向于较低的值,而生成器的损失值逐渐趋向于较高的值,则表示模型的训练进展良好。此外,可以通过比较生成器的输出结果与真实的1010格式规律数据来评估生成器的生成能力。

通过对模型的训练和评估,可以根据实验结果进行结果分析与讨论,进一步改进模型的性能和生成能力。

6. 总结

6.1 实训回顾

在这一部分,对整个实训过程进行回顾和总结,总结实训的目标、内容和步骤,以及实训中遇到的问题和解决方案。可以考虑以下内容:

  • 实训目标:总结实训的目标,即生成满足1010格式规律的数据。
  • 实训内容:回顾实训的主要内容,包括数据准备、模型构建、模型训练等步骤。
  • 实训步骤:总结实训的具体步骤和流程,以及每个步骤中的关键点和注意事项。
  • 问题和解决方案:记录实训过程中遇到的问题和困难,以及解决这些问题的方法和技巧。

6.2 下一步行动

在这一部分,提出下一步行动计划,探讨进一步改进和扩展的可能性。可以考虑以下内容:

  • 模型改进:讨论当前模型的局限性和不足之处,提出可能的改进方向和方法。
  • 数据集扩展:探讨使用更大规模的数据集进行训练的可行性,并分析扩展数据集的潜在好处。
  • 应用场景:讨论生成对抗网络在其他领域或任务中的应用可能性,探索将GAN扩展到其他数据生成或转换任务中的潜在价值。
本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

如何使用Python实现yolo系列模型onnx推理

2023-12-15 17:44:14

AI教程

VBot浏览器插件:让你搜索技术问题更高效

2023-12-15 17:56:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索