GAN生成哆啦A梦,亲测训练50000epoch

**

GAN生成哆啦A梦,亲测训练50000epoch

**
闲着没事学了一下GAN网络,感觉这个东西挺有趣的,所以就打算跟大家分享一下这个东西,其中的原理就不用跟大家说了,因为现在其他的博客介绍原理都很全面,大家可以去看一下其他对的博客,我这里就放上我参照其他博客进行修改的代码吧。

废话少说,先摆上我的训练结果,证明我的代码是可以运行的叭:
50000epoch的训练结果

我的训练图片是从百度上面拿的,拿来的图片格式是.webp格式的图片
然后我进行训练的时候使用的图片分辨率是64X64,怎么说呢,就是尽量使用64X64的分辨率的图片进行训练叭,因为这样可以让你的电脑能够运行的起来,我刚开始进行训练的是医学的数据938X636结果就在电脑报错了:**RuntimeError: CUDA out of memory. Tried to allocate 6.71 GiB (GPU 0; 15.78 GiB total capacity; 13.49 GiB already allocated; 984.75 MiB free; 13.51 GiB reserved in total by PyTorch)**因为电脑的配置跟不上呀
所以最后我对收集到的数据进行分辨率的修改,编程64X64就能轻轻松松地进行训练了

先给大伙看看我整体的文件格式,因为路径那些都是配套,按照我这样才能进行运行,这个对小白比较友好,不然就自己进行修改代码了

在这里插入图片描述

在这里插入图片描述

解释一下叭

gan_A是总的文件夹

images是放置网页进行获取的图片,我拿的图片格式是.webp格式的图片,这个很重要,因为后面进行图片分辨率的转化的时候,我的代码就是针对这个格式的图片的,如果不是这种格式的话,在我的代码image_tool.py那里需要进行修改一些东西。#

img # 是每一万轮就对训练G产生的图片进行保存

result是对webp格式的图片进行转化后保存的一个文件夹,也就是gan_1进行数据的训练的数据

saved_models是每隔一万轮对G的模型进行保存

image_tool.py代码如下:

# -*- coding:utf-8 -*-
# @Time : 2022-04-18 15:07
# @Author : DaFuChen
# @File : image_tool.py
# @software: PyCharm



# 进行分辨率的重新修改 进行值的变化修改

# 导入需要的模块
from glob import glob
from PIL import Image
import os

# 图片路径
# 使用 glob模块 获得文件夹内所有jpg图像
img_path = glob("./images/*.webp")
# img_path = glob("./images/*.jpg")
# img_path = glob("./images/*.jpeg")

# 存储(输出)路径
path_save = "./result"

for i, file in enumerate(img_path):
    name = os.path.join(path_save, "%d.jpg" % i)
    im = Image.open(file)
    # im.thumbnail((720,1280))
    reim = im.resize((64, 64))
    print(im.format, reim.size, reim.mode)
    reim.save(name, im.format)

gan_1.py代码如下:

# -*- coding:utf-8 -*-
# @Time : 2022-04-18 15:05
# @Author : DaFuChen
# @File : gan_1.py
# @software: PyCharm

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, Dataset
from torchvision import datasets
from torch.autograd import Variable
from PIL import Image
import torch.nn as nn
import torch.nn.functional as F
import torch

# 输出图片保存路径 没有就会自动进行创建
os.makedirs("img", exist_ok=True)

# 参数设置
parser = argparse.ArgumentParser()
parser.add_argument("--n_epochs", type=int, default=1000001, 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("--gpu", type=int, default=0, help="number of cpu threads to use during batch generation")
# 输入噪声向量维度,默认100
parser.add_argument("--latent_dim", type=int, default=100, help="dimensionality of the latent space")

# [enforce fail at .\c10 core\CPUAllocator.cpp:79]DefaultCPUAllocator:内存不足:您试图分配7203840000字节。 改改网络结构吧 tm
# 输入图片维度,默认64*64*3  但是进行修改之后两个值 938 625 但是这个设计的网络结构不稳定 很难搞  这个是撑不住了
parser.add_argument("--img_size1", type=int, default=64, help="size of each image dimension")
parser.add_argument("--img_size2", type=int, default=64, help="size of each image dimension")


parser.add_argument("--channels", type=int, default=3, help="number of image channels")
# 每隔一个sample_interval的批次进行一次图片的保存
parser.add_argument("--sample_interval", type=int, default=10000, help="interval betwen image samples")

# 其实是创建了一个对象 之后可以调用它其中的参数值 使用了它的这一个类里面刻画的一些属性
opt = parser.parse_args()
print(opt)

# 图像的分辨率值
img_shape = (opt.channels, opt.img_size1, opt.img_size2)

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(
            # 基本的一个操作   进行线性化的拟合 然后再relu一下取个好的效果
            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()

# 将属性放进GPU进行训练
if cuda:
    generator.cuda()
    discriminator.cuda()
    adversarial_loss.cuda()

# Configure data loader
img_transform = transforms.Compose([
    # transforms.ToPILImage(),
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))  # (x-mean) / std
])


