【Pytorch神经网络实战案例】14 构建条件变分自编码神经网络模型生成可控Fashon-MNST模拟数据

1 条件变分自编码神经网络生成模拟数据案例说明

在实际应用中,条件变分自编码神经网络的应用会更为广泛一些,因为它使得模型输出的模拟数据可控,即可以指定模型输出鞋子或者上衣。

1.1 案例描述

在变分自编码神经网络模型的技术上构建条件变分自编码神经网络模型,实现向模型输入标签,并使其生成与标签类别对应的模拟数据的功能。

1.2 条件变分自编码神经网络的实现条件

变分自编码神经网络在变分自编码神经网络基础之上,增加指导性条件。在编码阶段的输入端添加了与标签对应的特征,在解码阶段同样添加标签特征。这样,最终得到的模型将会把输入的标签特征当成原始数据的一部分,实现通过标签来生成可控模拟数据的效果。

在输入端添加标签时,一般是通过一个全连接层的变换将得到的结果连接到原始输入。

在解码阶段也将标签作为样本输入,与高斯分布的随机值一并运算,生成模拟样本。

1.2.1 条件变分自编码神经网络结构

2 实例代码编写

2.1 代码实战:引入模块并载入样本----Variational_cond_selfcoding.py(第1部分)

import torch
import torchvision
from torch import nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import transforms
import numpy as np
from scipy.stats import norm # 在模型可视化时使用该库的norm接口从标准的高斯分布中获取数值
import matplotlib.pylab as plt
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'  # 可能是由于是MacOS系统的原因# 1.1 引入模块并载入样本:定义基础函数,并且加载FashionMNIST数据集
# 定义样本预处理接口
img_transform = transforms.Compose([transforms.ToTensor()])def to_img(x): # 将张量转化为图片x = 0.5 * (x + 1)x = x.clamp(0,1)x = x.reshape(x.size(0),1,28,28)return xdef imshow(img): # 显示图片npimg = img.numpy()plt.axis('off')plt.imshow(np.transpose(npimg,(1,2,0)))plt.show()data_dir = './fashion_mnist/' # 加载数据集
train_dataset = torchvision.datasets.FashionMNIST(data_dir,train=True,transform=img_transform,download=True)
# 获取训练数据集
train_loader = DataLoader(train_dataset,batch_size=128,shuffle=True)
# 获取测试数据集
val_dataset = torchvision.datasets.FashionMNIST(data_dir,train=False,transform=img_transform)
test_loader = DataLoader(val_dataset,batch_size=10,shuffle=False)
# 指定设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print("所使用的设备为:",device)

2.2 代码实战:定义变分自编码神经网络的正向模型----Variational_cond_selfcoding.py(第2部分)

# 1.2 定义变分自编码神经网络模型的正向结构
class VAE(nn.Module):def __init__(self,hidden_1=256,hidden_2=256,in_decode_dim=2,hidden_3=256):super(VAE, self).__init__()self.fc1 = nn.Linear(784, hidden_1)self.fc21 = nn.Linear(hidden_2, 2)self.fc22 = nn.Linear(hidden_2, 2)self.fc3 = nn.Linear(in_decode_dim, hidden_3)self.fc4 = nn.Linear(hidden_3, 784)def encode(self,x): # 编码器方法:使用两层全连接网络将输入的图片进行压缩,对第二层中两个神经网络的输出结果代表均值(mean)与取对数(log)以后的方差(lg_var)。h1 = F.relu(self.fc1(x))return self.fc21(h1),self.fc22(h1)def reparametrize(self,mean,lg_var): # 采样器方法:对方差(lg_var)进行还原,并从高斯分布中采样,将采样数值映射到编码器输出的数据分布中。std = lg_var.exp().sqrt()# torch.FloatTensor(std.size())的作用是,生成一个与std形状一样的张量。然后,调用该张量的normal_()方法,系统会对该张量中的每个元素在标准高斯空间(均值为0、方差为1)中进行采样。eps = torch.FloatTensor(std.size()).normal_().to(device) # 随机张量方法normal_(),完成高斯空间的采样过程。return eps.mul(std).add_(mean)# 在torch.FloatTensor()# 函数中,传入Tensor的size类型,返回的是一个同样为size的张量。假如std的size为[batch,dim],则返回形状为[batch,dim]的未初始化张量,等同于torch.FloatTensor(#     batch,dim),但不等同于torchFloatTensor([batch,dim),这是值得注意的地方。def decode(self,z): # 解码器方法:输入映射后的采样值,用两层神经网络还原出原始图片。h3 = F.relu(self.fc3(z))return self.fc4(h3)def forward(self,x,*arg): # 正向传播方法:将编码器,采样器,解码器串联起来,根据输入的原始图片生成模拟图片mean,lg_var = self.encode(x)z = self.reparametrize(mean=mean,lg_var=lg_var)return self.decode(z),mean,lg_var

