pytorch生成对抗网络

ops/2025/2/2 10:57:41/

 人工智能例子汇总:AI常见的算法和例子-CSDN博客 

生成对抗网络(GAN,Generative Adversarial Network)是一种深度学习模型,由两个神经网络组成:生成器(Generator)和判别器(Discriminator)。这两个网络通过对抗过程共同训练,从而使生成器能够生成越来越真实的假数据。

GAN的基本工作原理:

  1. 生成器(G):它的任务是生成与真实数据相似的假数据。生成器通常从一个随机噪声(例如,均匀分布或高斯分布的噪声)开始,经过多层神经网络的处理,输出伪造的数据样本。

  2. 判别器(D):它的任务是区分输入数据是来自真实数据分布,还是生成器伪造的假数据。判别器通常是一个二分类器,其输出是一个表示“真实”或“假”的概率值。

训练过程:

  • 对抗过程:生成器和判别器相互博弈。生成器希望生成尽可能像真的数据,以骗过判别器;而判别器希望准确区分真假数据。最终,生成器会通过优化损失函数,使得生成的数据与真实数据尽可能相似,判别器的性能则被提升到一个极限,使得它不能再轻易地区分真假数据。
  • 数学公式:

  • 判别器的目标是最大化其输出的正确分类概率,即区分真假数据。
  • 生成器的目标是最小化其输出的“假数据”被判定为假的概率。

常见的GAN变种:

  1. DCGAN(Deep Convolutional GAN):使用卷积神经网络(CNN)来增强生成器和判别器的表现。
  2. WGAN(Wasserstein GAN):引入了Wasserstein距离,改进了训练稳定性。
  3. CycleGAN:能够在没有成对样本的情况下进行图像到图像的转换,例如将马变成斑马。

以下是一个简化的PyTorch GAN实现的框架,生成一个语音的梅尔频谱(假设已经处理了音频并提取了梅尔频谱特征)

