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