Keras - 模型編譯



前面我們學習瞭如何使用Sequential和Functional API建立模型的基礎知識。本章解釋如何編譯模型。編譯是建立模型的最後一步。編譯完成後,我們可以進入訓練階段。

讓我們學習一些有助於更好地理解編譯過程的概念。

損失函式 (Loss)

在機器學習中,損失函式用於查詢學習過程中的誤差或偏差。Keras在模型編譯過程中需要損失函式。

Keras在losses模組中提供了相當多的損失函式,它們如下:

  • 均方誤差 (mean_squared_error)
  • 平均絕對誤差 (mean_absolute_error)
  • 平均絕對百分比誤差 (mean_absolute_percentage_error)
  • 均方對數誤差 (mean_squared_logarithmic_error)
  • 平方鉸鏈損失 (squared_hinge)
  • 鉸鏈損失 (hinge)
  • 分類鉸鏈損失 (categorical_hinge)
  • 對數餘弦損失 (logcosh)
  • Huber損失 (huber_loss)
  • 分類交叉熵 (categorical_crossentropy)
  • 稀疏分類交叉熵 (sparse_categorical_crossentropy)
  • 二元交叉熵 (binary_crossentropy)
  • Kullback-Leibler 散度 (kullback_leibler_divergence)
  • 泊松損失 (poisson)
  • 餘弦相似度 (cosine_proximity)
  • is_categorical_crossentropy

所有上述損失函式都接受兩個引數:

  • y_true - 真實標籤(張量)

  • y_pred - 預測值,形狀與y_true相同

使用損失函式前,請按如下所示匯入losses模組:

from keras import losses

最佳化器 (Optimizer)

在機器學習中,最佳化是一個重要的過程,它透過比較預測值和損失函式來最佳化輸入權重。Keras提供了一些最佳化器,它們位於optimizers模組中,如下所示:

SGD - 隨機梯度下降最佳化器。

keras.optimizers.SGD(learning_rate = 0.01, momentum = 0.0, nesterov = False)

RMSprop - RMSProp 最佳化器。

keras.optimizers.RMSprop(learning_rate = 0.001, rho = 0.9)

Adagrad - Adagrad 最佳化器。

keras.optimizers.Adagrad(learning_rate = 0.01)

Adadelta - Adadelta 最佳化器。

keras.optimizers.Adadelta(learning_rate = 1.0, rho = 0.95)

Adam - Adam 最佳化器。

keras.optimizers.Adam(
   learning_rate = 0.001, beta_1 = 0.9, beta_2 = 0.999, amsgrad = False
)

Adamax - 來自Adam的Adamax最佳化器。

keras.optimizers.Adamax(learning_rate = 0.002, beta_1 = 0.9, beta_2 = 0.999)

Nadam - Nesterov Adam 最佳化器。

keras.optimizers.Nadam(learning_rate = 0.002, beta_1 = 0.9, beta_2 = 0.999)

使用最佳化器前,請按如下所示匯入optimizers模組:

from keras import optimizers

指標 (Metrics)

在機器學習中,指標用於評估模型的效能。它類似於損失函式,但不用於訓練過程。Keras在metrics模組中提供了相當多的指標,它們如下:

  • 準確率 (accuracy)
  • 二元準確率 (binary_accuracy)
  • 分類準確率 (categorical_accuracy)
  • 稀疏分類準確率 (sparse_categorical_accuracy)
  • top_k 分類準確率 (top_k_categorical_accuracy)
  • 稀疏 top_k 分類準確率 (sparse_top_k_categorical_accuracy)
  • 餘弦相似度 (cosine_proximity)
  • 克隆指標 (clone_metric)

與損失函式類似,指標也接受以下兩個引數:

  • y_true - 真實標籤(張量)

  • y_pred - 預測值,形狀與y_true相同

使用指標前,請按如下所示匯入metrics模組:

from keras import metrics

編譯模型

Keras模型提供了一個方法compile()來編譯模型。compile()方法的引數及其預設值如下所示:

compile(
   optimizer, 
   loss = None, 
   metrics = None, 
   loss_weights = None, 
   sample_weight_mode = None, 
   weighted_metrics = None, 
   target_tensors = None
)

重要的引數如下:

  • 損失函式
  • 最佳化器 (Optimizer)
  • 指標

編譯模型的示例程式碼如下:

from keras import losses 
from keras import optimizers 
from keras import metrics 

model.compile(loss = 'mean_squared_error',  
   optimizer = 'sgd', metrics = [metrics.categorical_accuracy])

其中:

  • 損失函式設定為mean_squared_error

  • 最佳化器設定為sgd

  • 指標設定為metrics.categorical_accuracy

模型訓練

模型使用NumPy陣列透過fit()進行訓練。此fit函式的主要目的是用於評估模型的訓練情況。這也可用於繪製模型效能圖。其語法如下:

model.fit(X, y, epochs = , batch_size = )

這裡:

  • X, y - 用於評估資料的元組。

  • epochs - 訓練期間需要評估模型的次數。

  • batch_size - 訓練例項數。

