您的位置:首页 > 游戏 > 游戏 > 版面设计图大全模板_青岛市疾病预防控制中心紧急提示_如何使用免费b站推广网站_搜索引擎优化的目的是

版面设计图大全模板_青岛市疾病预防控制中心紧急提示_如何使用免费b站推广网站_搜索引擎优化的目的是

2025/3/1 10:01:44 来源:https://blog.csdn.net/weixin_43414521/article/details/145134837  浏览:    关键词:版面设计图大全模板_青岛市疾病预防控制中心紧急提示_如何使用免费b站推广网站_搜索引擎优化的目的是
版面设计图大全模板_青岛市疾病预防控制中心紧急提示_如何使用免费b站推广网站_搜索引擎优化的目的是

>- **🍨 本文为[🔗365天深度学习训练营]中的学习记录博客**
>- **🍖 原作者:[K同学啊]**

本人往期文章可查阅: 深度学习总结

🏡 我的环境:

  • 语言环境:Python3.11
  • 编译器:PyCharm
  • 深度学习环境:Pytorch
    • torch==2.0.0+cu118
    • torchvision==0.18.1+cu118
  • 显卡:NVIDIA GeForce GTX 1660

论文地址:Conditional Image Synthesis with Auxiliary Classifier GANs

一、理论基础

        ACGAN的全称是 Auxiliary Classifier Generative Adversarial Network ,翻译成汉语的意思就是带辅助分类器的GAN,ACGAN的原理与GAN(CGAN)相似。对于CGAN和ACGAN,生成器输入均为潜在矢量及其标签,输出是属于输入类标签的伪造图像。

       对于CGAN,判别器的输入是图像(包含假的或真实的图像)及其标签,输出是图像属于真实图像的概率。对于ACGAN,判别器的输入是一副图像,而输出是该图像属于真实图像的概率以及其类别。

       图1是ACGAN的网络结构,可以发现该结构其实和之前的CGAN和SGAN都非常接近,可以说是两者的结合体。但这样的修改可以有效生成高质量的生成结果,并且使得训练更加稳定。

       本质上,在CGAN中,向网络提供了标签。在ACGAN中,使用辅助解码器网络重建辅助信息。ACGAN理论认为,强制网络执行其他任务可以提高原始任务的性能。在这种情况下,辅助任务是图像分类。原始任务是生成伪造图像。

项目代码:详见页面顶端,可直接下载

二、代码实现

1. 导入第三方库

此段代码与.py文件中的稍有区别,Jupyter Notebook 并不提供一个真正的命令行环境,因此 argparse 会尝试解析 Jupyter Notebook 启动时传递给内核的参数,而不是你期望的自定义参数,故使用 sys.argv 模拟命令行参数

import argparse,os,math
import numpy as np
import torchvision.transforms as transforms
from torchvision.utils import save_image
from torch.utils.data import DataLoader
from torchvision import datasets
from torch.autograd import Variable
import torch
import torch.nn as nn
import torch.nn.functional as F# 创建用于存储生成图像的目录
os.makedirs("images",exist_ok=True)# 模拟命令行参数
import sys
sys.argv=['script.py',  # 脚本名称'--n_epochs', '200','--batch_size', '64','--lr', '0.0002','--b1', '0.5','--b2', '0.999','--n_cpu', '8','--latent_dim', '100','--n_classes', '10','--img_size', '32','--channels', '1','--sample_interval', '400'
]# 解析命令行参数
parser=argparse.ArgumentParser()
parser.add_argument("--n_epochs",type=int,default=200,help="训练的总轮数")
parser.add_argument("--batch_size",type=int,default=64,help="每个批次的大小")
parser.add_argument("--lr",type=float,default=0.0002,help="Adam优化器的学习率")
parser.add_argument("--b1",type=float,default=0.5,help="Adam优化器的一阶动量衰减")
parser.add_argument("--b2",type=float,default=0.999,help="Adam优化器的二阶动量衰减")
parser.add_argument("--n_cpu",type=int,default=8,help="用于批次生成的CPU线程数")
parser.add_argument("--latent_dim",type=int,default=100,help="潜在空间的维度")
parser.add_argument("--n_classes",type=int,default=10,help="数据集的类别数")
parser.add_argument("--img_size",type=int,default=32,help="每个图像的尺寸")
parser.add_argument("--channels",type=int,default=1,help="图像通道数")
parser.add_argument("--sample_interval",type=int,default=400,help="图像采样间隔")
opt=parser.parse_args()
print(opt)# 检查是否支持GPU加速
cuda=True if torch.cuda.is_available() else False

