自編碼器結構:輸入->編碼器->嵌入->解碼器->輸出
輸入數據經過編碼壓縮得到低維度向量,這個部分稱為編碼器,因為它產生了低維度嵌入或者編碼。網絡的第二部分不同於在前向神經網絡中把嵌入映射為輸出標簽,而是把編碼器逆化,重建原始輸入,這個部分稱為解碼器。
自編碼器是一種類似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()