日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【機器學習】小孩都看得懂的 GAN

 漢無為 2021-11-19

0

GAN 是什么

GAN 的全稱是 Generative Adversarial Network,中文是生成對抗網(wǎng)絡。

圖片

一言以蔽之,GAN 包含了兩個神經(jīng)網(wǎng)絡,生成器(generator)和辨別器(discriminator),兩者互相博弈不斷變強,即生成器產(chǎn)出的東西越來越逼真,辨別器的識別能力越來越牛逼。

2

造假和鑒定

圖片

生成器辨別器之間的關(guān)系很像造假者(counterfeiter)和鑒定者(Appraiser)之間的關(guān)系。

  • 造假者不斷造出假貨,目的就是蒙騙鑒定者,在此過程中其造假能力越來越高。

  • 鑒定者不斷檢驗假貨,目的就是識破造假者,在此過程中其鑒定能力越來越高。

GAN 是造假者的,也是鑒定者的,但歸根結(jié)底還是造假者的。GAN 的最終目標是訓練出一個“完美”的造假者,即能讓生成讓鑒定者都蒙圈的產(chǎn)品。

一動圖勝千言,下圖展示“造假者如何一步步生成逼真的蒙娜麗莎畫而最終欺騙了鑒定者”的過程。

圖片

在此過程中,每當造假者生成一幅圖。鑒定者會給出反饋,造假者從中學到如何改進來畫出一張逼真圖。

3

造假鑒定網(wǎng)絡?

回到神經(jīng)網(wǎng)絡,造假者生成器來建模,鑒定者辨別器來建模。

圖片

根據(jù)上面動圖可知,辨別器的任務是區(qū)分哪些圖片是真實的,哪些圖片是生成器產(chǎn)生的。

接下來我們用 Python 創(chuàng)建一個極簡 GAN。

首先設置一個故事背景。

4

故事背景

在傾斜島(slanted island)上,每個人都是傾斜的,大概像左傾斜 45 度左右。

圖片

島主想做人臉生成器,由于島上的人的臉部特征非常簡單,因此用 2 * 2 像素的模糊人臉圖片。

圖片

限于技術(shù),島主只用了個一層的神經(jīng)網(wǎng)絡。

圖片

但在這個極度簡單的設置下,一層的 GAN 也能生成“傾斜人臉”。

5

辨別人臉

下圖展示四個人臉的樣子。

圖片

從 2*2 像素來表示人臉,深色代表此處有人臉,淺色代表此處沒有人臉。

圖片

如果不是人臉呢?那么其 2*2 像素圖中的元素就是隨機的,如下所示。

圖片

復習一下:

  • 人臉:對角線上是深色,非對角線上是淺色

  • 非人臉:任意四處都可能是深色或淺色

圖片

像素可以用 0 到 1 的數(shù)值來表示:

  • 人臉:對角線上的數(shù)值大,非對角線上的數(shù)值小

  • 非人臉:任意四處都可能是 0-1 之間的任意數(shù)值

圖片

弄清了人臉照片和非人臉照片用不同特征的 2*2 數(shù)值矩陣表示之后,接下來兩節(jié)我們來看如何構(gòu)建辨別器(discriminator)和生成器(generator)。

先分析辨別器。

6

辨別器

辨別器就是用來辨別人臉,那么當看到照片的像素值時,如何辨別呢?

圖片

簡單!上節(jié)已經(jīng)分析過:

  • 人臉:對角線上的數(shù)值大,非對角線上的數(shù)值小

  • 非人臉:任意四處都可能是 0-1 之間的任意數(shù)值

圖片


如果要用一個數(shù)值表示人臉和非人臉,該用什么樣的操作呢?也簡單,如下圖所示,加上 (1,1) 位置的元素,減去 (1,2) 位置的元素,減去 (2,1) 位置的元素,加上 (2,2) 位置的元素,得到一個數(shù)值就可以了。

圖片


