用Keras構建神經網路的3種方法
作者|Orhan Gazi Yalçın
編譯|VK
來源|Towards Datas Science
如果你看看不同的教程,搜尋,花大量時間研究關於TensorFlow的Stack Overflow,你可能已經意識到有很多不同的方法來構建神經網路模型。
這一直是TensorFlow面臨的問題。這就像是TensorFlow試圖找到通往光明的深度學習環境的道路。由於TensorFlow是目前市場上最成熟的深度學習庫,這基本上是你能得到的最好的。
Keras-TensorFlow的關係
背景
TensorFlow發展成為一個深度學習平臺並不是一夜之間發生的。最初,TensorFlow將自己推銷為一個符號數學庫,用於跨一系列任務的資料流程式設計。因此,TensorFlow最初提供的主張並不是一個純粹的機器學習庫。目標是建立一個高效的數學庫,以便在這種高效結構上構建的自定義機器學習演算法能夠在短時間內以高精度進行訓練。
然而,用低階api重複地從頭構建模型並不是很理想。因此,谷歌的工程師弗蘭•庫伊斯-克里特開發了Keras,作為一個獨立的高層次的深度學習庫。雖然Keras已經能夠執行在不同的庫之上,比如TensorFlow, Microsoft Cognitive Toolkit, Theano 或 PlaidML,但是TensorFlow過去和現在仍然是人們使用Keras的最常見的庫。
現狀
在看到了模型構建過程中的混亂之後,TensorFlow團隊宣佈Keras將成為在tensorflow2.0中構建和訓練模型的核心高階API。另一種高階API,Estimator api
Estimator API和Keras API
現在,讓我們回到問題上來:有很多不同的方法,人們使用TensorFlow來構建他們的模型。這個問題的主要原因是TensorFlow未能採用單一模型API。
在1.x版本中,對於生產級專案,模型構建API是Estimator API。但是,隨著最近的變化,keras api幾乎趕上了Estimator API。最初,Estimator API具有更高的可伸縮性,允許分散式,並且具有方便的跨平臺功能。然而,現在Estimator API的大部分優點都已被消除,因此,很快Keras API將很可能成為構建TensorFlow模型的唯一標準API。
因此,在本文中,我們將只關注在TensorFlow中構建模型的Keras API方法,其中有三種:
-
使用Sequential API
-
使用Functional API
-
模型子類化
我將直接將它們與相應的模型構建程式碼進行比較,這樣你就可以實際測試它們了。讓我們深入研究編碼。
進行比較的初始程式碼
為了測試這三種Keras方法,我們需要選擇一個深度學習問題。利用MNIST進行影象分類是一個非常簡單的任務。我們試圖實現的是利用著名的MNIST資料集訓練一個識別手寫數字的模型。
MNIST資料集(MNIST dataset)是一個大型手寫數字資料庫,通常用於訓練各種影象處理系統。MNIST資料庫包含6萬張訓練圖片和1萬張測試圖片,這些圖片來自美國人口普查局員工和美國高中生。如果你想遵循完整的教程,你可以找到我的關於影象分類的單獨教程:
https://towardsdatascience.com/image-classification-in-10-minutes-with-mnist-dataset-54c35b77a38d
通過下面的程式碼,我們將匯入所有層和模型,這樣在接下來的部分中就不會打擾我們了。我們還下載MNIST資料集並對其進行預處理,以便它可以用於我們將使用這三種不同方法構建的所有模型。只需執行以下程式碼:
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras import Input
from tensorflow.keras import Model
from tensorflow.estimator import DNNClassifier
from tensorflow.keras.datasets.mnist import load_data
(x_train, y_train), (x_test, y_test)= load_data( path="mnist.npz" )
# 確保這些值是浮點數,這樣除法後就可以得到小數點
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
# 通過將RGB程式碼除以最大RGB值來規範化
x_train /= 255
x_test /= 255
現在,這一部分已經結束,讓我們集中討論構建張量流模型的三種方法。
構建Keras模型的3種方法
有三種方法可以在TensorFlow中構建Keras模型:
-
Sequential API:當你試圖使用單個輸入、輸出和層分支構建簡單模型時,Sequential API是最好的方法。對於想快速學習的新手來說,這是一個很好的選擇。
-
Functional API:函式API是構建Keras模型最流行的方法。它可以完成Sequential API所能做的一切。此外,它允許多個輸入、多個輸出、分支和層共享。它是一種簡潔易用的方法,並且仍然允許很好的定製靈活性。
-
模型子類化:模型子類化是為需要完全控制模型、層和訓練過程的高階開發人員設計的。你需要建立一個定義模型的自定義類,而且你可能不需要它來執行日常任務。但是,如果你是一個有實驗需求的研究人員,那麼模型子類化可能是最好的選擇,因為它會給你所有你需要的靈活性。
讓我們看看這些方法是如何實現的。我們將建立一個具有單一平坦層的基本前饋神經網路,將二維影象陣列轉換為一維陣列和兩個全連線層。
Sequential API
在Sequential API中,我們需要tf.keras.Models模組。我們可以簡單地將下面的所有層作為一個單獨的層來傳遞。如你所見,這很簡單。
model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(256,'relu'),
Dense(10, "softmax"),
])
Functional API
對於Functional API,我們需要單獨定義我們的輸入。然後,我們需要建立一個輸出物件,同時建立所有層,這些層相互關聯並與輸出相關聯。最後,我們建立一個接受輸入和輸出作為引數的模型物件。程式碼仍然非常乾淨,但是我們在Functional API中有了更大的靈活性。
inputs = Input(shape=(28, 28))
x = Flatten()(inputs)
x = Dense(256, "relu")(x)
outputs = Dense(10, "softmax")(x)
model = Model(inputs=inputs, outputs=outputs, name="mnist_model")
模型子類化
讓我們繼續討論模型子類化。在模型子類化中,我們從建立一個擴充套件類基於tf.keras.Model 。模型子類化有兩個關鍵功能:
__init__
函式充當建構函式。多虧了__init__
,我們可以初始化模型的屬性(例如,layer)。super呼叫父建構函式( tf.keras.Model中的建構函式)self用於引用例項屬性。- call function是在定義層之後定義操作的地方。
為了使用模型子類化來構建同一個模型,我們需要編寫更多的程式碼,如下所示:
class CustomModel(tf.keras.Model):
def __init__(self, **kwargs):
super(CustomModel, self).__init__(**kwargs)
self.layer_1 = Flatten()
self.layer_2 = Dense(256, "relu")
self.layer_3 = Dense(10, "softmax")
def call(self, inputs):
x = self.layer_1(inputs)
x = self.layer_2(x)
x = self.layer_3(x)
return x
model = CustomModel(name='mnist_model')
結尾程式碼
現在你可以用三種不同的方法建立同一個模型,你可以選擇其中任何一個,構建模型,並執行下面的程式碼。
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x=x_train,y=y_train, epochs=10)
model.evaluate(x_test, y_test)
上面的行負責模型配置、訓練和評估。當我們比較這三種方法的效能時,我們發現它們非常接近,但略有不同。
Method | Sequential API | Functional API | Model Subclassing |
---|---|---|---|
Loss | 0.08746038377285004 | 0.08131594955921173 | 0.0781003013253212 |
Accuracy | 97.82% | 98.06% | 98.20% |
我們更復雜的模型子類化方法優於Sequential API和Functional API。這表明,這些方法在低端的設計上也有細微差別。然而,這些差異可以忽略不計。
最終評估
現在,你已經瞭解了這三種Keras方法之間的異同。但是,讓我們用一個表格來總結一下:
Feature | Sequential API | Functional API | Model Subclassing |
---|---|---|---|
Customization | Low | Medium | High |
Difficulty to Build | Easy | Medium | Difficult |
Layer Sharing | No | Yes | Yes |
Multiple Branch | No | Yes | Yes |
Multiple Input | No | Yes | Yes |
Multiple Output | No | Yes | Yes |
Best Suited For | Beginners | Professionals | Resarchers |
總之,如果你剛剛起步,請堅持使用Sequential API。在深入研究更復雜的模型時,請嘗試Functional API。如果你正在攻讀博士學位,或者只是喜歡進行獨立研究,試試模型子類化。如果你是專業人士,請堅持使用Functional API。它可能會滿足你的需要。
歡迎關注磐創AI部落格站:
http://panchuang.net/
sklearn機器學習中文官方文件:
http://sklearn123.com/
歡迎關注磐創部落格資源彙總站:
http://docs.panchuang.net/