Python 快速構建神經網絡

作者 | ZackSock       責編 | 歐陽姝黎

前言


機器學習一直是 Python 的一大熱門方向,其中由神經網絡算法衍生出來的深度學習在很多方面大放光彩。那神經網絡到底是個個什麼東西呢?

說到神經網絡很容易讓人們聯想到生物學中的神經網絡,而且很多時候也會把機器學習的神經網絡和生物神經網絡聯繫起來。但是其實人類至今都沒有完全理解生物神經網絡的運作,更不要談用計算機實現生物神經網絡了。

相比之下,機器學習中的神經網絡更像是一個數學函數。我們輸入一組數據,然後神經網絡會給我們返回一個結果。像下面這個簡單的函數:

和是常數)

我們給定一個 x,就能得到一個 y。只不過神經網絡的函數要比上面的函數複雜得多。

不過其實神經網絡的基礎就是上面的函數。下面我們就帶大家快速搭建一個神經網絡。

機器學習


在學習神經網絡之前,我們需要了解一些機器學習的知識。

2.1、什麼是機器學習?

假如我有下面一組數據:

1, 3, 5, 7, 9

現在讓你說出下一個數字可能是什麼。

對於人類智慧來說,我們可以很快地說出 11。但是對計算機來說卻不是那麼簡單,因爲計算機是不會思考的。那計算機要怎麼學習呢?這就需要人來指引了。

在機器學習中,人類需要告訴機器如何學習。然後通過人類告訴的學習方法來學習,並得到一個模型。

當然機器學習還有其它一些形式,我們不繼續討論。

2.2、如何學習?

對於機器學習來說,如何學習是一個非常重要的問題。其中已經出現了許多優秀的算法,這些算法的作用都是告訴機器如何學習。比如線性迴歸、邏輯迴歸、K 近鄰、決策樹、神經網絡等。

機器學習算法可以說是機器學習的靈魂。我們今天要實現的神經網絡也是一種機器學習算法,他是建立在邏輯迴歸的基礎之上的,而邏輯迴歸又建立在線性迴歸之上。因此線性迴歸和邏輯迴歸也是今天要學習的內容。

2.3、機器學習中的問題

機器學習的問題通常分爲兩大類,一個類是分類,一類是迴歸。

它們兩者的區別是結果是否離散。比如一個動物分類問題,我們得到的結果只可能是一個確定的動物。不會得到一個介於貓狗之間的動物。

而回歸問題的結果通常是一個數值,比如房價預測問題。我們可能得到 0-100 萬之間任意一個數值,也可能得到一個類似 40.023242 的小數。

其中線性迴歸就是解決迴歸問題的一大利器,而邏輯迴歸則是用於分類問題。下面我們就來看看這兩個算法。

線性迴歸和邏輯迴歸


可能你會好奇,爲什麼邏輯迴歸名字裏有個迴歸卻是不是解決迴歸問題的。相信看完下面的內容就不會有這個疑惑了。

3.1、線性迴歸

在前言中,我們介紹了一個簡單的函數:

其實它就是線性迴歸的基礎。線性迴歸算法就是找到一組最優的 w b,讓我們得到最接近真實的結果。我們還是用上面的數據:

1, 3, 5, 7, 9

對於上面這組數據,我們是要找序號和數值之間的關係,我們可以把上面的數據理解爲:

x, y
1, 1
2, 3
3, 5,
4, 7,
5, 9

其中 x 表示需要,y 表示具體的數值。我們稍加運算就可以得到下面這個函數:

我們得到了最優的一組參數 w=2, b = -1,通過這個函數我們就可以預測後面後面一千、一萬個數字。

不過有時候我們會有多個 x,這時我們就可以把上面的函數推廣爲:

這時候我們需要求的參數就多多了。下面我們來實際寫一個線性迴歸的程序。

3.2、線性迴歸實戰

這裏我們需要使用到 scikit-learn 模塊,安裝如下:

pip install scikit-learn

然後我們就可以開始寫代碼了。線性迴歸算法的實現被封裝在了 sklearn.linear_model 中的 LinearRegression,我們可以直接使用:

import numpy as np
from sklearn.linear_model import LinearRegression
# 準備x的數據
X = np.array([
    [1],
    [2],
    [3],
    [4],
    [5]
])
# 準備y的數據
y = np.array([1, 3, 5, 7, 9])
# 創建線性迴歸模塊
lr = LinearRegression()
# 填充數據並訓練
lr.fit(X, y)
# 輸出參數
print("w=", lr.coef_, "b=", lr.intercept_)

首先我們需要準備 X 和 y 的數據,這裏我們使用的是 ndarray 數組。這裏需要注意,我們 y 的的數據長度爲 5,則 X 的數據需要是 5*n。

準備好數據後我們需要創建線性迴歸模型,然後調用 fit 方法填充我們準備好的數據,並訓練。

訓練完成後我們可以查看一下模塊的參數,其中 coef_表示 w,而 intercept_表示 b。因爲 w 可以有多個,所以它應該是個數組,下面是輸出結果:

w= [2.] b= -1.0

和我們人工智慧得到的結果是一樣的。我們還可以調用 predict 方法預測後面的數據:

import numpy as np
from sklearn.linear_model import LinearRegression
X = np.array([
    [1],
    [2],
    [3],
    [4],
    [5]
])
y = np.array([1, 3, 5, 7, 9])
lr = LinearRegression()
lr.fit(X, y)
y_predict = lr.predict(np.array([[100]]))
print(y_predict)

這裏同樣需要注意 X 的數據是二維的。

3.3、邏輯迴歸

邏輯迴歸可以理解爲線性迴歸 + 特殊函數。我們可以思考下面這個問題。

現在需要寫一個程序來判斷每個人的分數是否及格,計分標準爲:總分 = 40% 數學 + 30% 語文 + 30% 英語。總分大於等於 60 爲及格,其餘爲不及格。

雖然是個很簡單的問題,但是我們還是需要討論一下。首先我們可以把計算總分的公式寫成下面的形式:

對於這個公式,我們可以得到 0-100 之間的任何一個數字。但是我想要得到的只有兩個結果,及格或者不及格。我們可以簡單理解爲 - 1 和 1。

那我們怎麼把上面的結果映射到 - 1 和 1 上呢?這就需要使用一個特殊的函數了,我們把這個函數叫做激活函數。我們可以用下面這個函數作爲激活函數:

這樣就可以把所有分數映射到 - 1 和 1 上了。(上面的函數在 y=60 處無定義,嚴格上來講上面的激活函數是不適用的)邏輯迴歸的圖示如下:

先通過一個線性模型得到一個結果,然後再通過激活函數將結果映射到指定範圍。

不過在實際應用中,我們通常會使用 Sigmoid、Tanh 和 ReLU 函數。下面是幾個激活函數的圖像:

下面我們來寫一個邏輯迴歸的例子。

3.4、邏輯迴歸實戰

我們用邏輯迴歸解決是否幾個的問題,邏輯迴歸的實現封裝在 linear_model.LogisticRegression 中,同樣可以直接使用,我們直接上代碼:

import numpy as np
from sklearn.linear_model import LogisticRegression
# 準備X的數據
X = np.array([
    [60],
    [20],
    [30],
    [80],
    [59],
    [90]
])
# 準備y的數據
y = np.array([1, 0, 0, 1, 0, 1])
# 創建邏輯迴歸模型
lr = LogisticRegression()
# 填充數據並訓練
lr.fit(X, y)
# 準備用於測試的數據
X_test = np.array([
    [62],
    [87],
    [39],
    [45]
])
# 判斷測試數據是否及格
y_predict = lr.predict(X_test)
print(y_predict)

代碼和線性迴歸只有一些細微的差別。在代碼中,我們用 0 表示不及格,1 表示及格。下面是我們測試數據輸出的結果:

[1 1 0 0]

可以看到所有結果都預測正確了。

有了上面的知識,我們就可以開始實現一個神經網絡了。

神經網絡


神經網絡是建立在邏輯迴歸之上的,可以說神經網絡就是一個邏輯迴歸的集合。

4.1、神經網絡

想必大家都聽說過,神經網絡是由大量的神經元組成的。不過你可能不知道,機器學習中的神經元就是我們前面學的邏輯迴歸。我們可以看下面這張圖:

可以看到和之前的邏輯迴歸很像,但是這裏使用了很多激活函數,而且參數數量也要多得多。

至於爲什麼要使用這麼多激活函數可以說就是爲了讓得到的函數非常複雜。如果我們的函數非常簡單,比如下面這組數據:

假如用下面的函數作爲我們的模型:

會得到下面這張圖像:

可以看到有許多點都不在直線上,所以預測的數據會有很多誤差。這個時候我們可以考慮二次,如:

4.2、輸入層、隱層、輸出層

隱藏層通常會特別複雜,我們可以通過調節隱層的層數和節點數來調整模型的複雜度。

4.3、神經網絡實戰

from sklearn.datasets import load_iris
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split

# 加載數據集
iris_data = load_iris()
# 拆分數據集
X_train, X_test, y_train, y_test = train_test_split(iris_data['data'], iris_data['target'], test_size=0.25, random_state=1)
# 創建神經網絡模型
mlp = MLPClassifier(solver='lbfgs', hidden_layer_sizes=[4, 2], random_state=0)
# 填充數據並訓練
mlp.fit(X_train, y_train)
# 評估模型
score = mlp.score(X_test, y_test)
print(score)

然後我們創建 MLPClassifier 類的實例,實際上它就是一個用於分類的多重感知機。我們只需要關注 hidden_layer_sizes 參數即可,它就是我們神經網絡的層數和節點數。因爲是一個二分類問題,所以這裏的輸出層有兩個節點。

下面輸出的結果:

0.9210526315789473

我們調用 mlp.score 評估模型的好壞,92% 的準確率也算是一個非常優秀的結果了。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/53UEgCXXXiTxKn-qXk0nvw