人臉得到的分數(shù)是 2(較大),非人臉得到的分數(shù)是 -0.5(較?。?。

圖片

設定一個閾值 1,得分大于 1 是人臉,小于 1 不是人臉。

將上述內(nèi)容用神經(jīng)網(wǎng)絡來表示,就成了下面的極簡辨別器了。注意除了“加減減加”矩陣 4 個元素之外,最后還加上一個偏置項(bias)得到最終得分。

圖片


辨別器最終要判斷是否是人臉,因此產(chǎn)出是一個概率,需要用 sigmoid 函數(shù)將得分 1 轉(zhuǎn)化成概率 0.73。給定概率閾值 0.5,由于 0.73 > 0.5,辨別器判斷該圖是人臉。

圖片


對另一張非人臉的圖,用同樣操作,最后算出得分 -0.5,用 sigmoid 函數(shù)轉(zhuǎn)換。給定概率閾值 0.5,由于 0.37 < 0.5,辨別器判斷該圖是人臉。

圖片

7

生成器

辨別器目標是判斷人臉。而生成器目標是生成人臉,那什么樣的矩陣像素是人臉圖呢?簡單!該規(guī)則被已經(jīng)分析多次了:

  • 人臉:對角線上的數(shù)值大,非對角線上的數(shù)值小

  • 非人臉:任意四處都可能是 0-1 之間的任意數(shù)值

圖片


現(xiàn)在來看生成過程。第一步就是從 0-1 之間隨機選取一個數(shù),比如 0.7。

圖片

回憶生成器的目的是生成人臉,即要保證最終 2*2 矩陣的對角線上的像素要大(用粗線表明),而非對角線上的像素要?。ㄓ眉毦€表明)。

圖片


舉例,生成矩陣 (1,1) 位置的值,w = 1, b = 1,計算的分 wz + b = 1.7。

圖片


同理計算矩陣其他三個位置的得分。

圖片


最后都用 sigmoid 函數(shù)將得分轉(zhuǎn)換一下,確保像素值在 0-1 之間。

圖片

注意按上圖這樣給權(quán)重 [1, -1, -1, 1] 和偏置 1,有因為 z 總是在 0 和 1 之間的一個正數(shù),這樣的一個神經(jīng)網(wǎng)絡(生成器)總可以生成一個像人臉的 2*2 的像素矩陣。

根據(jù)本節(jié)和上節(jié)的展示,我們已經(jīng)知道什么樣的辨別器可以判斷人臉,什么樣的生成器可以生成好的人臉,即什么樣的 GAN 是個好 GAN。這些都是由權(quán)重和偏置決定的,接下來看看它們是怎么訓練出來的。首先復習一下誤差函數(shù)(error function)。

8

誤差函數(shù)

通常把正類用 1 表示,負類用 0 表示。在本例中人臉是正類,用 1 表示;非人臉是負類,用 0 表示。

當標簽為 1 時(人臉),-ln(x) 是一個好的誤差函數(shù),因為

  • 當預測不準時(預測非人臉,假設 0.1),那么誤差應該較大,- ln(0.1) 較大。 

  • 當預測準時(預測人臉,假設 0.9),那么誤差應該較小,-ln(0.9) 較小。

圖片


當標簽為 0 時(非人臉),-ln(1-x) 是一個好的誤差函數(shù)。

  • 當預測準時(預測非人臉,假設 0.1),那么誤差應該較小,- ln(1-0.1) 較大。 

  • 當預測不準時(預測人臉,假設 0.9),那么誤差應該較大,-ln(1-0.9) 較小。

圖片


根據(jù)下面兩張總結(jié)圖再鞏固一下 ln 函數(shù)作為誤差函數(shù)的邏輯。

圖片

圖片

接下來就是 GAN 中博弈,即生成器辨別器放在一起會發(fā)生什么事情。

9

生成器和辨別器放在一起

復習一下兩者的結(jié)構(gòu)。

  • 生成器:輸入是一個 0-1 之間的隨機數(shù),輸出是圖片的像素矩陣

  • 辨別器:輸入是圖片像素矩陣,輸出是一個概率值

圖片


下面動圖展示了從生成器辨別器的流程。

圖片


因為該圖片是從生成器來的,不是真實圖片,因此一個好的辨別器會判斷這不是臉,那么使用標簽為 0 對應的誤差函數(shù),-ln(1-prediction)。

圖片

反過來,一個好的生成器想騙過辨別器,即想讓辨別器判斷這是臉,那么使用標簽為 1 對應的誤差函數(shù),-ln(prediction)。

