使用Auto Enconders 实现MNIST数据的生成
我的研究方向是医学图像分割,有一个想法是使用生成式的网络来对数据集进行预处理,使可供训练的图像增多,于是学习了自编码器,以后会更新AVE,GAN,CGAN等
自编码器是生成式深度学习的经典案例
自编码器的原理是通过对输入的x进行编码得到一个低维向量z,然后根据这个z通过解码器还原出x1。通俗来说是通过x得到x1。(看上去没啥用处,不妨想象一下通过x得出一个跟x非常相似又无关的x1,一个数据是否能衍生出大量类似的数据,充分发挥深度学习的创新能力)
网络架构
AE的网络架构非常简单,就是先编码再解码,我采用的是全连接层的设计,隐藏层激活都使用relu,输出层激活使用sigmoid函数,架构是四层架构:
784>>400>>20>>400>>784
代码实现
没用过visdom的先百度一下用法
import os
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
from torchvision import transforms
from torchvision.utils import save_image
import visdom# 需要这个命令来启动visdom python -m visdom.server
####
#定义超参
####
image_size=784
d_dim=400
z_dim=20
num_epochs=30
batch_size=128
learning_rate=0.001
#预处理
dataset=torchvision.datasets.MNIST(root="./data",
train=True,
transform=transforms.ToTensor(),
download=False)
data_loader=torch.utils.data.DataLoader(dataset,batch_size=batch_size,shuffle=True)
test_dataset=torchvision.datasets.MNIST('./data',train=False,transform=transforms.ToTensor())
test_loader=torch.utils.data.DataLoader(test_dataset,batch_size=batch_size,shuffle=False)
#构建模型
class AE(nn.Module):
def __init__(self):
super(AE, self).__init__()
self.fc1=nn.Linear(784,400)
self.fc2=nn.Linear(400,20)
self.fc3=nn.Linear(20,400)
self.fc4=nn.Linear(400,784)
def encode(self,x):
h1=F.relu(self.fc1(x))
h2=F.relu(self.fc2(h1))
return h2
def decode(self,z):
h3=F.relu(self.fc3(z))
h4=self.fc4(h3)
return torch.sigmoid(h4)
def forward(self,x):
'''
:param x:[b,1,28,28]
:return:
'''
batchsz=x.size(0)
x=x.view(batchsz,784)
x=self.encode(x)
x=self.decode(x)
#reshape
x=x.view(batchsz,1,28,28)
return x
#训练模型
x, _=iter(data_loader).next()
print('x:',x.shape)
device=torch.device('cuda:0' if torch.cuda.is_available() else "cpu")
model=AE().to(device)
print(model)
criteon=nn.MSELoss()
optimizer=torch.optim.Adam(model.parameters(),lr=learning_rate)
viz=visdom.Visdom()
for epoch in range(num_epochs):
for batchidx,(x, _) in enumerate(data_loader):
x=x.to(device)
x_hat=model(x)
loss=criteon(x_hat,x)
#backprop
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(epoch,'loss',loss.item())
x, _=iter(test_loader).next()
x = x.to(device)
with torch.no_grad():
x_hat=model(x)
viz.images(x,nrow=8,win='x',opts=dict(title='x'))
viz.images(x_hat, nrow=8, win='x_hat', opts=dict(title='x'))
如果能帮助到您就支持我一下吧!!