生成式對抗網路 (Generative Adversarial Network),簡稱GAN。
generative [ˋdʒɛnə͵rətɪv] 生殖的;有生產力的
Adversarial [͵ædvɚˋsɛrɪəl] 敵手的;對手的;對抗的
近來超級火紅的Generative Adversarial Network 中文翻譯為生成式對抗網路。這種演算法被自稱是 AI 大師的人解釋成好像可以產生出更新、更高解析、更高科技的最佳發明,簡直是可以無中生有 (Create something from nothing) 的尖端科技。但事實是殘酷的,由真實的事件(比如真實的照片)產生出人類無法辨識的假照片,這些照片都是假的。
生成對抗網路由一個生成網路與一個判別網路組成,通過兩個神經網路相互博弈的方式進行學習。該方法由 Ian(伊恩·古德費洛) 等人於2014年提出。生成網路從潛在空間(latent space)中隨機取樣作為輸入,其輸出結果需要盡量模仿訓練集中的真實樣本。判別網路的輸入則為真實樣本或生成網路的輸出,其目的是將生成網路的輸出從真實樣本中盡可能分辨出來。而生成網路則要盡可能地欺騙判別網路。兩個網路相互對抗、不斷調整參數,最終目的是使判別網路無法判斷生成網路的輸出結果是否真實。
生成對抗網路常用於生成以假亂真的圖片。此外,該方法還被用於生成影片、三維物體模型等。生成對抗網路雖然最開始提出是為了無監督學習,但經證明對半監督學習、完全監督學習 、強化學習也有效。 在2016年的一個研討會上,生成式對抗網路被譽為機器學習這二十年來最酷的想法。
監督式學習
在 Yolov8 的說明中,必需標示圖片中的物件是人類,腳踏車,杯子,餐桌…… 共80種。而每一種又有上千張圖片,這些全都需要人工標識並告知是那一個種類,最後才丟進模型進行訓練,這叫監督式學習。
標識圖片的工作,通常是由美工人員負責,所以一般公司都要聘請多位美工人員標識每天上千到上萬張的圖片。
非監督式學習
美工人員每天重複無腦的動作,一天上萬張圖不斷的標識,薪水低又每天加班。Gan 就是讓這些美工人員失業的最佳方案,因為它可以應用在非監督式學習,電腦自已標識圖片,然後自已訓練。
電腦不斷學習的結果
Gan 的真正作用,是要用在非監督式學習,並不是讓電腦不斷的學習,怎麼說呢?
讓 A 模型學習 B 模型的真實的事情,進而產生新的東西。然後新的東西再學習新的東西,一直不斷的學習,不就達成魔鬼終者的世界嗎! 那為啥不直接說會進入神的領域! 一台破電腦直接變成神?
不要忘了一件事,A 模型學習 B 模型真實的事件,產生出的新東西是假的。假的東西再學習假的,只會愈學愈假,最後就是四不像。
DCGAN
生成式對抗網路是無中生有的東西,DCGAN(Deep Convolutional GAN)是 GAN 的經典改良版,由 Alec Radford 等人在 2015 年提出。速度比 GAM 更快且像片品質更佳。
網路上的教學,都說 GAN 可以把模糊圖片變成高清晰、2D 可以變成 3D,是沒錯,因為連專家也判斷不出真假。但真的要產生 1024*768 的圖片,不是一般顯卡作的出來的。所以圖片大小僅限於100~200相素左右。
本篇使用 Mnist 的 60000 張真圖進行訓練。
模型組合
一開始若不把下面的模型組合搞清楚,程式碼就會看不懂。