圖片


好戲來了,用 G 表示生成器,D 表示辨別器,那么

  • G(z) 是生成器的產(chǎn)出,即像素矩陣,它也是辨別器的輸入

  • D(G(z)) 是辨別器的產(chǎn)出,即概率,又是上面誤差函數(shù)里的 prediction

為了使生成器辨別器都變強,我們希望最小化誤差函數(shù)

    -ln(D(G(z)) - ln(1-D(G(z))

其中 D(G(z)) 就是辨別器的 prediction。

圖片


將我們得到的誤差函數(shù)對比 GAN 論文中的目標函數(shù)(下圖),發(fā)現(xiàn)還是有些差別:

圖片

解釋如下:

辨別器除了接收生成器產(chǎn)出的圖片 G(z),還會接收真實圖片 x,在這時一個好的辨別器會判斷這是臉,那么使用標簽為 1 對應的誤差函數(shù),-ln(-prediction)。那么對于辨別器,需要最小化的誤差函數(shù)是

    -ln(D(x)) - ln(1-D(G(z))

將負號去掉,等價于最大化

    ln(D(x)) + ln(1-D(G(z))

這個不就是 V(D,G) 么?此過程是固定生成器,來優(yōu)化辨別器來識別假圖片。

V(D, G) 最大化后,在固定辨別器,來優(yōu)化生成器來生成以假亂真的圖片。但是生成器的誤差函數(shù)不是 -ln(D(G(z)) 嗎?怎么能和 V(D, G) 扯上關(guān)系呢?其實 -ln(D(G(z)) 等價于 ln(1-D(G(z)),這時 V(D, G) 的第二項,而其第一項 ln(D(x)) 對于 G 是個常數(shù),加不加都無所謂。

最后 V(D, G) 中的兩項都有期望符號,在實際優(yōu)化中我們就通過 n 個樣本的統(tǒng)計平均值來實現(xiàn)。第一項期望中的 x 從真實數(shù)據(jù)分布 p_data(x) 中來,第一項期望中的 z 從特定概率分布 p_z(z) 中來。

綜上,先通過 D 最大化 V(D,G) 再通過 G 最小化 V(D, G)。

10

訓練 GAN

在訓練中,當人臉來自生成器,通過最小化誤差函數(shù),辨別器輸出概率值接近 0。

圖片

當人臉來自真實圖片,通過最小化誤差函數(shù),辨別器輸出概率值接近 1。

圖片


當然所有神經(jīng)網(wǎng)絡的訓練算法都是梯度下降了。

OK,接下來的內(nèi)容確實不適合普通小孩了,對數(shù)學和編程有強烈興趣的小孩可以繼續(xù)看下去 圖片。

11

數(shù)學推導

辨別器:從像素矩陣到概率

圖片

圖片

生成器:從隨機數(shù) z 到像素矩陣

圖片

圖片

得到誤差函數(shù)相對于生成器和辨別器中的權(quán)重和偏置的各種偏導數(shù)后,就可以寫代碼實現(xiàn)了。

12

Python 實現(xiàn) - 準備工作

引入 numpy 和 matplotlib。





import numpy as npfrom numpy import randomfrom matplotlib import pyplot as plt%matplotlib inline

編寫繪畫人臉像素的函數(shù)。










def view_samples(samples, m, n):    fig, axes = plt.subplots(figsize=(10, 10),                              nrows=m, ncols=n,                              sharey=True, sharex=True)    for ax, img in zip(axes.flatten(), samples):        ax.xaxis.set_visible(False)        ax.yaxis.set_visible(False)        im = ax.imshow(1-img.reshape((2,2)), cmap='Greys_r')      return fig, axes

畫出四張人臉,注意其像素矩陣中對角線上的數(shù)值大,非對角線上的數(shù)值小。








faces = [np.array([1,0,0,1]), np.array([0.9,0.1,0.2,0.8]), np.array([0.9,0.2,0.1,0.8]), np.array([0.8,0.1,0.2,0.9]), np.array([0.8,0.2,0.1,0.9])] _ = view_samples(faces, 1, 4)

圖片

畫出二十張非人臉,注意其像素矩陣中的數(shù)都是隨機的。






noise = [np.random.randn(2,2) for i in range(20)]def generate_random_image():    return [np.random.random(), np.random.random(), np.random.random(), np.random.random()]
_ = view_samples(noise, 4,5)

圖片

13

Python 實現(xiàn) - 構(gòu)建辨別器

首先實現(xiàn) sigmoid 函數(shù)。



def sigmoid(x): return np.exp(x)/(1.0+np.exp(x))

用面向?qū)ο缶幊蹋∣OP)來編寫辨別器,代碼如下:

圖片

其中

  • __init__() 是構(gòu)建函數(shù)

  • forward() 函數(shù)將像素矩陣打平成向量 x,乘上權(quán)重 w 加上偏置 b 得到得分,再通過 sigmoid() 函數(shù)轉(zhuǎn)成概率

  • error_form_image() 計算當接收真實圖片為輸入的誤差函數(shù)

  • error_form_noise() 計算當接收生成器為輸入的誤差函數(shù)

  • derivatives_form_image() 計算當接收真實圖片為輸入誤差函數(shù)對權(quán)重 w 和偏置 b 的偏導數(shù) 

  • derivatives_form_noise() 計算當接收生成器為輸入誤差函數(shù)對權(quán)重 w 和偏置 b 的偏導數(shù) 

  • update_form_image() 計算當接收真實圖片為輸入時的梯度下降法

  • update_form_noise() 計算當接收生成器為輸入時的梯度下降法

14

Python 實現(xiàn) - 構(gòu)建生成器

用面向?qū)ο缶幊蹋∣OP)來編寫生成器,代碼如下:

圖片

其中

  • __init__() 是構(gòu)建函數(shù)

  • forward() 函數(shù)將隨機數(shù) z 乘上權(quán)重 w 加上偏置 b 得到得分,再通過 sigmoid() 函數(shù)轉(zhuǎn)成像素

  • error() 計算當固定辨別器為輸入的誤差函數(shù),分兩步:

    • 生成器的 forward() 函數(shù)得到像素

    • 辨別器的 forward() 函數(shù)得到概率

  • derivatives() 計算當固定辨別器為輸入誤差函數(shù)對權(quán)重 w 和偏置 b 的偏導數(shù),對著上一節(jié)數(shù)學公式看代碼 

  • update() 計算當固定辨別器為輸入時的梯度下降法

15

Python 實現(xiàn) - 訓練 GAN

設定 1000 期(epoch),即將數(shù)據(jù)遍歷 1000 遍開始訓練,記錄每期生成器辨別器的誤差。

圖片

畫出生成器辨別器的誤差函數(shù)圖,發(fā)現(xiàn)生成器逐步趨于穩(wěn)定。








plt.plot(errors_generator)plt.title('Generator error function')plt.legend('gen')plt.show()plt.plot(errors_discriminator)plt.legend('disc')plt.title('Discriminator error function')

圖片

圖片

16

Python 實現(xiàn) - 結(jié)果展示

生成圖片。









generated_images = []for i in range(4): z = random.random() generated_image = G.forward(z) generated_images.append(generated_image)_ = view_samples(generated_images, 1, 4)for i in generated_images: print(i)
[0.94688171 0.03401213 0.04080795 0.96308679]
[0.95653992 0.03437852 0.03579494 0.97063836]
[0.95056667 0.03414339 0.03893305 0.96599501]
[0.94228203 0.03386046 0.04309146 0.95941292]

圖片

打印出最終 GAN 的參數(shù),即生成器辨別器的權(quán)重和偏置。





print('Generator weights', G.weights)print('Generator biases', G.biases)print('Discriminator weights', D.weights)print('Discriminator bias', D.bias)
Generator weights [ 0.70702123 0.03720449 -0.45703394 0.79375751]
Generator biases [ 2.48490157 -3.36725912 -2.90139211 2.8172726 ]
Discriminator weights [ 0.60175083 -0.29127513 -0.40093314 0.37759987]
Discriminator bias -0.8955103005797729

帶有權(quán)重和偏置的 GAN 如下所示。

圖片

圖中粗線對應大權(quán)重,細線對應小或者負權(quán)重。對照前面生成器要生成逼真人臉的目標來看(即 2*2 矩陣的對角線上的值大),是不是這個權(quán)重很合理。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多