理解神經(jīng)網(wǎng)絡如何工作的最好方式是自己動手創(chuàng)建一個,這篇文章將會給你演示怎么做到這一點
神經(jīng)網(wǎng)絡(NN)榜苫,也稱之為人工神經(jīng)網(wǎng)絡(ANN)是钥,它是機器學習領域中學習算法集合中的子集粘秆,其核心概念略似生物神經(jīng)網(wǎng)絡的概念裳涛。
擁有五年以上經(jīng)驗的德國機器學習專家Andrey Bulezyuk說過:神經(jīng)網(wǎng)絡正在使機器學習發(fā)生革命性的巨變,因為他們能夠跨越廣泛的學科和行業(yè)來高效地建模復雜的抽象炬藤。
基本上晾捏,一個ANN由以下組件構(gòu)成:
- 輸入層:接受傳遞數(shù)據(jù)
- 隱藏層
- 輸出層
- 各層之間的權(quán)重
- 每個隱藏層都會有一個精心設計的激活函數(shù),對于此教程穿撮,我們將會使用
Sigmoid
激活函數(shù)
神經(jīng)網(wǎng)絡的類型有很多缺脉,在這個項目中痪欲,我們準備創(chuàng)建一個前饋神經(jīng)網(wǎng)絡,此類型的ANN將會直接從前到后傳遞數(shù)據(jù)
訓練前饋神經(jīng)元往往需要反向傳播攻礼,反向傳播為神經(jīng)網(wǎng)絡提供了相應的輸入和輸出集合业踢,輸入數(shù)據(jù)在被傳遞到神經(jīng)元的時候被處理,然后產(chǎn)生一個輸出
下面展示了一個簡單的神經(jīng)網(wǎng)絡結(jié)構(gòu)圖:
而且礁扮,理解神經(jīng)網(wǎng)絡如何工作做好的辦法就是去學習從頭開始構(gòu)建一個神經(jīng)網(wǎng)絡(不使用任何第三方庫知举,作者意思應該是不使用任何機器學習庫)。
在本文中太伊,我們將演示如何使用Python編程語言創(chuàng)建一個簡單的神經(jīng)網(wǎng)絡雇锡。
問題
這里用表格列出了我們需要解決的問題:
我們將會訓練一個特定的神經(jīng)網(wǎng)絡模型,當提供一組新數(shù)據(jù)的時候僚焦,使其能夠準確地預測輸出值锰提。
如你在表中所見,輸出值總是等于輸入數(shù)據(jù)的第一個值芳悲,因此我們期望的表中輸出(?)值是1欲账。
讓我們思考看看能不能使用一些Python代碼來給出相同的結(jié)果(再繼續(xù)閱讀之前,你可以在文章末尾仔細地閱讀此項目的代碼)
創(chuàng)建一個神經(jīng)網(wǎng)絡類
我們將在Python中創(chuàng)建一個NeuralNetwork
類來訓練神經(jīng)元以提供準確的預測芭概,該類還具有一些其他的輔助函數(shù)
盡管我們沒有使用任何一個神經(jīng)網(wǎng)絡庫用于這個簡單的神經(jīng)網(wǎng)絡示例赛不,我們也會導入numpy
包來協(xié)助計算。
該庫帶有以下四個重要方法:
- exp:用于生成自然指數(shù)
- array:用于生成矩陣
- dot:用于乘法矩陣
- random:用于生成隨機數(shù)(注意:我們將對隨機數(shù)進行播種以確保其有效分布)
應用 Sigmoid 激活函數(shù)
該神經(jīng)網(wǎng)絡將使用Sigmoid function作為激活函數(shù)罢洲,其繪制了一個典型的S
形曲線:
此函數(shù)可以將任意值映射到區(qū)間0~1之間踢故,它將幫助我們規(guī)范化輸入值的和權(quán)重乘積之和。
隨后惹苗,我們將創(chuàng)建Sigmoid函數(shù)的導數(shù)來幫助計算機對權(quán)重進行必要的調(diào)整殿较。
一個Sigmoid函數(shù)的輸出可以用來生成它的導數(shù),例如桩蓉,如果輸出變量是X
淋纲,那么它的導數(shù)將是x * (1-x)
。
推導過程如下:
訓練模型
在這個階段我們將教導神經(jīng)網(wǎng)絡進行準確預測院究,每個輸入都有一個權(quán)重 - 正面或負面洽瞬。
這意味著,如果輸入包含一個大的正面或者負面的權(quán)重數(shù)值將會更多地影響輸出值
請記住业汰,在最開始階段我們會對每個權(quán)重分配一個隨機值
下面是我們在這個神經(jīng)網(wǎng)絡示例問題中使用的訓練過程:
- 從訓練集獲取輸入數(shù)據(jù)伙窃,根據(jù)他們的權(quán)重進行調(diào)整,然后通過計算人工神經(jīng)網(wǎng)絡輸出的方法將它們抽取出來
- 我們計算了反向傳播的錯誤率样漆,在這種情況下为障,它是神經(jīng)元預測值和實際期望值之間的差異
- 根據(jù)誤差程度,我們利用Error Weighted Derivative formula對權(quán)重進行微調(diào)
- 我們對這個過程重復15,000次,在每次迭代中都會同時處理整個訓練集
我們使用.T
函數(shù)將矩陣從水平位置轉(zhuǎn)換到垂直位置鳍怨,因此數(shù)據(jù)會被這樣排序:
最終呻右,神經(jīng)元的權(quán)重將會被提供的訓練集優(yōu)化,因此鞋喇,如果神經(jīng)元被要求去思考一個新的情況声滥,而這個情況和前面的情況是一樣的,那么神經(jīng)元就可以做出準確的預測确徙,這就是反向傳播的發(fā)生方式。
總結(jié)
最終我們初始化了NeuralNetwork
類并且運行代碼
下面就是整體的項目代碼执桌,如何在Python項目中創(chuàng)建神經(jīng)網(wǎng)絡:
import numpy as np
class NeuralNetwork():
def __init__(self):
# seeding for random number generation
np.random.seed(1)
# converting weights to a 3 by 1 matrix with values from -1 to 1 and mean of 0
self.synaptic_weights = 2 * np.random.random((3, 1)) - 1
def sigmoid(self, x):
#applying the sigmoid function
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(self, x):
#computing derivative to the Sigmoid function
return x * (1 - x)
def train(self, training_inputs, training_outputs, training_iterations):
#training the model to make accurate predictions while adjusting weights continually
for iteration in range(training_iterations):
#siphon the training data via the neuron
output = self.think(training_inputs)
#computing error rate for back-propagation
error = training_outputs - output
#performing weight adjustments
adjustments = np.dot(training_inputs.T, error * self.sigmoid_derivative(output))
self.synaptic_weights += adjustments
def think(self, inputs):
#passing the inputs via the neuron to get output
#converting values to floats
inputs = inputs.astype(float)
output = self.sigmoid(np.dot(inputs, self.synaptic_weights))
return output
if __name__ == "__main__":
#initializing the neuron class
neural_network = NeuralNetwork()
print("Beginning Randomly Generated Weights: ")
print(neural_network.synaptic_weights)
#training data consisting of 4 examples--3 input values and 1 output
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
#training taking place
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!")
我們設法創(chuàng)建了一個簡單的神經(jīng)網(wǎng)絡鄙皇。
這個神經(jīng)網(wǎng)絡開始于自己給自己分配了一些隨機的權(quán)重,此后仰挣,它使用訓練數(shù)據(jù)訓練自己伴逸。
因此,如果出現(xiàn)新情況[1,0,0]膘壶,則其值為0.9999584错蝴。
你記得我們想要的正確答案是1嗎?
那么颓芭,這就非常接近了 —— 思考下S
形函數(shù)的輸出值在0到1之間顷锰。
當然,我們只使用一個神經(jīng)網(wǎng)絡來執(zhí)行這個簡單的任務亡问,如果我們連接數(shù)千個人工神經(jīng)網(wǎng)絡起來會怎樣官紫?我們能否100% 地模仿人類大腦的工作方式么?
如果你有任何疑問州藕,請留言