回覆列表
  • 1 # 機器之心Pro

    變分自編碼器(VAE)與生成對抗網路(GAN)一樣,是無監督學習最具前景的方法之一。本文中,牛津大學統計系在讀博士 Adam Kosiorek 從原理上向我們介紹了 VAE 目前面臨的挑戰。同時,文中也提出了對於該方法的幾種改進方向。

    隱變數模型

    假設你希望透過一個定義在 x∈RD 上的機率分佈來對整個世界建模,其中 p(x)表示 x 可能處於的狀態。這個世界可能非常複雜,我們無法知道 p(x)的具體形式。為了解決這個問題,我們引入另一個變數 z∈Rd 來描述 x 的背景資訊。例如 x 是一個影象,那麼 z 就可以記錄關於影象中可見物體的出現、數量、型別,以及畫面的背景和光影條件的資訊。這個新的變數使得我們可以將 p(x)表示為一個無限混合模型。

    這是一個混合模型,因為對於 z 的任意可能取值,都引入另一個條件分佈,並透過 z 的機率進行加權,最終得到 p(x)。

    在這樣的設定下,「給定 x 的觀測值,隱變數 z 是什麼」就成了一個非常有趣的問題。

    也就是說,我們希望知道後驗分佈 p(z∣x)。但是,z 和 x 之間可以呈現高度的非線性關係(比如,由一個多層神經網路實現),而且,D——我們觀測值的維度,和 d——隱變數的維度,也可能非常大。由於邊緣分佈和後驗分佈都需要對(1)式積分求值,我們認為它們都是無法計算的。

    我們可以通過蒙特卡羅抽樣,根據 p(x)≈1M∑Mm=1p(x∣z(m))p(x)≈1M∑m=1Mp(x∣z(m)), z(m)∼p(z) 來估計(1)式,但由於 z 的空間可能非常大,我們可能需要上百萬個 z 的樣本,來得到一個可靠的估計。

    在訓練一個機率模型的時候,我們可以使用引數分佈 - 它的引數由一個引數為θ∈Θ的神經網路來確定。現在,我們就可以使用極大似然估計來學習得到這些引數。

    這裡的問題是,我們無法最大化(1)式,因為我們無法估計它。為了解決這個問題,我們可以求助於重要抽樣(importance sampling)。當我們需要對原始(名義分佈)機率密度分佈(pdf)估算一個期望值時,IS 使得我們可以從另一個不同的機率分佈(建議分佈)中抽樣,然後將這些樣本對名義分佈求期望。用 qϕ(z∣x) 表示我們的建議分佈 - 其中的引數由引數為 ϕ∈Φ的神經網路確定。我們可以得到:

    根據重要性抽樣的文獻可知,最優的建議分佈,與名義分佈乘以某個函式成比例,其中這個函式的期望是我們希望估計的。在我們的設定下,「某個函式」就是 p(x|z)。根據貝葉斯定理,p(z∣x)=p(x∣z)p(z)/p(x),我們可以看到,最優建議分佈與後驗分佈成比例,顯然,後驗分佈無法求解。

    變分自編碼器的誕生

    幸運的是,事實上我們可以一箭雙鵰:透過一個學習到的建議分佈來近似估計後驗分佈,我們可以有效的得到邊緣分佈 pθ(x) 的估計。在這裡,我們無意間得到了一個自編碼的設定。為了學習我們的模型,我們需要:

    pθ(x,z) - 生成模型,其中包含:

    pθ(x∣z) - 一個機率形式的解碼器,以及

    p(z) - 一個定義在隱變數上的先驗分佈

    qϕ(z∣x) - 一個機率形式的編碼器

    為了近似估計後驗分佈,我們可以利用建議分佈和後驗分佈之間的 KL 散度(可以理解為兩個機率分佈之間的距離),而且我們可以最小化這個結果。

    這個時候,我們面臨的新問題就是:為了計算 KL 散度,我們需要知道後驗分佈。並非沒有可能,只要利用一點點代數運算,我們就能得到可以計算的目標函式。

    我在第二行展開了對數項,在第三行使用了貝葉斯定理以及 pθ(x) 和 z 是獨立的事實。最後一行中的 L(x;θ,ϕ) 是對數機率分佈 pθ(x) 的下界 - 即通常所說的證據下界(ELBO)。我們透過整理可以得到:

    只需要一個從建議分佈中抽得的樣本,我們就可以得到近似估計:

    我們透過尋找最大化 ELBO 的ϕ和θ(通常使用隨機梯度下降)來訓練模型:

    透過最大化 ELBO,我們或(1)最大化邊緣分佈,或(2)最小化 KL 散度,或同時完成。需要注意,ELBO 的近似估計是 f(x)=1、重要性權重為 w(x)=pθ(x,z)qϕ(z∣x) 的重要性抽樣的期望的對數形式。

    這個估計量有什麼問題?

    如果你足夠仔細的看重要性抽樣,就能發現,對建議分佈的支撐應該比對名義分佈的支撐更廣泛——應該同時避免估計量方差無限大和數值的不穩定性。在這裡,最好是來最佳化 KL(p∣∣q) 的倒數——因為它有模式平均性質,而不是最佳化 KL(q∣∣p),來試圖透過模式 q 去匹配找到一個最好的模式 p。這意味著我們需要從真實的後驗分佈中進行抽樣,而這是很困難的。作為替代,我們可以使用 ELBO 的 IS 估計,作為重要性加權自編碼器(IWAE)。這裡的想法很簡單:我們從建議分佈中抽取 k 個樣本,並從中計算出平均機率比,這裡的每一個樣本也叫「粒子」。

    已經證明,這個估計量是在最佳化修正後的 KL 散度 KL(qIS∣∣pIS),其中 qIS 和 pIS 的定義分別是:

    儘管和原始分佈看似接近,但 qIS 和 pIS 允許 q 和 p 中存在預想以外的小的變動。原始論文中證明,最佳化這個下界可以得到更好的生成模型。同時它也給出了一個近似後驗分佈 q 的熵更大的估計(更寬,更離散),併成功的超越了原始 KL 散度的模式匹配方法。還有一個有趣的結果,如果我們令粒子 K 的數量趨於無窮,我們就可以不需要推斷模型 q。

    IWAE(第一行)和 VAE(第二行)中 z 的後驗分佈。影象從 IWAE 論文中復現得到。

    IWAE 有什麼問題?

    重要性加權 ELBO,或 IWAE,推廣了原始的 ELBO:對於 K=1,我們有 LK=L1=L。同時有 logp(x)≥Ln+1≥Ln≥L1。換言之,我們用來估計 LK 的粒子越多,它的結果就會越接近資料真實對數機率分佈——即「界限越緊」。這意味著和原始 ELBO 的梯度相比,透過對 IWAE 求微分得到的梯度估計量可以幫助我們找到一個更好的梯度方向。除此之外,隨著 K 的增加,梯度估計量的方差會相應收縮。

    對於生成模型這些點非常好,但面對建議分佈的時候,就會出現問題。隨著 K 的增大,建議分佈中引數的梯度的大小會趨於 0,而且比方差收斂得還要快。

    令Δ(ϕ) 表示我們最佳化的目標函式(即 ELBO)在ϕ上的梯度的小批次估計。如果定義引數更新的訊號-噪聲比(SNR)如下:

    其中 E 和 V 分別表示期望和方差。可以看出對於 pθ,SNR 隨著 K 增加而增加,但對於 qϕ,SNR 隨著 K 增加而減小。這裡的結論很簡單:我們使用的粒子越多,我們的推斷模型效果就會越差。如果我們關心的是表示學習,我們就會遇到問題了。

    更好的估計量

    正如我們在最近的論文《Tighter Variational Bounds are Not Necessarily Better》中證明的,我們可以得到比 IWAE 更好的結果。思路是在推斷和生成模型中使用不同的目標,透過這種方法,我們可以保證兩個目標中都得到小方差非零梯度,最終得到更好的模型。

    不同的訓練目標在訓練時期中訊號-噪聲比

    在上圖中,我們比較了建議分佈 qϕ的引數ϕz 在更新中的 SNR。SNR 最高的 VAE 透過最最佳化 L1 來訓練。SNR 最低的 IWAE 則透過最最佳化 L64。中間的三條曲線使用的是不同的組合:生成模型中使用的 L64,推斷模型中使用的則是 L8 或 L1。在當前指標下,它們效果雖然沒有 VAE 好,但訓練出的建議分佈和生成模型都比使用 VAE 或 IWAE 得到的好。

    這裡有一個令人驚訝的副作用:使用我們新的估計量訓練的模型比使用 IWAE 本身訓練的模型達到了更高的 L64 界限。為什麼會這樣?透過研究有效樣本量(ESS)和資料的邊緣機率分佈的對數,似乎是最最佳化 L1,導致了性質最好的建議分佈但是性質最差的生成模型。如果我們將一個好的建議分佈和一個可以得出好的生成模型的目標結合在一起,我們應該可以得到這個目標的一個方差更小的估計,甚至因此可以得到更好的模型。請在這裡檢視我們論文的詳情。

    論文:Tighter Variational Bounds are Not Necessarily Better

    論文地址:https://arxiv.org/abs/1802.04537

    摘要:我們同時在理論和經驗上證明,使用更緊的資訊下界(ELBO)可能並不利於透過減少梯度估計量的訊號-噪聲比來學習推斷網路的過程。我們的結果對目前廣為應用的暗含假設:「更緊的 ELBO 是聯立模型學習和推斷攤銷模式中更合適的變分目標」提出了質疑。根據我們的研究,我們提出了三個新的演算法:偏重要性加權自編碼器(PIWAE)、多層重要性加權自編碼器(MIWAE)以及聯合重要性加權自編碼器(CIWAE);在這三個演算法中,標準的重要性自編碼器(IWAE)都可以作為一個特殊情況。我們證明了這三個自編碼器都可以在 IWAE 的基礎上取得效果提升——即使我們使用的是 IWAE 中的目標來測試效果。進一步來說,和 IWAE 相比,PIWAE 可以同時提升推斷網路和生成網路的效果。

  • 2 # 讀芯術

    全文共5718字,預計學習時長20分鐘或更長變分自動編碼器的厲害之處

    假設你正在開發一款開放性世界端遊,且遊戲裡的景觀設定相當複雜。

    你聘用了一個圖形設計團隊來製作一些植物和樹木以裝飾遊戲世界,但是將這些裝飾植物放進遊戲中之後,你發現它們看起來很不自然,因為同種植物的外觀看起來一模一樣,這時你該怎麼辦呢?

    首先,你可能會建議使用一些引數化來嘗試隨機地改變影象,但是多少改變才足夠呢?又需要多大的改變呢?還有一個重要的問題:實現這種改變的計算強度如何?

    這是使用變分自動編碼器的理想情況。我們可以訓練一個神經網路,使其學習植物的潛在特徵,每當我們將一個植物放入遊戲世界中,就可以從“已學習”的特徵中隨機抽取一個樣本,生成獨特的植物。事實上,很多開放性世界遊戲正在透過這種方法構建他們的遊戲世界設定。

    再看一個更圖形化的例子。假設我們是一個建築師,想要為任意形狀的建築生成平面圖。可以讓一個自動編碼器網路基於任意建築形狀來學習資料生成分佈,它將從資料生成分佈中提取樣本來生成一個平面圖。詳見下方的動畫。

    對於設計師來說,這些技術的潛力無疑是最突出的。

    再假設我們為一個時裝公司工作,需要設計一種新的服裝風格,可以基於“時尚”的服裝來訓練自動編碼器,使其學習時裝的資料生成分佈。隨後,從這個低維潛在分佈中提取樣本,並以此來創造新的風格。

    在該節中我們將研究fashion MNIST資料集。

    自動編碼器

    傳統自動編碼器

    自動編碼器其實就是非常簡單的神經結構。它們大體上是一種壓縮形式,類似於使用MP3壓縮音訊檔案或使用jpeg壓縮影象檔案。

    自動編碼器與主成分分析(PCA)密切相關。事實上,如果自動編碼器使用的啟用函式在每一層中都是線性的,那麼瓶頸處存在的潛在變數(網路中最小的層,即程式碼)將直接對應(PCA/主成分分析)的主要元件。通常,自動編碼器中使用的啟用函式是非線性的,典型的啟用函式是ReLU(整流線性函式)和sigmoid/S函式。

    網路背後的數學原理理解起來相對容易。從本質上看,可以把網路分成兩個部分:編碼器和解碼器。

    編碼器函式用ϕ表示,該函式將原始資料X對映到潛在空間F中(潛在空間F位於瓶頸處)。解碼器函式用ψ表示,該函式將瓶頸處的潛在空間F對映到輸出函式。此處的輸出函式與輸入函式相同。因此,我們基本上是在一些概括的非線性壓縮之後重建原始影象。

    編碼網路可以用啟用函式傳遞的標準神經網路函式表示,其中z是潛在維度。

    相似地,解碼網路可以用相同的方式表示,但需要使用不同的權重、偏差和潛在的啟用函式。

    隨後就可以利用這些網路函式來編寫損失函式,我們會利用這個損失函式透過標準的反向傳播程式來訓練神經網路。

    由於輸入和輸出的是相同的影象,神經網路的訓練過程並不是監督學習或無監督學習,我們通常將這個過程稱為自我監督學習。自動編碼器的目的是選擇編碼器和解碼器函式,這樣就可以用最少的資訊來編碼影象,使其可以在另一側重新生成。

    如果在瓶頸層中使用的節點太少,重新建立影象的能力將受到限制,導致重新生成的影象模糊或者和原影象差別很大。如果使用的節點太多,那麼就沒必要壓縮了。

    壓縮背後的理論其實很簡單,例如,每當你在Netflix下載某些內容時,傳送給你的資料都會被壓縮。一旦這個內容傳輸到電腦上就會通解壓演算法在電腦螢幕顯示出來。這類似於zip檔案的執行方式,只是這裡說的壓縮是在後臺透過流處理演算法完成的。

    去噪自動編碼器

    有幾種其它型別的自動編碼器。其中最常用的是去噪自動編碼器,本教程稍後會和Keras一起進行分析。這些自動編碼器在訓練前給資料新增一些白噪聲,但在訓練時會將誤差與原始影象進行比較。這就使得網路不會過度擬合影象中出現的任意噪聲。稍後,將使用它來清除文件掃描影象中的摺痕和暗黑區域。

    稀疏自動編碼器

    與其字義相反的是,稀疏自動編碼器具有比輸入或輸出維度更大的潛在維度。然而,每次網路執行時,只有很小一部分神經元會觸發,這意味著網路本質上是“稀疏”的。稀疏自動編碼器也是透過一種規則化的形式來減少網路過度擬合的傾向,這一點與去噪自動編碼器相似。

    收縮自動編碼器

    收縮編碼器與前兩個自動編碼器的執行過程基本相同,但是在收縮自動編碼器中,我們不改變結構,只是在丟失函式中新增一個正則化器。這可以被看作是嶺迴歸的一種神經形式。

    現在瞭解了自動編碼器是如何執行的,接下來看看自動編碼器的弱項。一些最顯著的挑戰包括:

    · 潛在空間中的間隙

    · 潛在空間中的可分性

    · 離散潛在空間

    這些問題都在以下圖中體現。

    MNIST資料集的潛在空間表示

    這張圖顯示了潛在空間中不同標記數字的位置。可以看到潛在空間中存在間隙,我們不知道字元在這些空間中是長什麼樣的。這相當於在監督學習中缺乏資料,因為網路並沒有針對這些潛在空間的情況進行過訓練。另一個問題就是空間的可分性,上圖中有幾個數字被很好地分離,但也有一些區域被標籤字元是隨機分佈的,這讓我們很難區分字元的獨特特徵(在這個圖中就是數字0-9)。還有一個問題是無法研究連續的潛在空間。例如,我們沒有針對任意輸入而訓練的統計模型(即使我們填補了潛在空間中的所有間隙也無法做到)。

    這些傳統自動編碼器的問題意味著我們還要做出更多努力來學習資料生成分佈並生成新的資料與影象。

    變分自動編碼器

    變分自動編碼器延續了傳統自動編碼器的結構,並利用這一結構來學習資料生成分佈,這讓我們可以從潛在空間中隨機抽取樣本。然後,可以使用解碼器網路對這些隨機樣本進行解碼,以生成獨特的影象,這些影象與網路所訓練的影象具有相似的特徵。

    對於熟悉貝葉斯統計的人來說,編碼器正在學習後驗分佈的近似值。這種分佈通常很難分析,因為它沒有封閉式的解。這意味著我們要麼執行計算上覆雜的取樣程式,如馬爾可夫鏈蒙特卡羅(MCMC)演算法,要麼採用變分方法。正如你可能猜測的那樣,變分自動編碼器使用變分推理來生成其後驗分佈的近似值。

    若對背後的數學理論不感興趣,也可以選擇跳過這篇變分自動編碼器(VAE)編碼教程。

    首先需要理解的是後驗分佈以及它無法被計算的原因。先看看下面的方程式:貝葉斯定理。這裡的前提是要知道如何從潛變數“z”生成資料“x”。這意味著要搞清p(z|x)。然而,該分佈值是未知的,不過這並不重要,因為貝葉斯定理可以重新表達這個機率。但是這還沒有解決所有的問題,因為分母(證據)通常很難解。但也不是就此束手無辭了,還有一個挺有意思的辦法可以近似這個後驗分佈值。那就是將這個推理問題轉化為一個最佳化問題。

    要近似後驗分佈值,就必須找出一個辦法來評估提議分佈與真實後驗分佈相比是否更好。而要這麼做,就需要貝葉斯統計員的最佳夥伴:KL散度。KL散度是兩個機率分佈相似度的度量。如果它們相等,那散度為零;而如果散度是正值,就代表這兩個分佈不相等。KL散度的值為非負數,但實際上它不是一個距離,因為該函式不具有對稱性。可以採用下面的方式使用KL散度:

    這個方程式看起來可能有點複雜,但是概念相對簡單。那就是先猜測可能生成資料的方式,並提出一系列潛在分佈Q,然後再找出最佳分佈q*,從將提議分佈和真實分佈的距離最小化,然後因其難解性將其近似。但這個公式還是有一個問題,那就是p(z|x)的未知值,所以也無法計算KL散度。那麼,應該怎麼解決這個問題呢?

    這裡就需要一些內行知識了。可以先進行一些計算上的修改並針對證據下界(ELBO)和p(x)重寫KL散度:

    有趣的是ELBO是這個方程中唯一取決於所選分佈的變數。而後者由於不取決於q,則不受所選分佈的影響。因此,可以在上述方程中透過將ELBO(負值)最大化來使KL散度最小化。這裡的重點是ELBO可以被計算,也就是說現在可以進行一個最佳化流程。

    所以現在要做的就是給Q做一個好的選擇,再微分ELBO,將其設為零,然後就大功告成了。可是開始的時候就會面臨一些障礙,即必須選擇最好的分佈系列。

    一般來說,為了簡化定義q的過程,會進行平均場變分推理。每個變分引數實質上是相互獨立的。因此,每個資料點都有一個單獨的q,可被相稱以得到一個聯合機率,從而獲得一個“平均場”q。

    實際上,可以選用任意多的場或者叢集。比如在MINIST資料集中,可以選擇10個叢集,因為可能有10個數字存在。

    要做的第二件事通常被稱為再引數化技巧,透過把隨機變數帶離導數完成,因為從隨機變數求導數的話會由於它的內在隨機性而產生較大的誤差。

    再引數化技巧較為深奧,但簡單來說就是可以將一個正態分佈寫成均值加標準差,再乘以誤差。這樣在微分時,我們不是從隨機變數本身求導數,而是從它的引數求得。

    這個程式沒有一個通用的閉型解,所以近似後驗分佈的能力仍然受到一定限制。然而,指數分佈族確實有一個閉型解。這意味著標準分佈,如正態分佈、二項分佈、泊松分佈、貝塔分佈等。所以,就算真正的後驗分佈值無法被查出,依然可以利用指數分佈族得出最接近的近似值。

    變分推理的奧秘在於選擇分佈區Q,使其足夠大以求得後驗分佈的近似值,但又不需要很長時間來計算。

    既然已經大致瞭解如何訓練網路學習資料的潛在分佈,那麼現在可以探討如何使用這個分佈生成資料。

    資料生成過程

    觀察下圖,可以看出對資料生成過程的近似認為應生成數字‘2’,所以它從潛在變數質心生成數值2。但是也許不希望每次都生成一摸一樣的數字‘2’,就好像上述端遊例子所提的植物,所以我們根據一個隨機數和“已學”的數值‘2’分佈範圍,在潛在空間給這一過程添加了一些隨機噪聲。該過程透過解碼器網路後,我們得到了一個和原型看起來不一樣的‘2’。

    這是一個非常簡化的例子,抽象描述了實際自動編碼器網路的體系結構。下圖表示了一個真實變分自動編碼器在其編碼器和解碼器網路使用卷積層的結構體系。從這裡可以觀察到,我們正在分別學習潛在空間中生成資料分佈的中心和範圍,然後從這些分佈“抽樣”生成本質上“虛假”的資料。

    該學習過程的固有性代表所有看起來很相似的引數(刺激相同的網路神經元放電)都聚集到潛在空間中,而不是隨意的分散。如下圖所示,可以看到數值2都聚集在一起,而數值3都逐漸地被推開。這一過程很有幫助,因為這代表網路並不會在潛在空間隨意擺放字元,從而使數值之間的轉換更有真實性。

    整個網路體系結構的概述如下圖所示。希望讀者看到這裡,可以比較清晰地理解整個過程。我們使用一組影象訓練自動編碼器,讓它學習潛在空間裡均值和標準值的差,從而形成我們的資料生成分佈。接下來,當我們要生成一個類似的影象,就從潛在空間的一個質心取樣,利用標準差和一些隨機誤差對它進行輕微的改變,然後使其透過解碼器網路。從這個例子可以明顯看出,最終的輸出看起來與輸入影象相似,但卻是不一樣的。

    變分自動編碼器編碼指南

    去噪自編碼器

    Fashion MNIST

    在第一個練習中,在Fashion MNIST資料集新增一些隨機噪聲(椒鹽噪聲),然後使用去噪自編碼器嘗試移除噪聲。首先進行預處理:下載資料,調整資料大小,然後新增噪聲。

    ## Download the data(x_train, y_train), (x_test, y_test) = datasets.fashion_mnist.load_data()## normalize and reshapex_train = x_train/255.x_test = x_test/255.x_train = x_train.reshape(-1, 28, 28, 1)x_test = x_test.reshape(-1, 28, 28, 1)# Lets add sample noise - Salt and Peppernoise = augmenters.SaltAndPepper(0.1)seq_object = augmenters.Sequential([noise])train_x_n = seq_object.augment_images(x_train * 255) / 255val_x_n = seq_object.augment_images(x_test * 255) / 255

    接著,給自編碼器網路建立結構。這包括多層卷積神經網路、編碼器網路的最大池化層和解碼器網路上的升級層。

    # input layerinput_layer =Input(shape=(28, 28, 1)) # encodingarchitectureencoded_layer1= Conv2D(64, (3, 3), activation="relu", padding="same")(input_layer)encoded_layer1= MaxPool2D( (2, 2), padding="same")(encoded_layer1)encoded_layer2= Conv2D(32, (3, 3), activation="relu", padding="same")(encoded_layer1)encoded_layer2= MaxPool2D( (2, 2), padding="same")(encoded_layer2)encoded_layer3= Conv2D(16, (3, 3), activation="relu", padding="same")(encoded_layer2)latent_view = MaxPool2D( (2, 2),padding="same")(encoded_layer3) # decodingarchitecturedecoded_layer1= Conv2D(16, (3, 3), activation="relu", padding="same")(latent_view)decoded_layer1= UpSampling2D((2, 2))(decoded_layer1)decoded_layer2= Conv2D(32, (3, 3), activation="relu", padding="same")(decoded_layer1)decoded_layer2= UpSampling2D((2, 2))(decoded_layer2)decoded_layer3= Conv2D(64, (3, 3), activation="relu")(decoded_layer2)decoded_layer3= UpSampling2D((2, 2))(decoded_layer3)output_layer = Conv2D(1, (3, 3), padding="same",activation="sigmoid")(decoded_layer3) # compile themodelmodel =Model(input_layer, output_layer)model.compile(optimizer="adam",loss="mse") # run themodelearly_stopping= EarlyStopping(monitor="val_loss", min_delta=0, patience=10, verbose=5,mode="auto")history =model.fit(train_x_n, x_train, epochs=20, batch_size=2048,validation_data=(val_x_n, x_test), callbacks=[early_stopping])

    所輸入的影象,新增噪聲的影象,和輸出影象。

    從時尚MNIST輸入的影象。

    新增椒鹽噪聲的輸入影象。

    從去噪網路輸出的影象。

    從這裡可以看到,我們成功從噪聲影象去除相當的噪聲,但同時也失去了一定量的服裝細節的解析度。這是使用穩健網路所需付出的代價之一。可以對該網路進行調優,使最終的輸出更能代表所輸入的影象。

    文字清理

    去噪自編碼器的第二個例子包括清理掃描影象的摺痕和暗黑區域。這是最終獲得的輸入和輸出影象。

    輸入的有噪聲文字資料影象。

    經清理的文字影象。

    為此進行的資料預處理稍微複雜一些,因此就不在這裡進行介紹,預處理過程和相關資料可在GitHub庫裡獲取。網路結構如下:

    input_layer= Input(shape=(258, 540, 1)) #encoderencoder= Conv2D(64, (3, 3), activation="relu", padding="same")(input_layer)encoder= MaxPooling2D((2, 2), padding="same")(encoder) #decoderdecoder= Conv2D(64, (3, 3), activation="relu", padding="same")(encoder)decoder= UpSampling2D((2, 2))(decoder)output_layer= Conv2D(1, (3, 3), activation="sigmoid", padding="same")(decoder) ae =Model(input_layer, output_layer) ae.compile(loss="mse",optimizer=Adam(lr=0.001)) batch_size= 16epochs= 200 early_stopping= EarlyStopping(monitor="val_loss",min_delta=0,patience=5,verbose=1,mode="auto")history= ae.fit(x_train, y_train, batch_size=batch_size, epochs=epochs,validation_data=(x_val, y_val), callbacks=[early_stopping])

    變分自編碼器

    最後的壓軸戲,是嘗試從FashionMNIST資料集現有的服裝中生成新影象。

    其中的神經結構較為複雜,包含了一個稱‘Lambda’層的取樣層。

    batch_size = 16latent_dim = 2 # Number of latent dimension parameters# ENCODER ARCHITECTURE: Input -> Conv2D*4 -> Flatten -> Denseinput_img = Input(shape=(28, 28, 1))x = Conv2D(32, 3, padding="same", activation="relu")(input_img)x = Conv2D(64, 3, padding="same", activation="relu", strides=(2, 2))(x)x = Conv2D(64, 3, padding="same", activation="relu")(x)x = Conv2D(64, 3, padding="same", activation="relu")(x)# need to know the shape of the network here for the decodershape_before_flattening = K.int_shape(x)x = Flatten()(x)x = Dense(32, activation="relu")(x)# Two outputs, latent mean and (log)variancez_mu = Dense(latent_dim)(x)z_log_sigma = Dense(latent_dim)(x)## SAMPLING FUNCTIONdef sampling(args): z_mu, z_log_sigma = args epsilon = K.random_normal(shape=(K.shape(z_mu)[0], latent_dim), mean=0., stddev=1.) return z_mu + K.exp(z_log_sigma) * epsilon# sample vector from the latent distributionz = Lambda(sampling)([z_mu, z_log_sigma])## DECODER ARCHITECTURE# decoder takes the latent distribution sample as inputdecoder_input = Input(K.int_shape(z)[1:])# Expand to 784 total pixelsx = Dense(np.prod(shape_before_flattening[1:]), activation="relu")(decoder_input)# reshapex = Reshape(shape_before_flattening[1:])(x)# use Conv2DTranspose to reverse the conv layers from the encoderx = Conv2DTranspose(32, 3, padding="same", activation="relu", strides=(2, 2))(x)x = Conv2D(1, 3, padding="same", activation="sigmoid")(x)# decoder model statementdecoder = Model(decoder_input, x)# apply the decoder to the sample from the latent distributionz_decoded = decoder(z)這就是體系結構,但還是需要插入損失函式再合併KL散度。# construct a custom layer to calculate the lossclass CustomVariationalLayer(Layer): def vae_loss(self, x, z_decoded): x = K.flatten(x) z_decoded = K.flatten(z_decoded) # Reconstruction loss xent_loss = binary_crossentropy(x, z_decoded) # KL divergence kl_loss = -5e-4 * K.mean(1 + z_log_sigma - K.square(z_mu) - K.exp(z_log_sigma), axis=-1) return K.mean(xent_loss + kl_loss) # adds the custom loss to the class def call(self, inputs): x = inputs[0] z_decoded = inputs[1] loss = self.vae_loss(x, z_decoded) self.add_loss(loss, inputs=inputs) return x# apply the custom loss to the input images and the decoded latent distribution sampley = CustomVariationalLayer()([input_img, z_decoded])# VAE model statementvae = Model(input_img, y)vae.compile(optimizer="rmsprop", loss=None)vae.fit(x=train_x, y=None, shuffle=True, epochs=20, batch_size=batch_size, validation_data=(val_x, None))

    現在,可以檢視重構的樣本,看看網路能夠學習到什麼。

    從這裡可以清楚看到鞋子、手袋和服裝之間的過渡。在此並沒有標出所有使畫面更清晰的潛在空間。也可以觀察到Fashion MNIST資料集現有的10件服裝的潛在空間和顏色程式碼。

    可看出這些服飾分成了不同的叢集。

    我們一起分享AI學習與發展的乾貨

  • 中秋節和大豐收的關聯?
  • 開發商預埋水管爆裂,過兩年質保期後就只有自認倒黴嗎,該怎麼辦?