pytorch笔记12--无监督的AutoEncoder(自编码)

1. AutoEncoder: 给特征属性降维

2. Data---->压缩(提取Data的关键信息,减小网络的运算压力)---->data(具有代表性的特征)---->解压(还原数据信息)---->Pred_Data

3. 使用Mnist数据集训练,将数据先压缩再解压,并用训练集的前5张图片可视化训练的过程,过程图和结果图如下:

可视化训练集前200张图片的预测类别结果:

# 使用MNIST数据集先压缩再解压,用压缩的特征进行分监督分类   (无监督)
import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import numpy as np

# Hyper parameters
EPOCH=10
BATCH_SIZE=64
LR=0.005
DOWNLOAD_MNIST=False

# mnist dataset
train_data=torchvision.datasets.MNIST(
    root='./mnist/',
    train=True,
    transform=torchvision.transforms.ToTensor(),
    download=DOWNLOAD_MNIST
)
train_loader=Data.DataLoader(dataset=train_data,batch_size=BATCH_SIZE,shuffle=True)
# AutoEncoder: encoder & decoder, 压缩后得到压缩的特征值,再从压缩的特征值中解压出原图
class AutoEncoder(nn.Module):
    def __init__(self):
        super(AutoEncoder, self).__init__()
        self.encoder=nn.Sequential(
            nn.Linear(28*28,128),
            nn.Tanh(),
            nn.Linear(128,64),
            nn.Tanh(),
            nn.Linear(64,12),
            nn.Tanh(),
            nn.Linear(12,3)    #压缩为3个特征(3d),进行3D图像的可视化
        )
        self.decoder=nn.Sequential(
            nn.Linear(3,12),
            nn.Tanh(),
            nn.Linear(12,64),
            nn.Tanh(),
            nn.Linear(64,128),
            nn.Tanh(),
            nn.Linear(128,28*28),
            nn.Sigmoid() # 让输出值在 (0,1)
        )
    def forward(self,x):
        encoded=self.encoder(x)
        decoded=self.decoder(encoded)
        return encoded,decoded    # 返回压缩后的结果 和 解压后的结果

autoencoder=AutoEncoder()

# training
optimizer=torch.optim.Adam(autoencoder.parameters(),lr=LR)
loss_func=nn.MSELoss()

f,a=plt.subplots(2,5,figsize=(5,2))
plot_data=train_data.data[:5].view(-1,28*28).type(torch.FloatTensor)/255   # 训练过程中显示的图片
for i in range(5):
    a[0][i].imshow(np.reshape(plot_data.data.numpy()[i],(28,28)),cmap='gray')
    a[0][i].set_xticks(())     # 是刻度不显示
    a[0][i].set_yticks(())

for epoch in range(EPOCH):
    for step,(x,label) in enumerate(train_loader):
        b_x=x.view(-1,28*28)   # reshape x to(batch,28*28)
        b_y=x.view(-1,28*28)

        encoded,decoded=autoencoder(b_x)

        loss=loss_func(decoded,b_y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if step%100==0:    # 每100步更新一次解压的图片
            print('Epoch: ',epoch,'| train loss: %.4f'%loss.data.numpy())

            # 显示解压过程中的图片变化(第一行是原图,第二行是训练过程中的图片)
            _,decoded_data=autoencoder(plot_data)
            for i in range(5):
                a[1][i].clear()
                a[1][i].imshow(np.reshape(decoded_data.data.numpy()[i],(28,28)),cmap='gray')
                a[1][i].set_xticks(())
                a[1][i].set_yticks(())
            plt.draw()
            plt.pause(0.05)
plt.show()

# 可视化效果
view_data=train_data.data[:200].view(-1,28*28).type(torch.FloatTensor)/255
encoded_data,_=autoencoder(view_data)   # 提取压缩的特征值
fig=plt.figure(2)
ax=Axes3D(fig)

# X,Y,Z: 图片压缩后的3个特征值
X=encoded_data.data[:,0].numpy()
Y=encoded_data.data[:,1].numpy()
Z=encoded_data.data[:,2].numpy()
labels=train_data.targets[:200].numpy()
for x,y,z,lbl in zip(X,Y,Z,labels):
    c=cm.rainbow(int(255*lbl/9))            #上色  0~9
    ax.text(x,y,z,lbl,fontdict={'color':c})

ax.set_xlim(X.min(),X.max())
ax.set_ylim(Y.min(),Y.max())
ax.set_zlim(Z.min(),Z.max())
plt.show()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章