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