2.3 代码实战:损失函数与训练函数的完善----Variational_cond_selfcoding.py(第3部分)

# 1.3 完成损失函数和训练函数
reconstruction_function = nn.MSELoss(size_average=False)def loss_function(recon_x,x,mean,lg_var): # 损失函数:将MSE的损失缩小到一半,再与KL散度相加,目的在于使得输出的模拟样本可以有更灵活的变化空间。MSEloss = reconstruction_function(recon_x,x) # MSE损失KLD = -0.5 * torch.sum(1 + lg_var -  mean.pow(2) - lg_var.exp())return 0.5 * MSEloss + KLDdef train(model,num_epochs = 50): # 训练函数optimizer = torch.optim.Adam(model.parameters(),lr=1e-3)display_step = 5for epoch in range(num_epochs):model.train()train_loss = 0for batch_idx, data in enumerate(train_loader):img,label = dataimg = img.view(img.size(0),-1).to(device)y_one_hot = torch.zeros(label.shape[0],10).scatter_(1,label.view(label.shape[0],1),1).to(device)optimizer.zero_grad()recon_batch, mean, lg_var = model(img, y_one_hot)loss = loss_function(recon_batch, img, mean, lg_var)loss.backward()train_loss += loss.dataoptimizer.step()if epoch % display_step == 0:print("Epoch:", '%04d' % (epoch + 1), "cost=", "{:.9f}".format(loss.data))print("完成训练 cost=",loss.data)

2.4 代码实战:定义条件变分自编码神经网络模型----Variational_cond_selfcoding.py(第3部分)

# 1.4 定义条件变分自编码神经网络模型
class CondVAE(VAE): # 继承VAE类,实现条件变分自编码神经网络模型的正向结构。def __init__(self, hidden_1=256, hidden_2=512,in_decode_dim=2 + 10, hidden_3=256):super(CondVAE, self).__init__(hidden_1, hidden_2, in_decode_dim, hidden_3)self.labfc1 = nn.Linear(10, hidden_1)def encode(self, x, lab):h1 = F.relu(self.fc1(x))lab1 = F.relu(self.labfc1(lab))h1 = torch.cat([h1, lab1], axis=1)return self.fc21(h1), self.fc22(h1)def decode(self, z, lab):h3 = F.relu(self.fc3(torch.cat([z, lab], axis=1)))return self.fc4(h3)def forward(self, x, lab):mean, lg_var = self.encode(x, lab)z = self.reparametrize(mean, lg_var)return self.decode(z, lab), mean, lg_var

2.5 代码实战:训练模型并输出可视化结果----Variational_cond_selfcoding.py(第4部分)

