本文實例講述了Python實現的人工神經網絡算法。分享給大家供大家參考,具體如下:
注意:本程序使用Python3編寫,額外需要安裝numpy工具包用於矩陣運算,未測試python2是否可以運行。
本程序實現了《機器學習》書中所述的反向傳播算法訓練人工神經網絡,理論部分請參考我的讀書筆記。
在本程序中,目標函數是由一個輸入x和兩個輸出y組成,
x是在範圍【-3.14, 3.14】之間隨機生成的實數,而兩個y值分別對應 y1 = sin(x),y2 = 1。
隨機生成一萬份訓練樣例,經過網絡的學習訓練後,再用隨機生成的五份測試數據驗證訓練結果。
調節算法的學習速率,以及隱藏層個數、隱藏層大小,訓練新的網絡,可以觀察到參數對於學習結果的影響。
算法代碼如下:
#!usr/bin/env python3
# -*- coding:utf-8 -*-
import numpy as np
import math
# definition of sigmoid funtion
# numpy.exp work for arrays.
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# definition of sigmoid derivative funtion
# input must be sigmoid function's result
def sigmoid_output_to_derivative(result):
return result*(1-result)
# init training set
def getTrainingSet(nameOfSet):
setDict = {
"sin": getSinSet(),
}
return setDict[nameOfSet]
def getSinSet():
x = 6.2 * np.random.rand(1) - 3.14
x = x.reshape(1,1)
# y = np.array([5 *x]).reshape(1,1)
# y = np.array([math.sin(x)]).reshape(1,1)
y = np.array([math.sin(x),1]).reshape(1,2)
return x, y
def getW(synapse, delta):
resultList = []
# 遍歷隱藏層每個隱藏單元對每個輸出的權值,比如8個隱藏單元,每個隱藏單元對兩個輸出各有2個權值
for i in range(synapse.shape[0]):
resultList.append(
(synapse[i,:] * delta).sum()
)
resultArr = np.array(resultList).reshape(1, synapse.shape[0])
return resultArr
def getT(delta, layer):
result = np.dot(layer.T, delta)
return result
def backPropagation(trainingExamples, etah, input_dim, output_dim, hidden_dim, hidden_num):
# 可行條件
if hidden_num < 1:
print("隱藏層數不得小於1")
return
# 初始化網絡權重矩陣,這個是核心
synapseList = []
# 輸入層與隱含層1
synapseList.append(2*np.random.random((input_dim,hidden_dim)) - 1)
# 隱含層1與隱含層2, 2->3,,,,,,n-1->n
for i in range(hidden_num-1):
synapseList.append(2*np.random.random((hidden_dim,hidden_dim)) - 1)
# 隱含層n與輸出層
synapseList.append(2*np.random.random((hidden_dim,output_dim)) - 1)
iCount = 0
lastErrorMax = 99999
# while True:
for i in range(10000):
errorMax = 0
for x, y in trainingExamples:
iCount += 1
layerList = []
# 正向傳播
layerList.append(
sigmoid(np.dot(x,synapseList[0]))
)
for j in range(hidden_num):
layerList.append(
sigmoid(np.dot(layerList[-1],synapseList[j+1]))
)
# 對於網絡中的每個輸出單元k,計算它的誤差項
deltaList = []
layerOutputError = y - layerList[-1]
# 收斂條件
errorMax = layerOutputError.sum() if layerOutputError.sum() > errorMax else errorMax
deltaK = sigmoid_output_to_derivative(layerList[-1]) * layerOutputError
deltaList.append(deltaK)
iLength = len(synapseList)
for j in range(hidden_num):
w = getW(synapseList[iLength - 1 - j], deltaList[j])
delta = sigmoid_output_to_derivative(layerList[iLength - 2 - j]) * w
deltaList.append(delta)
# 更新每個網絡權值w(ji)
for j in range(len(synapseList)-1, 0, -1):
t = getT(deltaList[iLength - 1 -j], layerList[j-1])
synapseList[j] = synapseList[j] + etah * t
t = getT(deltaList[-1], x)
synapseList[0] = synapseList[0] + etah * t
print("最大輸出誤差:")
print(errorMax)
if abs(lastErrorMax - errorMax) < 0.0001:
print("收斂了")
print("####################")
break
lastErrorMax = errorMax
# 測試訓練好的網絡
for i in range(5):
xTest, yReal = getSinSet()
layerTmp = sigmoid(np.dot(xTest,synapseList[0]))
for j in range(1, len(synapseList), 1):
layerTmp = sigmoid(np.dot(layerTmp,synapseList[j]))
yTest = layerTmp
print("x:")
print(xTest)
print("實際的y:")
print(yReal)
print("神經元網絡輸出的y:")
print(yTest)
print("最終輸出誤差:")
print(np.abs(yReal - yTest))
print("#####################")
print("迭代次數:")
print(iCount)
if __name__ == '__main__':
import datetime
tStart = datetime.datetime.now()
# 使用什麼樣的訓練樣例
nameOfSet = "sin"
x, y = getTrainingSet(nameOfSet)
# setting of parameters
# 這裏設置了學習速率。
etah = 0.01
# 隱藏層數
hidden_num = 2
# 網絡輸入層的大小
input_dim = x.shape[1]
# 隱含層的大小
hidden_dim = 100
# 輸出層的大小
output_dim = y.shape[1]
# 構建訓練樣例
trainingExamples = []
for i in range(10000):
x, y = getTrainingSet(nameOfSet)
trainingExamples.append((x, y))
# 開始用反向傳播算法訓練網絡
backPropagation(trainingExamples, etah, input_dim, output_dim, hidden_dim, hidden_num)
tEnd = datetime.datetime.now()
print("time cost:")
print(tEnd - tStart)
最後給大家推薦一個口碑不錯的python聚集地【點擊進入】,這裏有很多的老前輩學習技巧,學習心得,面試技巧,職場經歷等分享,更爲大家精心準備了零基礎入門資料,實戰項目資料,每天都有程序員定時講解Python技術,分享一些學習的方法和需要留意的小細節