5分鐘入門GANS:原理解釋和keras代碼實現

2020-12-04 deephub

本篇文章包含以下內容

介紹歷史直觀解釋訓練過程GAN在MNIST數據集上的KERAS實現介紹

生成式敵對網絡通常也稱為GANs,用於生成圖像而不需要很少或沒有輸入。GANs允許我們生成由神經網絡生成的圖像。在我們深入討論這個理論之前,我想向您展示GANs構建您興奮感的能力。把馬變成斑馬(反之亦然)。

歷史

生成式對抗網絡(GANs)是由Ian Goodfellow (GANs的GAN Father)等人於2014年在其題為「生成式對抗網絡」的論文中提出的。它是一種可替代的自適應變分編碼器(VAEs)學習圖像的潛在空間,以生成合成圖像。它的目的是創造逼真的人工圖像,幾乎無法與真實的圖像區分。

GAN的直觀解釋

生成器和鑑別器網絡:

生成器網絡的目的是將隨機圖像初始化並解碼成一個合成圖像。

鑑別器網絡的目的是獲取這個輸入,並預測這個圖像是來自真實的數據集還是合成的。

正如我們剛才看到的,這實際上就是GANs,兩個相互競爭的敵對網絡。

GAN的訓練過程

GANS的訓練是出了名的困難。在CNN中,我們使用梯度下降來改變權重以減少損失。

然而,在GANs中,每一次重量的變化都會改變整個動態系統的平衡。

在GAN的網絡中,我們不是在尋求將損失最小化,而是在我們對立的兩個網絡之間找到一種平衡。

我們將過程總結如下

輸入隨機生成的噪聲圖像到我們的生成器網絡中生成樣本圖像。我們從真實數據中提取一些樣本圖像,並將其與一些生成的圖像混合在一起。將這些混合圖像輸入到我們的鑑別器中,鑑別器將對這個混合集進行訓練並相應地更新它的權重。然後我們製作更多的假圖像,並將它們輸入到鑑別器中,但是我們將它們標記為真實的。這樣做是為了訓練生成器。我們在這個階段凍結了鑑別器的權值(鑑別器學習停止),並且我們使用來自鑑別器的反饋來更新生成器的權值。這就是我們如何教我們的生成器(製作更好的合成圖像)和鑑別器更好地識別贗品的方法。流程圖如下

對於本文,我們將使用MNIST數據集生成手寫數字。GAN的架構是:

使用KERAS實現GANS

首先,我們加載所有必要的庫

import os os.environ["KERAS_BACKEND"] = "tensorflow" import numpy as np from tqdm import tqdm import matplotlib.pyplot as plt from keras.layers import Input from keras.models import Model, Sequential from keras.layers.core import Reshape, Dense, Dropout, Flatten from keras.layers.advanced_activations import LeakyReLU from keras.layers.convolutional import Convolution2D, UpSampling2D from keras.layers.normalization import BatchNormalization from keras.datasets import mnist from keras.optimizers import Adam from keras import backend as K from keras import initializers K.set_image_dim_ordering('th') # Deterministic output. # Tired of seeing the same results every time? Remove the line below. np.random.seed(1000) # The results are a little better when the dimensionality of the random vector is only 10. # The dimensionality has been left at 100 for consistency with other GAN implementations. randomDim = 100

現在我們加載數據集。這裡使用MNIST數據集,所以不需要單獨下載和處理。

(X_train, y_train), (X_test, y_test) = mnist.load_data() X_train = (X_train.astype(np.float32) - 127.5)/127.5 X_train = X_train.reshape(60000, 784)

接下來,我們定義生成器和鑑別器的結構

# Optimizer adam = Adam(lr=0.0002, beta_1=0.5)#generator generator = Sequential() generator.add(Dense(256, input_dim=randomDim, kernel_initializer=initializers.RandomNormal(stddev=0.02))) generator.add(LeakyReLU(0.2)) generator.add(Dense(512)) generator.add(LeakyReLU(0.2)) generator.add(Dense(1024)) generator.add(LeakyReLU(0.2)) generator.add(Dense(784, activation='tanh')) generator.compile(loss='binary_crossentropy', optimizer=adam)#discriminator discriminator = Sequential() discriminator.add(Dense(1024, input_dim=784, kernel_initializer=initializers.RandomNormal(stddev=0.02))) discriminator.add(LeakyReLU(0.2)) discriminator.add(Dropout(0.3)) discriminator.add(Dense(512)) discriminator.add(LeakyReLU(0.2)) discriminator.add(Dropout(0.3)) discriminator.add(Dense(256)) discriminator.add(LeakyReLU(0.2)) discriminator.add(Dropout(0.3)) discriminator.add(Dense(1, activation='sigmoid')) discriminator.compile(loss='binary_crossentropy', optimizer=adam)

現在我們把發生器和鑑別器結合起來同時訓練。

# Combined network discriminator.trainable = False ganInput = Input(shape=(randomDim,)) x = generator(ganInput) ganOutput = discriminator(x) gan = Model(inputs=ganInput, outputs=ganOutput) gan.compile(loss='binary_crossentropy', optimizer=adam) dLosses = [] gLosses = []

三個函數,每20個epoch繪製並保存結果,並保存模型。

# Plot the loss from each batch def plotLoss(epoch): plt.figure(figsize=(10, 8)) plt.plot(dLosses, label='Discriminitive loss') plt.plot(gLosses, label='Generative loss') plt.xlabel('Epoch') plt.ylabel('Loss') plt.legend() plt.savefig('images/gan_loss_epoch_%d.png' % epoch) # Create a wall of generated MNIST images def plotGeneratedImages(epoch, examples=100, dim=(10, 10), figsize=(10, 10)): noise = np.random.normal(0, 1, size=[examples, randomDim]) generatedImages = generator.predict(noise) generatedImages = generatedImages.reshape(examples, 28, 28) plt.figure(figsize=figsize) for i in range(generatedImages.shape[0]): plt.subplot(dim[0], dim[1], i+1) plt.imshow(generatedImages[i], interpolation='nearest', cmap='gray_r') plt.axis('off') plt.tight_layout() plt.savefig('images/gan_generated_image_epoch_%d.png' % epoch) # Save the generator and discriminator networks (and weights) for later use def saveModels(epoch): generator.save('models/gan_generator_epoch_%d.h5' % epoch) discriminator.save('models/gan_discriminator_epoch_%d.h5' % epoch)

訓練函數

def train(epochs=1, batchSize=128): batchCount = X_train.shape[0] / batchSize print 'Epochs:', epochs print 'Batch size:', batchSize print 'Batches per epoch:', batchCount for e in xrange(1, epochs+1): print '-'*15, 'Epoch %d' % e, '-'*15 for _ in tqdm(xrange(batchCount)): # Get a random set of input noise and images noise = np.random.normal(0, 1, size=[batchSize, randomDim]) imageBatch = X_train[np.random.randint(0, X_train.shape[0], size=batchSize)] # Generate fake MNIST images generatedImages = generator.predict(noise) # print np.shape(imageBatch), np.shape(generatedImages) X = np.concatenate([imageBatch, generatedImages]) # Labels for generated and real data yDis = np.zeros(2*batchSize) # One-sided label smoothing yDis[:batchSize] = 0.9 # Train discriminator discriminator.trainable = True dloss = discriminator.train_on_batch(X, yDis) # Train generator noise = np.random.normal(0, 1, size=[batchSize, randomDim]) yGen = np.ones(batchSize) discriminator.trainable = False gloss = gan.train_on_batch(noise, yGen) # Store loss of most recent batch from this epoch dLosses.append(dloss) gLosses.append(gloss) if e == 1 or e % 20 == 0: plotGeneratedImages(e) saveModels(e) # Plot losses from every epoch plotLoss(e)

至此一個簡單的GAN已經完成了,完整的代碼在這裡找到

github/bhaveshgoyal27/mediumblogs/blob/master/KerasMNISTGAN.py

作者:Bhavesh Goyal

deephub翻譯組