# 1.5 训练模型并输出可视化结果
if __name__ == '__main__':model = CondVAE().to(device) # 实例化模型train(model, 50)# 将指定的one_hot标签输入模型,便可得到对应的模拟数据sample = iter(test_loader) # 取出10个样本,用于测试images, labels = sample.next()# 将标签转化为one_hot编码,取10个测试样本与标签。y_one_hots = torch.zeros(labels.shape[0], 10).scatter_(1, labels.view(labels.shape[0], 1), 1)# 将标签输入模型,生成模拟数据images2 = images.view(images.size(0), -1)with torch.no_grad():pred, mean, lg_var = model(images2.to(device), y_one_hots.to(device))pred = to_img(pred.cpu().detach())    # 将生成的模拟数据转化为图片print("标签值:", labels) # 输出标签# 标签值: tensor([9, 2, 1, 1, 6, 1, 4, 6, 5, 7])# 输出可视化结果z_sample = torch.randn(10, 2).to(device)x_decoded = model.decode(z_sample, y_one_hots.to(device)) # 将取得的10个标签与随机的高斯分布采样值z_sample一起输入模型,得到与标签相对应的模拟数据。rel = torch.cat([images, pred, to_img(x_decoded.cpu().detach())], axis=0)imshow(torchvision.utils.make_grid(rel, nrow=10))plt.show()# 根据标签生成模拟数据一共有3行图片,第1行是原始图片,第2行是将原始图片输入模型后所得到的模拟图片,第3行是将原始标签输入模型后生成的模拟图片。# 比较第2行和第3行图片可以看出,使用原始图片生成的模拟图片还会带有一些原来的样子,而使用标签生成的模拟图片已经学会了数据的分布规则,并能生成截然不同却带有相同意义的数据。

 3  代码汇总(Variational_cond_selfcoding.py)