运行结果:  

Namespace(n_epochs=200, batch_size=64, lr=0.0002, b1=0.5, b2=0.999, n_cpu=8, latent_dim=100, n_classes=10, img_size=32, channels=1, sample_interval=400)

2. 初始化权重

# 初始化神经网络权重的函数
def weights_init_normal(m):classname=m.__class__.__name__if classname.find("Conv")!=-1:torch.nn.init.normal_(m.weight.data,0.0,0.02)elif classname.find("BatchNorm2d")!=-1:torch.nn.init.normal_(m.weight.data,1.0,0.02)torch.nn.init.constant_(m.bias.data,0.0)

3. 构建网络模型

# 生成器网络类
class Generator(nn.Module):def __init__(self):super(Generator,self).__init__()# 为类别标签创建嵌入层self.label_emb=nn.Embedding(opt.n_classes,opt.latent_dim)# 计算上采样前的初始大小self.init_size=opt.img_size//4 # Initial size before upsampling# 第一层线性层self.l1=nn.Sequential(nn.Linear(opt.latent_dim,128*self.init_size**2))# 卷积层块self.conv_blocks=nn.Sequential(nn.BatchNorm2d(128),nn.Upsample(scale_factor=2),nn.Conv2d(128,128,3,stride=1,padding=1),nn.BatchNorm2d(128,0.8),nn.LeakyReLU(0.2,inplace=True),nn.Upsample(scale_factor=2),nn.Conv2d(128,64,3,stride=1,padding=1),nn.BatchNorm2d(64,0.8),nn.LeakyReLU(0.2,inplace=True),nn.Conv2d(64,opt.channels,3,stride=1,padding=1),nn.Tanh(),)def forward(self,noise,labels):# 将标签嵌入到噪声中gen_input=torch.mul(self.label_emb(labels),noise)# 通过第一层线性层out=self.l1(gen_input)# 重新整形为合适的形状out=out.view(out.shape[0],128,self.init_size,self.init_size)# 通过卷积层块生成图像img=self.conv_blocks(out)return img# 判别器网络类
class Discriminator(nn.Module):def __init__(self):super(Discriminator,self).__init__()# 定义判别器块的函数def discriminator_block(in_filters,out_filters,bn=True):"""返回每个判别器块的层"""block=[nn.Conv2d(in_filters,out_filters,3,2,1),nn.LeakyReLU(0.2,inplace=True),nn.Dropout2d(0.25)]if bn:block.append(nn.BatchNorm2d(out_filters,0.8))return block# 判别器的卷积层块self.conv_blocks=nn.Sequential(*discriminator_block(opt.channels,16,bn=False),*discriminator_block(16,32),*discriminator_block(32,64),*discriminator_block(64,128),)# 下采样后图像的高度和宽度ds_size=opt.img_size//2**4# 输出层self.adv_layer=nn.Sequential(nn.Linear(128*ds_size**2,1),nn.Sigmoid())self.aux_layer=nn.Sequential(nn.Linear(128*ds_size**2,opt.n_classes),nn.Softmax())def forward(self,img):out=self.conv_blocks(img)out=out.view(out.shape[0],-1)validity=self.adv_layer(out)label=self.aux_layer(out)return validity,label

4. 模型初始化

# 损失函数
adversarial_loss=torch.nn.BCELoss()
auxiliary_loss=torch.nn.CrossEntropyLoss()# 初始化生成器和判别器
generator=Generator()
discriminator=Discriminator()if cuda:generator.cuda()discriminator.cuda()adversarial_loss.cuda()auxiliary_loss.cuda()# 初始化权重
generator.apply(weights_init_normal)
discriminator.apply(weights_init_normal)

运行结果:

Discriminator((conv_blocks): Sequential((0): Conv2d(1, 16, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(1): LeakyReLU(negative_slope=0.2, inplace=True)(2): Dropout2d(p=0.25, inplace=False)(3): Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(4): LeakyReLU(negative_slope=0.2, inplace=True)(5): Dropout2d(p=0.25, inplace=False)(6): BatchNorm2d(32, eps=0.8, momentum=0.1, affine=True, track_running_stats=True)(7): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(8): LeakyReLU(negative_slope=0.2, inplace=True)(9): Dropout2d(p=0.25, inplace=False)(10): BatchNorm2d(64, eps=0.8, momentum=0.1, affine=True, track_running_stats=True)(11): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))(12): LeakyReLU(negative_slope=0.2, inplace=True)(13): Dropout2d(p=0.25, inplace=False)(14): BatchNorm2d(128, eps=0.8, momentum=0.1, affine=True, track_running_stats=True))(adv_layer): Sequential((0): Linear(in_features=512, out_features=1, bias=True)(1): Sigmoid())(aux_layer): Sequential((0): Linear(in_features=512, out_features=10, bias=True)(1): Softmax(dim=None))
)

5. 配置数据集

# 配置数据加载器
os.makedirs(r"E:\DATABASE\G-series\acgan\data",exist_ok=True)
dataloader=torch.utils.data.DataLoader(datasets.MNIST(r"E:\DATABASE\G-series\acgan\data",train=True,download=False,transform=transforms.Compose([transforms.Resize(opt.img_size),transforms.ToTensor(),transforms.Normalize([0.5],[0.5])]),),batch_size=opt.batch_size,shuffle=True,
)

6. 模型训练

# 优化器
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))FloatTensor=torch.cuda.FloatTensor if cuda else torch.FloatTensor
LongTensor=torch.cuda.LongTensor if cuda else torch.LongTensor# 保存生成图像的函数
def sample_image(n_row,batches_done):"""保存从0到n_classes的生成数字的图像网络"""# 采样噪声z=Variable(FloatTensor(np.random.normal(0,1,(n_row**2,opt.latent_dim))))# 为n行生成标签从0到n_classeslabels=np.array([num for _ in range(n_row) for num in range(n_row)])labels=Variable(LongTensor(labels))gen_imgs=generator(z,labels)save_image(gen_imgs.data,"images/%d.png"%batches_done,nrow=n_row,normalize=True)# --------
# 训练
# --------for epoch in range(opt.n_epochs):for i,(imgs,labels) in enumerate(dataloader):batch_size=imgs.shape[0]# 真实数据的标签valid=Variable(FloatTensor(batch_size,1).fill_(1.0),requires_grad=False)# 生成数据的标签fake=Variable(FloatTensor(batch_size,1).fill_(0.0),requires_grad=False)# 配置输入real_imgs=Variable(imgs.type(FloatTensor))labels=Variable(labels.type(LongTensor))# --------------# 训练生成器# --------------optimizer_G.zero_grad()# 采样噪声和标签作为生成器的输入z=Variable(FloatTensor(np.random.normal(0,1,(batch_size,opt.latent_dim))))gen_labels=Variable(LongTensor(np.random.randint(0,opt.n_classes,batch_size)))# 生成一批图像gen_imgs=generator(z,gen_labels)# 损失度量生成器的欺骗判别器的能力validity,pred_label=discriminator(gen_imgs)g_loss=0.5*(adversarial_loss(validity,valid)+auxiliary_loss(pred_label,gen_labels))g_loss.backward()optimizer_G.step()# --------------# 训练判别器# ---------------optimizer_D.zero_grad()# 真实图像的损失real_pred,real_aux=discriminator(real_imgs)d_real_loss=(adversarial_loss(real_pred,valid)+auxiliary_loss(real_aux,labels))/2# 生成图像的损失fake_pred,fake_aux=discriminator(gen_imgs.detach())d_fake_loss=(adversarial_loss(fake_pred,fake)+auxiliary_loss(fake_aux,gen_labels))/2# 判别器的总损失d_loss=(d_real_loss+d_fake_loss)/2# 计算判别器的准确率pred=np.concatenate([real_aux.data.cpu().numpy(),fake_aux.data.cpu()],axis=0)gt=np.concatenate([labels.data.cpu().numpy(),gen_labels.data.cpu().numpy()],axis=0)d_acc=np.mean(np.argmax(pred,axis=1)==gt)d_loss.backward()optimizer_D.step()print("[Epoch %d/%d] [Batch %d/%d] [D_loss:%f,acc:%d%%] [G_loss:%f]" % (epoch,opt.n_epochs,i,len(dataloader),d_loss.item(),100*d_acc,g_loss.item()))batches_done=epoch*len(dataloader)+iif batches_done % opt.sample_interval==0:sample_image(n_row=10,batches_done=batches_done)

7. 训练结果

三、心得体会

       与前面的GAN和CGAN相比,类似地方较多。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com