VAE個人理解|計算機如何生成圖片

聲明:本文旨在通過口頭表達與直覺理解的方式,帶大家瞭解什麼是VAE:變分自編碼器以及它具體幹了啥,lz的理解可能並不準確,如果有誤也請大家指出來

什麼是VAE?

Vae的全名是Variational Autoencoder,中文全名叫作 變分 自編碼器(AE) ,說文解字,我們先說說看什麼叫做自編碼器

什麼是AE?

自編碼器(AE)由encoder和decoder組成,分別叫編碼器與解碼器,編碼器將圖片壓縮成隱變量,解碼器負責將隱變量轉換爲圖片,簡單理解一下可以看成是壓縮和解壓的過程|這和圖片生成有什麼關係?這個流程乍一看確實就是個喂原圖輸出原圖的過程(訓練好的話),不過如果我們稍微對隱變量進行一些修改,是不是理論上就有可能生成新的圖片?完全沒問題,不過我們接着看

我們舉個栗子,可以看到編碼器把這個man的圖片處理成了6個數據,這就是隱變量,我們可以看到每個數字都有一個label對應,不過在實際中我們是完全不知道這6個數據是代表什麼的|我也可以硬改啊?這麼做效率很低,而且生成的圖片很有可能是啥都不是的圖片

不同於AE,VAE修改了編碼器,使它生成一組平均值與方差,從而構建一個高斯分佈(正態分佈),一方面限定了取值範圍,保證生成的圖片是正常的,凸起點我個人理解是在該點下生成圖片的期望較大,另外一方面增加了隨機性,畢竟期望較大的點不止一個

我現在根據圖片生成了幾組平均值與標準差,我只需要構建幾個高斯分佈接着隨機取值餵給編碼器就可以了是吧?包不是的,你的編碼器和解碼器現在啥都不會,它沒辦法重構那張圖片給你,那簡單啊!取值餵給解碼,你不是寫了unionLoss聯合損失嗎?進行梯度下降反向傳播,縮小聯合損失不就行了?問題在於隨機取樣是不可微的,這意味着沒有梯度,沒梯度我下降個dam,我怎麼縮小損失?

重參數技巧

初看非常抽象但是理解了就會發現非常的精妙,不同於直接在生成的高斯分佈中取值,我們是在標準正態分佈中取值,接着(圖上有寫)後重構出了一個值Xn,爲什麼要這麼做?首先是解決了沒梯度的問題,保證模型可以進行優化,其次我們先賣個關子,來看看unionLoss聯合損失,它由兩部分組成,分別是KL+BCEloss,KL表示KL散度,用於衡量分佈於分佈之間的差異,我們上面還沒提到的變分(變分推斷)的理念就在這裏體現,通過縮小unionLoss其實就是讓生成的高斯分佈去逼近標準正態分佈,BCEloss(二元交叉熵損失函數)用於衡量生成圖像與輸入圖像之間的差異,聯合損失本質上就是:既讓生成的分佈去逼近標準高斯分佈,又讓生成的圖片儘量與原圖片吻合,這兩者是相互牽制的關係,因爲生成的分佈並不一定是標準正態分佈

我們優化的其中一個目的不就是讓生成分佈去趨近於標準正態分佈嗎?均值和方差不就分別是0和1嗎?你再代入一下重參數的重構公式,就會發現,整了半天不就是在標準正態分佈中取值嗎!就是這樣,由於優化,我們的平均值和方差會向0和1偏移,所以說重參數是非常巧妙的一個做法

要想生成圖片,我們只需要往訓練好的decoder中喂標準正態分佈中隨機取得的數即可

看到這裏你已經完全理解了一遍VAE了(也許)

代碼實現

我們基於理論用pytroch構建一個VAE模型,用線性核

寫一個重參數的重構函數,前向傳播生成對數方差而不是方差便於損失函數的計算

循環訓練

訓練了不知道幾個epoch的結果,這個時候我們只需要隨機在高斯分佈採樣輸入decoder就能生成數字了,起碼能看(bushi

應用|指定數字生成

構建一個labelGene模型,根據輸入數字轉換成獨熱編碼形式的向量+標準正態分佈噪點,接着輸入labelGene模型生成隱變量,直接輸入解碼器生成圖片,圖片都比較像,直接加噪點不太行,懶得給大夥展示了,或許用重參數重構會更好,後續再試試看(畫完發現原模型沒有重參)

再次聲明:個人理解,可能有誤,有誤請指出

更多遊戲資訊請關註:電玩幫遊戲資訊專區

電玩幫圖文攻略 www.vgover.com