理論參考文章文章
項(xiàng)目參考文章
我自己的項(xiàng)目代碼
自己的理解和總結(jié):
對(duì)H隨機(jī)賦值然后求來達(dá)到最小化代價(jià)函數(shù)的目的,加快了運(yùn)算速度。
一、數(shù)學(xué)原理
對(duì)于一個(gè)單隱層神經(jīng)網(wǎng)絡(luò),結(jié)構(gòu)如下圖:


假設(shè)有m個(gè)輸入節(jié)點(diǎn),M個(gè)隱藏神經(jīng)元,N個(gè)輸出節(jié)點(diǎn)。
- 前向傳播的詳細(xì)矩陣推導(dǎo)
第i個(gè)神經(jīng)元的輸入為:(m項(xiàng)輸入乘以對(duì)應(yīng)權(quán)重矩陣)
即
極限學(xué)習(xí)機(jī)的網(wǎng)絡(luò)訓(xùn)練模型可用數(shù)學(xué)表達(dá)式表示如下:(N個(gè)輸出節(jié)點(diǎn)的值)
-
基于代價(jià)函數(shù)最小,優(yōu)化神經(jīng)網(wǎng)絡(luò)參數(shù)
和
極限學(xué)習(xí)機(jī)的優(yōu)化過程就是尋求最優(yōu)解使得損失函數(shù)最小的過程。
令:
則:
最優(yōu)的情況為:
即:
其中表示表示網(wǎng)絡(luò)的輸入權(quán)值和隱藏層節(jié)點(diǎn)閾值,H表示網(wǎng)絡(luò)關(guān)于樣本的隱藏層輸出矩陣,
表示輸出權(quán)值矩陣,
表示樣本集的目標(biāo)值矩陣。
-
訓(xùn)練過程
這里分析了為什么極限學(xué)習(xí)速度快。
在傳統(tǒng)的單層神經(jīng)網(wǎng)絡(luò)中,input weight不可以隨機(jī)產(chǎn)生,必須在求解過程中和output weight一起進(jìn)行update,這一過程必須運(yùn)用iteration的方式進(jìn)行,運(yùn)算時(shí)間較長(zhǎng)。ELM證明了input weight隨機(jī)產(chǎn)生并且在之后的計(jì)算中固定也可以達(dá)到同樣的目的,所以在求解過程中只需要求output weight。 這樣就可以運(yùn)用簡(jiǎn)單的矩陣運(yùn)算一步求出標(biāo)準(zhǔn)解而大大提高運(yùn)算效率。
極限學(xué)習(xí)機(jī)算法的訓(xùn)練過程可歸結(jié)為一個(gè)非線性優(yōu)化問題。
當(dāng)隱藏層節(jié)點(diǎn)的激活函數(shù)可微時(shí),網(wǎng)絡(luò)的輸入權(quán)值和隱藏層節(jié)點(diǎn)閾值可以隨機(jī)賦值,此時(shí)矩陣H是一個(gè)常數(shù)矩陣,極限學(xué)習(xí)機(jī)的學(xué)習(xí)過程可等價(jià)位求取線性系統(tǒng)最小范數(shù)的最小二乘解
,其計(jì)算公式為:
,
是矩陣H的廣義逆,可以通過奇異值分解求得。
通過這種方式就可以計(jì)算出學(xué)習(xí)網(wǎng)絡(luò)的輸出權(quán)值。
同迭代算法相比,極限學(xué)習(xí)機(jī)及大地提高了網(wǎng)絡(luò)的泛化能力和學(xué)習(xí)速度。
為什么”當(dāng)隱藏層節(jié)點(diǎn)的激活函數(shù)可微時(shí),網(wǎng)絡(luò)的輸入權(quán)值和隱藏層節(jié)點(diǎn)閾值可以隨機(jī)賦值“?
我自己的理解是,激活函數(shù)都得可微,這樣才能進(jìn)行反向傳播吧。(雖然這里沒有涉及反向傳播)
下面我們從具體的高維數(shù)據(jù)來分析:
# 計(jì)算h
x.shape
(3647, 5)
b.shape
(3647, 90)
w.shape
(5, 90)
h = sigmoid(np.dot(x, w) + b)
(3647, 90)
# h為隱神經(jīng)元的輸出
H_.shape
(90, 3647)
T.shape
(3647, 1)
beta.shape
(90, 1)
體會(huì)如下:
- w和x的點(diǎn)乘把維度項(xiàng)給抵消掉了:不同的輸出x與同一個(gè)神經(jīng)元連接的權(quán)重w是相同的
- beta并不是單純地相乘,也是相乘之后再相加,起到了點(diǎn)乘的效果
二、評(píng)價(jià)/與Deep learning的區(qū)別:
- ELM最初只是一種特殊單隱層神經(jīng)網(wǎng)絡(luò),有解析解,因此簡(jiǎn)單、快速;而深度學(xué)習(xí)需要參數(shù)更新,樣本需求大、速度慢;
線性和非線性的區(qū)別
DL具有明確的‘學(xué)習(xí)’意味或者說是非線性特征抽取的能力,因?yàn)樗梢愿鶕?jù)數(shù)據(jù)和任務(wù)調(diào)整參數(shù),使得DL在諸多場(chǎng)景下都適用;盡管ELM也是學(xué)習(xí)模型,但它本質(zhì)上是線性的(至少答主是這么理解),看它的優(yōu)化函數(shù),本質(zhì)上就是嶺回歸,是線性的。
優(yōu)化函數(shù)- 性能上,不可否認(rèn)ELM在低維度簡(jiǎn)單的小數(shù)據(jù)集上效果是要略優(yōu)于DL的,但在復(fù)雜數(shù)據(jù)上,如語音、圖像上,DL依舊是獨(dú)領(lǐng)風(fēng)騷。另外,ELM不能或者很難作生成模型。
三、項(xiàng)目實(shí)現(xiàn)
ELM實(shí)現(xiàn)思路:

下面用MNIST dataset來訓(xùn)練網(wǎng)絡(luò)實(shí)現(xiàn)手寫數(shù)字的分類。
數(shù)據(jù)準(zhǔn)備
- 導(dǎo)入必要庫
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import MinMaxScaler
- 讀入dataset
train = pd.read_csv('mnist_train.csv')
test = pd.read_csv('mnist_test.csv')
- 用sckikit-learn包中的
MinMaxScaler歸一化數(shù)據(jù)到(0,1)之間,然后用OneHotEncoder把tagets轉(zhuǎn)化成one-hot encoding format. -
MinMaxScaler:數(shù)據(jù)(x)按照最小值中心化后,再按極差(最大值 - 最小值)縮放,數(shù)據(jù)移動(dòng)了最小值個(gè)單位,并且會(huì)被收斂到[0,1]之間。 -
StandardScaler()(更常用):數(shù)據(jù)(x)按均值(μ)中心化后,再按標(biāo)準(zhǔn)差(σ)縮放,數(shù)據(jù)就會(huì)服從為均值為0,方差為1的正態(tài)分布(即標(biāo)準(zhǔn)正態(tài)分布) -
scaler.fit_transform這個(gè)函數(shù)計(jì)算數(shù)據(jù)的均值和方差,并基于此進(jìn)行數(shù)據(jù)轉(zhuǎn)化 -
onehotencoder:對(duì)target/label進(jìn)行onehot編碼。
對(duì)類別變量進(jìn)行“二進(jìn)制化”操作,然后將其作為模型訓(xùn)練的特征。
關(guān)于one hot編碼的講解
onehotencoder = OneHotEncoder(categories='auto')
scaler = MinMaxScaler()
X_train = scaler.fit_transform(train.values[:,1:])
y_train = onehotencoder.fit_transform(train.values[:,:1]).toarray()
X_test = scaler.fit_transform(test.values[:,1:])
y_test = onehotencoder.fit_transform(test.values[:,:1]).toarray()
初始化網(wǎng)絡(luò)
需要確定如下參數(shù):
- The size of the input layer, which is the number of input features
- Number of hidden neurons
- Input to hidden weights
- Hidden layer activation function
輸入層的尺寸取決于the number of input features of the dataset
input_size = X_train.shape[1]
隱藏神經(jīng)元數(shù)目初始化為1000
hidden_size = 1000
輸入權(quán)重和偏差biases的基于高斯分布的初始化
input_weights = np.random.normal(size=[input_size,hidden_size])
biases = np.random.normal(size=[hidden_size])
激活函數(shù)設(shè)置為Relu函數(shù)
def relu(x):
return np.maximum(x, 0, x)
進(jìn)一步的計(jì)算
計(jì)算輸出權(quán)重:

公式中, H (dagger) is the Moore–Penrose generalized inverse of matrix H, and T is our target.
先計(jì)算H:
def hidden_nodes(X):
G = np.dot(X, input_weights)
G = G + biases
H = relu(G)
return H
再計(jì)算。
output_weights = np.dot(pinv2(hidden_nodes(X_train)), y_train)
用pinv這個(gè)函數(shù)就可以計(jì)算H的逆,進(jìn)而計(jì)算H的逆和T的點(diǎn)乘。
模型測(cè)試
def predict(X):
out = hidden_nodes(X)
out = np.dot(out, output_weights)
return out
prediction = predict(X_test)
correct = 0
total = X_test.shape[0]
for i in range(total):
predicted = np.argmax(prediction[i])
actual = np.argmax(y_test[i])
correct += 1 if predicted == actual else 0
accuracy = correct/total
print('Accuracy for ', hidden_size, ' hidden nodes: ', accuracy)
