最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

pytorch 實(shí)現(xiàn)變分自動(dòng)編碼器的操作

 更新時(shí)間:2021年05月24日 09:45:47   作者:xckkcxxck  
這篇文章主要介紹了pytorch 實(shí)現(xiàn)變分自動(dòng)編碼器的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

本來以為自動(dòng)編碼器是很簡(jiǎn)單的東西,但是也是看了好多資料仍然不太懂它的原理。先把代碼記錄下來,有時(shí)間好好研究。

這個(gè)例子是用MNIST數(shù)據(jù)集生成為例子

# -*- coding: utf-8 -*-
"""
Created on Fri Oct 12 11:42:19 2018
@author: www
""" 
import os 
import torch
from torch.autograd import Variable
import torch.nn.functional as F
from torch import nn
from torch.utils.data import DataLoader
 
from torchvision.datasets import MNIST
from torchvision import transforms as tfs
from torchvision.utils import save_image 
im_tfs = tfs.Compose([
    tfs.ToTensor(),
    tfs.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]) # 標(biāo)準(zhǔn)化
])
 
train_set = MNIST('E:\data', transform=im_tfs)
train_data = DataLoader(train_set, batch_size=128, shuffle=True)
 
class VAE(nn.Module):
    def __init__(self):
        super(VAE, self).__init__()
 
        self.fc1 = nn.Linear(784, 400)
        self.fc21 = nn.Linear(400, 20) # mean
        self.fc22 = nn.Linear(400, 20) # var
        self.fc3 = nn.Linear(20, 400)
        self.fc4 = nn.Linear(400, 784)
 
    def encode(self, x):
        h1 = F.relu(self.fc1(x))
        return self.fc21(h1), self.fc22(h1)
 
    def reparametrize(self, mu, logvar):
        std = logvar.mul(0.5).exp_()
        eps = torch.FloatTensor(std.size()).normal_()
        if torch.cuda.is_available():
            eps = Variable(eps.cuda())
        else:
            eps = Variable(eps)
        return eps.mul(std).add_(mu)
 
    def decode(self, z):
        h3 = F.relu(self.fc3(z))
        return F.tanh(self.fc4(h3))
 
    def forward(self, x):
        mu, logvar = self.encode(x) # 編碼
        z = self.reparametrize(mu, logvar) # 重新參數(shù)化成正態(tài)分布
        return self.decode(z), mu, logvar # 解碼,同時(shí)輸出均值方差 
 
net = VAE() # 實(shí)例化網(wǎng)絡(luò)
if torch.cuda.is_available():
    net = net.cuda()
    
x, _ = train_set[0]
x = x.view(x.shape[0], -1)
if torch.cuda.is_available():
    x = x.cuda()
x = Variable(x)
_, mu, var = net(x) 
print(mu)
 
#可以看到,對(duì)于輸入,網(wǎng)絡(luò)可以輸出隱含變量的均值和方差,這里的均值方差還沒有訓(xùn)練
 
#下面開始訓(xùn)練 
reconstruction_function = nn.MSELoss(size_average=False) 
def loss_function(recon_x, x, mu, logvar):
    """
    recon_x: generating images
    x: origin images
    mu: latent mean
    logvar: latent log variance
    """
    MSE = reconstruction_function(recon_x, x)
    # loss = 0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
    KLD_element = mu.pow(2).add_(logvar.exp()).mul_(-1).add_(1).add_(logvar)
    KLD = torch.sum(KLD_element).mul_(-0.5)
    # KL divergence
    return MSE + KLD 
optimizer = torch.optim.Adam(net.parameters(), lr=1e-3)
 
def to_img(x):
    '''
    定義一個(gè)函數(shù)將最后的結(jié)果轉(zhuǎn)換回圖片
    '''
    x = 0.5 * (x + 1.)
    x = x.clamp(0, 1)
    x = x.view(x.shape[0], 1, 28, 28)
    return x
 
for e in range(100):
    for im, _ in train_data:
        im = im.view(im.shape[0], -1)
        im = Variable(im)
        if torch.cuda.is_available():
            im = im.cuda()
        recon_im, mu, logvar = net(im)
        loss = loss_function(recon_im, im, mu, logvar) / im.shape[0] # 將 loss 平均
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
 
    if (e + 1) % 20 == 0:
        print('epoch: {}, Loss: {:.4f}'.format(e + 1, loss.item()))
        save = to_img(recon_im.cpu().data)
        if not os.path.exists('./vae_img'):
            os.mkdir('./vae_img')
        save_image(save, './vae_img/image_{}.png'.format(e + 1))                    
          

