多層感知器(Multilayer perceptron, MLP)的一層,可以表示為 = f(xTW + b),其中的 x 為輸入向量,W 為權重矩陣,b 為偏差向量,f 為激勵函數(activation function), 為輸出向量。並且由於堆疊多層時,每一層的每個輸出都是完全連接到下一層的每個輸入,所以這樣的每一層又叫做全連接層(fully connected layer)。多層感知器或者其他各種類神經網路的訓練,則首先需要使用損失函數(loss function)評估網路算出來的 和標準答案的 y 之間的差異,經由你所選用的工具(例如 PyTorch 或者 Tensorflow)進行微分求出梯度以後,再使用各種最佳化(求極值)的方法(optmizer)來更新每個 W 和 b。如此反覆進行之後,通常就可以訓練出恰當的類神經網路。

對於激勵函數、損失函數以及最佳化方法,可以依照你要處理的問題特性,或者實際效果來選擇。常用的激勵函數有 sigmoid、ReLU、tanh,損失函數則有常用於回歸問題的 mean squared error (MSE),以及常用於分類問題的 cross entropy 等可以選擇。最佳化方法則通常有 SGD (stochastic gradient descent)、Momentum、AdaGrad、RMSProp,以及 Adam 等方式,若無特殊需求,且在可以選擇的情況下,通常你可以先試試看 Adam。

若要使用 MLP 解決問題,有很多工具可以幫忙,常見的有像是 PyTorchTensorFlow,以及 Chainer 等等,不過這些工具為了能讓你做更自由的調整,所以在真正的類神經網路本身和資料的事前處理,都有許多工作要自己做,因此以下還是先使用 scikit-learn 的 neural_network.MLPClassifier 來示範 MLP 的使用,範例的資料集是 Wine Data Set

import numpy as np
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier

dataset = load_wine()
print('Data shapes:', dataset.data.shape, dataset.target.shape)

X_train, X_test, y_train, y_test = train_test_split(dataset.data, dataset.target)
print('Training data shapes:', X_train.shape, y_train.shape)
print('Test data shapes:', X_test.shape, y_test.shape)

model = MLPClassifier(hidden_layer_sizes=(256, 256))
model.fit(X_train, y_train)
pred = model.predict(X_test)
print('Accuracy: {:.2f}%'.format(100*np.mean(pred == y_test)))

hidden = np.maximum(X_test @ model.coefs_[0] + model.intercepts_[0], 0)
hidden = np.maximum(hidden @ model.coefs_[1] + model.intercepts_[1], 0)
pred = np.argmax(hidden @ model.coefs_[2] + model.intercepts_[2], axis=1)

print('Accuracy: {:.2f}%'.format(100*np.mean(pred == y_test)))

在上述範例中,我們只調整了隱藏層的數目,而其他如 learning rate(相當於每次更新權重時「大膽」的程度,通常太大會讓網路不容易收斂到好的結果,太小會導致網路收斂很慢)及 batch size(每次更新權重時,要看多少資料)等參數則維持預設。範例中的隱藏層數目是一組有機會讓測試集準確率在 90% 上下(實際結果會隨著訓練與測試集的亂數切分而有差異)的參數,各位可以試著跟其他的參數一併調整看看。