注:本系列所有部落格將持續更新併發布在github上,您可以通過github下載本系列所有文章筆記檔案。

 

Keras是一個基於Python編寫的高層神經網路API,憑藉使用者友好性、模組化以及易擴充套件等有點大受好評,考慮到Keras的優良特性以及它的受歡迎程度,TensorFlow2.0中將Keras的程式碼吸收了進來,化身為tf.keras模組供使用者使用。

使用tf.keras提供的高層API,可以輕鬆得完成建模三部曲——模型構建、訓練、評估等工作。下面我們分別來說說如何使用tf.keras完成這三部曲。

 

1 模型構建¶

 

我們知道,神經網路模型就是層的堆疊,tf.keras提供的Sequential類物件就是層容器,可以輕鬆實現對層的堆疊,建立網路模型。用Sequential建立一個全連線網路模型:

In [3]:
import tensorflow as tf
from tensorflow import keras  # 為方便使用,keras一般單獨匯入
from tensorflow.keras import layers
In [2]:
model = tf.keras.Sequential()
# 往模型中新增一個有64個神經元組成的層,啟用函式為relu:
model.add(layers.Dense(64, activation='relu'))
# 再新增一個:
model.add(layers.Dense(64, activation='relu'))
# 新增一個有10個神經元的softmax層作為輸出層:
model.add(layers.Dense(10, activation='softmax'))
 

也可以在使用Sequential例項化模型時,通過傳入由層組成的列表來新增層。我們換一種方式實現上面的模型構建過程,兩種方式是完全等效的:

In [6]:
model = tf.keras.Sequential([
    layers.Dense(64, activation='relu'),
    layers.Dense(64, activation='relu'),
    layers.Dense(10, activation='softmax')]
)
 

你看,用tf.keras建立一個模型,就是這麼簡單,只需要往Sequential中傳入一個個tf.keras.layers定義的層就好了。進一步的,我們研究一下tf.keras.layers怎麼個性化地建立層。

 

定義神經網路層通過tf.keras.layers模組中的Dense類實現,Dense類構造引數如下:

  • units:指定神經元個數,必須是一個正整數。
  • activation:啟用函式,可以是可以是一個可呼叫物件或標識一個物件的字串
  • use_bias:布林型,是否使用是否使用偏置項
  • kernel_initializer和bias_initializer:權值、偏置初始化方法,可以是一個可呼叫物件或標識一個物件的字串
  • kernel_regularizer和bias_regularizer:對權值、偏置進行正則化的方法,可以是一個可呼叫物件或標識一個物件的字串
  • activity_regularizer:對層的輸出進行正則化的方法,可以是一個可呼叫物件或標識一個物件的字串
  • kernel_constraint和bias_constraint:對權值矩陣、偏置矩陣的約束方法,可以是一個可呼叫物件或標識一個物件的字串
In [6]:
# 有64個神經元,啟用函式為sigmoid的層
layers.Dense(64, activation='sigmoid')
# 或者:
layers.Dense(64, activation=tf.keras.activations.sigmoid)

# 對權值矩陣進行正則化:
layers.Dense(64, kernel_regularizer=tf.keras.regularizers.l1(0.01))

# 對偏置向量進行正則化:
layers.Dense(64, bias_regularizer=tf.keras.regularizers.l2(0.01))

# 指定權值隨機正交初始化:
layers.Dense(64, kernel_initializer='orthogonal')

# 指定偏置為常數:
layers.Dense(64, bias_initializer=tf.keras.initializers.Constant(2.0))
Out[6]:
<tensorflow.python.keras.layers.core.Dense at 0x7f486247abd0>
 

2 訓練模型¶

2.1 配置:compile()¶

 

