Python實(shí)現(xiàn)的人工神經(jīng)網(wǎng)絡(luò)算法示例【基于反向傳播算法】
本文實(shí)例講述了Python實(shí)現(xiàn)的人工神經(jīng)網(wǎng)絡(luò)算法。分享給大家供大家參考,具體如下:
注意:本程序使用Python3編寫,額外需要安裝numpy工具包用于矩陣運(yùn)算,未測試python2是否可以運(yùn)行。
本程序?qū)崿F(xiàn)了《機(jī)器學(xué)習(xí)》書中所述的反向傳播算法訓(xùn)練人工神經(jīng)網(wǎng)絡(luò),理論部分請參考我的讀書筆記。
在本程序中,目標(biāo)函數(shù)是由一個(gè)輸入x和兩個(gè)輸出y組成,
x是在范圍【-3.14, 3.14】之間隨機(jī)生成的實(shí)數(shù),而兩個(gè)y值分別對(duì)應(yīng) y1 = sin(x),y2 = 1。
隨機(jī)生成一萬份訓(xùn)練樣例,經(jīng)過網(wǎng)絡(luò)的學(xué)習(xí)訓(xùn)練后,再用隨機(jī)生成的五份測試數(shù)據(jù)驗(yàn)證訓(xùn)練結(jié)果。
調(diào)節(jié)算法的學(xué)習(xí)速率,以及隱藏層個(gè)數(shù)、隱藏層大小,訓(xùn)練新的網(wǎng)絡(luò),可以觀察到參數(shù)對(duì)于學(xué)習(xí)結(jié)果的影響。
算法代碼如下:
#!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 = []
# 遍歷隱藏層每個(gè)隱藏單元對(duì)每個(gè)輸出的權(quán)值,比如8個(gè)隱藏單元,每個(gè)隱藏單元對(duì)兩個(gè)輸出各有2個(gè)權(quán)值
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("隱藏層數(shù)不得小于1")
return
# 初始化網(wǎng)絡(luò)權(quán)重矩陣,這個(gè)是核心
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]))
)
# 對(duì)于網(wǎng)絡(luò)中的每個(gè)輸出單元k,計(jì)算它的誤差項(xiàng)
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)
# 更新每個(gè)網(wǎng)絡(luò)權(quán)值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
# 測試訓(xùn)練好的網(wǎng)絡(luò)
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("實(shí)際的y:")
print(yReal)
print("神經(jīng)元網(wǎng)絡(luò)輸出的y:")
print(yTest)
print("最終輸出誤差:")
print(np.abs(yReal - yTest))
print("#####################")
print("迭代次數(shù):")
print(iCount)
if __name__ == '__main__':
import datetime
tStart = datetime.datetime.now()
# 使用什么樣的訓(xùn)練樣例
nameOfSet = "sin"
x, y = getTrainingSet(nameOfSet)
# setting of parameters
# 這里設(shè)置了學(xué)習(xí)速率。
etah = 0.01
# 隱藏層數(shù)
hidden_num = 2
# 網(wǎng)絡(luò)輸入層的大小
input_dim = x.shape[1]
# 隱含層的大小
hidden_dim = 100
# 輸出層的大小
output_dim = y.shape[1]
# 構(gòu)建訓(xùn)練樣例
trainingExamples = []
for i in range(10000):
x, y = getTrainingSet(nameOfSet)
trainingExamples.append((x, y))
# 開始用反向傳播算法訓(xùn)練網(wǎng)絡(luò)
backPropagation(trainingExamples, etah, input_dim, output_dim, hidden_dim, hidden_num)
tEnd = datetime.datetime.now()
print("time cost:")
print(tEnd - tStart)
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python加密解密算法與技巧總結(jié)》、《Python編碼操作技巧總結(jié)》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》及《Python入門與進(jìn)階經(jīng)典教程》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
相關(guān)文章
python二進(jìn)制串轉(zhuǎn)字符串的方法詳解
這篇文章主要介紹了python二進(jìn)制串轉(zhuǎn)字符串的方法詳解,使用json,可以自動(dòng)檢測編碼,但需要注意的是,它返回的是python對(duì)象,不一定是字符串,具體是什么對(duì)象要視原始內(nèi)容而定,需要的朋友可以參考下2023-11-11
在pycharm中運(yùn)行js文件以及附加node.js下載步驟
js文件需要用node來運(yùn)行,所以首先要安裝node軟件,下面這篇文章主要給大家介紹了關(guān)于在pycharm中運(yùn)行js文件以及附加node.js下載步驟的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
PyQt5中多線程模塊QThread使用方法的實(shí)現(xiàn)
這篇文章主要介紹了PyQt5中多線程模塊QThread使用方法的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
如何解決jupyter notebook無法導(dǎo)入自己安裝的包
這篇文章主要介紹了如何解決jupyter notebook無法導(dǎo)入自己安裝的包問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
Python+Appium自動(dòng)化操作微信的教程分享
Appium?是一個(gè)開源的自動(dòng)化測試工具,支持?Android、iOS?平臺(tái)上的原生應(yīng)用,支持?Java、Python、PHP?等多種語言。本文主要介紹了Python+Appium自動(dòng)化操作微信的教程,希望對(duì)大家有所幫助2023-01-01