import torch
import torchvision
from torch import nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import transforms
import numpy as np
from scipy.stats import norm # 在模型可视化时使用该库的norm接口从标准的高斯分布中获取数值
import matplotlib.pylab as plt
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'  # 可能是由于是MacOS系统的原因# 1.1 引入模块并载入样本:定义基础函数,并且加载FashionMNIST数据集
# 定义样本预处理接口
img_transform = transforms.Compose([transforms.ToTensor()])def to_img(x): # 将张量转化为图片x = 0.5 * (x + 1)x = x.clamp(0,1)x = x.reshape(x.size(0),1,28,28)return xdef imshow(img): # 显示图片npimg = img.numpy()plt.axis('off')plt.imshow(np.transpose(npimg,(1,2,0)))plt.show()data_dir = './fashion_mnist/' # 加载数据集
train_dataset = torchvision.datasets.FashionMNIST(data_dir,train=True,transform=img_transform,download=True)
# 获取训练数据集
train_loader = DataLoader(train_dataset,batch_size=128,shuffle=True)
# 获取测试数据集
val_dataset = torchvision.datasets.FashionMNIST(data_dir,train=False,transform=img_transform)
test_loader = DataLoader(val_dataset,batch_size=10,shuffle=False)
# 指定设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print("所使用的设备为:",device)# 1.2 定义变分自编码神经网络模型的正向结构
class VAE(nn.Module):def __init__(self,hidden_1=256,hidden_2=256,in_decode_dim=2,hidden_3=256):super(VAE, self).__init__()self.fc1 = nn.Linear(784, hidden_1)self.fc21 = nn.Linear(hidden_2, 2)self.fc22 = nn.Linear(hidden_2, 2)self.fc3 = nn.Linear(in_decode_dim, hidden_3)self.fc4 = nn.Linear(hidden_3, 784)def encode(self,x): # 编码器方法:使用两层全连接网络将输入的图片进行压缩,对第二层中两个神经网络的输出结果代表均值(mean)与取对数(log)以后的方差(lg_var)。h1 = F.relu(self.fc1(x))return self.fc21(h1),self.fc22(h1)def reparametrize(self,mean,lg_var): # 采样器方法:对方差(lg_var)进行还原,并从高斯分布中采样,将采样数值映射到编码器输出的数据分布中。std = lg_var.exp().sqrt()# torch.FloatTensor(std.size())的作用是,生成一个与std形状一样的张量。然后,调用该张量的normal_()方法,系统会对该张量中的每个元素在标准高斯空间(均值为0、方差为1)中进行采样。eps = torch.FloatTensor(std.size()).normal_().to(device) # 随机张量方法normal_(),完成高斯空间的采样过程。return eps.mul(std).add_(mean)# 在torch.FloatTensor()# 函数中,传入Tensor的size类型,返回的是一个同样为size的张量。假如std的size为[batch,dim],则返回形状为[batch,dim]的未初始化张量,等同于torch.FloatTensor(#     batch,dim),但不等同于torchFloatTensor([batch,dim),这是值得注意的地方。def decode(self,z): # 解码器方法:输入映射后的采样值,用两层神经网络还原出原始图片。h3 = F.relu(self.fc3(z))return self.fc4(h3)def forward(self,x,*arg): # 正向传播方法:将编码器,采样器,解码器串联起来,根据输入的原始图片生成模拟图片mean,lg_var = self.encode(x)z = self.reparametrize(mean=mean,lg_var=lg_var)return self.decode(z),mean,lg_var# 1.3 完成损失函数和训练函数
reconstruction_function = nn.MSELoss(size_average=False)def loss_function(recon_x,x,mean,lg_var): # 损失函数:将MSE的损失缩小到一半,再与KL散度相加,目的在于使得输出的模拟样本可以有更灵活的变化空间。MSEloss = reconstruction_function(recon_x,x) # MSE损失KLD = -0.5 * torch.sum(1 + lg_var -  mean.pow(2) - lg_var.exp())return 0.5 * MSEloss + KLDdef train(model,num_epochs = 50): # 训练函数optimizer = torch.optim.Adam(model.parameters(),lr=1e-3)display_step = 5for epoch in range(num_epochs):model.train()train_loss = 0for batch_idx, data in enumerate(train_loader):img,label = dataimg = img.view(img.size(0),-1).to(device)y_one_hot = torch.zeros(label.shape[0],10).scatter_(1,label.view(label.shape[0],1),1).to(device)optimizer.zero_grad()recon_batch, mean, lg_var = model(img, y_one_hot)loss = loss_function(recon_batch, img, mean, lg_var)loss.backward()train_loss += loss.dataoptimizer.step()if epoch % display_step == 0:print("Epoch:", '%04d' % (epoch + 1), "cost=", "{:.9f}".format(loss.data))print("完成训练 cost=",loss.data)# 1.4 定义条件变分自编码神经网络模型
class CondVAE(VAE): # 继承VAE类,实现条件变分自编码神经网络模型的正向结构。def __init__(self, hidden_1=256, hidden_2=512,in_decode_dim=2 + 10, hidden_3=256):super(CondVAE, self).__init__(hidden_1, hidden_2, in_decode_dim, hidden_3)self.labfc1 = nn.Linear(10, hidden_1)def encode(self, x, lab):h1 = F.relu(self.fc1(x))lab1 = F.relu(self.labfc1(lab))h1 = torch.cat([h1, lab1], axis=1)return self.fc21(h1), self.fc22(h1)def decode(self, z, lab):h3 = F.relu(self.fc3(torch.cat([z, lab], axis=1)))return self.fc4(h3)def forward(self, x, lab):mean, lg_var = self.encode(x, lab)z = self.reparametrize(mean, lg_var)return self.decode(z, lab), mean, lg_var# 1.5 训练模型并输出可视化结果
if __name__ == '__main__':model = CondVAE().to(device) # 实例化模型train(model, 50)# 将指定的one_hot标签输入模型,便可得到对应的模拟数据sample = iter(test_loader) # 取出10个样本,用于测试images, labels = sample.next()# 将标签转化为one_hot编码,取10个测试样本与标签。y_one_hots = torch.zeros(labels.shape[0], 10).scatter_(1, labels.view(labels.shape[0], 1), 1)# 将标签输入模型,生成模拟数据images2 = images.view(images.size(0), -1)with torch.no_grad():pred, mean, lg_var = model(images2.to(device), y_one_hots.to(device))pred = to_img(pred.cpu().detach())    # 将生成的模拟数据转化为图片print("标签值:", labels) # 输出标签# 标签值: tensor([9, 2, 1, 1, 6, 1, 4, 6, 5, 7])# 输出可视化结果z_sample = torch.randn(10, 2).to(device)x_decoded = model.decode(z_sample, y_one_hots.to(device)) # 将取得的10个标签与随机的高斯分布采样值z_sample一起输入模型,得到与标签相对应的模拟数据。rel = torch.cat([images, pred, to_img(x_decoded.cpu().detach())], axis=0)imshow(torchvision.utils.make_grid(rel, nrow=10))plt.show()# 根据标签生成模拟数据一共有3行图片,第1行是原始图片,第2行是将原始图片输入模型后所得到的模拟图片,第3行是将原始标签输入模型后生成的模拟图片。# 比较第2行和第3行图片可以看出,使用原始图片生成的模拟图片还会带有一些原来的样子,而使用标签生成的模拟图片已经学会了数据的分布规则,并能生成截然不同却带有相同意义的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469329.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hibernate持久化对象

