首页 > 编程知识 正文

pytorch怎么用,pytorch怎么学

时间:2023-05-03 10:37:58 阅读:26720 作者:2751

http://www.Sina.com/:在50行代码下GAN(pytorch )-PyTorch中文网【小修改】在pytorch上GAN——mnist (包括所有评论和网络思想) _清凌的博客

在进入技术水平之前,为了照顾新入门的开发人员,首先介绍一下什么是GAN。

2014年,Ian Goodfellow和蒙特利尔大学的同事发表了一篇震撼学术界的论文。 没错,我说的是《Generative Adversarial Nets》,这标志着对网(GAN )的诞生。 这得益于计算图和博弈论的创新结合。 他们的研究表明,给定足够的建模能力,两个游戏模型可以通过简单的反向传播(backpropagation )协同训练。

这两种模式的作用定位非常鲜明。 给定实际的数据集r,g是生成器,其任务是产生能够以假乱真的假数据; 另一方面,d是判别器,从实际数据集或g获取数据,并标记为判别真伪。 Ian Goodfellow的比喻是,g就像一个假货作坊,试图让做好的东西尽可能接近真的东西来蒙混过去。 d是文物鉴定专家,必须能区分真品和高仿。 (但是在这个例子中,伪造者g看不到原始数据,只有d的鉴定结果——前者盲工作)。

理想的情况是,随着D和g的持续训练,直到g基本上成为假货制造者为止,——都做得很好,但由于d无法正确区分两种数据分布,所以输给了g。

事实上,Ian Goodfellow展示的这个技术本质上就是,g可以对原始数据集进行无监督的学习,从而找到以更低维度的方法来表示数据。 无监督学习很重要,就像杨乐村说的那样,“无监督学习是蛋糕的糕体”。 这句话里的蛋糕,就是无数学者、开发者所追求的“真正的AI”。

二、核心思想判断器的任务是判假为真; 生成器的任务是让生成的东西真正变好。 两者交替反复训练。

三、核心代码real_label=variable(Torch.ones ) num_img ).cuda ) #定义真实图像的label为1fake_label=variable ) torch. 判断为假的real_out=d(real_img )将真实图像放入判别器的real_out=real_out.squeeze () 128,1 ) ) 128,) )。 将real_label(#判断为真的fake_img=g(z ) )随机噪声放入生成网络中,假图像fake_out=d ) fake_img ) #判别器判断假图像,fakke _ ou img fake_label )对于用于获得假图像的lossd _ loss=d _ loss _ reald _ loss _ fake #损失,由G:生成的fake_img=g(z )随机噪声被输入到生成器得到经过判别器得到的结果fake _ out=fake _ out.squeeze (g _ loss #=criterion (fake _ out,real_label ) )所得到的伪图像和实际图像的ll /usr/真正的鞋垫/env python #-* -编码: utf-8-- * # coding=utf-8 import torch.autogradimporttorch.nnasnnfromtorch.autogradimportvariablefromtorchvisionimportttransformsformsfroratorch t创建tsave_imageimportOS#文件夹ifnotOS.path.exists('./img ' ) :OS.mkdir )./I mkdir (x1 ) out=out.#