補(bǔ)充:PyTorch 深度學(xué)習(xí)快速入門——變分自動(dòng)編碼器

變分編碼器是自動(dòng)編碼器的升級(jí)版本,其結(jié)構(gòu)跟自動(dòng)編碼器是類似的,也由編碼器和解碼器構(gòu)成。

回憶一下,自動(dòng)編碼器有個(gè)問題,就是并不能任意生成圖片,因?yàn)槲覀儧]有辦法自己去構(gòu)造隱藏向量,需要通過一張圖片輸入編碼我們才知道得到的隱含向量是什么,這時(shí)我們就可以通過變分自動(dòng)編碼器來解決這個(gè)問題。

其實(shí)原理特別簡(jiǎn)單,只需要在編碼過程給它增加一些限制,迫使其生成的隱含向量能夠粗略的遵循一個(gè)標(biāo)準(zhǔn)正態(tài)分布,這就是其與一般的自動(dòng)編碼器最大的不同。

這樣我們生成一張新圖片就很簡(jiǎn)單了,我們只需要給它一個(gè)標(biāo)準(zhǔn)正態(tài)分布的隨機(jī)隱含向量,這樣通過解碼器就能夠生成我們想要的圖片,而不需要給它一張?jiān)紙D片先編碼。

一般來講,我們通過 encoder 得到的隱含向量并不是一個(gè)標(biāo)準(zhǔn)的正態(tài)分布,為了衡量?jī)煞N分布的相似程度,我們使用 KL divergence,利用其來表示隱含向量與標(biāo)準(zhǔn)正態(tài)分布之間差異的 loss,另外一個(gè) loss 仍然使用生成圖片與原圖片的均方誤差來表示。

KL divergence 的公式如下

重參數(shù) 為了避免計(jì)算 KL divergence 中的積分,我們使用重參數(shù)的技巧,不是每次產(chǎn)生一個(gè)隱含向量,而是生成兩個(gè)向量,一個(gè)表示均值,一個(gè)表示標(biāo)準(zhǔn)差,這里我們默認(rèn)編碼之后的隱含向量服從一個(gè)正態(tài)分布的之后,就可以用一個(gè)標(biāo)準(zhǔn)正態(tài)分布先乘上標(biāo)準(zhǔn)差再加上均值來合成這個(gè)正態(tài)分布,最后 loss 就是希望這個(gè)生成的正態(tài)分布能夠符合一個(gè)標(biāo)準(zhǔn)正態(tài)分布,也就是希望均值為 0,方差為 1

所以最后我們可以將我們的 loss 定義為下面的函數(shù),由均方誤差和 KL divergence 求和得到一個(gè)總的 loss

def loss_function(recon_x, x, mu, logvar):
    """
    recon_x: generating images
    x: origin images
    mu: latent mean
    logvar: latent log variance
    """
    MSE = reconstruction_function(recon_x, x)
    # loss = 0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
    KLD_element = mu.pow(2).add_(logvar.exp()).mul_(-1).add_(1).add_(logvar)
    KLD = torch.sum(KLD_element).mul_(-0.5)
    # KL divergence
    return MSE + KLD

用 mnist 數(shù)據(jù)集來簡(jiǎn)單說明一下變分自動(dòng)編碼器

import os 
import torch
from torch.autograd import Variable
import torch.nn.functional as F
from torch import nn
from torch.utils.data import DataLoader
 
from torchvision.datasets import MNIST
from torchvision import transforms as tfs
from torchvision.utils import save_image
 
im_tfs = tfs.Compose([
    tfs.ToTensor(),
    tfs.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5]) # 標(biāo)準(zhǔn)化
])
 
train_set = MNIST('./mnist', transform=im_tfs)
train_data = DataLoader(train_set, batch_size=128, shuffle=True)
 
