作者|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/