首先產生 generator 模型,此模型輸入雜訊,經過權重計算,由 generator(noise) 產生 Fake images。
接下來建立 discriminator 鑑識模型,此模型的 Input 輸入資料就是 generator 的 Fake images ,再使用 discriminator.train_on_batch() 產生黃色端的 validity 資料。
請注意 discriminator.trainable = True,訓練時黃色的權重會被調整而提高辨識能力。但本程式沒有辨識的功能,而是直接告知這是真圖或是假圖,所以把 trainable 設為 False,以提高訓練效能。
combine 是 generator 及 discriminator 的結合體。此模型的 Input 會傳給 generator 的 Input,輸出 Fake images 後傳給 discriminator 的 Input, discriminator 的 validity 最後再傳給 combine 的 validity 。
那麼 generator 裏的權重要如何訓練呢? 就是由 combine.train_on_batch() 啟動訓練,讓 generator 產生的圖像愈來愈接近真實的狀況。
安裝套件
底下使用 pytorch,請先安裝如下套件
🔒 更多內容,請登入會員繼續閱讀。
立即登入觀念
使用 Mnist 的手寫資料進行訓練,然後由這些資料無中生出其它的圖片。本例的模型訓練需一點時間,無法訓練的人,請由如下網址下載。
載入圖片資料
pytorch 也有 Mnist 的手寫資料,請由如下代碼測試
🔒 更多內容,請登入會員繼續閱讀。
立即登入train = True 時,會有60000張圖片,train=False 時,只有 10000張。第一次執行時,download 必需是 True。若第一次沒資料而 download 為 False,則會報錯。
dataset 是圖型及 Label 的資料,此處只要顯示圖片,所以不需要 transform。若要進行模型訓練,需使用 transforms.ToSensor 轉換成 pytorch 格式。

Generator 模型
新增 Generator.py,內容如下
🔒 更多內容,請登入會員繼續閱讀。
立即登入Discriminator 模型
Discriminator 模型是判別器,完整代碼如下。
🔒 更多內容,請登入會員繼續閱讀。
立即登入模型訓練
底下是訓練模型的完整代碼
🔒 更多內容,請登入會員繼續閱讀。
立即登入產生假圖
底下是產生假圖的完整代碼
🔒 更多內容,請登入會員繼續閱讀。
立即登入
Tensorflow 版
安裝套件
請先安裝如下套件
pip install tensorflow==2.10.1 matplotlib
程式運作流程
主程式中產生 gan=Gan() 物件。這個物件建構子會產生二個模型
generator 模型
此模型 input 層接收隨機產生的 100 個雜訊,用這個雜訊產生 256 => 512 => 1024 個資料,最後產生 784 個點形成圖片。
🔒 更多內容,請登入會員繼續閱讀。
立即登入Discriminator [dɪˋskrɪmə͵netɚ] 模型 (鑑識器)
用來判斷產生的圖片與原圖的相似度,輸入層是 784 個相素的圖片,最後縮小成 512 => 256 => 1 個資料
🔒 更多內容,請登入會員繼續閱讀。
立即登入combine
combine 由 generator 及 discriminator 二個模型組合成成
self.combine= Model(input, self.discriminator(self.generator(input))
請注意,要訓練 generator 的權重,不是由 generator.train() 訓練,而是由 combine.train_on_batch() 開始訓練。
train
最後再由主程式啟動 train 開始訓練。
模型下載
底下的完整代碼,訓練需要一段時間,沒顯卡會非常的久。所以無法訓練的人,請由本站下載 gan_mnist。本模型是本人訓練 10 萬次的結果。
完整代碼
本篇的完整代碼是參考 https://github.com/eriklindernoren/Keras-GAN/blob/master/gan/gan.py 修改而來的。
修改的部份為
1. 將模型獨立成一個類別
2. 訓練的指令放在主程式中
3. 一次讀入10000張圖片訓練
完整代碼如下
🔒 更多內容,請登入會員繼續閱讀。
立即登入結果
一開始產生的照片如下

最後一次產生的照片如下

這種無中生有的東西竟然會發生在這世界上,人類想當上帝真的是想瘋了。
載入 generator 模型直接產生新圖
前面的代碼中,我們將 generator 的權重儲存在 gan_mnist 目錄中。所以下次不想重新訓練,而是想直接產生新圖時,就可以使用如下代碼
