手把手教你用Python創建簡單的神經網絡(附代碼)
了解神經網絡工作方式的***途徑莫過于親自創建一個神經網絡,本文將演示如何做到這一點。
神經網絡(NN)又稱人工神經網絡(ANN),是機器學習領域中基于生物神經網絡概念的學習算法的一個子集。
擁有五年以上經驗的德國機器學習專家Andrey Bulezyuk聲稱:“神經網絡正在徹底改變機器學習,因為它們能夠在廣泛的學科和行業中為抽象對象高效建模。”
人工神經網絡基本上由以下組件組成:
- 輸入層:接收并傳遞數據
- 隱藏層
- 輸出層
- 各層之間的權重
- 每個隱藏層都有一個激活函數。在這個簡單的神經網絡Python教程中,我們將使用Sigmoid激活函數。
神經網絡有多種類型。在本項目中,我們將創建前饋或感知神經網絡。這種類型的ANN直接將數據從前向后傳遞。
前饋神經元的訓練往往需要反向傳播,它為網絡提供了相應的輸入和輸出集。當輸入數據被傳送到神經元時,經過處理后,產生一個輸出。
下面的圖表顯示了一個簡單的神經網絡的結構:
了解神經網絡如何工作的***方法是學習如何從頭開始構建神經網絡(而不是采用任何庫)。
在本文中,我們將演示如何利用Python編程語言創建一個簡單的神經網絡。
問題
如下是一個展示問題的表格。
我們將提供一個新的數據集,利用它訓練神經網絡,從而能夠預測正確的輸出值。
正如上表所示,輸出值總是等于輸入部分中的***個值。因此,我們期望輸出的值為1。
讓我們看看是否可以使用Python代碼來得出相同的結果(你可以在本文末尾仔細閱讀這個項目的代碼,然后再繼續閱讀本文)。
創建一個NeuralNetwork類
我們將用Python創建一個NeuralNetwork類來訓練神經元,以期給出準確的預測。這個類還會有其他的幫助函數。
即使我們不會在這個簡單的神經網絡示例中使用神經網絡庫,我們也將導入numpy庫來輔助計算。
numpy庫提供了以下四種重要方法:
- exp—用于生成自然指數
- array—用于生成矩陣
- dot—用于矩陣相乘
- random—用于生成隨機數。請注意,我們將生成隨機數,以確保它們的有效分布。
1. 應用Sigmoid函數
我們將使用Sigmoid函數,來繪制一個特征“S”型曲線,作為神經網絡的激活函數。
此函數可以將任何值映射到0到1之間的值,它將有助于我們對輸入的加權和歸一化。
此后,我們將創建Sigmoid函數的導數,以幫助計算權重的調整參數。
可以利用Sigmoid函數的輸出來生成它的導數。例如,如果輸出變量為“x”,則其導數為x*(1-x)。
2. 訓練模型
這是我們教神經網絡做出準確預測的階段。每個輸入都有一個權重-可為正值或負值。這意味著:有較大的正權重或負權重的輸入會對結果的輸出產生更大的影響。請記住,我們最初是通過為每個隨機數分配一個權重后開始的。
下面是這個神經網絡示例的訓練過程:
***步:從訓練數據集中提取輸入,根據訓練數據集的權重進行調整,并通過一種計算神經網絡輸出的方法對其進行篩選。
第二步:計算反向傳播錯誤率。在這種情況下,它是神經元的預測輸出與訓練數據集的期望輸出之間的差異。
第三步:利用誤差加權導數公式,根據所得到的誤差范圍,進行了一些較小的權值調整。
第四步:對這一過程進行15000次迭代。在每次迭代中,整個訓練集被同時處理。
我們使用“.T”函數將矩陣從水平位置轉換為垂直位置。因此,數字將以如下方式存儲:
最終,神經元的權重將根據所提供的訓練數據進行優化。隨后,如果讓神經元考慮一個新的狀態,與先前的狀態相同,它便可以作出一個準確的預測。這就是反向傳播的方式。
打包運行
***,NeuralNetwork類初始化成功后,可以運行代碼了。
下面是如何在Python項目中創建神經網絡的完整代碼:
- 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
- inputsinputs = 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!")
運行代碼之后的輸出:
這樣,我們便成功地創建了一個簡單的神經網絡。
神經元首先給自己分配一些隨機權重,接著,利用訓練實例進行了自我訓練。
之后,如果出現新的狀態[1,0,0],則它得出的數值為0.9999584。
還記得我們想要的正確答案是1嗎?
這個數值非常接近,Sigmoid函數輸出值在0到1之間。
當然,在這個例子中,我們只使用一個神經元網絡來完成簡單的任務。如果我們把幾千個人工神經網絡連接在一起,情況將會是怎樣呢?我們能不能完全模仿人類的思維方式呢?