class VAE(nn.Module):
    def __init__(self):
        super(VAE, self).__init__()
 
        self.fc1 = nn.Linear(784, 400)
        self.fc21 = nn.Linear(400, 20) # mean
        self.fc22 = nn.Linear(400, 20) # var
        self.fc3 = nn.Linear(20, 400)
        self.fc4 = nn.Linear(400, 784)
 
    def encode(self, x):
        h1 = F.relu(self.fc1(x))
        return self.fc21(h1), self.fc22(h1)
 
    def reparametrize(self, mu, logvar):
        std = logvar.mul(0.5).exp_()
        eps = torch.FloatTensor(std.size()).normal_()
        if torch.cuda.is_available():
            eps = Variable(eps.cuda())
        else:
            eps = Variable(eps)
        return eps.mul(std).add_(mu)
 
    def decode(self, z):
        h3 = F.relu(self.fc3(z))
        return F.tanh(self.fc4(h3))
 
    def forward(self, x):
        mu, logvar = self.encode(x) # 編碼
        z = self.reparametrize(mu, logvar) # 重新參數(shù)化成正態(tài)分布
        return self.decode(z), mu, logvar # 解碼,同時(shí)輸出均值方差
 
net = VAE() # 實(shí)例化網(wǎng)絡(luò)
if torch.cuda.is_available():
    net = net.cuda()
x, _ = train_set[0]
x = x.view(x.shape[0], -1)
if torch.cuda.is_available():
    x = x.cuda()
x = Variable(x)
_, mu, var = net(x) 
print(mu) 
 
Variable containing:  Columns 0 to 9  -0.0307 -0.1439 -0.0435  0.3472  0.0368 -0.0339  0.0274 -0.5608  0.0280  0.2742  Columns 10 to 19  -0.6221 -0.0894 -0.0933  0.4241  0.1611  0.3267  0.5755 -0.0237  0.2714 -0.2806 [torch.cuda.FloatTensor of size 1x20 (GPU 0)]

可以看到,對(duì)于輸入,網(wǎng)絡(luò)可以輸出隱含變量的均值和方差,這里的均值方差還沒有訓(xùn)練 下面開始訓(xùn)練

reconstruction_function = nn.MSELoss(size_average=False) 
def loss_function(recon_x, x, mu, logvar):
    """
    recon_x: generating images
    x: origin images
    mu: latent mean
    logvar: latent log variance
    """
    MSE = reconstruction_function(recon_x, x)
    # loss = 0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
    KLD_element = mu.pow(2).add_(logvar.exp()).mul_(-1).add_(1).add_(logvar)
    KLD = torch.sum(KLD_element).mul_(-0.5)
    # KL divergence
    return MSE + KLD 
optimizer = torch.optim.Adam(net.parameters(), lr=1e-3)
 
def to_img(x):
    '''
    定義一個(gè)函數(shù)將最后的結(jié)果轉(zhuǎn)換回圖片
    '''
    x = 0.5 * (x + 1.)
    x = x.clamp(0, 1)
    x = x.view(x.shape[0], 1, 28, 28)
    return x
 
for e in range(100):
    for im, _ in train_data:
        im = im.view(im.shape[0], -1)
        im = Variable(im)
        if torch.cuda.is_available():
            im = im.cuda()
        recon_im, mu, logvar = net(im)
        loss = loss_function(recon_im, im, mu, logvar) / im.shape[0] # 將 loss 平均
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
 
    if (e + 1) % 20 == 0:
        print('epoch: {}, Loss: {:.4f}'.format(e + 1, loss.data[0]))
        save = to_img(recon_im.cpu().data)
        if not os.path.exists('./vae_img'):
            os.mkdir('./vae_img')
        save_image(save, './vae_img/image_{}.png'.format(e + 1))
  
epoch: 20, Loss: 61.5803 epoch: 40, Loss: 62.9573 epoch: 60, Loss: 63.4285 epoch: 80, Loss: 64.7138 epoch: 100, Loss: 63.3343