讓我們來看一個使用numpy隨機資料的簡單示例來理解這個概念。

建立資料

讓我們使用以下命令使用numpy建立x和y的隨機資料:

import numpy as np 

x_train = np.random.random((100,4,8)) 
y_train = np.random.random((100,10))

現在,建立隨機驗證資料:

x_val = np.random.random((100,4,8)) 
y_val = np.random.random((100,10))

建立模型

讓我們建立一個簡單的順序模型:

from keras.models import Sequential model = Sequential()

新增層

建立要新增到模型的層:

from keras.layers import LSTM, Dense 

# add a sequence of vectors of dimension 16 
model.add(LSTM(16, return_sequences = True)) 
model.add(Dense(10, activation = 'softmax'))

編譯模型

現在模型已定義。您可以使用以下命令進行編譯:

model.compile(
   loss = 'categorical_crossentropy', optimizer = 'sgd', metrics = ['accuracy']
)

應用fit()

現在我們應用fit()函式來訓練我們的資料:

model.fit(x_train, y_train, batch_size = 32, epochs = 5, validation_data = (x_val, y_val))

建立多層感知器人工神經網路 (Multi-Layer Perceptron ANN)

我們已經學習瞭如何建立、編譯和訓練Keras模型。

讓我們運用我們的知識,建立一個基於簡單的MPL的人工神經網路。

資料集模組 (Dataset module)

在建立模型之前,我們需要選擇一個問題,需要收集所需的資料並將資料轉換為NumPy陣列。收集資料後,我們可以準備模型並使用收集到的資料進行訓練。資料收集是機器學習中最困難的階段之一。Keras提供了一個特殊的模組datasets,用於下載線上機器學習資料以進行訓練。它從線上伺服器獲取資料,處理資料並將資料作為訓練集和測試集返回。讓我們檢查Keras資料集模組提供的資料。該模組中提供的資料如下:

  • CIFAR10 小型影像分類
  • CIFAR100 小型影像分類
  • IMDB 電影評論情感分類
  • 路透社新聞主題分類
  • MNIST 手寫數字資料庫
  • Fashion-MNIST 時尚服裝資料庫
  • 波士頓房價迴歸資料集

讓我們使用MNIST 手寫數字資料庫 (或minst) 作為我們的輸入。minst包含60,000張28x28的灰度影像。它包含10個數字。它還包含10,000張測試影像。

可以使用以下程式碼載入資料集:

from keras.datasets import mnist 

(x_train, y_train), (x_test, y_test) = mnist.load_data()

其中

  • 第1行從keras資料集模組匯入minst

  • 第3行呼叫load_data函式,該函式將從線上伺服器獲取資料,並將其作為2個元組返回。第一個元組(x_train, y_train)表示形狀為(樣本數, 28, 28)的訓練資料及其形狀為(樣本數,)的數字標籤。第二個元組(x_test, y_test)表示形狀相同的測試資料。

其他資料集也可以使用類似的API獲取,並且每個API返回的資料都類似,只是資料的形狀不同。資料的形狀取決於資料的型別。

建立模型

讓我們選擇一個簡單的多層感知器 (MLP),如下所示,並嘗試使用Keras建立模型。

Create Model

模型的核心特徵如下:

  • 輸入層包含784個值 (28 x 28 = 784)。

  • 第一個隱藏層Dense包含512個神經元和“relu”啟用函式。

  • 第二個隱藏層Dropout的值為0.2。

  • 第三個隱藏層,同樣是Dense,包含512個神經元和“relu”啟用函式。

  • 第四個隱藏層Dropout的值為0.2。

  • 第五個也是最後一層包含10個神經元和“softmax”啟用函式。

  • 使用categorical_crossentropy作為損失函式。

  • 使用RMSprop()作為最佳化器。

  • 使用accuracy作為指標。

  • 使用128作為批次大小。

  • 使用20作為輪數。

步驟1 - 匯入模組

讓我們匯入必要的模組。

import keras 
from keras.datasets import mnist 
from keras.models import Sequential 
from keras.layers import Dense, Dropout 
from keras.optimizers import RMSprop 
import numpy as np

步驟2 - 載入資料

讓我們匯入mnist資料集。

(x_train, y_train), (x_test, y_test) = mnist.load_data()

步驟3 - 處理資料

讓我們根據我們的模型更改資料集,以便它可以饋送到我們的模型中。

x_train = x_train.reshape(60000, 784) 
x_test = x_test.reshape(10000, 784) 
x_train = x_train.astype('float32') 
x_test = x_test.astype('float32') 
x_train /= 255 
x_test /= 255 

y_train = keras.utils.to_categorical(y_train, 10) 
y_test = keras.utils.to_categorical(y_test, 10)

其中

  • reshape用於將輸入從(28, 28)元組重塑為(784,)。

  • to_categorical用於將向量轉換為二元矩陣。

步驟4 - 建立模型

讓我們建立實際的模型。

model = Sequential() 
model.add(Dense(512, activation = 'relu', input_shape = (784,))) 
model.add(Dropout(0.2)) 
model.add(Dense(512, activation = 'relu'))
model.add(Dropout(0.2)) 
model.add(Dense(10, activation = 'softmax'))

步驟5 - 編譯模型

讓我們使用選擇的損失函式、最佳化器和指標來編譯模型。

model.compile(loss = 'categorical_crossentropy',     
   optimizer = RMSprop(), 
   metrics = ['accuracy'])

步驟6 - 訓練模型

讓我們使用fit()方法訓練模型。

history = model.fit(
   x_train, y_train, 
   batch_size = 128, 
   epochs = 20, 
   verbose = 1, 
   validation_data = (x_test, y_test)
)

最終想法

我們已經建立了模型,載入了資料,並將資料訓練到模型中。我們仍然需要評估模型並預測未知輸入的輸出,這將在接下來的章節中學習。

import keras 
from keras.datasets import mnist 
from keras.models import Sequential 
from keras.layers import Dense, Dropout 
from keras.optimizers import RMSprop 
import numpy as np 

(x_train, y_train), (x_test, y_test) = mnist.load_data() 

x_train = x_train.reshape(60000, 784) 
x_test = x_test.reshape(10000, 784) 
x_train = x_train.astype('float32') 
x_test = x_test.astype('float32') 
x_train /= 255 
x_test /= 255 

y_train = keras.utils.to_categorical(y_train, 10) 
y_test = keras.utils.to_categorical(y_test, 10) 

model = Sequential() 
model.add(Dense(512, activation='relu', input_shape = (784,))) 
model.add(Dropout(0.2)) 
model.add(Dense(512, activation = 'relu')) model.add(Dropout(0.2)) 
model.add(Dense(10, activation = 'softmax'))
model.compile(loss = 'categorical_crossentropy', 
   optimizer = RMSprop(), 
   metrics = ['accuracy']) 

history = model.fit(x_train, y_train, 
   batch_size = 128, epochs = 20, verbose = 1, validation_data = (x_test, y_test))

執行應用程式將給出以下內容作為輸出:

Train on 60000 samples, validate on 10000 samples Epoch 1/20 
60000/60000 [==============================] - 7s 118us/step - loss: 0.2453 
- acc: 0.9236 - val_loss: 0.1004 - val_acc: 0.9675 Epoch 2/20 
60000/60000 [==============================] - 7s 110us/step - loss: 0.1023 
- acc: 0.9693 - val_loss: 0.0797 - val_acc: 0.9761 Epoch 3/20 
60000/60000 [==============================] - 7s 110us/step - loss: 0.0744 
- acc: 0.9770 - val_loss: 0.0727 - val_acc: 0.9791 Epoch 4/20 
60000/60000 [==============================] - 7s 110us/step - loss: 0.0599 
- acc: 0.9823 - val_loss: 0.0704 - val_acc: 0.9801 Epoch 5/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0504 
- acc: 0.9853 - val_loss: 0.0714 - val_acc: 0.9817 Epoch 6/20 
60000/60000 [==============================] - 7s 111us/step - loss: 0.0438 
- acc: 0.9868 - val_loss: 0.0845 - val_acc: 0.9809 Epoch 7/20 
60000/60000 [==============================] - 7s 114us/step - loss: 0.0391 
- acc: 0.9887 - val_loss: 0.0823 - val_acc: 0.9802 Epoch 8/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0364 
- acc: 0.9892 - val_loss: 0.0818 - val_acc: 0.9830 Epoch 9/20 
60000/60000 [==============================] - 7s 113us/step - loss: 0.0308 
- acc: 0.9905 - val_loss: 0.0833 - val_acc: 0.9829 Epoch 10/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0289 
- acc: 0.9917 - val_loss: 0.0947 - val_acc: 0.9815 Epoch 11/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0279 
- acc: 0.9921 - val_loss: 0.0818 - val_acc: 0.9831 Epoch 12/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0260 
- acc: 0.9927 - val_loss: 0.0945 - val_acc: 0.9819 Epoch 13/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0257 
- acc: 0.9931 - val_loss: 0.0952 - val_acc: 0.9836 Epoch 14/20
60000/60000 [==============================] - 7s 112us/step - loss: 0.0229 
- acc: 0.9937 - val_loss: 0.0924 - val_acc: 0.9832 Epoch 15/20 
60000/60000 [==============================] - 7s 115us/step - loss: 0.0235 
- acc: 0.9937 - val_loss: 0.1004 - val_acc: 0.9823 Epoch 16/20 
60000/60000 [==============================] - 7s 113us/step - loss: 0.0214 
- acc: 0.9941 - val_loss: 0.0991 - val_acc: 0.9847 Epoch 17/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0219 
- acc: 0.9943 - val_loss: 0.1044 - val_acc: 0.9837 Epoch 18/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0190 
- acc: 0.9952 - val_loss: 0.1129 - val_acc: 0.9836 Epoch 19/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0197 
- acc: 0.9953 - val_loss: 0.0981 - val_acc: 0.9841 Epoch 20/20 
60000/60000 [==============================] - 7s 112us/step - loss: 0.0198 
- acc: 0.9950 - val_loss: 0.1215 - val_acc: 0.9828
廣告