神經網絡(NN),也被稱為人工神經網絡(ANN),是機器學習領域中學習算法的子集,大體上借鑒了生物神經網絡的概念。目前,神經網絡在計算機視覺、自然語言處理等領域應用廣泛。德國資深機器學習專家 Andrey Bulezyuk
說到,“神經網絡正在徹底改變機器學習,因為它們能夠有效地模拟各種學科和行業的複雜抽象,且無需太多人工參與。”
大體上,人工神經網絡基本包含以下元件:
- 接收資料并傳遞資料的輸入層(input layer);
- 隐藏層(hidden layer);
- 輸出層(output layer);
- 層與層之間的權重(weight);
- 每個隐藏層使用的激活函數(activation function);
在本文教程中,使用的是簡單的Sigmoid激活函數,但注意一點,在深層神經網絡模型中, sigmoid激活函數一般不作為首選,原因是其易發生梯度彌散現象。
此外,人工神經網絡有幾種不同類型的神經網絡,比如前饋神經網絡、卷積神經網絡及遞歸神經網絡等。本文将以簡單的前饋或感覺神經網絡為例,這種類型的人工神經網絡是直接從前到後傳遞資料的,簡稱前向傳播過程。
而訓練前饋神經元通常需要反向傳播算法,這就需要為網絡提供相應的輸入和輸出集。當輸入資料被傳輸到神經元時,它會經過相應的處理,并将産生的輸出傳輸給下一層。
下圖簡單展示了一個神經網絡結構:

此外,了解神經網絡如何工作的最好方法是學習如何在不使用任何工具箱的前提下從頭開始建構一個。在本文中,我們将示範如何使用Python建立一個簡單的神經網絡。
問題
下表顯示了我們将解決的問題:
我們将訓練神經網絡,以便在提供一組新資料時可以預測出正确的輸出值。
從表中看到,輸出的值始終等于輸入節中的第一個值。是以,我們可以期望新情形的輸出(?)值為1。
下面讓我們看看是否可以使用一些Python代碼來得到相同的結果。
建立神經網絡類|NeuralNetwork Class
我們将在Python中建立一個NeuralNetwork類來訓練神經元以提供準确的預測,該類還包含其他輔助函數。我們不會将神經網絡庫用于建立這個簡單的神經網絡示例中,但會導入基本的Numpy庫來協助計算。
Numpy庫是處理資料的一種基本庫,它具有以下四種重要的計算方法:
- EXP——用于産生所述自然指數;
- array——用于生成矩陣;
- dot——用于矩陣相乘;
- random——用于生成随機數;
應用Sigmoid函數
我們将使用Sigmoid函數,它繪制出一個“S”形曲線,将其作為本文建立的神經網絡的激活函數。
此函數可以将任何值映射到0到1之間,并能幫助我們規範化輸入的權重和。
此後,我們将建立Sigmoid函數的導數,以幫助計算權重的基本調整。
可以使用Sigmoid函數的輸出來生成其導數。例如,如果輸出變量是“x”,那麼它的導數将是x *(1-x)。
訓練模型
訓練模型意味着我們将教導神經網絡進行準确預測的階段。每個輸入都有一個權重(weights)——正或負的,這意味着具有大值正權重或大值負權重的輸入将多所得到的輸出有更大地影響。
注意,模型訓練最初時,每個權重的初始化都是随機數。
以下是本文建構的神經網絡示例問題中訓練過程:
- 1.從訓練資料集中擷取輸入,根據它們的權重進行一些調整,并通過計算神經網絡輸出的方法來一層一層的傳輸;
- 2.計算反向傳播的錯誤率。在這種情況下,它是神經元預測得到的輸出與訓練資料集的預期輸出之間的誤差;
- 3.根據得到的誤差範圍,使用 誤差權重導數公式 進行一些小的權重調整;
- 4.将此過程重複15,000次,在每次疊代過程中,同時處理整個訓練集;
在這裡,我們使用“.T”函數對矩陣求偏置。是以,數字将以這種方式存儲:
最終,神經元的權重将針對所提供的訓練資料進行優化。是以,如果神經網絡的輸出與期望的輸出一緻時,說明訓練完成,可以進行準确的預測,這就是反向傳播的方式。
封裝
最後,初始化NeuralNetwork類後并運作整個程式,以下是如何在Python項目中建立神經網絡的完整代碼:
import numpy as np
class NeuralNetwork():
def __init__(self):
# 設定随機數種子
np.random.seed(1)
# 将權重轉化為一個3x1的矩陣,其值分布為-1~1,并且均值為0
self.synaptic_weights = 2 * np.random.random((3, 1)) - 1
def sigmoid(self, x):
# 應用sigmoid激活函數
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(self, x):
#計算Sigmoid函數的偏導數
return x * (1 - x)
def train(self, training_inputs, training_outputs, training_iterations):
# 訓練模型
for iteration in range(training_iterations):
# 得到輸出
output = self.think(training_inputs)
# 計算誤差
error = training_outputs - output
# 微調權重
adjustments = np.dot(training_inputs.T, error * self.sigmoid_derivative(output))
self.synaptic_weights += adjustments
def think(self, inputs):
# 輸入通過網絡得到輸出
# 轉化為浮點型資料類型
inputs = inputs.astype(float)
output = self.sigmoid(np.dot(inputs, self.synaptic_weights))
return output
if __name__ == "__main__":
# 初始化神經類
neural_network = NeuralNetwork()
print("Beginning Randomly Generated Weights: ")
print(neural_network.synaptic_weights)
#訓練資料
training_inputs = np.array([[0,0,1],
[1,1,1],
[1,0,1],
[0,1,1]])
training_outputs = np.array([[0,1,1,0]]).T
# 開始訓練
neural_network.train(training_inputs, training_outputs, 15000)
print("Ending Weights After Training: ")
print(neural_network.synaptic_weights)
user_input_one = str(input("User Input One: "))
user_input_two = str(input("User Input Two: "))
user_input_three = str(input("User Input Three: "))
print("Considering New Situation: ", user_input_one, user_input_two, user_input_three)
print("New Output data: ")
print(neural_network.think(np.array([user_input_one, user_input_two, user_input_three])))
print("Wow, we did it!")
以下是運作代碼後産生的輸出:
以上是我們設法建立的一個簡單的神經網絡。首先神經網絡開始為自己配置設定一些随機權,此後,它使用訓練樣例訓練自身。
是以,如果出現新的樣本輸入[1,0,0],則其輸出值為0.9999584。而期望的的正确答案是1,可以說二者是非常接近了,考慮到Sigmoid函數是非線性函數,這點誤差是可以接受的。
此外,本文隻使用了一層神經網絡來執行簡單的任務。如果我們将數千個這些人工神經網絡集合在一起會發生什麼情況呢?我們可以100%模仿人類思維嗎?答案是肯定的,但是目前實作起來是比較困難的,隻能說是十分相近。對此感興趣的讀者可以閱讀與深度學習相關的資料。
作者資訊
Michael J. Garbade,LiveEdu公司的首席執行官
本文由阿裡雲雲栖社群組織翻譯。
文章原标題《How to Create a Simple Neural Network in Python》,譯者:海棠,審校:Uncle_LLD。
文章為簡譯,更為詳細的内容,
請檢視原文。