转载于:https://www.cnblogs.com/jianxin-lilang/p/6440101.html

MTK8127添加一个新的camera驱动

简单总结一下 mtk 的all in one 这个文档台强大了,如果第一次配置摄像头,可以找这个文档来看。 1、kernel层添加 +mediatek/custom/mid713l_lp_lvds/kernel/imgsensor/bf3703_yuv/ 驱动文件夹 +bf3703yuv_CameraCustomized.h +bf3703yuv_Camera_Sensor_para.h +bf3…

【Pytorch神经网络理论篇】 23 对抗神经网络:概述流程 + WGAN模型 + WGAN-gp模型 + 条件GAN + WGAN-div + W散度

同学你好!本文章于2021年末编写,获得广泛的好评! 故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现, Pytorch深度学习理论篇(2023版)目录地址…

[haoi2011]防线修建

动态加点维护凸包。 论STL的熟练运用。 #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<iostream> #include<string> #include<map> #include<set> #include<cstdlib> #include<…

【Pytorch神经网络实战案例】15 WGAN-gp模型生成Fashon-MNST模拟数据

1 WGAN-gp模型生成模拟数据案例说明 使用WGAN-gp模型模拟Fashion-MNIST数据的生成&#xff0c;会使用到WGAN-gp模型、深度卷积GAN(DeepConvolutional GAN&#xff0c;DCGAN)模型、实例归一化技术。 1.1 DCGAN中的全卷积 WGAN-gp模型侧重于GAN模型的训练部分&#xff0c;而DCG…

Android启动过程深入解析

转载自&#xff1a;http://blog.jobbole.com/67931/ 当按下Android设备电源键时究竟发生了什么&#xff1f;Android的启动过程是怎么样的&#xff1f;什么是Linux内核&#xff1f;桌面系统linux内核与Android系统linux内核有什么区别&#xff1f;什么是引导装载程序&#xff1…

android 解析网络数据(JSON)

解析json数据&#xff0c;获取你需要的信息 首先在manifest中添加允许访问网络的权限信息 <uses-permission android:name"android.permission.INTERNET"/> Main package com.chuanxidemo.shaoxin.demo08;import android.os.Bundle; import android.support.an…

【Pytorch神经网络实战案例】16 条件WGAN模型生成可控Fashon-MNST模拟数据

1 条件GAN前置知识 条件GAN也可以使GAN所生成的数据可控&#xff0c;使模型变得实用&#xff0c; 1.1 实验描述 搭建条件GAN模型&#xff0c;实现向模型中输入标签&#xff0c;并使其生成与标签类别对应的模拟数据的功能&#xff0c;基于WGAN-gp模型改造实现带有条件的wGAN-…

Android bootchart(二)

这篇文章讲一下MTK8127开机启动的时间 MTK8127发布版本开机时间大约在&#xff12;&#xff10;秒左右&#xff0c;如果发现开机时间变长&#xff0c;大部分是因为加上了客户订制的东西&#xff0c;代码累赘太多了。 &#xff11;、下面看一下&#xff2d;&#xff34;&#…

Android Camera框架

