半監督學習背景下的生成對抗網路
作者:Jakub Langr
編譯:weakish
在許多研究人員和我的朋友看來, 生成對抗學習/網路(Generative Adverserial Learning/Networks,GANs) 很可能是AI的未來發展方向之一。GAN在商業上有很清晰的吸引力:可以基於較少的資料訓練,可以建立迷人的應用(例如3D模型生成),有大量研究潛力。
本文包括一定的技術內容,也有一些高層的虛擬碼,但我將盡力讓這篇文章容易理解,也希望這篇文章不會太枯燥。

GAN這一切都是最前沿的內容,本文提到的一些內容甚至是一兩年前剛在學術期刊上釋出的內容。所以,除非你是這方面的博後,初次接觸GAN可能會讓你覺得不同尋常(至少對我來說是這樣的)。同時這也意味著其中有一些研究沒有對應的理論,你需要應對一些超奇怪的bug. 不過因為我最近完成了(好吧,我真的很喜歡上MOOC)Parag Mital開設的非常棒的 ofollow,noindex">Creative Applications of Deep Learning with TensorFlow (基於TensorFlow的深度學習創意應用)課程,我決定分享一些我學到的東西。
半監督學習大致上指在訓練中同時使用標註過的(監督)和未標註過的(無監督)樣本,這是一個比較老的概念了。它的核心思想意義很大:在典型的監督設定下,我們有大量沒有使用的資料。例如,在房價(標註)資料上的線性迴歸。我們都明白線性迴歸可以生成房價,但大多數房子沒有出售,然而我們也許仍然能取得相關資料,比如從城市規劃資料中獲取。這些資料可以給我們提供更多的資訊,例如對比不同區域,哪裡的房子相對而言供不應求,哪裡大面積的房子更多。不以某種形式利用這些資料很蠢,但傳統的演算法沒法使用它們。
因此,半監督學習(SSL)意味著使用不同技術以某種方式在機器學習(ML)模型的訓練中新增這些資料。這並非微不足道:如果把訓練ML想象出建立一棵決策樹,接著通過檢查是否得出正確答案評估決策樹的表現。那麼,很不幸,在未標註資料上,沒有正確答案(因為在資料收集期間房子未曾出售),所以沒法進行學習,因為ML演算法無法連線正確答案(因此無法計算損失)。在這篇文章中,我希望集中討論其中一種稱為生成對抗網路的SSL技術。
GAN有兩個網路組成。第一個網路建立世界的內在版本(即通常房子是什麼樣的):這稱為生成模型(G),基本上它基於一切資料學習,因為它不需要標籤,只需要資料集中典型房屋的所有特徵。第二個網路,稱為判別器(D),和G對抗,同時從真實資料集和生成器生成的房屋樣本中取樣,決定資料看起來是不是真的。
換句話說,想象我們正在嘗試標註貓或狗,在這一情形下,G將學習如何生成影象,並逐漸使生成的影象越來越像貓或狗。
接著,我們大致上讓G和D互相競爭,以產生最好的結果:我們希望每次G變得更好時,D也能變得更好,相互匹配(我們需要確保G或D沒有勝出對方太多)。這也正是驅動AlphaGo的核心原則之一。基本上,我們讓G生成影象,讓D對此加以評判。所以G會傳遞一組影象給D,而D會輸出0或1(代表真假)並傳回G。接著G會根據哪些影象騙過了D、哪些沒騙過而努力生成更好的樣本。

所以我希望你明白了上面的過程,我們可以基於大量未標註資料構建一個生成器,並讓它學習資料的某些結構(即,典型樣本看起來是什麼樣的),接著讓它在競爭中使生成資料儘可能接近真實資料。經過這一過程,我們可能得到一些看起來相當不錯的合成數據,這些合成數據的數量幾乎是無限的。另外,我想指出(省略大量說明):生成器只能生成和之前見過的資料相似的資料。人們很容易忘記這點,沒有魔法。

從最高層的抽象看,這一切大概是這樣的:
# 獲取資料 real_data = pd.read('real_data.csv')# 形狀 (n樣本, n特徵加標籤) unlabelled_data = pd.read('unlabelled_data.csv')# 形狀 (n樣本, n特徵) # 建立兩個物件 generator = GeneratorClass() discriminator = DiscriminatorClass() # 預訓練生成器 generator.train(unlabelled_data) # 獲取合成數據 synthetic_data = make_compete(generator, discriminator, real_data) # 形狀 (任意數量, n特徵)
好吧,細心的讀者可能會注意到我們沒有描述如何標記生成樣本。理想情況下,我們想要生成標註資料(例如,附帶價格的房屋,或者附帶物體描述的影象)。感謝大量的訓練例項,我們有辦法做到這點。如果你回頭看看之前的示意圖,你會看到其中提到了稱為“潛空間”的東西。潛空間是一種控制生成什麼樣的影象的方法。如果我們訓練貓狗生成器,其中一個維度將控制影象有多像貓/狗。它也允許我們獲取兩者之間的中間值,所以我們可以得到狗貓或者七分貓三分狗。換句話說,潛空間可以看成某種種子因素——為G提供一些初始輸入免得它總是生成一樣的東西,但是事實上這一種子因素具備一致的潛(“隱藏”)性質,特定的維度對應某種意義的。
簡單修改上面的虛擬碼,以清楚地表明這一點:
# 形狀 (任意數量, n特徵) synthetic_cats = make_compete(generator, discriminator, real_data, input_noise=latent_feature_space.cat) # 形狀 (任意數量, n特徵) synthetic_dogs = make_compete(generator, discriminator, real_data, input_noise=latent_feature_space.dog)
最棒的地方在於,理論上,我們甚至不需要有為當前任務標註的資料就可以生成相應樣本(不過有標註資料會有很大幫助)。例如,我們可能有打上了好孩子和壞孩子的資料,然後我們可以訓練G生成貓或狗的新樣本(根據潛空間的一個引數決定是貓是狗),其中既有好孩子,也有壞孩子(基於潛空間的另一個引數決定)。比方說,我們可以基於影象判斷狗的好壞(例如,如果我們看到狗破壞財物就標記為壞孩子,否則就標記為好孩子)。那麼我們就可以在潛空間中發現對應這些特徵的引數,然後通過插值生成貓狗或者狗貓。
再舉一個例子,我們可以下載大量未標註的名人面部影象,然後讓G生成面部,並通過操作潛空間得到明確的雄性樣本或雌性樣本,接著據此訓練另一個識別雄性或雌性影象的分類器(無需標註過的資料!)這正是我曾經做過的專案。你可能想要知道“我們如何得到不同屬性的潛空間表示?”很不幸,這個問題的答案超出了本文的範圍。
唷,時候不早了:我希望給出一些可以實際執行的程式碼,這樣讀者可以自行試驗。不過,我覺得這篇部落格文章已經夠長了,所以,對實際程式碼感興趣的讀者,請訪問我的另一篇部落格文章: http:// jakublangr.com/gans-cod e.html