import torch
import torch.nn as nn
import torch.optim as optim
import torchaudio
import matplotlib.pyplot as plt# 生成器(Generator)
class Generator(nn.Module):def __init__(self, z_dim=100):super(Generator, self).__init__()self.fc = nn.Sequential(nn.Linear(z_dim, 128),nn.ReLU(),nn.Linear(128, 256),nn.ReLU(),nn.Linear(256, 512),nn.ReLU(),nn.Linear(512, 1024),nn.ReLU(),nn.Linear(1024, 80),  # 80表示梅尔频谱的时间步(例如:80个梅尔频率)nn.Tanh()  # 生成梅尔频谱,范围在[-1, 1]之间)def forward(self, z):return self.fc(z)# 判别器(Discriminator)
class Discriminator(nn.Module):def __init__(self):super(Discriminator, self).__init__()self.fc = nn.Sequential(nn.Linear(80, 512),  # 输入为梅尔频谱的时间步nn.LeakyReLU(0.2),nn.Linear(512, 256),nn.LeakyReLU(0.2),nn.Linear(256, 1),nn.Sigmoid()  # 输出判定是“真”还是“假”)def forward(self, x):return self.fc(x)# 初始化生成器和判别器
z_dim = 100
generator = Generator(z_dim)
discriminator = Discriminator()# 优化器
lr = 0.0002
g_optimizer = optim.Adam(generator.parameters(), lr=lr, betas=(0.5, 0.999))
d_optimizer = optim.Adam(discriminator.parameters(), lr=lr, betas=(0.5, 0.999))# 损失函数
criterion = nn.BCELoss()# 加载数据(假设已经提取了梅尔频谱特征,取一个示例)
def load_example_mel_spectrogram():# 假设这是一个真实梅尔频谱的示例,实际数据应从音频文件中提取mel = torch.rand((80))  # 生成一个假的梅尔频谱数据return mel.unsqueeze(0)  # 扩展维度以适应网络# 训练GAN
num_epochs = 1000
for epoch in range(num_epochs):# 真实数据real_data = load_example_mel_spectrogram()real_labels = torch.ones(real_data.size(0), 1)  # 标签为1表示真实数据# 假数据z = torch.randn(real_data.size(0), z_dim)  # 随机噪声fake_data = generator(z)fake_labels = torch.zeros(real_data.size(0), 1)  # 标签为0表示假数据# 训练判别器discriminator.zero_grad()real_loss = criterion(discriminator(real_data), real_labels)fake_loss = criterion(discriminator(fake_data.detach()), fake_labels)d_loss = (real_loss + fake_loss) / 2d_loss.backward()d_optimizer.step()# 训练生成器generator.zero_grad()g_loss = criterion(discriminator(fake_data), real_labels)  # 生成器希望判别器判定为真实g_loss.backward()g_optimizer.step()if epoch % 100 == 0:print(f"Epoch [{epoch}/{num_epochs}], D Loss: {d_loss.item()}, G Loss: {g_loss.item()}")# 可视化生成的梅尔频谱(只显示最后一次生成的结果)if epoch == num_epochs - 1:plt.figure(figsize=(10, 4))plt.imshow(fake_data.detach().numpy(), aspect='auto', origin='lower')plt.title(f"Generated Mel Spectrogram - Epoch {epoch}")plt.colorbar()plt.show()# 测试阶段:使用训练好的生成器进行语音生成
z_test = torch.randn(1, z_dim)  # 创建一个新的随机噪声向量
generated_mel_spectrogram = generator(z_test)# 可视化生成的梅尔频谱
plt.figure(figsize=(10, 4))
plt.imshow(generated_mel_spectrogram.detach().numpy(), aspect='auto', origin='lower')
plt.title("Generated Mel Spectrogram from Test Data")
plt.colorbar()
plt.show()

解释:

  1. 测试阶段

    • 在训练完成后,我们使用一个新的随机噪声向量z_test来生成一个新的梅尔频谱。
    • generated_mel_spectrogram = generator(z_test)是生成梅尔频谱的过程。
  2. 可视化

    • 使用plt.imshow()来可视化生成的梅尔频谱图,origin='lower'是确保频谱图正确显示。
    • plt.colorbar()添加颜色条,以便更清晰地理解梅尔频谱的数值范围。

结果:

  • 在训练过程中,你会看到每个epoch的损失值,并在最后一次epoch时显示生成的梅尔频谱。
  • 在测试阶段,生成器会基于随机噪声生成一个新的梅尔频谱并进行可视化,帮助你观察最终模型生成的语音特征。

http://www.ppmy.cn/ops/155014.html

相关文章

Linux抢占式内核:技术演进与源码解析

一、引言 Linux内核作为全球广泛使用的开源操作系统核心,其设计和实现一直是计算机科学领域的研究热点。从早期的非抢占式内核到2.6版本引入的抢占式内核,Linux在实时性和响应能力上取得了显著进步。本文将深入探讨Linux抢占式内核的引入背景、技术实现以及与非抢占式内核的…

C++,STL 简介:历史、组成、优势

文章目录 引言一、STL 的历史STL 的核心组成三、STL 的核心优势四、结语进一步学习资源: 引言 C 是一门强大且灵活的编程语言,但其真正的魅力之一在于其标准库——尤其是标准模板库(Standard Template Library, STL)。STL 提供了…

L30.【LeetCode笔记】设计链表

1.题目 707. 设计链表 - 力扣(LeetCode) 你可以选择使用单链表或者双链表,设计并实现自己的链表。 单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。 如果是双向…

Pdf to forms如何实现?如何在3分钟内将PDF自动转换为Microsoft Forms

通过将杂乱的文件转换为标准化表单,简化数据收集——无需手动操作。 问题:为什么非标准文件会破坏您的工作流程 每天,企业和教育工作者都淹没在非结构化数据中:PDF报告、CSV导出或保存为TXT文件的手写笔记。手动将这些数据复制到…

使用pandas的read_excel()报错:

ImportError: Unable to import required dependencies: numpy: Error importing numpy: you should not try to import numpy from its source directory; please exit the numpy source tree, and relaunch your python interpreter from there. 问题原因&a…

深度学习中常用的评价指标方法

深度学习中常用的评价指标方法因任务类型(如分类、回归、分割等)而异。以下是一些常见的评价指标: 1. 分类任务 准确率(Accuracy) 定义:正确预测的样本数占总样本数的比例。 公式:AccuracyTPT…

算法题(54):插入区间

审题: 需要我们把newinterval的区间与interval的区间合并起来,并返回合并后的二维数组地址 思路: 方法一:排序合并区间 我们可以先把newinterval插入到interval中,进行排序然后复用合并区间的代码 方法二:模…

golang 使用双向链表作为container/heap的载体

MyHeap:container/heap的数据载体,需要实现以下方法: Len:堆中数据个数 Less:第i个元素 是否必 第j个元素 值小 Swap:交换第i个元素和 第j个元素 Push:向堆中追加元素 Pop:从堆…