變分自動(dòng)編碼器雖然比一般的自動(dòng)編碼器效果要好,而且也限制了其輸出的編碼 (code) 的概率分布,但是它仍然是通過直接計(jì)算生成圖片和原始圖片的均方誤差來生成 loss,這個(gè)方式并不好,生成對(duì)抗網(wǎng)絡(luò)中,我們會(huì)講一講這種方式計(jì)算 loss 的局限性,然后會(huì)介紹一種新的訓(xùn)練辦法,就是通過生成對(duì)抗的訓(xùn)練方式來訓(xùn)練網(wǎng)絡(luò)而不是直接比較兩張圖片的每個(gè)像素點(diǎn)的均方誤差

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • python將回車作為輸入內(nèi)容的實(shí)例

    python將回車作為輸入內(nèi)容的實(shí)例

    今天小編就為大家分享一篇python將回車作為輸入內(nèi)容的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • Python全棧之學(xué)習(xí)HTML

    Python全棧之學(xué)習(xí)HTML

    這篇文章主要為大家介紹了Python全棧之HTML,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Python爬蟲基礎(chǔ)講解之scrapy框架

    Python爬蟲基礎(chǔ)講解之scrapy框架

    scrapy是一個(gè)使用Python語(yǔ)言(基于Twisted框架)編寫的開源網(wǎng)絡(luò)爬蟲框架,目前由scrapinghub Ltd維護(hù).Scrapy簡(jiǎn)單易用、靈活易拓展、開發(fā)社區(qū)活躍,并且是跨平臺(tái)的.在Linux、MaxOS以及windows平臺(tái)都可以使用,需要的朋友可以參考下
    2021-06-06
  • Python socket非阻塞模塊應(yīng)用示例

    Python socket非阻塞模塊應(yīng)用示例

    這篇文章主要介紹了Python socket非阻塞模塊,結(jié)合實(shí)例形式分析了Python socket非阻塞模塊通信相關(guān)操作技巧,需要的朋友可以參考下
    2019-09-09
  • Python實(shí)現(xiàn)Canny及Hough算法代碼實(shí)例解析

    Python實(shí)現(xiàn)Canny及Hough算法代碼實(shí)例解析

    這篇文章主要介紹了Python實(shí)現(xiàn)Canny與Hough算法代碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Python 中如何寫注釋

    Python 中如何寫注釋

    這篇文章主要介紹了如何在 Python 中注釋,幫助其他開發(fā)者理解你的代碼,以及代碼的目的。感興趣的朋友可以了解下
    2020-08-08
  • Python爬蟲番外篇之Cookie和Session詳解

    Python爬蟲番外篇之Cookie和Session詳解

    這篇文章主要介紹了Python爬蟲番外篇之Cookie和Session詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12
  • Python做智能家居溫濕度報(bào)警系統(tǒng)

    Python做智能家居溫濕度報(bào)警系統(tǒng)

    本文為大家?guī)砹薖ython通過HTTP協(xié)議做一個(gè)廉價(jià)的溫濕度報(bào)警系統(tǒng)。感興趣的朋友跟隨小編一起看看吧
    2018-09-09
  • python爬蟲之驗(yàn)證碼篇3-滑動(dòng)驗(yàn)證碼識(shí)別技術(shù)

    python爬蟲之驗(yàn)證碼篇3-滑動(dòng)驗(yàn)證碼識(shí)別技術(shù)

    本篇涉及到的驗(yàn)證碼為滑動(dòng)驗(yàn)證碼,不同于極驗(yàn)證,本驗(yàn)證碼難度略低,需要的將滑塊拖動(dòng)到矩形區(qū)域右側(cè)即可完成。對(duì)python爬蟲滑動(dòng)驗(yàn)證碼識(shí)別技術(shù)感興趣的朋友跟隨小編一起看看吧
    2019-04-04
  • 利用Python微信群發(fā)英語(yǔ)每日一句

    利用Python微信群發(fā)英語(yǔ)每日一句

    這篇文章主要為大家詳細(xì)介紹了Python如何利用wxauto實(shí)現(xiàn)微信群發(fā)消息,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11

最新評(píng)論

长宁区| 隆安县| 许昌县| 阜新市| 沙洋县| 宣汉县| 林芝县| 通州区| 台北县| 喀喇沁旗| 丹阳市| 鄂州市| 金沙县| 榕江县| 米林县| 山东省| 罗源县| 舒兰市| 甘肃省| 高陵县| 汪清县| 历史| 云龙县| 横峰县| 巢湖市| 区。| 九龙县| 木里| 南漳县| 澄城县| 德清县| 玉门市| 黄浦区| 慈利县| 延长县| 顺义区| 榆树市| 湖口县| 郯城县| 文昌市| 赫章县|