相關焦點

  • Keras入門系列教程:兩分鐘構建你的第一個神經網絡模型
    導入tf.kerastf.keras是TensorFlow實現的 Keras API規範。這是一個用於構建和訓練模型的高級API,其中包括對TensorFlow特定功能的一流支持,例如急切執行, tf.data pipeline和estimators。
  • 十個生成模型(GANs)的最佳案例和原理 | 代碼+論文
    5、僅根據文本描述來生成圖像能否僅根據文本來自動生成逼真圖像?了解物體運動和場景動力學是計算機視覺中的一個核心問題。對於視頻識別任務(如動作分類)和視頻生成任務(如未來預測),需要構建一個能理解如何進行轉換場景的模型。然而,創建動態模型十分具有挑戰性,因為物體和場景的變化方式有很多種。這是利用一個能從背景中分離前景的模型實現的,它通過強制背景變成靜止的,並且該網絡能學習到哪些物體正在移動以及哪些處於靜止。
  • TensorFlow(Keras)中的正則化技術及其實現(附代碼)
    相反,本文介紹了一些標準的正則化方法以及如何使用TensorFlow(Keras)在神經網絡中實現它們。有關數學的更多詳細信息,Raimi Karim和Renu Khandelwal的這些文章合理地介紹了L1和L2正則化數學。
  • 初學AI神經網絡應該選擇Keras或是Pytorch框架?
    Powerful,是深度學習入門的絕佳技術路線舉個tensorflow1.0的例子(偽代碼)定義Variable、constant、placeholder等。 初始化global_variables_initializersession回話狀態。
  • 圖像分類入門,輕鬆拿下90%準確率|教你用Keras搞Fashion-MNIST
    這個數據集致力於成為手寫數字數據集MNIST的替代品,可用作機器學習算法的基準測試,也同樣適合新手入門。在TensorFlow中,可以使用tf.keras函數來編寫Keras程序,這樣就能充分利用動態圖機制eager execution和tf.data函數。下面可能還會遇到其他深度學習名詞,我們就不提前介紹啦。
  • 小白學CNN以及Keras的速成
    Keras Documentation 就是Keras的官方文檔,裡面可以查閱所有的函數,並且可以在github上看他的開原始碼,非常方便。安裝也很簡單,打開終端,輸入pip install keras 就可以等待安裝了。下面就給一個簡單的例子,來看一看Keras到底有多簡單。
  • Keras和TensorFlow究竟哪個會更好?
    我會使用基於 TensorFlow 的標準 keras 模塊和 tf.keras 模塊,來實現一個卷積神經網絡(CNN)。然後,基於一個示例數據集,來訓練這些 CNN,然後檢查所得結果,你會發現,Keras 和 TensorFlow 是可以和諧共處的。
  • TensorFlow 2.1指南:keras模式、渴望模式和圖形模式(附代碼)
    經過一些實驗後,我發現在TensorFlow 2.1中,有3種構建模型的方法:Keras模式(tf.keras):基於圖形定義,並在以後運行圖形。渴望模式:基於定義執行的所有迭代定義圖的操作。圖形模式(tf.function):之前兩種方法的混合。讓我們來看看代碼。
  • Keras 2發布:實現與TensorFlow的直接整合
    事實上,繼續發展將會出現 Keras 技術規範的兩個不同實現:(a)TensorFlow 的內部實現(如 tf.keras),純由 TensorFlow 寫成,與 TensorFlow 的所有功能深度兼容;(b)外部的多後臺實現,同時支持 Theano 和 TensorFlow(並可能在未來有更多的後臺)。
  • 用Keras和「直方圖均衡」為深度學習實現「圖像擴充」
    這麼做非常簡單,但是我在這裡省略了代碼和圖像,是因為我們在沒有看到原始圖像的情況下,無法判斷一張貓狗的圖像是否被水平翻轉了。首先,我們將輸入sic-kit圖像庫中的必要單元,然後對sci-kit圖像文件中的代碼進行修改和調整,以便查看數據集第一張圖片的擴充圖像集。
  • 從小白到入門:用Keras進行圖像基礎分類
    【IT168 資訊】在這篇文章中,將解釋一些在keras中經常需要的常見操作。首先,如何保存模型並使用它們進行預測,從數據集中顯示圖像並從加載系統中圖像並預測其類別。
  • 了解1D和3D卷積神經網絡|Keras
    但是,現實世界中還使用了其他兩種類型的卷積神經網絡,即1維CNN和3維CNN。在本指南中,我們將介紹1D和3D CNN及其在現實世界中的應用。我假設你已經大體上熟悉卷積網絡的概念。2維CNN | Conv2D這是在Lenet-5架構中首次引入的標準卷積神經網絡。Conv2D通常用於圖像數據。
  • 谷歌推出新框架:只需5行代碼,就能提高模型準確度和魯棒性
    如果用上這些數據的結構化信息,就能實現更高的模型精度,或者用更少的樣本來訓練模型,特別是在標記樣本數量相對較少的情況。另外,NSL也能用於抵禦對抗攻擊,因為對抗樣本往往是在原來樣本上做的一種微擾,利用這一層關係,可以提高模型在對抗攻擊下的魯棒性。谷歌表示,這種NSL技術是通用的,可以應用於任意神經架構,包括前饋神經網絡、CNN和RNN。
  • Keras結合Keras後端搭建個性化神經網絡模型(不用原生Tensorflow)
    它幫我們實現了一系列經典的神經網絡層(全連接層、卷積層、循環層等),以及簡潔的迭代模型的接口,讓我們能在模型層面寫代碼,從而不用仔細考慮模型各層張量之間的數據流動。但是,當我們有了全新的想法,想要個性化模型層的實現,Keras的高級API是不能滿足這一要求的,而換成Tensorflow又要重新寫很多輪子,這時,Keras的後端就派上用場了。
  • Keras官方中文版文檔正式發布了
    Keras 的一個核心原則是使事情變得相當簡單,同時又允許用戶在需要的時候能夠進行完全的控制(終極的控制是原始碼的易擴展性)。深度學習背後的思想很簡單,那麼它們的實現又何必要那麼痛苦呢?使用簡介Keras 模型的使用一般可以分為順序模型(Sequential)和 Keras 函數式 API,順序模型是多個網絡層的線性堆疊,而 Keras 函數式 API 是定義複雜模型(如多輸出模型、有向無環圖,或具有共享層的模型)的方法。
  • 初學者怎樣使用Keras進行遷移學習
    這樣,就代碼而言,該過程變得更加簡單。 必須有一個主數據文件夾,在該數據文件夾中,每個包含相應圖像的數據類必須有一個文件夾。文件夾的名稱必須是其各自類的名稱。 模型的構建是一個三步過程: 導入預先訓練的模型並添加密集層。 將數據加載到ImageDataGenerators中。 訓練和評估模型。
  • 利用遺傳算法優化GANs
    適應性強:可以改編並插入許多不同的測試和方法來操縱遺傳算法的靈活性。可以通過使代理傳播生成器網絡並使用鑑別器作為測試,在遺傳算法內創建GAN。這是一個至關重要的好處,這使我相信將來遺傳算法的使用將更加廣泛。可解釋的:對於普通的神經網絡,該算法的學習模式是不可解釋的。
  • 用TensorFlow和Keras構建卷積神經網絡
    全文共9940字,預計學習時長20分鐘或更長不同神經網絡結構各有所長。本文主要介紹如何在Python中使用TensorFlow和Keras構建卷積神經網絡。手動表達像素之間的關係是難以實現的。難以想像人應該如何徒手釐清像素之間的關係!想要真正理解每一個卷積對圖片的作用,強烈推薦此網站:http://setosa.io/ev/image-kernels/。它比任何一本書或教程的幫助都大。之前已經介紹到了一些理論。現在進入到實踐環節。
  • 人工智慧算法:訓練神經網絡中的批量歸一化(附代碼)
    而且,如果您還沒有這樣做的話,本文將解釋BN的基本直覺,包括其起源以及如何使用TensorFlow和Keras在神經網絡中實現它。對於那些熟悉BN技術並且只想專注於實現的人,可以跳到下面的「代碼」部分。
  • 使用Keras構建具有自定義結構和層次圖卷積神經網絡
    來源:DeepHub IMBA本文約3600字,建議閱讀5分鐘本文為你介紹了如何構建具有自定義結構和層次的神經網絡:Keras中的圖卷積神經網絡(GCNN)。正如你可以從上面的代碼中推斷出的那樣,對於每個模型,我們將執行50次迭代,在每次迭代中,我們將隨機選擇一個標記為10%的集合(訓練集),並對模型進行100個epoch的訓練。需要指出的是,本教程的範圍不是訓練CORA數據集上最精確的模型。相反,我們只是想提供一個使用keras自定義層實現自定義模型的示例!