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()

 

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