pytorch實現autoencoder


 關於autoencoder的內容簡介可以參考這一篇博客,可以說寫的是十分詳細了https://sherlockliao.github.io/2017/06/24/vae/

 

盜圖一張,自動編碼器講述的是對於一副輸入的圖像,或者是其他的信號,經過一系列操作,比如卷積,或者linear變換,變換得到一個向量,這個向量就叫做對這個圖像的編碼,這個過程就叫做encoder,對於一個特定的編碼,經過一系列反卷積或者是線性變換,得到一副圖像,這個過程叫做decoder,即解碼。

然而自動編碼器有什么用,看到上面的博客所寫

所以現在自動編碼器主要應用有兩個方面,第一是數據去噪,第二是進行可視化降維。然而自動編碼器還有着一個功能就是生成數據。

然而現在還沒有用過這方面的應用,在這里需要着重說明一點的是autoencoder並不是聚類,因為雖然對於每一副圖像都沒有對應的label,但是autoencoder的任務並不是對圖像進行分類啊。

就事論事,下面來分析一下一個大神寫的關於autoencoder的代碼,這里先給出github鏈接

先奉上代碼

 1 # -*-coding: utf-8-*-
 2 __author__ = 'SherlockLiao'
 3 
 4 import torch
 5 import torchvision
 6 from torch import nn
 7 from torch.autograd import Variable
 8 from torch.utils.data import DataLoader
 9 from torchvision import transforms
10 from torchvision.utils import save_image
11 from torchvision.datasets import MNIST
12 import os
13 
14 if not os.path.exists('./dc_img'):
15     os.mkdir('./dc_img')
16 
17 
18 def to_img(x):  # 將vector轉換成矩陣
19     x = 0.5 * (x + 1)
20     x = x.clamp(0, 1)
21     x = x.view(x.size(0), 1, 28, 28)
22     return x
23 
24 
25 num_epochs = 100
26 batch_size = 128
27 learning_rate = 1e-3
28 
29 img_transform = transforms.Compose([
30     transforms.ToTensor(),
31     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
32 ])
33 
34 dataset = MNIST('./data', transform=img_transform)
35 dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
36 
37 
38 class autoencoder(nn.Module):
39     def __init__(self):
40         super(autoencoder, self).__init__()
41         self.encoder = nn.Sequential(
42             nn.Conv2d(1, 16, 3, stride=3, padding=1),  # b, 16, 10, 10
43             nn.ReLU(True),
44             nn.MaxPool2d(2, stride=2),  # b, 16, 5, 5
45             nn.Conv2d(16, 8, 3, stride=2, padding=1),  # b, 8, 3, 3
46             nn.ReLU(True),
47             nn.MaxPool2d(2, stride=1)  # b, 8, 2, 2
48         )
49         self.decoder = nn.Sequential(
50             nn.ConvTranspose2d(8, 16, 3, stride=2),  # b, 16, 5, 5
51             nn.ReLU(True),
52             nn.ConvTranspose2d(16, 8, 5, stride=3, padding=1),  # b, 8, 15, 15
53             nn.ReLU(True),
54             nn.ConvTranspose2d(8, 1, 2, stride=2, padding=1),  # b, 1, 28, 28
55             nn.Tanh()  # 將輸出值映射到-1~1之間
56         )
57 
58     def forward(self, x):
59         x = self.encoder(x)
60         x = self.decoder(x)
61         return x
62 
63 
64 model = autoencoder().cuda()
65 criterion = nn.MSELoss()
66 optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate,
67                              weight_decay=1e-5)
68 
69 for epoch in range(num_epochs):
70     for data in dataloader:
71         img, _ = data  # img是一個b*channel*width*height的矩陣
72         img = Variable(img).cuda()
73         # ===================forward=====================
74         output = model(img)
75         a = img.data.cpu().numpy()
76         b = output.data.cpu().numpy()
77         loss = criterion(output, img)
78         # ===================backward====================
79         optimizer.zero_grad()
80         loss.backward()
81         optimizer.step()
82     # ===================log========================
83     print('epoch [{}/{}], loss:{:.4f}'
84           .format(epoch+1, num_epochs, loss.data[0]))
85     if epoch % 10 == 0:
86         pic = to_img(output.cpu().data)  # 將decoder的輸出保存成圖像
87         save_image(pic, './dc_img/image_{}.png'.format(epoch))
88 
89 torch.save(model.state_dict(), './conv_autoencoder.pth')
View Code

可以說是寫的相當清晰了,卷積,pooling,卷積,pooling,最后encoder輸出的是一個向量,這個向量的尺寸是8*2*2,一共是32個元素,然后對這個8*2*2的元素進行反卷積操作,pytorch關於反卷積的操作的尺寸計算可以看這里

大概就這樣開始訓練,save_image是util中的一個函數,給定某一個batchsize的圖像,將這個圖像保存成8列,特定行的操作。

訓練的loss如下

輸出的圖像如下,從左到右,從上往下,依次為epoch遞增的情況

    

    

其實還是可以發現,隨着epoch的增加,經過decoder生成的圖像越來越接近真實圖片

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM