注:本系列所有博客將持續更新並發布在github上,您可以通過github下載本系列所有文章筆記文件。
Keras是一個基於Python編寫的高層神經網絡API,憑借用戶友好性、模塊化以及易擴展等有點大受好評,考慮到Keras的優良特性以及它的受歡迎程度,TensorFlow2.0中將Keras的代碼吸收了進來,化身為tf.keras模塊供用戶使用。
使用tf.keras提供的高層API,可以輕松得完成建模三部曲——模型構建、訓練、評估等工作。下面我們分別來說說如何使用tf.keras完成這三部曲。
1 模型構建¶
我們知道,神經網絡模型就是層的堆疊,tf.keras提供的Sequential類對象就是層容器,可以輕松實現對層的堆疊,創建網絡模型。用Sequential創建一個全連接網絡模型:
import tensorflow as tf
from tensorflow import keras # 為方便使用,keras一般單獨導入
from tensorflow.keras import layers
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實例化模型時,通過傳入由層組成的列表來添加層。我們換一種方式實現上面的模型構建過程,兩種方式是完全等效的:
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:對權值矩陣、偏置矩陣的約束方法,可以是一個可調用對象或標識一個對象的字符串
# 有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))
<tensorflow.python.keras.layers.core.Dense at 0x7f486247abd0>
建立好模型之后,接下來當然是要進行訓練模型了。不過,在訓練前還需要做一些配置工作,例如指定優化器、損失函數、評估指標等,這些配置參數的過程一般通過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模塊中定義的可調用對象,也可以用於指代評估方法的字符串。
在知道怎么配置模型訓練參數后,就可以根據實際應用情況合理選擇優化器、損失函數、評估方法等:
# 回歸模型
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數據進行模型訓練。
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
<tensorflow.python.keras.callbacks.History at 0x7f74a4755650>
如何使用驗證數據集的話,可以這樣:
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
<tensorflow.python.keras.callbacks.History at 0x7f749c548810>
3 評估與預測¶
是騾子是馬,拉出來溜溜就知道了,訓練好的模型性能如何,評估測試一下就知道了。可以使用模型自帶的evaluate()方法和predict()方法對模型進行評估和預測。
# 如果是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
[153591.27975, 0.093]
# 如果數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
[153946.23779296875, 0.093]
使用predict()方法進行預測:
# numpy數據
result = model.predict(data, batch_size=32)
print(result.shape)
(1000, 10)
# dataset數據
result = model.predict(dataset)
print(result.shape)
(1000, 10)