美文网首页
Pytorch袖珍手册之八

Pytorch袖珍手册之八

作者: 深思海数_willschang | 来源:发表于2021-08-24 09:24 被阅读0次
    pytorch pocket reference
    原书下载地址:
    我用阿里云盘分享了「OReilly.PyTorch.Pocket.R...odels.149209000X.pdf」,你可以不限速下载🚀
    复制这段内容打开「阿里云盘」App 即可获取
    链接:https://www.aliyundrive.com/s/NZvnGbTYr6C

    第四章 基于已有网络设计进行神经网络应用开发

    这一章主要通过三个例子来表现Pytorch在神经网络开发应用的便捷性及高效性。

    • 基于迁移学习的图片分类
    • 自然语言处理里的情感分析
    • GAN,生成图片

    GAN,基于Fashion MNIST数据生成图片

    深度学习另一个应用场景就是生成学习(generative learning),主要通过模型来生成数据,如图片,音乐,文本和时间系列数据等。

    在本章节的例子中,我们通过构建一个GAN模型生成如Fashion-MNIST里的图片数据。

    • 数据预处理 Data Processing
      跟之前的两个例子有些不同,GAN模型主要通过学习训练数据来生成一些跟训练数据相似的数据,以达到“以假弄真”的作用。
    %matplotlib inline
    import matplotlib.pyplot as plt
    import numpy as np
    import torch
    import torch.nn as nn
    from torch import optim
    from torch.utils.data import DataLoader
    from torchvision import datasets,transforms
    from torchvision.utils import make_grid
    
    
    CODING_SIZE = 100
    BATCH_SIZE = 32
    IMAGE_SIZE = 64
    
    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    
    # 定义transforms
    transform = transforms.Compose(
        [
            transforms.Resize(IMAGE_SIZE),
            transforms.ToTensor()
        ]
    )
    
    dataset = datasets.FashionMNIST(
        './data',
        train=True,
        download=True,
        transform=transform
    )
    
    dataloader = DataLoader(
            dataset,
            batch_size=BATCH_SIZE,
            shuffle=True,
            num_workers=0 # 在windows下无法用多进程
        )
    
    
    # 数据可视化,查看数据情况
    data_batch, labels_batch = next(iter(dataloader))
    # batch_size 32, 4*8
    grid_img = make_grid(data_batch, nrow=8)
    plt.figure(figsize=(10,10))
    plt.imshow(grid_img.permute(1, 2, 0))
    
    Fashion MNIST
    • 模型构建 生成器&判别器
    # 生成器模型构建
    class Generator(nn.Module):
        def __init__(self, coding_sz):
            super(Generator, self).__init__()
            self.net = nn.Sequential(
                # 反卷积操作
                nn.ConvTranspose2d(coding_sz, 1024, 1, 1),
                nn.BatchNorm2d(1024),
                nn.ReLU(),
                nn.ConvTranspose2d(1024, 512, 4, 2, 1),
                nn.BatchNorm2d(512),
                nn.ReLU(),
                nn.ConvTranspose2d(512, 256, 4, 2, 1),
                
                nn.BatchNorm2d(256),
                nn.ReLU(),
                nn.ConvTranspose2d(256, 128, 4, 2, 1),
                nn.BatchNorm2d(128),
                nn.ReLU(),
                nn.ConvTranspose2d(128, 1, 4, 2, 1),
                nn.Tanh()       
            )
            
        def forwar(self, input):
            return self.net(input)
        
    netG = Generator(CODING_SIZE).to(device)
    
    
    # 判别器模型构建
    class Discriminator(nn.Module):
        def __init__(self):
            super(Discriminator, self).__init__()
            self.net = nn.Sequential(
                nn.Conv2d(1, 128, 4, 2, 1),
                nn.LeakyReLU(0.2),
                nn.Conv2d(128, 256, 4, 2, 1),
                nn.BatchNorm2d(256),
                nn.LeakyReLU(0.2),
                nn.Conv2d(256, 512, 4, 2, 1),
                nn.BatchNorm2d(512),
                nn.LeakyReLU(0.2),
                nn.Conv2d(512, 1024, 4, 2, 1),
                nn.BatchNorm2d(1024),
                nn.LeakyReLU(0.2),
                nn.Conv2d(1024, 1, 4, 1, 0),
                nn.Sigmoid()
            )
            
        def forward(self, input):
            return self.net(input)
        
    netD = Discriminator().to(device)
    
    # DCGAN paper found that it helps to initialize the weights 
    def weights_init(m):
        classname = m.__class__.__name__
        if classname.find('Conv') != -1:
            nn.init.normal_(m.weight.data, 0.0, 0.02)
        elif classname.find('BatchNorm') != -1:
            nn.init.normal_(m.weight.data, 1.0, 0.02)
            nn.init.constant_(m.bias.data, 0)
            
    
    netG.apply(weights_init)
    netD.apply(weights_init)
    “”“
    Generator(
      (net): Sequential(
        (0): ConvTranspose2d(100, 1024, kernel_size=(1, 1), stride=(1, 1))
        (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): ReLU()
        (3): ConvTranspose2d(1024, 512, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
        (4): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (5): ReLU()
        (6): ConvTranspose2d(512, 256, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
        (7): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (8): ReLU()
        (9): ConvTranspose2d(256, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
        (10): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (11): ReLU()
        (12): ConvTranspose2d(128, 1, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
        (13): Tanh()
      )
    )
    ============================================================================================
    Discriminator(
      (net): Sequential(
        (0): Conv2d(1, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
        (1): LeakyReLU(negative_slope=0.2)
        (2): Conv2d(128, 256, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
        (3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (4): LeakyReLU(negative_slope=0.2)
        (5): Conv2d(256, 512, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
        (6): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (7): LeakyReLU(negative_slope=0.2)
        (8): Conv2d(512, 1024, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
        (9): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (10): LeakyReLU(negative_slope=0.2)
        (11): Conv2d(1024, 1, kernel_size=(4, 4), stride=(1, 1))
        (12): Sigmoid()
      )
    )
    ”“”
    
    • 训练模型
    # 训练模型
    """
    In each epoch, we will first train the discriminator with a real batch of data, 
    then use the generator to create a fake batch, and then train the discriminator with the generated fake batch of data. 
    Lastly, we will train the generator NN to produce better fakes.
    """
    # 定义损失函数及优化器
    criterion = nn.BCELoss()
    optimizerG = optim.Adam(netG.parameters(), lr=0.0002, betas=(0.5, 0.999))
    optimizerD = optim.Adam(netD.parameters(), lr=0.0001, betas=(0.5, 0.999))
    
    # 定义真假数据标签值
    real_labels = torch.full((BATCH_SIZE,), 1., dtype=torch.float, device=device)
    fake_labels = torch.full((BATCH_SIZE,), 0., dtype=torch.float, device=device)
    
    
    G_losses = []
    D_losses = []
    D_real = []
    D_fake = []
    N_EPOCHS = 5
    
    z = torch.randn((BATCH_SIZE, 100)).view(-1, 100, 1, 1).to(device)
    test_out_images = []
    
    for epoch in range(N_EPOCHS):
        print(f'Epoch: {epoch}')
        for i, batch in enumerate(dataloader):
            if (i%200==0):
                print(f'batch: {i} of {len(dataloader)}')
        
            # 训练判别器,基于真数据
            netD.zero_grad()
            real_images = batch[0].to(device) *2. - 1.
            output = netD(real_images).view(-1) 
            errD_real = criterion(output, real_labels)
            D_x = output.mean().item()
    
            # 训练判别器,基于假数据
            noise = torch.randn((BATCH_SIZE, CODING_SIZE))
            noise = noise.view(-1,100,1,1).to(device)
            fake_images = netG(noise)
            output = netD(fake_images).view(-1) 
            errD_fake = criterion(output, fake_labels)
            D_G_z1 = output.mean().item()
            errD = errD_real + errD_fake
            errD.backward(retain_graph=True) 
            optimizerD.step()
    
            # 训练生成器,产生更逼真数据
            netG.zero_grad()
            output = netD(fake_images).view(-1) 
            errG = criterion(output, real_labels)
            errG.backward() 
            D_G_z2 = output.mean().item()
            optimizerG.step()
    
            # 保存中间变量值,用于后续画图
            G_losses.append(errG.item())
            D_losses.append(errD.item())
    
            D_real.append(D_x)
            D_fake.append(D_G_z2)
    
        test_images = netG(z).to('cpu').detach() 
        test_out_images.append(test_images)
            
             
    grid_img = make_grid((test_out_images[0]+1.)/2., nrow=8)
    plt.imshow(grid_img.permute(1, 2, 0)) 
    
    image.png
    • 训练过程中,生成判别模型损失值情况
    plt.figure(figsize=(10,5))
    plt.title("Generator and Discriminator Loss During Training")
    plt.plot(G_losses,label="G")
    plt.plot(D_losses,label="D")
    plt.xlabel("iterations")
    plt.ylabel("Loss")
    plt.legend()
    plt.show()
    
    image.png
    • Discriminator Results
    plt.figure(figsize=(10,5))
    plt.title("Discriminator Results")
    plt.plot(D_real,label="D(real)")
    plt.plot(D_fake,label="D(fake)")
    plt.xlabel("iterations")
    plt.ylabel("Percentage Real")
    plt.legend()
    plt.show()
    
    image.png
    • 模型生成图片数据效果
    grid_img = make_grid((test_out_images[4]+1.)/2., nrow=8)
    plt.imshow(grid_img.permute(1, 2, 0))
    
    image.png

    相关文章

      网友评论

          本文标题:Pytorch袖珍手册之八

          本文链接:https://www.haomeiwen.com/subject/axitiltx.html