自编码器实现MNIST图片分类

  自编码器结构:输入->编码器->嵌入->解码器->输出

  输入数据经过编码压缩得到低维度向量,这个部分称为编码器,因为它产生了低维度嵌入或者编码。网络的第二部分不同于在前向神经网络中把嵌入映射为输出标签,而是把编码器逆化,重建原始输入,这个部分称为解码器。

  自编码器是一种类似PCA的神经网络,它是无监督学习方法,目标输出就是其输入。

###加载库和配置参数###
import os
import pdb
import torch
import torchvision
from torch import nn
from torch.autograd import Variable
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision.datasets import MNIST
from torchvision.utils import save_image
from torchvision import datasets
import matplotlib.pyplot as plt

#配置参数
torch.manual_seed(1)#设置随机数种子,确保结果可重复
batch_size=128
learning_rate=1e-2
num_epochs=10

#下载数据库和预处理
train_dataset=datasets.MNIST(
    root='./data',#数据保持的位置
    train=True,#训练集
    #一个取值范围是【0,255】的PIL.Image转化为取值范围是[0,1.0]的torch.FloadTensor
    transform=transforms.ToTensor(),
    download=True
)
test_dataset=datasets.MNIST(
    root='./data',
    train=False,
    transform=transforms.ToTensor()
)
#数据的批处理,尺寸大小为batch_size
#在训练集中,shuffle必须设置为True,表示次序是随机的
train_loader=DataLoader(train_dataset,batch_size=batch_size,shuffle=True)
test_loader=DataLoader(test_dataset,batch_size=10000,shuffle=False)

####自编码器模型####
##################
class autoencoder(nn.Module):
    def __init__(self):
        super(autoencoder,self).__init__()
        self.encoder=nn.Sequential(
            nn.Linear(28*28,1000),
            nn.ReLU(True),
            nn.Linear(1000,500),
            nn.ReLU(True),
            nn.Linear(500,250),
            nn.ReLU(True),
            nn.Linear(250,2)
        )
        self.decoder=nn.Sequential(
            nn.Linear(2,250),
            nn.ReLU(True),
            nn.Linear(250,500),
            nn.ReLU(True),
            nn.Linear(500,1000),
            nn.ReLU(True),
            nn.Linear(1000,28*28),
            nn.Tanh()
        )
    def forward(self,x):
        x=self.encoder(x)
        x=self.decoder(x)
        return x

model=autoencoder().cuda()
criterion=nn.MSELoss()
optimizer=torch.optim.Adam(
    model.parameters(),lr=learning_rate,weight_decay=1e-5
)

###模型训练###
for epoch in range(num_epochs):
    for data in train_loader:
        img,_=data
        img=img.view(img.size(0),-1)
        img=Variable(img).cuda()
        ###forward###
        output=model(img)
        loss=criterion(output,img)
        ###backward###
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        ####log#####
    print('epoch [{}/{}],loss:{:.4f}'.format(epoch+1,num_epochs,loss.item()))


###测试模型###
#由于训练和测试BatchNorm,Dropout配置不同,需要说明是否进行模型测试
model.eval()
eval_loss=0
for data in test_loader:#test set批处理
    img,label=data

    img=img.view(img.size(0),-1)

    img=Variable(img).cuda()
    with torch.no_grad():
        label=Variable(label)
    out=model(img).cuda().data.cpu().numpy()
    y=(label.data).numpy()
    plt.scatter(out[:,0],out[:,1],c=y)
    plt.colorbar()
    plt.title('autocoder of MNIST test dataset')
    plt.show()

猜你喜欢

转载自www.cnblogs.com/candyRen/p/12110953.html