生成手寫字體,手寫制作
chanong
安妮(Anne) 編輯自O'Reilly
量子比特出品| 公眾號QbitAI
生成對抗網(wǎng)絡是過去20 年來機器學**領域最酷的想法。第——章
自從Ian Goodfellow 和蒙特利爾大學的同事兩年前提出這一概念以來,生成對抗網(wǎng)絡(GAN) 的發(fā)展勢頭一直強勁。
在O'Reilly 上發(fā)表的這篇文章中,作者為初學者解答了有關GAN 基礎知識的問題,并教大家如何使用GAN 創(chuàng)建一個可以生成手寫數(shù)字的程序。
本教程由Jon Bruner(管理硬件、互聯(lián)網(wǎng)、制造和電子領域出版物的O'Reilly 編輯團隊成員)和Adit Deshpande(加州大學洛杉磯分校計算機科學專業(yè)二年級學生)創(chuàng)建。
Qubit 提示:本文中描述的所有代碼都可以在GitHub 上下載。
https://github.com/jonbruner/generative-adversarial-networks
立即開始您的GAN 之旅——
簡介GAN 是學**創(chuàng)建類似于已知輸入數(shù)據(jù)的合成數(shù)據(jù)的神經(jīng)網(wǎng)絡。研究人員現(xiàn)在能夠使用GAN 來合成從臥室到專輯封面的照片序列,并且它們還表現(xiàn)出了反映高階語義邏輯的不可思議的能力。
雖然這些例子相當復雜,但構建一個可以生成簡單圖像的GAN 并不困難。在本教程中,您將從頭開始學**如何構建一個分析手寫數(shù)字圖像的GAN,以及如何訓練它生成新圖像。其實說白了,就是教神經(jīng)網(wǎng)絡如何寫字。
上圖是本教程中構建的GAN 生成的示例圖像。
GAN 架構GAN 包括兩種模型:生成模型和判別模型。
判別模型是一種分類器,用于確定特定圖像是數(shù)據(jù)集中的真實圖像還是人工創(chuàng)建的假圖像。這基本上是卷積神經(jīng)網(wǎng)絡(CNN)形式的二元分類器。
生成模型通過反卷積神經(jīng)網(wǎng)絡將隨機輸入值轉換為圖像。
在幾次訓練迭代的過程中,鑒別器和生成器的權重和偏差通過反向傳播進行訓練。鑒別器學**如何從生成器生成的一堆假數(shù)字圖像中找到真正的數(shù)字圖像。同時,生成器學**如何通過鑒別器的反饋生成欺騙性圖像,從而阻止鑒別器識別。
準備工作我們將創(chuàng)建一個可以生成手寫數(shù)字的GAN,旨在愚弄最好的分類器(當然包括人類)。使用Google 的開源TensorFlow 在GPU 上輕松訓練神經(jīng)網(wǎng)絡。
TensorFlow下載地址:
https://www.tensorflow.org/
我們希望您在學**本教程之前對TensorFlow 有一定的了解。如果您以前沒有遇到過這種情況,我們建議您先閱讀相關文章和教程。
加載MNIST 數(shù)據(jù)首先,我們需要將一系列真實的手寫數(shù)字圖像輸入到分類器中。這可以被認為是判別器的參考。這里使用的深度學**基準數(shù)據(jù)集MNIST是一個手寫數(shù)字圖片的數(shù)據(jù)庫,其中每張圖片都是0到9的單個數(shù)字,并且每張圖片都有抗鋸齒,這是一張灰度圖像。該數(shù)據(jù)庫包含由美國國家標準技術研究所收集、由人口普查局員工和高中生編寫的70,000 張數(shù)字圖像。
MNIST 數(shù)據(jù)集鏈接(英文):
http://yann.lecun.com/exdb/mnist/
讓我們首先導入TensorFlow 和其他有用的數(shù)據(jù)庫。首先,我們需要使用TensorFlow 的便捷函數(shù)導入MNIST 圖像。該函數(shù)也可以稱為read_data_sets。
您創(chuàng)建的MNIST 變量包含圖像和標簽,數(shù)據(jù)集分為訓練集和驗證集(盡管標簽不是本教程的關注點)?梢酝ㄟ^調用mnist中的next_batch來獲取,所以我們加載圖片來看一下。
該圖像最初格式化為784 像素列,可以轉換為28x28 像素圖像并在PyPlot 中顯示。
如果我們再次運行上面的單元格,我們將看到來自MNIST 訓練集的不同圖像。
判別網(wǎng)絡判別器采用圖像大小為28x28x1 的輸入圖像,并返回單個標量值,該標量值描述輸入圖像—— 的置信度,并確定其是否來自MNIST 圖像的卷積神經(jīng)網(wǎng)絡。集或發(fā)電機。
判別器的結構與TensorFlow中的樣本CNN分類模型密切相關。它有兩個具有5 5 像素特征的卷積層和兩個計算圖像中每個像素的權重增量的全連接層。
創(chuàng)建神經(jīng)網(wǎng)絡后,您通常需要初始化權重和偏差,您可以使用tf.get_variable 完成該任務。權重用截斷正態(tài)分布初始化,偏差用0 初始化。
tf.nn.conv2d() 是TensorFlow 的標準卷積函數(shù)。它包含四個參數(shù):第一個參數(shù)是輸入圖像(輸入體積)(本例中為28x28像素圖像),第二個參數(shù)是濾波器/權重矩陣,最后:您還可以更改“stride”和“padding”的卷積。這兩個參數(shù)控制輸出圖像的大小。
事實上,上面是一個常規(guī)的簡單二元分類器,所以如果你是CNN 的新手,你應該熟悉它。
定義了判別器之后,我們需要回顧一下生成模型。模型的整個結構基于Tim O’Shea 編寫的簡單生成器代碼。
代碼鏈接:
https://github.com/osh/KerasGAN
事實上,您可以將生成器視為一種反卷積神經(jīng)網(wǎng)絡。判別器是典型的CNN,可以將2D 或3D 像素值矩陣轉換為概率。然而,生成器需要d 維向量,并且需要轉換為28*28 圖像。 ReLU 和批量歸一化通常用于穩(wěn)定每一層的輸出。
該神經(jīng)網(wǎng)絡使用三個卷積層和插值,直到形成28*28 像素的圖像。
向輸出層添加了tf.sigmoid() 激活函數(shù)。這會壓縮灰度以顯示白色或黑色,從而產(chǎn)生更清晰的圖像。
生成樣本圖像定義了生成器和判別函數(shù)后,我們來看看未經(jīng)訓練的生成器會生成什么樣的樣本。
首先,打開TensorFlow 并為生成器創(chuàng)建一個占位符。占位符的形式為None x z_dimensions,其中關鍵字None 表示其值可以在會話期間確定。通常,您使用None 作為第一個維度,因此批量大小是可變的。如果使用關鍵字None,則不需要指定batch_size。
接下來,創(chuàng)建一個變量來保存生成器的輸出( generated_image_output ) 并使用輸入隨機噪聲向量對其進行初始化。 np.random.normal() 函數(shù)具有三個參數(shù),前兩個參數(shù)定義正態(tài)分布的平均值和標準差,最后一個定義向量的形狀(1 x 100) 。
接下來,您需要初始化所有變量,將z_batch 放入占位符中,并運行這部分代碼。
sess.run() 函數(shù)有兩個參數(shù)。第一個參數(shù)稱為“get”參數(shù),定義計算所需的值。在這種情況下,我想看看生成器輸出什么。如果您查看最后一個代碼片段,您可以看到生成函數(shù)的輸出存儲在generated_image_output 中。使用generated_image_output 作為第一個參數(shù)。
第二個參數(shù)對應輸入字典,可以在運行時替換計算圖。這就是您在占位符中輸入的內容。在此示例中,我們需要在之前定義的z_placeholder 中輸入z_batch 變量,并在PyPlot 中將圖像大小調整為28*28 像素。
看起來是正確的噪音。接下來,我們需要訓練生成網(wǎng)絡的權重和偏差,將隨機數(shù)轉換為可辨別的數(shù)字。我們再看一下?lián)p失函數(shù)和優(yōu)化。
訓練GAN 由于存在兩個損失函數(shù),構建和調試GAN 變得很復雜。一種鼓勵生成器創(chuàng)建更好的圖像,另一種鼓勵標識符區(qū)分哪些圖像是真實的,哪些是由生成器生成的。
同時訓練生成器和鑒別器。如果鑒別器善于區(qū)分圖像來自何處,則生成器還可以適當調整權重和偏差以產(chǎn)生更真實的圖像。
該網(wǎng)絡的輸入和輸出是:
因此,首先讓我們考慮一下您的網(wǎng)絡需要什么。判別器的目標是將MNIST 圖像正確標記為真,而判別器生成的標簽為假。計算鑒別器的兩個損失。一種是損失Dx和1(代表MNIST真實圖像),另一種是損失Dg和0(代表生成圖像)。在TensorFlow的tf.nn.sigmoid_cross_entropy_with_logits()函數(shù)中運行該函數(shù),計算Dx和0以及Dg和1之間的交叉熵損失。
sigmoid_cross_entropy_with_logits 在未縮放的值上運行,而不是在0 和1 之間的概率值。查看鑒別器的最后一行。這里沒有softmax或sigmoid函數(shù)層。如果鑒別器變得“飽和”,或者有足夠的信心在給定生成的圖像的情況下返回0,則鑒別器的梯度下降變得毫無用處。
tf.reduce_mean() 函數(shù)選擇交叉熵函數(shù)返回的矩陣中所有元素的平均值。這是一種將損失減少到單個標量值而不是向量或矩陣的方法。
接下來,讓我們設置生成器的損失函數(shù)。我希望生成的網(wǎng)絡圖像能夠欺騙鑒別器。給定生成的圖像,判別器可以輸出接近1 的值并計算Dg 和1 之間的損失。
現(xiàn)在損失函數(shù)已經(jīng)完成,我們需要定義優(yōu)化器。生成網(wǎng)絡優(yōu)化器只需要升級生成器權重,而不需要升級判別器。同樣,在訓練判別器時,我們需要修改生成器的權重。
為了使它們不同,我們需要創(chuàng)建兩個變量列表。一個包含鑒別器權重和偏差,另一個包含生成器權重和偏差。因此,命名TensorFlow 變量需要仔細考慮。
接下來,您需要制定兩個優(yōu)化器,通常選擇具有自適應學**率和動量的Adam 優(yōu)化算法。調用Adam 最小值函數(shù)并指定要更新的變量——。這是訓練生成器時的生成器權重和偏差,以及訓練判別器時的判別器權重和偏差。
我們?yōu)殍b別器設置了兩種不同的訓練方案。一種使用真實圖像來訓練鑒別器,另一種使用生成的“假圖像”來訓練鑒別器。有時你需要使用不同的學**率或單獨使用它們來調整學**的其他方面。
你說的其他方面是什么意思?代碼下載鏈接:
https://github.com/jonbruner/ezgan
GAN 收斂很困難,通常需要很長時間來訓練。 TensorBoard 允許您跟蹤訓練過程。您可以繪制標量屬性(例如損失)、查看訓練中的樣本圖像以及查看神經(jīng)網(wǎng)絡內的拓撲。
想了解更多關于TensorBoard 的信息嗎?鏈接:
https://www.tensorflow.org/get_started/summaries_and_tensorboard
如果您在自己的計算機上運行此腳本,請確保包含以下單元格:接下來,在終端窗口中運行tensorboard —logdir=tensorboard/,并在瀏覽器中輸入http://localhost:6006以打開TensorBoard。
接下來,給鑒別器一些簡單的原始訓練迭代。這種方法有助于形成對生成器有用的梯度。
接下來,繼續(xù)主訓練循環(huán)。在訓練生成器時,我們需要向生成器輸入一個隨機z 向量,并將其輸出傳遞給判別器(這是前面定義的Dg 變量)。生成器的權重和偏差的改變主要是為了產(chǎn)生可以欺騙鑒別器的圖像。
要訓練判別器,請從MNIST 數(shù)據(jù)集中為其提供一組正例,并將它們用作負例,以便在生成的圖像上再次訓練判別器。
訓練GAN 通常需要很長時間,因此如果您是本教程的新手,我們建議您暫時不要運行此代碼塊。但是,您可以首先運行以下代碼塊來生成預訓練模型。
如果您想自己運行這段代碼,請做好長時間等待的準備。在相對較快的GPU 上大約需要3 小時,在桌面CPU 上可能需要更長的時間10 倍。
所以我建議你跳過上面的內容,直接運行下一個單元格。您可以將經(jīng)過10 小時訓練的模型加載到快速GPU 機器上,并嘗試經(jīng)過訓練的GAN。
訓練并不容易眾所周知,訓練GAN 很困難。如果沒有正確的超參數(shù)、網(wǎng)絡架構和訓練過程,鑒別器將壓倒生成器。
一種常見的失敗模式是鑒別器壓倒了生成器,生成的圖像被明確定義為假圖像。如果判別器是絕對確定的,則生成器就沒有斜率可以減小。這就是為什么我們構建一個產(chǎn)生未縮放輸出的判別器,而不是通過sigmoid 函數(shù)將輸出推至0 或1。
在另一種常見的故障模式(模態(tài)崩潰)中,生成器發(fā)現(xiàn)并利用鑒別器中的弱點。當生成大量相似圖像時,無論生成器的輸入z 變量如何,都可以識別這一點。模態(tài)崩潰可以通過“加強”鑒別器來修復,例如通過調整訓練速率或重新配置層。
研究人員已經(jīng)找到了幾種幫助構建穩(wěn)定GAN 的小方法。
想讓你的GAN也穩(wěn)定嗎?代碼鏈接:
https://github.com/soumith/ganhacks
結論GAN 具有重塑我們每天互動的數(shù)字世界的巨大潛力。這個領域還很年輕,因此下一個新的GAN 發(fā)現(xiàn)可能來自您。
附加信息1. Ian Goodfellow 及其合作伙伴于2014 年發(fā)表的GAN 論文
論文鏈接:
https://arxiv.org/abs/1406.2661
2. Goodfellow 最近的教程揭開了GAN 的神秘面紗。
教程鏈接:
https://arxiv.org/abs/1701.00160
3. Alec Radford、Luke Metz、Soumith Chintala 等人的論文。它介紹了本教程生成器中使用的復雜GAN 的基本結構。
論文鏈接:
https://arxiv.org/abs/1511.06434
GitHub 上的DCGAN 代碼:
https://github.com/Newmu/dcgan_code
【就這樣】
筆記
量子比特組建了一個針對自動駕駛相關領域學**的學生和一線工程師的自動駕駛技術小組。任何人都可以添加量子比特微信(qbitbot),關注“自動駕駛”申請參與~
招聘
Qubit正在招聘編輯、記者、運營、產(chǎn)品等職位,辦公地點將位于北京中關村。相關詳情請在公眾號對話界面回復“招募”。