建立好模型之後,接下來當然是要進行訓練模型了。不過,在訓練前還需要做一些配置工作,例如指定優化器、損失函式、評估指標等,這些配置引數的過程一般通過tf.keras.Model.compile方法進行,先來熟悉一下tf.keras.Model.compile方法的三個常用引數:

  • optimizer:tf.keras.optimizers模組中的優化器例項化物件,例如 tf.keras.optimizers.Adam或 tf.keras.optimizers.SGD的例項化物件,當然也可以使用字串來指代優化器,例如'adam'和'sgd'。
  • loss:損失函式,例如交叉熵、均方差等,通常是tf.keras.losses模組中定義的可呼叫物件,也可以用用於指代損失函式的字串。
  • metrics:元素為評估方法的list,通常是定義在tf.keras.metrics模組中定義的可呼叫物件,也可以用於指代評估方法的字串。
 

在知道怎麼配置模型訓練引數後,就可以根據實際應用情況合理選擇優化器、損失函式、評估方法等:

In [7]:
# 迴歸模型
model.compile(optimizer=tf.keras.optimizers.Adam(0.01),  # 指定優化器,學習率為0.01
              loss='mse',       # 指定均方差作為損失函式
              metrics=['mae'])  # 新增絕對值誤差作為評估方法

# 分類模型
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.01),
              loss=tf.keras.losses.CategoricalCrossentropy(),  # 分類模型多用交叉熵作為損失函式
              metrics=[tf.keras.metrics.CategoricalAccuracy()])
 

通過compile()配置好模型後,就可以開始訓練了。tf.keras中提供了fit()方法對模型進行訓練,先來看看fit()方法的主要引數:

  • x和y:訓練資料和目標資料
  • epochs:訓練週期數,每一個週期都是對訓練資料集的一次完整迭代
  • batch_size:簇的大小,一般在資料集是numpy陣列型別時使用
  • validation_data:驗證資料集,模型訓練時,如果你想通過一個額外的驗證資料集來監測模型的效能變換,就可以通過這個引數傳入驗證資料集
  • verbose:日誌顯示方式,verbose=0為不在標準輸出流輸出日誌資訊,verbose=1為輸出進度條記錄,verbose=2為每個epoch輸出一行記錄
  • callbacks:回撥方法組成的列表,一般是定義在tf.keras.callbacks中的方法
  • validation_split:從訓練資料集抽取部分資料作為驗證資料集的比例,是一個0到1之間的浮點數。這一引數在輸入資料為dataset物件、生成器、keras.utils.Sequence物件是無效。
  • shuffle:是否在每一個週期開始前打亂資料
 

下面分別說說如何使用fit()方法結合numpy資料和tf.data.Dataset資料進行模型訓練。

In [8]:
import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

model.fit(data, labels, epochs=10, batch_size=32)
 
Train on 1000 samples
Epoch 1/10
1000/1000 [==============================] - 1s 554us/sample - loss: 206.2688 - categorical_accuracy: 0.1050
Epoch 2/10
1000/1000 [==============================] - 0s 34us/sample - loss: 911.8347 - categorical_accuracy: 0.0990
Epoch 3/10
1000/1000 [==============================] - 0s 30us/sample - loss: 1879.7505 - categorical_accuracy: 0.0980
Epoch 4/10
1000/1000 [==============================] - 0s 28us/sample - loss: 3141.3959 - categorical_accuracy: 0.0940
Epoch 5/10
1000/1000 [==============================] - 0s 36us/sample - loss: 4673.7791 - categorical_accuracy: 0.1010
Epoch 6/10
1000/1000 [==============================] - 0s 36us/sample - loss: 6526.8757 - categorical_accuracy: 0.0960
Epoch 7/10
1000/1000 [==============================] - 0s 31us/sample - loss: 8571.8533 - categorical_accuracy: 0.1020
Epoch 8/10
1000/1000 [==============================] - 0s 33us/sample - loss: 11070.1039 - categorical_accuracy: 0.0970
Epoch 9/10
1000/1000 [==============================] - 0s 36us/sample - loss: 13533.4661 - categorical_accuracy: 0.1050
Epoch 10/10
1000/1000 [==============================] - 0s 25us/sample - loss: 17259.2291 - categorical_accuracy: 0.1000
Out[8]:
<tensorflow.python.keras.callbacks.History at 0x7f74a4755650>
 