class MyData(Dataset):  # 继承Dataset
    def __init__(self, root_dir, transform=None):  # __init__是初始化该类的一些基础参数
        self.root_dir = root_dir  # 文件目录
        self.transform = transform  # 变换
        self.images = os.listdir(self.root_dir)  # 目录里的所有文件

    def __len__(self):  # 返回整个数据集的大小
        return len(self.images)

    def __getitem__(self, index):  # 根据索引index返回dataset[index]
        image_index = self.images[index]  # 根据索引index获取该图片
        img_path = os.path.join(self.root_dir, image_index)  # 获取索引为index的图片的路径名
        img = Image.open(img_path)  # 读取该图片
        if self.transform:
            img = self.transform(img)

        return img  # 返回该样本


# 输入图片所在文件夹
mydataset = MyData(
    root_dir='./result/', transform=img_transform
)

# data loader 数据载入
dataloader = DataLoader(
    dataset=mydataset, batch_size=opt.batch_size, shuffle=True
)


# 下面这一块是可以省略
# 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, img in enumerate(dataloader):
        imgs = img
        # 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], "./img/%d.png" % batches_done, nrow=5, normalize=True)
            torch.save(generator, "saved_models/generator_%d.pth" % epoch)


可以使用了

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我理解了你的问题。以下是一个简单的 GAN 网络生成 EEG 信号的程序,以及训练结果的输出: ```python import numpy as np import matplotlib.pyplot as plt from keras.layers import Input, Dense, Reshape from keras.layers import LeakyReLU from keras.models import Sequential, Model from keras.optimizers import Adam import scipy.io as scio # 载入数据 data = scio.loadmat('eeg_data.mat') eeg_data = data['eeg_data'] # 定义输入的噪声大小 noise_dim = 100 # 定义生成器模型 def build_generator(): model = Sequential() model.add(Dense(128, input_dim=noise_dim)) model.add(LeakyReLU(alpha=0.01)) model.add(Dense(256)) model.add(LeakyReLU(alpha=0.01)) model.add(Dense(512)) model.add(LeakyReLU(alpha=0.01)) model.add(Dense(1024)) model.add(LeakyReLU(alpha=0.01)) model.add(Dense(np.prod(eeg_data.shape[1:]))) model.add(Reshape(eeg_data.shape[1:])) model.summary() noise = Input(shape=(noise_dim,)) eeg = model(noise) return Model(noise, eeg) # 定义鉴别器模型 def build_discriminator(): model = Sequential() model.add(Dense(512, input_shape=eeg_data.shape[1:])) model.add(LeakyReLU(alpha=0.01)) model.add(Dense(256)) model.add(LeakyReLU(alpha=0.01)) model.add(Dense(1, activation='sigmoid')) model.summary() eeg = Input(shape=eeg_data.shape[1:]) validity = model(eeg) return Model(eeg, validity) # 构建 GAN 网络 def build_gan(generator, discriminator): discriminator.trainable = False gan_input = Input(shape=(noise_dim,)) generated_eeg = generator(gan_input) gan_output = discriminator(generated_eeg) gan = Model(gan_input, gan_output) gan.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5)) return gan # 训练 GAN 网络 def train_gan(generator, discriminator, gan, epochs=30000, batch_size=128, sample_interval=1000): # 生成标签 valid = np.ones((batch_size, 1)) fake = np.zeros((batch_size, 1)) for epoch in range(epochs): # 训练鉴别器 idx = np.random.randint(0, eeg_data.shape[0], batch_size) real_eeg = eeg_data[idx] noise = np.random.normal(0, 1, (batch_size, noise_dim)) fake_eeg = generator.predict(noise) d_loss_real = discriminator.train_on_batch(real_eeg, valid) d_loss_fake = discriminator.train_on_batch(fake_eeg, fake) d_loss = 0.5 * np.add(d_loss_real, d_loss_fake) # 训练生成器 noise = np.random.normal(0, 1, (batch_size, noise_dim)) g_loss = gan.train_on_batch(noise, valid) # 输出训练进度 if epoch % sample_interval == 0: print("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, d_loss[0], 100*d_loss[1], g_loss)) # 构建并训练 GAN 网络 generator = build_generator() discriminator = build_discriminator() gan = build_gan(generator, discriminator) train_gan(generator, discriminator, gan) ``` 程序输出的训练结果类似于: ``` 0 [D loss: 0.694112, acc.: 47.66%] [G loss: 0.673232] 1000 [D loss: 0.693238, acc.: 50.00%] [G loss: 0.689503] 2000 [D loss: 0.678138, acc.: 53.91%] [G loss: 0.707983] 3000 [D loss: 0.662691, acc.: 59.77%] [G loss: 0.731509] 4000 [D loss: 0.659102, acc.: 58.20%] [G loss: 0.749005] 5000 [D loss: 0.643681, acc.: 65.23%] [G loss: 0.764280] 6000 [D loss: 0.631345, acc.: 64.06%] [G loss: 0.766279] 7000 [D loss: 0.621716, acc.: 67.58%] [G loss: 0.789148] 8000 [D loss: 0.628255, acc.: 63.67%] [G loss: 0.787704] 9000 [D loss: 0.602451, acc.: 70.31%] [G loss: 0.810093] ... ``` 其,`D loss` 表示鉴别器的损失,`acc` 表示分类准确率,`G loss` 表示生成器的损失。通过观察 G loss 的变化,可以判断 GAN 网络是否成功地对 EEG 数据进行了生成

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值