本文實例講述了Python實現的人工神經網絡算法。分享給大家供大家參考,具體如下:
注意:本程序使用Python3編寫,額外需要安裝numpy工具包用于矩陣運算,未測試python2是否可以運行。
本程序實現了《機器學習》書中所述的反向傳播算法訓練人工神經網絡,理論部分請參考我的讀書筆記。
在本程序中,目標函數是由一個輸入x和兩個輸出y組成,
x是在范圍【-3.14, 3.14】之間隨機生成的實數,而兩個y值分別對應 y1 = sin(x),y2 = 1。
隨機生成一萬份訓練樣例,經過網絡的學習訓練后,再用隨機生成的五份測試數據驗證訓練結果。
調節算法的學習速率,以及隱藏層個數、隱藏層大小,訓練新的網絡,可以觀察到參數對于學習結果的影響。
算法代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#!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程序設計有所幫助。
原文鏈接:http://blog.csdn.net/miangangzhen/article/details/51281989