ion = 100# 图像预处理img_transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,)) # (x-mean) / std])# mnist dataset mnist数据集下载mnist = datasets.MNIST( root='./data/', train=True, transform=img_transform, download=True)# data loader 数据载入dataloader = torch.utils.data.DataLoader( dataset=mnist, batch_size=batch_size, shuffle=True)# 定义判别器 #####Discriminator######使用多层网络来作为判别器# 将图片28x28展开成784,然后通过多层感知器,中间经过斜率设置为0.2的LeakyReLU激活函数,# 最后接sigmoid激活函数得到一个0到1之间的概率进行二分类。class discriminator(nn.Module): def __init__(self): super(discriminator, self).__init__() self.dis = nn.Sequential( nn.Linear(784, 256), # 输入特征数为784,输出为256 nn.LeakyReLU(0.2), # 进行非线性映射 nn.Linear(256, 256), # 进行一个线性映射 nn.LeakyReLU(0.2), nn.Linear(256, 1), nn.Sigmoid() # 也是一个激活函数,二分类问题中, # sigmoid可以班实数映射到【0,1】,作为概率值, # 多分类用softmax函数 ) def forward(self, x): x = self.dis(x) return x# ###### 定义生成器 Generator ###### 输入一个100维的0~1之间的欣慰的帅哥分布,然后通过第一层线性变换将其映射到256维,# 然后通过LeakyReLU激活函数,接着进行一个线性变换,再经过一个LeakyReLU激活函数,# 然后经过线性变换将其变成784维,最后经过Tanh激活函数是希望生成的假的图片数据分布# 能够在-1~1之间。class generator(nn.Module): def __init__(self): super(generator, self).__init__() self.gen = nn.Sequential( nn.Linear(100, 256), # 用线性变换将输入映射到256维 nn.ReLU(True), # relu激活 nn.Linear(256, 256), # 线性变换 nn.ReLU(True), # relu激活 nn.Linear(256, 784), # 线性变换 nn.Tanh() # Tanh激活使得生成数据分布在【-1,1】之间,因为输入的真实数据的经过transforms之后也是这个分布 ) def forward(self, x): x = self.gen(x) return x# 创建对象D = discriminator()G = generator()if torch.cuda.is_available(): D = D.cuda() G = G.cuda()# 首先需要定义loss的度量方式 (二分类的交叉熵)# 其次定义 优化函数,优化函数的学习率为0.0003criterion = nn.BCELoss() # 是单目标二分类交叉熵函数d_optimizer = torch.optim.Adam(D.parameters(), lr=0.0003)g_optimizer = torch.optim.Adam(G.parameters(), lr=0.0003)# ##########################进入训练##判别器的判断过程#####################for epoch in range(num_epoch): # 进行多个epoch的训练 for i, (img, _) in enumerate(dataloader): num_img = img.size(0) # view()函数作用是将一个多行的Tensor,拼接成一行 # 第一个参数是要拼接的tensor,第二个参数是-1 # =============================训练判别器================== img = img.view(num_img, -1) # 将图片展开为28*28=784 real_img = Variable(img).cuda() # 将tensor变成Variable放入计算图中 real_label = Variable(torch.ones(num_img)).cuda() # 定义真实的图片label为1 fake_label = Variable(torch.zeros(num_img)).cuda() # 定义假的图片的label为0 # ########判别器训练train##################### # 分为两部分:1、真的图像判别为真;2、假的图像判别为假 # 计算真实图片的损失 real_out = D(real_img) # 将真实图片放入判别器中 real_out = real_out.squeeze() # (128,1) -> (128,) d_loss_real = criterion(real_out, real_label) # 得到真实图片的loss real_scores = real_out # 得到真实图片的判别值,输出的值越接近1越好 # 计算假的图片的损失 z = Variable(torch.randn(num_img, z_dimension)).cuda() # 随机生成一些噪声 fake_img = G(z).detach() # 随机噪声放入生成网络中,生成一张假的图片。 # 避免梯度传到G,因为G不用更新, detach分离 fake_out = D(fake_img) # 判别器判断假的图片, fake_out = fake_out.squeeze() # (128,1) -> (128,) d_loss_fake = criterion(fake_out, fake_label) # 得到假的图片的loss fake_scores = fake_out # 得到假图片的判别值,对于判别器来说,假图片的损失越接近0越好 # 损失函数和优化 d_loss = d_loss_real + d_loss_fake # 损失包括判真损失和判假损失 d_optimizer.zero_grad() # 在反向传播之前,先将梯度归0 d_loss.backward() # 将误差反向传播 d_optimizer.step() # 更新参数 # ==================训练生成器============================ # ###############################生成网络的训练############################### # 原理:目的是希望生成的假的图片被判别器判断为真的图片, # 在此过程中,将判别器固定,将假的图片传入判别器的结果与真实的label对应, # 反向传播更新的参数是生成网络里面的参数, # 这样可以通过更新生成网络里面的参数,来训练网络,使得生成的图片让判别器以为是真的 # 这样就达到了对抗的目的 # 计算假的图片的损失 z = Variable(torch.randn(num_img, z_dimension)).cuda() # 得到随机噪声 fake_img = G(z) # 随机噪声输入到生成器中,得到一副假的图片 output = D(fake_img) # 经过判别器得到的结果 output = output.squeeze() g_loss = criterion(output, real_label) # 得到的假的图片与真实的图片的label的loss # bp and optimize g_optimizer.zero_grad() # 梯度归0 g_loss.backward() # 进行反向传播 g_optimizer.step() # .step()一般用在反向传播后面,用于更新生成网络的参数 # 打印中间的损失 if (i + 1) % 100 == 0: print('Epoch[{}/{}],d_loss:{:.6f},g_loss:{:.6f} ' 'D real: {:.6f},D fake: {:.6f}'.format( epoch, num_epoch, d_loss.data.item(), g_loss.data.item(), real_scores.data.mean(), fake_scores.data.mean() # 打印的是真实图片的损失均值 )) if epoch == 0: real_images = to_img(real_img.cpu().data) save_image(real_images, './img/real_images.png') fake_images = to_img(fake_img.cpu().data) save_image(fake_images, './img/fake_images-{}.png'.format(epoch + 1))# 保存模型torch.save(G.state_dict(), './generator.pth')torch.save(D.state_dict(), './discriminator.pth') 五、效果

迭代至100次, loss

Epoch[99/100],d_loss:0.843549,g_loss:2.033646 D real: 0.750062,D fake: 0.285924
Epoch[99/100],d_loss:0.686604,g_loss:2.199523 D real: 0.787562,D fake: 0.240696

效果图

                     fake                                                               real

               

 

 效果还行,就是噪声多。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。