PyTorch新手求助:基于DCGAN架构处理.npy文件生成新样本
适配DCGAN处理(128,7752)维度数据的分步指南
DCGAN原本为图像类二维张量设计,你的需求是处理一维特征向量(7752维),核心是将DCGAN的卷积/反卷积逻辑替换为适配一维数据的结构,以下是具体实现步骤:
1. 数据加载与预处理
首先将.npy文件转为PyTorch可处理的张量,并做归一化(GAN对输入范围敏感,通常归一化到[-1,1]):
import numpy as np import torch from torch.utils.data import Dataset, DataLoader class NPYDataset(Dataset): def __init__(self, file_path): self.data = np.load(file_path) # 归一化到[-1,1],保存原数据范围用于后续还原 self.original_min = self.data.min() self.original_max = self.data.max() self.data = (self.data - self.original_min) / (self.original_max - self.original_min) * 2 - 1 self.data = torch.tensor(self.data, dtype=torch.float32) def __len__(self): return len(self.data) def __getitem__(self, idx): return self.data[idx] # 加载数据集,替换为你的.npy文件路径 dataset = NPYDataset("input_data.npy") dataloader = DataLoader(dataset, batch_size=128, shuffle=True)
2. 重构DCGAN生成器
生成器从随机噪声生成7752维向量,新手优先用全连接结构(直观易调试):
class Generator(torch.nn.Module): def __init__(self, latent_dim=100, output_dim=7752): super().__init__() self.model = torch.nn.Sequential( torch.nn.Linear(latent_dim, 256), torch.nn.LeakyReLU(0.2), torch.nn.Linear(256, 512), torch.nn.LeakyReLU(0.2), torch.nn.Linear(512, 1024), torch.nn.LeakyReLU(0.2), torch.nn.Linear(1024, output_dim), torch.nn.Tanh() # 输出匹配输入的[-1,1]范围 ) def forward(self, x): return self.model(x)
若想贴近原DCGAN的卷积逻辑,可改用一维转置卷积版:
class ConvGenerator(torch.nn.Module): def __init__(self, latent_dim=100, output_dim=7752): super().__init__() self.init_len = output_dim // 16 self.init_channels = 256 self.fc = torch.nn.Linear(latent_dim, self.init_channels * self.init_len) self.model = torch.nn.Sequential( torch.nn.BatchNorm1d(self.init_channels), torch.nn.LeakyReLU(0.2), torch.nn.ConvTranspose1d(self.init_channels, 128, 4, 2, 1), torch.nn.BatchNorm1d(128), torch.nn.LeakyReLU(0.2), torch.nn.ConvTranspose1d(128, 64, 4, 2, 1), torch.nn.BatchNorm1d(64), torch.nn.LeakyReLU(0.2), torch.nn.ConvTranspose1d(64, 32, 4, 2, 1), torch.nn.BatchNorm1d(32), torch.nn.LeakyReLU(0.2), torch.nn.ConvTranspose1d(32, 1, 4, 2, 1), torch.nn.Tanh() ) self.output_dim = output_dim def forward(self, x): x = self.fc(x).view(x.size(0), self.init_channels, self.init_len) x = self.model(x).view(x.size(0), self.output_dim) return x
3. 重构DCGAN判别器
判别器负责区分真实数据与生成数据,同样提供两种实现:
全连接版:
class Discriminator(torch.nn.Module): def __init__(self, input_dim=7752): super().__init__() self.model = torch.nn.Sequential( torch.nn.Linear(input_dim, 1024), torch.nn.LeakyReLU(0.2), torch.nn.Dropout(0.3), torch.nn.Linear(1024, 512), torch.nn.LeakyReLU(0.2), torch.nn.Dropout(0.3), torch.nn.Linear(512, 256), torch.nn.LeakyReLU(0.2), torch.nn.Dropout(0.3), torch.nn.Linear(256, 1), torch.nn.Sigmoid() # 输出0-1的真假概率 ) def forward(self, x): return self.model(x)
一维卷积版:
class ConvDiscriminator(torch.nn.Module): def __init__(self, input_dim=7752): super().__init__() self.model = torch.nn.Sequential( torch.nn.Conv1d(1, 32, 4, 2, 1), torch.nn.LeakyReLU(0.2), torch.nn.Conv1d(32, 64, 4, 2, 1), torch.nn.BatchNorm1d(64), torch.nn.LeakyReLU(0.2), torch.nn.Conv1d(64, 128, 4, 2, 1), torch.nn.BatchNorm1d(128), torch.nn.LeakyReLU(0.2), torch.nn.Conv1d(128, 256, 4, 2, 1), torch.nn.BatchNorm1d(256), torch.nn.LeakyReLU(0.2), ) self.fc = torch.nn.Linear(256 * (input_dim // 16), 1) self.sigmoid = torch.nn.Sigmoid() def forward(self, x): x = x.view(x.size(0), 1, -1) x = self.model(x).flatten(1) return self.sigmoid(self.fc(x))
4. 训练流程实现
遵循标准GAN训练逻辑,交替优化判别器与生成器:
# 设备初始化 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") latent_dim = 100 generator = Generator(latent_dim=latent_dim).to(device) discriminator = Discriminator().to(device) # 损失与优化器 criterion = torch.nn.BCELoss() opt_gen = torch.optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999)) opt_disc = torch.optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999)) # 训练循环 epochs = 100 for epoch in range(epochs): for real_data in dataloader: real_data = real_data.to(device) batch_size = real_data.size(0) # 训练判别器 real_labels = torch.ones(batch_size, 1).to(device) fake_labels = torch.zeros(batch_size, 1).to(device) # 真实数据损失 disc_real_loss = criterion(discriminator(real_data), real_labels) # 生成假数据并计算损失 noise = torch.randn(batch_size, latent_dim).to(device) fake_data = generator(noise) disc_fake_loss = criterion(discriminator(fake_data.detach()), fake_labels) disc_loss = disc_real_loss + disc_fake_loss opt_disc.zero_grad() disc_loss.backward() opt_disc.step() # 训练生成器 gen_loss = criterion(discriminator(fake_data), real_labels) opt_gen.zero_grad() gen_loss.backward() opt_gen.step() print(f"Epoch {epoch+1}/{epochs} | Disc Loss: {disc_loss.item():.4f} | Gen Loss: {gen_loss.item():.4f}")
5. 生成并保存新.npy文件
训练完成后,用生成器生成新数据并还原到原数据范围:
# 生成指定数量的样本 num_samples = 1000 generator.eval() with torch.no_grad(): noise = torch.randn(num_samples, latent_dim).to(device) generated_data = generator(noise).cpu().numpy() # 还原到原数据范围 generated_data = (generated_data + 1) / 2 * (dataset.original_max - dataset.original_min) + dataset.original_min # 保存为.npy文件 np.save("generated_data.npy", generated_data)
关键注意事项
- 若出现模式崩溃(生成样本高度雷同),可尝试调小学习率、增加Dropout比例,或改用WGAN-GP损失函数。
- 若显存不足,可降低批量大小(如64、32),或减少模型隐藏层维度。
- 卷积版模型需确保输入输出维度匹配,若计算后长度不符,可在最后加线性层修正。
内容的提问来源于stack exchange,提问作者Mark Stent
相关产品推荐
相关产品推荐