总体介绍 Android Camera 框架从整体上看是一个 client/service 的架构, 有两个进程: client 进程,可以看成是 AP 端,主要包括 JAVA 代码与一些 native c/c++代码; service 进 程,属于服务端,是 native c/c++代码,主要负责和 linux kernel 中的 camera driver 交互,搜集 li…

【Pytorch神经网络实战案例】17 带W散度的WGAN-div模型生成Fashon-MNST模拟数据

1 WGAN-div 简介 W散度的损失函数GAN-dv模型使用了W散度来替换W距离的计算方式&#xff0c;将原有的真假样本采样操作换为基于分布层面的计算。 2 代码实现 在WGAN-gp的基础上稍加改动来实现&#xff0c;重写损失函数的实现。 2.1 代码实战&#xff1a;引入模块并载入样本-…

runtime如何实现weak属性

首先了解weak是一种非拥有关系,属性所值对象销毁时,属性值会情况(nil). Runtime对注册的类会进行布局,对于weak对象会放入hash表中,用weak指向的内存地址作为key,当对象引用计数器为0时会dealloc,假如weak指向的对象内存地址为a,那么就会以a为键,在这个weak表中搜索,找到以a为键…

计算机地址分配

1、计算机寻址 在linux下可以通过查看proc/ioport来看他们的地址段范围 weiqifa@weiqifa-Inspiron-3847:~/weiqifa/new_tm100/tm100$ cat /proc/ioports 0000-0cf7 : PCI Bus 0000:000000-001f : dma10020-0021 : pic10040-0043 : timer

【Pytorch神经网络理论篇】 24 神经网络中散度的应用:F散度+f-GAN的实现+互信息神经估计+GAN模型训练技巧

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

angularjs控制器之间的数据共享与通信

1、可以写一个service服务&#xff0c;从而达到数据和代码的共享; var appangular.module(app,[]);app.service(ObjectService, [ObjectService]); function ObjectService() {var list {};return {get: function(id){return list[id];},set: function(id, v){list[id] v;}} …

【Pytorch神经网络实战案例】18 最大化深度互信信息模型DIM实现搜索最相关与最不相关的图片

图片搜索器分为图片的特征提取和匹配两部分&#xff0c;其中图片的特征提取是关键。将使用一种基于无监督模型的提取特征的方法实现特征提取&#xff0c;即最大化深度互信息&#xff08;DeepInfoMax&#xff0c;DIM&#xff09;方法。 1 最大深度互信信息模型DIM简介 在DIM模型…

linux tar 解压命令总结

把常用的tar解压命令总结下&#xff0c;当作备忘&#xff1a; tar -c: 建立压缩档案 -x&#xff1a;解压 -t&#xff1a;查看内容 -r&#xff1a;向压缩归档文件末尾追加文件 -u&#xff1a;更新原压缩包中的文件 这五个是独立的命令&#xff0c;压缩解压都要用到其中一…

经典c语言题

1. 用预处理指令#define 声明一个常数&#xff0c;用以表明1年中有多少秒&#xff08;忽略闰年问题&#xff09; #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 2. 写一个“标准”宏MIN&#xff0c;这个宏输入两个参数并返回较小的一个。 #define MIN(A,B) ((A) < (B) ?…

【Pytorch神经网络实战案例】19 神经网络实现估计互信息的功能

1 案例说明&#xff08;实现MINE正方法的功能&#xff09; 定义两组具有不同分布的模拟数据&#xff0c;使用神经网络的MINE的方法计算两个数据分布之间的互信息 2 代码编写 2.1 代码实战&#xff1a;准备样本数据 import torch import torch.nn as nn import torch.nn.fun…

当前进程(Linux Devices Driver)

尽管内核模块不像应用程序一样顺序执行,内核做的大部分动作是代表一个特定进程的,内核代码可以引用当前进程,通过存取全局项current,它在asm/current.h中定义,它产生一个指针指向结构task_struct,在linux/sched.h定义,current指针指向当前在运行的进程,在一个系统调用执行…