如何使用驗證資料集的話,可以這樣:

In [10]:
import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

val_data = np.random.random((100, 32))
val_labels = np.random.random((100, 10))

model.fit(data, labels, epochs=10, batch_size=32,
          validation_data=(val_data, val_labels))  # 驗證資料集以元組的形式傳入
 
Train on 1000 samples, validate on 100 samples
Epoch 1/10
1000/1000 [==============================] - 0s 34us/sample - loss: 67219.8359 - categorical_accuracy: 0.0960 - val_loss: 55306.6777 - val_categorical_accuracy: 0.1000
Epoch 2/10
1000/1000 [==============================] - 0s 32us/sample - loss: 73732.5724 - categorical_accuracy: 0.0920 - val_loss: 89920.2088 - val_categorical_accuracy: 0.1100
Epoch 3/10
1000/1000 [==============================] - 0s 50us/sample - loss: 79956.1480 - categorical_accuracy: 0.1020 - val_loss: 101092.6750 - val_categorical_accuracy: 0.1000
Epoch 4/10
1000/1000 [==============================] - 0s 36us/sample - loss: 84322.9844 - categorical_accuracy: 0.0970 - val_loss: 117610.5700 - val_categorical_accuracy: 0.1000
Epoch 5/10
1000/1000 [==============================] - 0s 38us/sample - loss: 91992.0751 - categorical_accuracy: 0.1130 - val_loss: 94200.0838 - val_categorical_accuracy: 0.1000
Epoch 6/10
1000/1000 [==============================] - 0s 38us/sample - loss: 97189.2044 - categorical_accuracy: 0.0910 - val_loss: 89020.5294 - val_categorical_accuracy: 0.1100
Epoch 7/10
1000/1000 [==============================] - 0s 33us/sample - loss: 107109.9905 - categorical_accuracy: 0.0930 - val_loss: 102350.4259 - val_categorical_accuracy: 0.1200
Epoch 8/10
1000/1000 [==============================] - 0s 41us/sample - loss: 114450.2496 - categorical_accuracy: 0.1010 - val_loss: 102719.3653 - val_categorical_accuracy: 0.1100
Epoch 9/10
1000/1000 [==============================] - 0s 41us/sample - loss: 124694.8415 - categorical_accuracy: 0.0950 - val_loss: 142269.8362 - val_categorical_accuracy: 0.1100
Epoch 10/10
1000/1000 [==============================] - 0s 44us/sample - loss: 131952.7791 - categorical_accuracy: 0.0800 - val_loss: 158925.8294 - val_categorical_accuracy: 0.0900
Out[10]:
<tensorflow.python.keras.callbacks.History at 0x7f749c548810>
 

3 評估與預測¶

 

是騾子是馬,拉出來溜溜就知道了,訓練好的模型效能如何,評估測試一下就知道了。可以使用模型自帶的evaluate()方法和predict()方法對模型進行評估和預測。

In [12]:
# 如果是numpy資料,可以這麼使用
data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

model.evaluate(data, labels, batch_size=32)
 
1000/1 [=================================================] - 0s 17us/sample - loss: 161163.7180 - categorical_accuracy: 0.0930
Out[12]:
[153591.27975, 0.093]
In [13]:
# 如果數Dataset物件,可以這麼使用
dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)

model.evaluate(dataset)
 
32/32 [==============================] - 0s 579us/step - loss: 153946.2378 - categorical_accuracy: 0.0930
Out[13]:
[153946.23779296875, 0.093]
 

使用predict()方法進行預測:

In [14]:
# numpy資料
result = model.predict(data, batch_size=32)
print(result.shape)
 
(1000, 10)
In [16]:
# dataset資料
result = model.predict(dataset)
print(result.shape)
 
(1000, 10)
<