1. 程式人生 > >【機器學習筆記21】神經網路(多層感知機)

【機器學習筆記21】神經網路(多層感知機)

【參考資料】 【1】《深度學習》 花書 6.1

亦或問題

由於單層感知機相當於在一個空間增加了一個超平面進行分類,那麼對於像亦或問題這樣的情況則無法完成。 在這裡插入圖片描述

因此在多層感知機中增加了一個隱藏層,即一個啟用函式。現代神經網路最常用的啟用函式是整流線性單元,ReLU函式,如下: 在這裡插入圖片描述

我們推導如下:

第一步:亦或資料的輸入表示為: X=[00011011] X=\begin{bmatrix} 0 & 0 \\ 0 & 1 \\ 1 & 0 \\ 1 & 1 \end{bmatrix}

第二步:乘以權值 W=[111

1] W=\begin{bmatrix} 1 & 1 \\ 1 & 1 \\ \end{bmatrix} 以及偏差 C=[12] C=\begin{bmatrix} 1 \\ -2 \end{bmatrix}

第三步: 得到新的輸入矩陣為: X1=[01101021] X^1=\begin{bmatrix} 0 & -1 \\ 1 & 0 \\ 1 & 0 \\ 2 & 1 \end{bmatrix} 將其用ReLU啟用函式處理得到: Y

=[00101021] Y=\begin{bmatrix} 0 & 0 \\ 1 & 0 \\ 1 & 0 \\ 2 & 1 \end{bmatrix} 如圖所示:

在這裡插入圖片描述

第四步: 由上圖可以直觀的看到,原來的[0,1],[1,0]被對映到了新空間的[0,1],因此亦或問題變的可以分類。最後的權重向量為: w=[0110] w=\begin{bmatrix} 0 \\ 1 \\ 1 \\ 0 \end{bmatrix}

多層感知機的理論結論

萬能近似定理: 一個前饋神經網路如果具有線性輸出層和至少一層具有任何一種擠壓性質的啟用函式的隱藏層,只要給予網路足夠數量的隱藏單元,它可以任意精度來儘速任何從一個有限維空間到另一個有限維空間的Borel可測函式。前饋網路的導數也可以任意好的來近似函式的導數。

知乎上的這個回答,是採用分段函式的思想解釋多層感知器的。也就是說sigmoid函式相當於把原來的線性函式拆分成兩個線性函式,如下連結。

多層感知機程式(基於Keras)
import numpy as np
from keras.models import Sequential
from keras.layers import Dense,Dropout
from keras import optimizers



def _test_multi_perceptron_01():


    x_train = np.array([[0, 0],[1, 0],[0, 1],[1, 1]], dtype=int);
    y_train = np.array([[1], [0], [0], [1]], dtype=int)

    model = Sequential()

    model.add(Dense(units=1, input_dim=2, activation='linear', use_bias=False, init="glorot_uniform"))

    sgd = optimizers.SGD(lr=0.05, decay=1e-6, momentum=0.11, nesterov=True)

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

    model.fit(x_train, y_train,
          epochs=2000,
          batch_size=4)


    score = model.evaluate(x_train, y_train, verbose=0)

    print('_test_multi_perceptron_01 Test loss:', score[0])
    print('_test_multi_perceptron_01 Test accuracy:', score[1])

    pass

"""
增加了一個隱含層,隱含層的啟用函式採用非線性整流relu
"""
def _test_multi_perceptron_02():

    x_train = np.array([[0, 0],[1, 0],[0, 1],[1, 1]], dtype=int);
    y_train = np.array([[1], [0], [0], [1]], dtype=int)

    model = Sequential()

    """
    relu 是一個折線
    """
    model.add(Dense(input_dim=2,output_dim=4,  activation='relu', init="glorot_uniform"))
    model.add(Dense(input_dim=4,output_dim=1,  activation='linear', init="glorot_uniform"))

    model.summary()

    sgd = optimizers.SGD(lr=0.05, decay=1e-6, momentum=0.11, nesterov=True)

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

    model.fit(x_train, y_train,
          epochs=1000,
          batch_size=4)


    score = model.evaluate(x_train, y_train, verbose=0)

    print('_test_multi_perceptron_02 Test loss:', score[0])
    print('_test_multi_perceptron_02 Test accuracy:', score[1])

    pass


"""
說明:

多層感知器,增加一層隱含層,解決異或問題,對應筆記《16.神經網路(多層感知機 - 亦或問題)》

作者:fredric

日期:2018-8-18

"""
if __name__ == "__main__":

    print("multiple perceptron test >>>>>>>>")

    #_test_multi_perceptron_01()

    _test_multi_perceptron_02()