1. 程式人生 > >pytorch + visdom AutoEncode 和 VAE(Variational Autoencoder) 處理 手寫數字資料集(MNIST)

pytorch + visdom AutoEncode 和 VAE(Variational Autoencoder) 處理 手寫數字資料集(MNIST)

環境

系統:win10
cpu:i7-6700HQ
gpu:gtx965m
python : 3.6
pytorch :0.3

資料

使用 mnist,使用方法前面文章有。

train_dataset = datasets.MNIST('./mnist', True, transforms.ToTensor(), download=False)
train_loader = DataLoader(train_dataset, BATCH_SIZE, True)

並非分類問題,只要訓練集就可以,不需要測試集。

視覺化一下資料:

dataiter = iter(train_loader)
inputs, _ = dataiter.next
() inputs = inputs[:20] # 視覺化visualize viz.images(inputs, nrow=8, padding=3)

這裡寫圖片描述

AutoEncoder (自編碼)

自編碼是什麼呢,百度找的解釋:

這裡寫圖片描述

我們結合簡單的神經網路看,更直觀一些:

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

自編碼分為兩個部分:編碼(encode),解碼(decode);編碼就是說把輸入的東東,通過神經層(編碼過程)提煉出 n 個 特徵點,上面的神經網路是 3 個 ,輸出的這n 個 特徵點就是 得到的 code ,經過解碼過程將這個提煉的 code 反向輸出,生成原尺寸資料,根據與原資料對比(loss),來判斷特徵值是否為最優,通過反覆訓練學習,可以獲得具有原圖一類共同特徵的圖片,但是也有缺點,就是由於兼顧所有,導致影象模糊。

我們訓練10個 epochs看一下效果:

這裡寫圖片描述

發下生成的圖從模糊逐漸能看清數字,但是3和8,7和9 搞不清楚。。

接下來,我們把簡單的nn,換成cnn,看看效果如何。。

self.en_conv = nn.Sequential(
            nn.Conv2d(1, 16, 4, 2, 1),
            nn.BatchNorm2d(16),
            nn.Tanh(),
            nn.Conv2d(16, 32, 4, 2, 1),
            nn.BatchNorm2d(32),
            nn.Tanh(),
            nn.Conv2d(32, 16, 3, 1, 1),
            nn.BatchNorm2d(16),
            nn.Tanh()
        )
self.en_fc = nn.Linear(16*7*7, 3)
self.de_fc = nn.Linear(3, 16*7*7)
self.de_conv = nn.Sequential(
            nn.ConvTranspose2d(16, 16, 4, 2, 1),
            nn.BatchNorm2d(16),
            nn.Tanh(),
            nn.ConvTranspose2d(16, 1, 4, 2, 1),
            nn.Sigmoid()
        )

10個epoch後 效果圖:

這裡寫圖片描述

我們在訓練結束後將一部分測試集資料匯入取其編碼,因為是3個值,用3d散點圖視覺化:

這裡寫圖片描述

(注:圖中標籤1~10,其實為0~9)

可見4、9比較相似難以區分, 3、5、8相似
程式碼在這 。。

VAE(Variational Autoencoder)

由於Autoencoder 只是在資料原有的基礎上進行學習,生成的資料的侷限性很大,不能在原資料基礎上合理的生成新資料, 而VAE可以通過對編碼器新增約束,強迫它產生服從單位高斯分佈的潛在變數。

這裡寫圖片描述

VAE的編碼器會產生兩個向量:一個是均值向量,一個是標準差向量,根據兩個向量對高斯分佈的擬合度上進行權衡,加上生成圖片的準確度,生成新的loss值。

這裡寫圖片描述

根據生成的兩個向量生成新的向量,用以產生隨機的潛在變數,提高net 的生成圖片的能力。

這裡寫圖片描述

網路如下:

self.conv1 = nn.Sequential(nn.Conv2d(1, 16, 4, 2, 1),
                           nn.BatchNorm2d(16),
                           nn.ReLU(True))
self.conv2 = nn.Sequential(nn.Conv2d(16, 32, 4, 2, 1),
                           nn.BatchNorm2d(32),
                           nn.ReLU(True))
self.conv3 = nn.Sequential(nn.Conv2d(32, 16, 3, 1, 1),
                           nn.BatchNorm2d(16),
                           nn.ReLU(True))

self.fc_encode1 = nn.Linear(16 * 7 * 7, hidden_size)
self.fc_encode2 = nn.Linear(16 * 7 * 7, hidden_size)
self.fc_decode = nn.Linear(hidden_size, 16 * 7 * 7)

self.deconv1 = nn.Sequential(nn.ConvTranspose2d(16, 16, 4, 2, 1),
                             nn.BatchNorm2d(16),
                             nn.ReLU())
self.deconv2 = nn.Sequential(nn.ConvTranspose2d(16, 1, 4, 2, 1),
                             nn.Sigmoid())

3個hidden 10個epochs ,效果如下:

這裡寫圖片描述

數字已經有明顯的形態,不過不夠清晰,我們用10個hidden,訓練18個epochs:

這裡寫圖片描述

增加隱藏層後,發現效果明顯比之前好很多,7個epoch就已經形狀相仿了。

將hidden設定為3,畫3d 散點圖如下:

這裡寫圖片描述

程式碼在這。