【DCGAN】生成对抗网络,手写数字识别

基于paddle,aistudio的DCGAN

主要用于记录自己学习经历。

1   导入必要的包

import os
import random
import paddle
import paddle.nn as nn
import paddle.optimizer as optim
import paddle.vision.datasets as dset
import paddle.vision.transforms as transforms
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

2   定义数据集

demo_dataset = paddle.vision.datasets.MNIST(mode='train')

3   查看数据集

demo_dataset[5][0]

4   查看数据集维度

for data in dataloader:
    break

data[0].shape

5   参数初始化模块

@paddle.no_grad()
def normal_(x, mean=0., std=1.):
    temp_value = paddle.normal(mean, std, shape=x.shape) 
    # 该op返回符合正态分布(均值为mean,标准差为std的正态随机分布)的随机Tensor。
    x.set_value(temp_value)
    return x

@paddle.no_grad()
def uniform_(x, a=-1., b=1.):
    temp_value = paddle.uniform(min=a, max=b, shape=x.shape)
    # 该op返回值服从范围[min,max]内均值分布的随机Tensor,性状为shape,数据类型为dtype
    x.set_value(temp_value)
    return x

@paddle.no_grad()
def constant_(x, value):
    temp_value = paddle.full(x.shape, value, x.dtype)
    # 该op创造形状大小为shape并且数据类型为dtype的Tensor,其中元素值均为fill_value。
    x.set_value(temp_value)
    return x

def weights_init(m):
    classname = m.__class__.__name__
    if hasattr(m, 'weight') and classname.find('Conv') != -1:
        normal_(m.weight, 0.0, 0.02)
    elif classname.find('BatchNorm') != -1:
        normal_(m.weight, 1.0, 0.02)
        constant_(m.bias, 0)

6   生成器代码

# Layer 给予OOD实现的动态图Layer,包含该Layer的参数,前序运动的结构等信息

class Generator(nn.Layer):
    def __init__(self, ):
        super(Generator, self).__init__()
        # 顺序容器。子Layer将按构造函数参数的顺序添加到此容器中。
        # 传递给构造函数的参数可以Layers或可迭代的name Layer元组。
        self.gen = nn.Sequential(
            # input is Z, [B, 100, 1, 1] -> [B, 64 * 4, 4, 4]
            nn.Conv2DTranspose(100, 64 * 4, 4, 1, 0, bias_attr=False),
            # 二维转置神经层
            # 改层根据输入(input),卷积核(kernel)和空洞大小(dilations),步长(stride)
            # 填充(padding)来计算输出特征层大小或者通过output_size指定输出特征层大小。
            # 输入(Input)和输出(Output)为NCHW或NHWC格式,其中N是批尺寸,C为通道数(channel)
            # H为特征层高度,W为特征层宽度。卷积核是MCHW格式,M是输出图像通道数,
            # C是输入图像通道数,H是卷积核高度,W是卷积核宽度。
            # 如果组数大于1,C等于输入图像通道数除以组数的结果。
            # 转置卷积的计算过程相当于卷积的反向计算。
            # 转置卷积又被称为反卷积(但其实并不是真正的反卷积)。
            nn.BatchNorm2D(64 * 4),
            # 该接口用于构建 BatchNorm2D 类的一个可调用对象。
            # 可以处理4D的Tensor, 实现了批归一化层(Batch Normalization Layer)的功能,
            # 可用作卷积和全连接操作的批归一化函数,
            # 根据当前批次数据按通道计算的均值和方差进行归一化。
            nn.ReLU(True),
            # state size. [B, 64 * 4, 4, 4] -> [B, 64 * 2, 8, 8]
            nn.Conv2DTranspose(64 * 4, 64 * 2, 4, 2, 1, bias_attr=False),
            nn.BatchNorm2D(64 * 2),
            nn.ReLU(True),
            # state size. [B, 64 * 2, 8, 8] -> [B, 64, 16, 16]
            nn.Conv2DTranspose( 64 * 2, 64, 4, 2, 1, bias_attr=False),
            nn.BatchNorm2D(64),
            nn.ReLU(True),
            # state size. [B, 64, 16, 16] -> [B, 1, 32, 32]
            nn.Conv2DTranspose( 64, 1, 4, 2, 1, bias_attr=False),
            nn.Tanh()
            # Tanh激活层
        )

    def forward(self, x):
        return self.gen(x)


netG = Generator()
# Apply the weights_init function to randomly initialize all weights
#  to mean=0, stdev=0.2.
netG.apply(weights_init)
# 用来对模型的参数进行初始化  将netG中参数都过weights_init进行初始化

# Print the model
print(netG)

7   判别器代码

class Discriminator(nn.Layer):
    def __init__(self,):
        super(Discriminator, self).__init__()
        self.dis = nn.Sequential(

            # input [B, 1, 32, 32] -> [B, 64, 16, 16]
            nn.Conv2D(1, 64, 4, 2, 1, bias_attr=False),
            nn.LeakyReLU(0.2),

            # state size. [B, 64, 16, 16] -> [B, 128, 8, 8]
            nn.Conv2D(64, 64 * 2, 4, 2, 1, bias_attr=False),
            nn.BatchNorm2D(64 * 2),
            nn.LeakyReLU(0.2),

            # state size. [B, 128, 8, 8] -> [B, 256, 4, 4]
            nn.Conv2D(64 * 2, 64 * 4, 4, 2, 1, bias_attr=False),
            nn.BatchNorm2D(64 * 4),
            nn.LeakyReLU(0.2),

            # state size. [B, 256, 4, 4] -> [B, 1, 1, 1] -> [B, 1]
            nn.Conv2D(64 * 4, 1, 4, 1, 0, bias_attr=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        return self.dis(x)

netD = Discriminator()
netD.apply(weights_init)
print(netD)

8   二分类的交叉熵损失函数

loss = nn.BCELoss()
# 该接口用于创建一个BCELoss的可调用类,
# 用于计算输入input和标签label之间的二值交叉熵损失值

fixed_noise = paddle.rand([32, 100, 1, 1],dtype='float32')

real_label = 1.
fake_label = 0.

optimizerD = optim.Adam(parameters=netD.parameters(),learning_rate=0.0002,beta1=0.5,beta2=0.999)
optimizerG = optim.Adam(parameters=netG.parameters(),learning_rate=0.0002,beta1=0.5,beta2=0.999)
# Adam优化器出自 Adam论文 的第二节。
#能够利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。

9   进行训练,先训练生成器,后训练判别器

losses = [[],[]]
now = 0
for pass_id in range(10):
    for batch_id,(data,target) in enumerate (dataloader):
        # enumerate  一般用于for中  获取字典索引和元素值

        optimizerD.clear_grad()
        # 梯度清空  防止积累
        real_img = data
        bs_size = real_img.shape[0]
        label = paddle.full((bs_size,1,1,1),real_label,dtype='float32')
        real_out = netD(real_img)
        errD_real = loss(real_out,label)
        errD_real.backward()


        noise = paddle.randn([bs_size,100,1,1],'float32')
        fake_img = netG(noise)
        label = paddle.full((bs_size,1,1,1),fake_label,dtype='float32')
        fake_out = netD(fake_img.detach())
        errD_fake = loss(fake_out,label)
        errD_fake.backward()
        optimizerD.step()
        optimizerD.clear_grad()


        errD = errD_real+errD_fake
        losses[0].append(errD.numpy()[0])


        optimizerG.clear_grad()
        noise = paddle.randn([bs_size,100,1,1],'float32')
        fake = netG(noise)
        label = paddle.full((bs_size,1,1,1),real_label,dtype=np.float32,)
        output = netD(fake)
        errG = loss(output,label)
        errG.backward()
        optimizerG.step()
        optimizerG.clear_grad()

        losses[1].append(errG.numpy()[0])


        if batch_id % 100 == 0:
            generated_image = netG(noise).numpy()
            imgs = []
            plt.figure(figsize=(15,15))
            try:
                for i in range(10):
                    image = generated_image[i].transpose()
                    image = np.where(image > 0, image, 0)
                    image = image.transpose((1,0,2))
                    plt.subplot(10, 10, i + 1)
                    
                    plt.imshow(image[...,0], vmin=-1, vmax=1)
                    plt.axis('off')
                    plt.xticks([])
                    plt.yticks([])
                    plt.subplots_adjust(wspace=0.1, hspace=0.1)
                msg = 'Epoch ID={0} Batch ID={1} \n\n D-Loss={2} G-Loss={3}'.format(pass_id, batch_id, errD.numpy()[0], errG.numpy()[0])
                print(msg)
                plt.suptitle(msg,fontsize=20)
                plt.draw()
                plt.savefig('{}/{:04d}_{:04d}.png'.format('work', pass_id, batch_id), bbox_inches='tight')
                plt.pause(0.01)
            except IOError:
                print(IOError)
    paddle.save(netG.state_dict(), "work/generator.params")

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.版本:matlab2014/2019a,内含运行结果,不会运行可私信 2.领域:智能优化算法、神经网络预测、信号处理、元胞自动机、图像处理、路径规划、无人机等多种领域的Matlab仿真,更多内容可点击博主头像 3.内容:标题所示,对于介绍可点击主页搜索博客 4.适合人群:本科,硕士等教研学习使用 5.博客介绍:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可si信 ### 团队长期从事下列领域算法的研究和改进: ### 1 智能优化算法及应用 **1.1 改进智能优化算法方面(单目标和多目标)** **1.2 生产调度方面** 1.2.1 装配线调度研究 1.2.2 车间调度研究 1.2.3 生产线平衡研究 1.2.4 水库梯度调度研究 **1.3 路径规划方面** 1.3.1 旅行商问题研究(TSP、TSPTW) 1.3.2 各类车辆路径规划问题研究(vrp、VRPTW、CVRP) 1.3.3 机器人路径规划问题研究 1.3.4 无人机三维路径规划问题研究 1.3.5 多式联运问题研究 1.3.6 无人机结合车辆路径配送 **1.4 三维装箱求解** **1.5 物流选址研究** 1.5.1 背包问题 1.5.2 物流选址 1.5.4 货位优化 ##### 1.6 电力系统优化研究 1.6.1 微电网优化 1.6.2 配电网系统优化 1.6.3 配电网重构 1.6.4 有序充电 1.6.5 储能双层优化调度 1.6.6 储能优化配置 ### 2 神经网络回归预测、时序预测、分类清单 **2.1 bp预测和分类** **2.2 lssvm预测和分类** **2.3 svm预测和分类** **2.4 cnn预测和分类** ##### 2.5 ELM预测和分类 ##### 2.6 KELM预测和分类 **2.7 ELMAN预测和分类** ##### 2.8 LSTM预测和分类 **2.9 RBF预测和分类** ##### 2.10 DBN预测和分类 ##### 2.11 FNN预测 ##### 2.12 DELM预测和分类 ##### 2.13 BIlstm预测和分类 ##### 2.14 宽度学习预测和分类 ##### 2.15 模糊小波神经网络预测和分类 ##### 2.16 GRU预测和分类 ### 3 图像处理算法 **3.1 图像识别** 3.1.1 车牌、交通标志识别(新能源、国内外、复杂环境下车牌) 3.1.2 发票、身份证、银行卡识别 3.1.3 人脸类别和表情识别 3.1.4 打靶识别 3.1.5 字符识别(字母、数字、手写体、汉字、验证码) 3.1.6 病灶识别 3.1.7 花朵、药材、水果蔬菜识别 3.1.8 指纹、手势、虹膜识别 3.1.9 路面状态和裂缝识别 3.1.10 行为识别 3.1.11 万用表和表盘识别 3.1.12 人民币识别 3.1.13 答题卡识别 **3.2 图像分割** **3.3 图像检测** 3.3.1 显著性检测 3.3.2 缺陷检测 3.3.3 疲劳检测 3.3.4 病害检测 3.3.5 火灾检测 3.3.6 行人检测 3.3.7 水果分级 **3.4 图像隐藏** **3.5 图像去噪** **3.6 图像融合** **3.7 图像配准** **3.8 图像增强** **3.9 图像压缩** ##### 3.10 图像重建 ### 4 信号处理算法 **4.1 信号识别** **4.2 信号检测** **4.3 信号嵌入和提取** **4.4 信号去噪** ##### 4.5 故障诊断 ##### 4.6 脑电信号 ##### 4.7 心电信号 ##### 4.8 肌电信号 ### 5 元胞自动机仿真 **5.1 模拟交通流** **5.2 模拟人群疏散** **5.3 模拟病毒扩散** **5.4 模拟晶体生长** ### 6 无线传感器网络 ##### 6.1 无线传感器定位 ##### 6.2 无线传感器覆盖优化 ##### 6.3 室内定位 ##### 6.4 无线传感器通信及优化 ##### 6.5 无人机通信中继优化
生成对抗网络GAN)是一种强大的深度学习技术,可以用于许多应用,包括手写体数字识别。在这里,我将向你展示如何使用Python实现手写体数字识别GAN。 首先,需要安装必要的库,包括TensorFlow和Keras。可以使用以下命令安装它们: ``` pip install tensorflow pip install keras ``` 接下来,我们需要准备MNIST数据集。可以使用以下代码加载数据集: ```python from keras.datasets import mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() ``` 现在,我们将创建两个神经网络 - 一个生成器和一个判别器。生成器将随机噪声作为输入并生成手写数字图像,而判别器将接受手写数字图像并输出它们的真假。 ```python from keras.models import Sequential from keras.layers import Dense, Flatten, Reshape, Dropout from keras.layers.convolutional import Conv2DTranspose, Conv2D from keras.layers.normalization import BatchNormalization from keras.layers.advanced_activations import LeakyReLU def create_generator(): generator = Sequential() generator.add(Dense(128 * 7 * 7, input_dim=100, activation=LeakyReLU(0.2))) generator.add(Reshape((7, 7, 128))) generator.add(Conv2DTranspose(64, (3,3), strides=(2,2), padding='same', activation=LeakyReLU(0.2))) generator.add(BatchNormalization()) generator.add(Conv2DTranspose(1, (3,3), strides=(2,2), padding='same', activation='tanh')) return generator def create_discriminator(): discriminator = Sequential() discriminator.add(Conv2D(64, (3,3), padding='same', input_shape=(28,28,1))) discriminator.add(LeakyReLU(0.2)) discriminator.add(Dropout(0.25)) discriminator.add(Conv2D(128, (3,3), strides=(2,2), padding='same')) discriminator.add(LeakyReLU(0.2)) discriminator.add(Dropout(0.25)) discriminator.add(Flatten()) discriminator.add(Dense(1, activation='sigmoid')) return discriminator generator = create_generator() discriminator = create_discriminator() ``` 现在,我们将定义GAN模型。我们将训练生成器和判别器,以便它们可以通过相互竞争的方式共同学习并提高性能。 ```python from keras.optimizers import Adam def create_gan(generator, discriminator): discriminator.trainable = False gan = Sequential() gan.add(generator) gan.add(discriminator) gan.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.0002, beta_1=0.5)) return gan gan = create_gan(generator, discriminator) ``` 现在我们将定义训练循环: ```python import numpy as np import matplotlib.pyplot as plt def train(generator, discriminator, gan, x_train, epochs=50, batch_size=128): # Rescale -1 to 1 x_train = x_train / 127.5 - 1. x_train = np.expand_dims(x_train, axis=3) real = np.ones((batch_size, 1)) fake = np.zeros((batch_size, 1)) for epoch in range(epochs): # Train discriminator idx = np.random.randint(0, x_train.shape[0], batch_size) real_imgs = x_train[idx] noise = np.random.normal(0, 1, (batch_size, 100)) fake_imgs = generator.predict(noise) d_loss_real = discriminator.train_on_batch(real_imgs, real) d_loss_fake = discriminator.train_on_batch(fake_imgs, fake) d_loss = 0.5 * np.add(d_loss_real, d_loss_fake) # Train generator noise = np.random.normal(0, 1, (batch_size, 100)) g_loss = gan.train_on_batch(noise, real) # Plot the progress print("Epoch {}, Discriminator Loss: {}, Generator Loss: {}".format(epoch, d_loss, g_loss)) # Generate some digits to check the progress if epoch % 10 == 0: noise = np.random.normal(0, 1, (25, 100)) gen_imgs = generator.predict(noise) gen_imgs = 0.5 * gen_imgs + 0.5 fig, axs = plt.subplots(5, 5) cnt = 0 for i in range(5): for j in range(5): axs[i,j].imshow(gen_imgs[cnt,:,:,0], cmap='gray') axs[i,j].axis('off') cnt += 1 plt.show() train(generator, discriminator, gan, x_train, epochs=1000, batch_size=128) ``` 在训练之后,我们可以使用生成器来生成一些手写数字图像: ```python noise = np.random.normal(0, 1, (25, 100)) gen_imgs = generator.predict(noise) gen_imgs = 0.5 * gen_imgs + 0.5 fig, axs = plt.subplots(5, 5) cnt = 0 for i in range(5): for j in range(5): axs[i,j].imshow(gen_imgs[cnt,:,:,0], cmap='gray') axs[i,j].axis('off') cnt += 1 plt.show() ``` 这就是用Python实现手写体数字识别GAN的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值