├── README.md ├── __pycache__ ├── RBF1.cpython-36.pyc ├── RBF2.cpython-36.pyc ├── RBF3.cpython-36.pyc ├── Hopfile.cpython-36.pyc ├── IrisTest.cpython-36.pyc └── Perception.cpython-36.pyc ├── Perception.py ├── RBF2.py ├── RBF3.py ├── RBF1.py ├── iris.csv ├── GUI.py ├── Hopfile.py └── IrisTest.py /README.md: -------------------------------------------------------------------------------- 1 | 神经网络课程的实验,包括用感知器实现莺尾花分类,BP神经网络实现水果分类,RBF网络实现拟合函数,Hopfiled网络实现数字识别。里面包含一个简单的GUI,初学wxpython,只是实现一个事件绑定这样的功能,很简单。 -------------------------------------------------------------------------------- /__pycache__/RBF1.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ilannd/Neural-Network-experiment/HEAD/__pycache__/RBF1.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/RBF2.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ilannd/Neural-Network-experiment/HEAD/__pycache__/RBF2.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/RBF3.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ilannd/Neural-Network-experiment/HEAD/__pycache__/RBF3.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/Hopfile.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ilannd/Neural-Network-experiment/HEAD/__pycache__/Hopfile.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/IrisTest.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ilannd/Neural-Network-experiment/HEAD/__pycache__/IrisTest.cpython-36.pyc -------------------------------------------------------------------------------- /__pycache__/Perception.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ilannd/Neural-Network-experiment/HEAD/__pycache__/Perception.cpython-36.pyc -------------------------------------------------------------------------------- /Perception.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | import random 4 | 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | 8 | xh_number = 5000 9 | 10 | 11 | class My_Per: 12 | def __init__(self, lr=0.01): 13 | self.lr = lr 14 | self.errors = [] 15 | self.b = random.random() 16 | self.w = [random.uniform(-1, 1) for _ in range(2)] 17 | 18 | def train(self, Px, t): 19 | update = self.lr * (t - self.predict(Px)) 20 | self.b += update 21 | self.w[0] += update * Px[0] 22 | self.w[1] += update * Px[1] 23 | 24 | def predict(self, Px): 25 | number = self.w[0] * Px[0] + self.w[1] * Px[1] + self.b 26 | return np.where(number >= 0, 1, 0) 27 | 28 | 29 | def main(): 30 | P = [[3.6, 6.6], [9.3, 6.3], [7.1, 8.1], [4.0, 4.1], [4.2, 4.2], [2.8, 2.9], [7.1, 7.3], [9.2, 7.6], [8.1, 7.8], 31 | [2.9, 4.9], [9.3, 8.2], [4.2, 3.5]] 32 | T = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1] 33 | my_per = My_Per(0.01) 34 | plt.figure() 35 | x1 = [3.6, 2.9, 4.2, 4.0, 4.2, 2.8, 7.1, 9.2, 8.1, 9.3, 9.3, 7.1] 36 | x2 = [6.6, 4.9, 3.5, 4.1, 4.2, 2.9, 7.3, 7.6, 7.8, 6.3, 8.2, 8.1] 37 | plt.plot(x1[:6], x2[:6], "ro") 38 | plt.plot(x1[7:], x2[7:], "bo") 39 | # plt.scatter(x1, x2) 40 | for i in range(xh_number): 41 | for i in range(12): 42 | Px = P[i] 43 | t = T[i] 44 | my_per.train(Px, t) 45 | print(-my_per.w[0] / my_per.w[1]) 46 | print(-my_per.b / my_per.w[1]) 47 | x = np.arange(1, 13) 48 | y = -my_per.w[0] / my_per.w[1] * x - (my_per.b / my_per.w[1])*2.9 49 | # y=-(my_per.w[0]*x+my_per.b)/my_per.w[1] 50 | plt.plot(x, y) 51 | 52 | plt.show() 53 | 54 | 55 | if __name__ == "__main__": 56 | main() 57 | -------------------------------------------------------------------------------- /RBF2.py: -------------------------------------------------------------------------------- 1 | from scipy import * 2 | from scipy.linalg import norm, pinv 3 | 4 | from matplotlib import pyplot as plt 5 | 6 | 7 | class RBF: 8 | 9 | def __init__(self, indim, numCenters, outdim): 10 | self.indim = indim 11 | self.outdim = outdim 12 | self.numCenters = numCenters 13 | self.centers = [random.uniform(0.01, 1.5, indim) for i in range(numCenters)] 14 | self.beta = 8 15 | self.W = random.random((self.numCenters, self.outdim)) 16 | 17 | def _basisfunc(self, c, d): 18 | assert len(d) == self.indim 19 | return exp(-self.beta * norm(c - d) ** 2) 20 | 21 | def _calcAct(self, X): 22 | # calculate activations of RBFs 23 | G = zeros((X.shape[0], self.numCenters), float) 24 | for ci, c in enumerate(self.centers): 25 | for xi, x in enumerate(X): 26 | G[xi, ci] = self._basisfunc(c, x) 27 | return G 28 | 29 | def train(self, X, Y): 30 | """ X: matrix of dimensions n x indim 31 | y: column vector of dimension n x 1 """ 32 | 33 | # choose random center vectors from training set 34 | rnd_idx = random.permutation(X.shape[0])[:self.numCenters] 35 | self.centers = [X[i, :] for i in rnd_idx] 36 | 37 | print("center", self.centers) 38 | # calculate activations of RBFs 39 | G = self._calcAct(X) 40 | print(G) 41 | 42 | # calculate output weights (pseudoinverse) 43 | self.W = dot(pinv(G), Y) 44 | 45 | def test(self, X): 46 | """ X: matrix of dimensions n x indim """ 47 | 48 | G = self._calcAct(X) 49 | Y = dot(G, self.W) 50 | return Y 51 | 52 | 53 | def main(): 54 | n = 100 55 | x = mgrid[0:10:complex(0, n)].reshape(n, 1) 56 | y = 0.5 + 0.3 * sin(x) 57 | # rbf regression 58 | rbf = RBF(1, 100, 1) 59 | rbf.train(x,y) 60 | z = rbf.test(x) 61 | # plot original data 62 | plt.figure() 63 | plt.plot(x,y,'k-') 64 | # plot learned model 65 | plt.plot(x,z,'r-',linewidth=2) 66 | 67 | # plot rbfs 68 | # plt.plot(rbf.centers, zeros(rbf.numCenters), 'gs') 69 | '''for c in rbf.centers: 70 | # RF prediction lines 71 | cx = arange(c - 0.14, c + 0.14, 0.01) 72 | cy = [rbf._basisfunc(array([cx_]), array([c])) for cx_ in cx] 73 | plt.plot(cx, cy, '-', color='gray', linewidth=0.2)''' 74 | # plt.xlim(-1.2, 1.2) 75 | plt.show() 76 | 77 | 78 | -------------------------------------------------------------------------------- /RBF3.py: -------------------------------------------------------------------------------- 1 | from scipy import * 2 | from scipy.linalg import norm, pinv 3 | 4 | from matplotlib import pyplot as plt 5 | 6 | 7 | class RBF: 8 | 9 | def __init__(self, indim, numCenters, outdim): 10 | self.indim = indim 11 | self.outdim = outdim 12 | self.numCenters = numCenters 13 | self.centers = [random.uniform(0.01, 1.5, indim) for i in range(numCenters)] 14 | self.beta = 8 15 | self.W = random.random((self.numCenters, self.outdim)) 16 | 17 | def _basisfunc(self, c, d): 18 | assert len(d) == self.indim 19 | return exp(-self.beta * norm(c - d) ** 2) 20 | 21 | def _calcAct(self, X): 22 | # calculate activations of RBFs 23 | G = zeros((X.shape[0], self.numCenters), float) 24 | for ci, c in enumerate(self.centers): 25 | for xi, x in enumerate(X): 26 | G[xi, ci] = self._basisfunc(c, x) 27 | return G 28 | 29 | def train(self, X, Y): 30 | """ X: matrix of dimensions n x indim 31 | y: column vector of dimension n x 1 """ 32 | 33 | # choose random center vectors from training set 34 | rnd_idx = random.permutation(X.shape[0])[:self.numCenters] 35 | self.centers = [X[i, :] for i in rnd_idx] 36 | 37 | print("center", self.centers) 38 | # calculate activations of RBFs 39 | G = self._calcAct(X) 40 | print(G) 41 | 42 | # calculate output weights (pseudoinverse) 43 | self.W = dot(pinv(G), Y) 44 | 45 | def test(self, X): 46 | """ X: matrix of dimensions n x indim """ 47 | 48 | G = self._calcAct(X) 49 | Y = dot(G, self.W) 50 | return Y 51 | 52 | 53 | def main(): 54 | n = 100 55 | x = mgrid[0:10:complex(0, n)].reshape(n, 1) 56 | y = 0.5 + 0.3 * sin(2 * x) 57 | # rbf regression 58 | rbf = RBF(1, 100, 1) 59 | rbf.train(x,y) 60 | z = rbf.test(x) 61 | 62 | # plot original data 63 | plt.figure() 64 | plt.plot(x,y,'k-') 65 | plt.plot(x, y, 'k-') 66 | 67 | # plot learned model 68 | plt.plot(x,z,'r-',linewidth=2) 69 | 70 | # plot rbfs 71 | # plt.plot(rbf.centers, zeros(rbf.numCenters), 'gs') 72 | '''for c in rbf.centers: 73 | # RF prediction lines 74 | cx = arange(c - 0.14, c + 0.14, 0.01) 75 | cy = [rbf._basisfunc(array([cx_]), array([c])) for cx_ in cx] 76 | plt.plot(cx, cy, '-', color='gray', linewidth=0.2)''' 77 | # plt.xlim(-1.2, 1.2) 78 | plt.show() 79 | -------------------------------------------------------------------------------- /RBF1.py: -------------------------------------------------------------------------------- 1 | from scipy import * 2 | from scipy.linalg import norm, pinv 3 | 4 | from matplotlib import pyplot as plt 5 | 6 | 7 | class RBF: 8 | 9 | def __init__(self, indim, numCenters, outdim): 10 | self.indim = indim 11 | self.outdim = outdim 12 | self.numCenters = numCenters 13 | self.centers = [random.uniform(0.01, 1.5, indim) for i in range(numCenters)] 14 | self.beta = 8 15 | self.W = random.random((self.numCenters, self.outdim)) 16 | 17 | def _basisfunc(self, c, d): 18 | assert len(d) == self.indim 19 | return exp(-self.beta * norm(c - d) ** 2) 20 | 21 | def _calcAct(self, X): 22 | # calculate activations of RBFs 23 | G = zeros((X.shape[0], self.numCenters), float) 24 | for ci, c in enumerate(self.centers): 25 | for xi, x in enumerate(X): 26 | G[xi, ci] = self._basisfunc(c, x) 27 | return G 28 | 29 | def train(self, X, Y): 30 | """ X: matrix of dimensions n x indim 31 | y: column vector of dimension n x 1 """ 32 | 33 | # choose random center vectors from training set 34 | rnd_idx = random.permutation(X.shape[0])[:self.numCenters] 35 | self.centers = [X[i, :] for i in rnd_idx] 36 | 37 | print("center", self.centers) 38 | # calculate activations of RBFs 39 | G = self._calcAct(X) 40 | print(G) 41 | 42 | # calculate output weights (pseudoinverse) 43 | self.W = dot(pinv(G), Y) 44 | 45 | def test(self, X): 46 | """ X: matrix of dimensions n x indim """ 47 | 48 | G = self._calcAct(X) 49 | Y = dot(G, self.W) 50 | return Y 51 | 52 | 53 | def main(): 54 | n = 60 55 | x = mgrid[0.1:1.5:complex(0, n)].reshape(n, 1) 56 | # set y and add random noise 57 | y = exp(-x) 58 | # y += random.normal(0, 0.1, y.shape) 59 | # rbf regression 60 | rbf = RBF(1, 30, 1) 61 | rbf.train(x,y) 62 | z = rbf.test(x) 63 | # plot original data 64 | plt.figure() 65 | plt.plot(x,y,'k-') 66 | # plot learned model 67 | plt.plot(x,z,'r-',linewidth=2) 68 | 69 | # plot rbfs 70 | # plt.plot(rbf.centers, zeros(rbf.numCenters), 'gs') 71 | '''for c in rbf.centers: 72 | # RF prediction lines 73 | cx = arange(c - 0.14, c + 0.14, 0.01) 74 | cy = [rbf._basisfunc(array([cx_]), array([c])) for cx_ in cx] 75 | plt.plot(cx, cy, '-', color='gray', linewidth=0.2)''' 76 | # plt.xlim(-1.2, 1.2) 77 | plt.show() 78 | 79 | 80 | -------------------------------------------------------------------------------- /iris.csv: -------------------------------------------------------------------------------- 1 | Sepal_Length,Sepal_Width,Petal_Length,Petal_Width,Species 2 | 5.1,3.5,1.4,0.2,setosa 3 | 4.9,3,1.4,0.2,setosa 4 | 4.7,3.2,1.3,0.2,setosa 5 | 4.6,3.1,1.5,0.2,setosa 6 | 5,3.6,1.4,0.2,setosa 7 | 5.4,3.9,1.7,0.4,setosa 8 | 4.6,3.4,1.4,0.3,setosa 9 | 5,3.4,1.5,0.2,setosa 10 | 4.4,2.9,1.4,0.2,setosa 11 | 4.9,3.1,1.5,0.1,setosa 12 | 5.4,3.7,1.5,0.2,setosa 13 | 4.8,3.4,1.6,0.2,setosa 14 | 4.8,3,1.4,0.1,setosa 15 | 4.3,3,1.1,0.1,setosa 16 | 5.8,4,1.2,0.2,setosa 17 | 5.7,4.4,1.5,0.4,setosa 18 | 5.4,3.9,1.3,0.4,setosa 19 | 5.1,3.5,1.4,0.3,setosa 20 | 5.7,3.8,1.7,0.3,setosa 21 | 5.1,3.8,1.5,0.3,setosa 22 | 5.4,3.4,1.7,0.2,setosa 23 | 5.1,3.7,1.5,0.4,setosa 24 | 4.6,3.6,1,0.2,setosa 25 | 5.1,3.3,1.7,0.5,setosa 26 | 4.8,3.4,1.9,0.2,setosa 27 | 5,3,1.6,0.2,setosa 28 | 5,3.4,1.6,0.4,setosa 29 | 5.2,3.5,1.5,0.2,setosa 30 | 5.2,3.4,1.4,0.2,setosa 31 | 4.7,3.2,1.6,0.2,setosa 32 | 4.8,3.1,1.6,0.2,setosa 33 | 5.4,3.4,1.5,0.4,setosa 34 | 5.2,4.1,1.5,0.1,setosa 35 | 5.5,4.2,1.4,0.2,setosa 36 | 4.9,3.1,1.5,0.2,setosa 37 | 5,3.2,1.2,0.2,setosa 38 | 5.5,3.5,1.3,0.2,setosa 39 | 4.9,3.6,1.4,0.1,setosa 40 | 4.4,3,1.3,0.2,setosa 41 | 5.1,3.4,1.5,0.2,setosa 42 | 5,3.5,1.3,0.3,setosa 43 | 4.5,2.3,1.3,0.3,setosa 44 | 4.4,3.2,1.3,0.2,setosa 45 | 5,3.5,1.6,0.6,setosa 46 | 5.1,3.8,1.9,0.4,setosa 47 | 4.8,3,1.4,0.3,setosa 48 | 5.1,3.8,1.6,0.2,setosa 49 | 4.6,3.2,1.4,0.2,setosa 50 | 5.3,3.7,1.5,0.2,setosa 51 | 5,3.3,1.4,0.2,setosa 52 | 7,3.2,4.7,1.4,versicolor 53 | 6.4,3.2,4.5,1.5,versicolor 54 | 6.9,3.1,4.9,1.5,versicolor 55 | 5.5,2.3,4,1.3,versicolor 56 | 6.5,2.8,4.6,1.5,versicolor 57 | 5.7,2.8,4.5,1.3,versicolor 58 | 6.3,3.3,4.7,1.6,versicolor 59 | 4.9,2.4,3.3,1,versicolor 60 | 6.6,2.9,4.6,1.3,versicolor 61 | 5.2,2.7,3.9,1.4,versicolor 62 | 5,2,3.5,1,versicolor 63 | 5.9,3,4.2,1.5,versicolor 64 | 6,2.2,4,1,versicolor 65 | 6.1,2.9,4.7,1.4,versicolor 66 | 5.6,2.9,3.6,1.3,versicolor 67 | 6.7,3.1,4.4,1.4,versicolor 68 | 5.6,3,4.5,1.5,versicolor 69 | 5.8,2.7,4.1,1,versicolor 70 | 6.2,2.2,4.5,1.5,versicolor 71 | 5.6,2.5,3.9,1.1,versicolor 72 | 5.9,3.2,4.8,1.8,versicolor 73 | 6.1,2.8,4,1.3,versicolor 74 | 6.3,2.5,4.9,1.5,versicolor 75 | 6.1,2.8,4.7,1.2,versicolor 76 | 6.4,2.9,4.3,1.3,versicolor 77 | 6.6,3,4.4,1.4,versicolor 78 | 6.8,2.8,4.8,1.4,versicolor 79 | 6.7,3,5,1.7,versicolor 80 | 6,2.9,4.5,1.5,versicolor 81 | 5.7,2.6,3.5,1,versicolor 82 | 5.5,2.4,3.8,1.1,versicolor 83 | 5.5,2.4,3.7,1,versicolor 84 | 5.8,2.7,3.9,1.2,versicolor 85 | 6,2.7,5.1,1.6,versicolor 86 | 5.4,3,4.5,1.5,versicolor 87 | 6,3.4,4.5,1.6,versicolor 88 | 6.7,3.1,4.7,1.5,versicolor 89 | 6.3,2.3,4.4,1.3,versicolor 90 | 5.6,3,4.1,1.3,versicolor 91 | 5.5,2.5,4,1.3,versicolor 92 | 5.5,2.6,4.4,1.2,versicolor 93 | 6.1,3,4.6,1.4,versicolor 94 | 5.8,2.6,4,1.2,versicolor 95 | 5,2.3,3.3,1,versicolor 96 | 5.6,2.7,4.2,1.3,versicolor 97 | 5.7,3,4.2,1.2,versicolor 98 | 5.7,2.9,4.2,1.3,versicolor 99 | 6.2,2.9,4.3,1.3,versicolor 100 | 5.1,2.5,3,1.1,versicolor 101 | 5.7,2.8,4.1,1.3,versicolor 102 | 6.3,3.3,6,2.5,virginica 103 | 5.8,2.7,5.1,1.9,virginica 104 | 7.1,3,5.9,2.1,virginica 105 | 6.3,2.9,5.6,1.8,virginica 106 | 6.5,3,5.8,2.2,virginica 107 | 7.6,3,6.6,2.1,virginica 108 | 4.9,2.5,4.5,1.7,virginica 109 | 7.3,2.9,6.3,1.8,virginica 110 | 6.7,2.5,5.8,1.8,virginica 111 | 7.2,3.6,6.1,2.5,virginica 112 | 6.5,3.2,5.1,2,virginica 113 | 6.4,2.7,5.3,1.9,virginica 114 | 6.8,3,5.5,2.1,virginica 115 | 5.7,2.5,5,2,virginica 116 | 5.8,2.8,5.1,2.4,virginica 117 | 6.4,3.2,5.3,2.3,virginica 118 | 6.5,3,5.5,1.8,virginica 119 | 7.7,3.8,6.7,2.2,virginica 120 | 7.7,2.6,6.9,2.3,virginica 121 | 6,2.2,5,1.5,virginica 122 | 6.9,3.2,5.7,2.3,virginica 123 | 5.6,2.8,4.9,2,virginica 124 | 7.7,2.8,6.7,2,virginica 125 | 6.3,2.7,4.9,1.8,virginica 126 | 6.7,3.3,5.7,2.1,virginica 127 | 7.2,3.2,6,1.8,virginica 128 | 6.2,2.8,4.8,1.8,virginica 129 | 6.1,3,4.9,1.8,virginica 130 | 6.4,2.8,5.6,2.1,virginica 131 | 7.2,3,5.8,1.6,virginica 132 | 7.4,2.8,6.1,1.9,virginica 133 | 7.9,3.8,6.4,2,virginica 134 | 6.4,2.8,5.6,2.2,virginica 135 | 6.3,2.8,5.1,1.5,virginica 136 | 6.1,2.6,5.6,1.4,virginica 137 | 7.7,3,6.1,2.3,virginica 138 | 6.3,3.4,5.6,2.4,virginica 139 | 6.4,3.1,5.5,1.8,virginica 140 | 6,3,4.8,1.8,virginica 141 | 6.9,3.1,5.4,2.1,virginica 142 | 6.7,3.1,5.6,2.4,virginica 143 | 6.9,3.1,5.1,2.3,virginica 144 | 5.8,2.7,5.1,1.9,virginica 145 | 6.8,3.2,5.9,2.3,virginica 146 | 6.7,3.3,5.7,2.5,virginica 147 | 6.7,3,5.2,2.3,virginica 148 | 6.3,2.5,5,1.9,virginica 149 | 6.5,3,5.2,2,virginica 150 | 6.2,3.4,5.4,2.3,virginica 151 | 5.9,3,5.1,1.8,virginica 152 | -------------------------------------------------------------------------------- /GUI.py: -------------------------------------------------------------------------------- 1 | import wx 2 | import time 3 | 4 | from Test import IrisTest, Perception, Hopfile, RBF1, RBF2, RBF3 5 | 6 | ID_EXIT = 200 7 | ID_ABOUT = 201 8 | ID_MR = 100 9 | Version = "0.1" 10 | ReleaseDate = "2020-11-11" 11 | 12 | 13 | class MainFrame(wx.Frame): 14 | def __init__(self, parent, id, title): 15 | wx.Frame.__init__(self, parent, id, title, size=(500, 300)) 16 | # 状态栏的创建 17 | self.setupStatusBar() 18 | # 显示按钮功能 19 | self.initUi() 20 | # 菜单栏的创建 21 | self.setupMenuBar() 22 | 23 | def initUi(self): 24 | # 显示按钮功能 25 | self.button1 = wx.Button(self, -1, u"实验一", (100, 20), (60, 30)) # (20,20)表示在Frame里的左上角坐标位置,(60,30)表示Button大小 26 | self.Bind(wx.EVT_BUTTON, self.OnClick, 27 | self.button1) # 将wx.EVT_BUTTON绑定到self.buttonOK上,通过self.OnClick这个行为来实现它的功能 28 | 29 | self.button2 = wx.Button(self, -1, u"实验二", (100, 80), (60, 30)) 30 | self.Bind(wx.EVT_BUTTON, self.OnClick, self.button2) 31 | 32 | self.button3 = wx.Button(self, -1, u"实验三(1)", (200, 20), (60, 30)) 33 | self.Bind(wx.EVT_BUTTON, self.OnClick, self.button3) 34 | 35 | self.button4 = wx.Button(self, -1, u"实验三(2)", (200, 80), (60, 30)) 36 | self.Bind(wx.EVT_BUTTON, self.OnClick, self.button4) 37 | 38 | self.button5 = wx.Button(self, -1, u"实验三(3)", (300, 20), (60, 30)) 39 | self.Bind(wx.EVT_BUTTON, self.OnClick, self.button5) 40 | 41 | self.button6 = wx.Button(self, -1, u"实验四", (300, 80), (60, 30)) 42 | self.Bind(wx.EVT_BUTTON, self.OnClick, self.button6) 43 | 44 | 45 | def setupStatusBar(self): 46 | # 状态栏的创建 47 | sb = self.CreateStatusBar(2) # 创建状态栏,2的意思是有两个内容,分成两个 48 | self.SetStatusWidths([-1, -2]) # 分为两个,比例为1:2 49 | self.SetStatusText("Ready", 0) # Ready是里面的内容,0表示第一个 50 | # timer 51 | self.timer = wx.PyTimer(self.Notify) # derived from wx.Timer #Notify函数设置显示的时间格式 52 | self.timer.Start(1000, wx.TIMER_CONTINUOUS) # 1000表示1秒钟开始,后面的表示一直在跑不停 53 | self.Notify() 54 | 55 | def setupMenuBar(self): 56 | # 创建菜单栏 57 | # 主菜单 58 | menubar = wx.MenuBar() 59 | # 子菜单:退出(Quit) 60 | fmenu = wx.Menu() 61 | fmenu.Append(ID_EXIT, u'退出(&Q)', 'Terminate the program') 62 | # 将子菜单添加到文件(File)中 63 | menubar.Append(fmenu, u'文件(&F)') 64 | # 子菜单:关于(About) 65 | hmenu = wx.Menu() 66 | # 将子菜单添加到帮助(Help)中 67 | hmenu.Append(ID_ABOUT, u'关于(&A)', 'More information about this program') 68 | menubar.Append(hmenu, u'帮助(&H)') 69 | self.SetMenuBar(menubar) # 加入frame里面 70 | # 菜单中子菜单,时间行为的绑定即实现 71 | wx.EVT_MENU(self, ID_EXIT, self.OnMenuExit) 72 | wx.EVT_MENU(self, ID_ABOUT, self.OnMenuAbout) 73 | wx.EVT_CLOSE(self, self.OnCloseWindow) 74 | 75 | def OnClick(self, event): 76 | if event.GetEventObject() == self.button1: 77 | IrisTest.iris() 78 | elif event.GetEventObject() == self.button2: 79 | Perception.main() 80 | elif event.GetEventObject() == self.button3: 81 | RBF1.main() 82 | elif event.GetEventObject() == self.button4: 83 | RBF2.main() 84 | elif event.GetEventObject() == self.button5: 85 | RBF3.main() 86 | elif event.GetEventObject() == self.button6: 87 | Hopfile.main() 88 | else: 89 | print("NO button is clicked") 90 | 91 | def Notify(self): 92 | t = time.localtime(time.time()) 93 | st = time.strftime('%Y-%m-%d %H:%M:%S', t) 94 | self.SetStatusText(st, 1) # 将时间显示在后一个 95 | 96 | def OnMenuExit(self, event): 97 | self.Close() 98 | 99 | def OnMenuAbout(self, event): 100 | dlg = AboutDialog(None, -1) 101 | dlg.ShowModal() 102 | dlg.Destory() 103 | 104 | def OnCloseWindow(self, event): 105 | self.Destroy() 106 | 107 | 108 | class AboutDialog(wx.Dialog): 109 | def __init__(self, parent, id): 110 | wx.Dialog.__init__(self, parent, id, 'About Me', size=(200, 200)) 111 | # 布局管理 112 | self.sizer1 = wx.BoxSizer(wx.VERTICAL) 113 | self.sizer1.Add(wx.StaticText(self, -1, u"神经网络实验报告"), 0, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=20) 114 | self.sizer1.Add(wx.StaticText(self, -1, u"(C) 2020 吕玉玺"), 0, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=10) 115 | self.sizer1.Add(wx.StaticText(self, -1, u"Version %s , %s" % (Version, ReleaseDate)), 0, 116 | wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=10) 117 | self.sizer1.Add(wx.StaticText(self, -1, u"Author : 吕玉玺"), 0, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=10) 118 | self.sizer1.Add(wx.Button(self, wx.ID_OK), 0, wx.ALIGN_CENTER | wx.BOTTOM, border=20) 119 | self.SetSizer(self.sizer1) 120 | 121 | 122 | class App(wx.App): 123 | def __init__(self): 124 | # 如果要重写__init__,必须要调用wx.App的__init__,否则OnInit方法不会被调用 125 | super(self.__class__, self).__init__() 126 | # wx.App.__init__(self) 127 | 128 | def OnInit(self): 129 | self.version = u"报告" # 这里把"第二课“用Unicode编码,表示Unicode字符串,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时出现乱码 130 | self.title = u"神经网络实验" + self.version 131 | frame = MainFrame(None, -1, self.title) 132 | frame.Show(True) 133 | 134 | return True 135 | 136 | 137 | if __name__ == "__main__": 138 | app = App() 139 | app.MainLoop() 140 | -------------------------------------------------------------------------------- /Hopfile.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu May 16 15:37:25 2019 4 | 5 | @author: Dell 6 | """ 7 | 8 | import numpy as np 9 | from neupy import algorithms 10 | import random 11 | 12 | 13 | # 绘图 14 | def draw_bin_image(image_matrix): 15 | for row in image_matrix.tolist(): 16 | print('| ' + ' '.join(' *'[val] for val in row)) 17 | 18 | 19 | # 加噪函数,在记忆样本的基础上增加30%的噪声: 20 | def addnoise(Data): 21 | for x in range(0, 30): 22 | if random.randint(0, 10) > 8: 23 | Data[0, x] = random.randint(0, 1) 24 | 25 | return Data 26 | 27 | 28 | zero = np.matrix([ 29 | 0, 1, 1, 1, 0, 30 | 1, 0, 0, 0, 1, 31 | 1, 0, 0, 0, 1, 32 | 1, 0, 0, 0, 1, 33 | 1, 0, 0, 0, 1, 34 | 0, 1, 1, 1, 0 35 | ]) 36 | 37 | one = np.matrix([ 38 | 0, 1, 1, 0, 0, 39 | 0, 0, 1, 0, 0, 40 | 0, 0, 1, 0, 0, 41 | 0, 0, 1, 0, 0, 42 | 0, 0, 1, 0, 0, 43 | 0, 0, 1, 0, 0 44 | ]) 45 | 46 | two = np.matrix([ 47 | 1, 1, 1, 0, 0, 48 | 0, 0, 0, 1, 0, 49 | 0, 0, 0, 1, 0, 50 | 0, 1, 1, 0, 0, 51 | 1, 0, 0, 0, 0, 52 | 1, 1, 1, 1, 1, 53 | ]) 54 | three = np.matrix([ 55 | 1, 1, 1, 1, 1, 56 | 0, 0, 0, 0, 1, 57 | 1, 1, 1, 1, 0, 58 | 1, 1, 1, 1, 0, 59 | 0, 0, 0, 0, 1, 60 | 1, 1, 1, 1, 1, 61 | ]) 62 | four = np.matrix([ 63 | 0, 0, 1, 1, 0, 64 | 0, 1, 0, 1, 0, 65 | 1, 0, 0, 1, 0, 66 | 1, 1, 1, 1, 1, 67 | 0, 0, 0, 1, 0, 68 | 0, 0, 0, 1, 0, 69 | ]) 70 | five = np.matrix([ 71 | 1, 1, 1, 1, 1, 72 | 1, 0, 0, 0, 0, 73 | 1, 1, 1, 0, 0, 74 | 0, 0, 1, 1, 1, 75 | 0, 0, 0, 0, 1, 76 | 1, 1, 1, 1, 1, 77 | ]) 78 | six = np.matrix([ 79 | 0, 0, 1, 1, 0, 80 | 0, 1, 0, 0, 0, 81 | 1, 1, 1, 1, 0, 82 | 1, 0, 0, 0, 1, 83 | 1, 0, 0, 0, 1, 84 | 0, 1, 1, 1, 0, 85 | ]) 86 | seven = np.matrix([ 87 | 1, 1, 1, 1, 1, 88 | 0, 0, 0, 0, 1, 89 | 0, 0, 0, 1, 0, 90 | 0, 0, 1, 0, 0, 91 | 0, 1, 0, 0, 0, 92 | 1, 0, 0, 0, 0, 93 | ]) 94 | eight = np.matrix([ 95 | 1, 1, 1, 1, 1, 96 | 1, 0, 0, 0, 1, 97 | 0, 1, 1, 1, 0, 98 | 0, 1, 1, 1, 0, 99 | 1, 0, 0, 0, 1, 100 | 1, 1, 1, 1, 1, 101 | ]) 102 | nine = np.matrix([ 103 | 1, 1, 1, 1, 1, 104 | 1, 0, 0, 0, 1, 105 | 1, 0, 0, 0, 1, 106 | 1, 1, 1, 1, 1, 107 | 0, 0, 0, 1, 0, 108 | 1, 1, 1, 0, 0, 109 | ]) 110 | 111 | 112 | def main(): 113 | draw_bin_image(zero.reshape((6, 5))) 114 | print("\n") 115 | draw_bin_image(one.reshape((6, 5))) 116 | print("\n") 117 | draw_bin_image(two.reshape((6, 5))) 118 | print("\n") 119 | draw_bin_image(three.reshape((6, 5))) 120 | print("\n") 121 | draw_bin_image(four.reshape((6, 5))) 122 | print("\n") 123 | draw_bin_image(five.reshape((6, 5))) 124 | print("\n") 125 | draw_bin_image(six.reshape((6, 5))) 126 | print("\n") 127 | draw_bin_image(seven.reshape((6, 5))) 128 | print("\n") 129 | draw_bin_image(eight.reshape((6, 5))) 130 | print("\n") 131 | draw_bin_image(nine.reshape((6, 5))) 132 | print("\n") 133 | 134 | data = np.concatenate([zero, one, two, three, four], axis=0) 135 | dhnet = algorithms.DiscreteHopfieldNetwork(mode='sync') 136 | dhnet.train(data) 137 | ''' 138 | half_zero = np.matrix([ 139 | 0, 1, 1, 1, 0, 140 | 1, 0, 0, 0, 1, 141 | 1, 0, 0, 0, 1, 142 | 0, 0, 0, 0, 0, 143 | 0, 0, 0, 0, 0, 144 | 0, 0, 0, 0, 0, 145 | ])''' 146 | ran_zero = addnoise(zero) 147 | print("对数字0进行随机添加噪声") 148 | draw_bin_image(ran_zero.reshape((6, 5))) 149 | print("\n") 150 | result = dhnet.predict(ran_zero) 151 | print("对数字0进行联想记忆得到结果") 152 | draw_bin_image(result.reshape((6, 5))) 153 | print("\n") 154 | 155 | ran_one = addnoise(one) 156 | print("对数字1进行随机添加噪声") 157 | draw_bin_image(ran_one.reshape((6, 5))) 158 | print("\n") 159 | result = dhnet.predict(ran_one) 160 | print("对数字1进行联想记忆得到结果") 161 | draw_bin_image(result.reshape((6, 5))) 162 | print("\n") 163 | 164 | ran_two = addnoise(two) 165 | print("对数字2进行随机添加噪声") 166 | draw_bin_image(ran_two.reshape((6, 5))) 167 | print("\n") 168 | result = dhnet.predict(ran_two) 169 | print("对数字2进行联想记忆得到结果") 170 | draw_bin_image(result.reshape((6, 5))) 171 | print("\n") 172 | 173 | ran_three = addnoise(three) 174 | print("对数字3进行随机添加噪声") 175 | draw_bin_image(ran_three.reshape((6, 5))) 176 | print("\n") 177 | result = dhnet.predict(ran_three) 178 | print("对数字3进行联想记忆得到结果") 179 | draw_bin_image(result.reshape((6, 5))) 180 | print("\n") 181 | 182 | ran_four = addnoise(four) 183 | print("对数字4进行随机添加噪声") 184 | draw_bin_image(ran_four.reshape((6, 5))) 185 | print("\n") 186 | result = dhnet.predict(ran_four) 187 | print("对数字4进行联想记忆得到结果") 188 | draw_bin_image(result.reshape((6, 5))) 189 | print("\n") 190 | 191 | data = np.concatenate([five, six, seven, eight, nine], axis=0) 192 | dhnet = algorithms.DiscreteHopfieldNetwork(mode='sync') 193 | dhnet.train(data) 194 | ''' 195 | from neupy import utils 196 | utils.reproducible() 197 | 198 | dhnet.n_times = 400 199 | ''' 200 | ran_five = addnoise(five) 201 | print("对数字5进行随机添加噪声") 202 | draw_bin_image(ran_five.reshape((6, 5))) 203 | print("\n") 204 | result = dhnet.predict(ran_five) 205 | print("对数字5进行联想记忆得到结果") 206 | draw_bin_image(result.reshape((6, 5))) 207 | print("\n") 208 | 209 | ran_six = addnoise(six) 210 | print("对数字6进行随机添加噪声") 211 | draw_bin_image(ran_six.reshape((6, 5))) 212 | print("\n") 213 | result = dhnet.predict(ran_six) 214 | print("对数字6进行联想记忆得到结果") 215 | draw_bin_image(result.reshape((6, 5))) 216 | print("\n") 217 | 218 | ran_seven = addnoise(seven) 219 | print("对数字7进行随机添加噪声") 220 | draw_bin_image(ran_seven.reshape((6, 5))) 221 | print("\n") 222 | result = dhnet.predict(ran_seven) 223 | print("对数字7进行联想记忆得到结果") 224 | draw_bin_image(result.reshape((6, 5))) 225 | print("\n") 226 | 227 | ran_eight = addnoise(eight) 228 | print("对数字8进行随机添加噪声") 229 | draw_bin_image(ran_eight.reshape((6, 5))) 230 | print("\n") 231 | result = dhnet.predict(ran_eight) 232 | print("对数字8进行联想记忆得到结果") 233 | draw_bin_image(result.reshape((6, 5))) 234 | print("\n") 235 | 236 | ran_nine = addnoise(nine) 237 | print("对数字9进行随机添加噪声") 238 | draw_bin_image(ran_nine.reshape((6, 5))) 239 | print("\n") 240 | result = dhnet.predict(ran_nine) 241 | print("对数字9进行联想记忆得到结果") 242 | draw_bin_image(result.reshape((6, 5))) 243 | print("\n") 244 | 245 | 246 | if __name__ == "__main__": 247 | main() 248 | ''' 249 | half_two = np.matrix([ 250 | 0, 0, 0, 0, 0, 251 | 0, 0, 0, 0, 0, 252 | 0, 0, 0, 0, 0, 253 | 0, 1, 1, 0, 0, 254 | 1, 0, 0, 0, 0, 255 | 1, 1, 1, 1, 1, 256 | ]) 257 | 258 | draw_bin_image(half_two.reshape((6, 5))) 259 | print("\n") 260 | 261 | result = dhnet.predict(half_zero) 262 | draw_bin_image(result.reshape((6, 5))) 263 | print("\n") 264 | 265 | result = dhnet.predict(half_two) 266 | draw_bin_image(result.reshape((6, 5))) 267 | print("\n") 268 | ''' 269 | 270 | ''' 271 | half_two = np.matrix([ 272 | 1, 1, 1, 0, 0, 273 | 0, 0, 0, 1, 0, 274 | 0, 0, 0, 1, 0, 275 | 0, 0, 0, 0, 0, 276 | 0, 0, 0, 0, 0, 277 | 0, 0, 0, 0, 0, 278 | ]) 279 | 280 | result = dhnet.predict(half_two) 281 | draw_bin_image(result.reshape((6, 5))) 282 | print("\n") 283 | 284 | from neupy import utils 285 | utils.reproducible() 286 | 287 | dhnet.mode = 'async' 288 | dhnet.n_times = 400 289 | 290 | result = dhnet.predict(half_two) 291 | draw_bin_image(result.reshape((6, 5))) 292 | print("\n") 293 | 294 | result = dhnet.predict(half_two) 295 | draw_bin_image(result.reshape((6, 5))) 296 | print("\n") 297 | 298 | from neupy import plots 299 | import matplotlib.pyplot as plt 300 | 301 | plt.figure(figsize=(14, 12)) 302 | plt.title("Hinton diagram") 303 | plots.hinton(dhnet.weight) 304 | plt.show() 305 | ''' 306 | -------------------------------------------------------------------------------- /IrisTest.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import math 3 | import random 4 | import pandas as pd 5 | from matplotlib import pyplot as plt 6 | import numpy as np 7 | 8 | flowerLables = {0: 'Iris-setosa', 9 | 1: 'Iris-versicolor', 10 | 2: 'Iris-virginica'} 11 | 12 | random.seed(0) # 只要我们设置相同的seed,就能确保每次生成的随机数相同。如果不设置seed,则每次会生成不同的随机数 13 | 14 | 15 | # 生成区间[a, b)内的随机数 16 | def rand(a, b): 17 | return (b - a) * random.random() + a # random.random() 生成0—1之间的随机数 18 | 19 | 20 | # 生成大小 I*J 的矩阵,默认零矩阵 21 | def makeMatrix(I, J, fill=0.0): # fill = 0.0为默认值参数,调用函数可修改默认值 22 | m = [] 23 | for i in range(I): 24 | m.append([fill] * J) # m.append列表尾部追加成员; [0.0]是一个列表,列表支持乘法运算,[0.0]*5 的结果是[0.0 0.0 0.0 0.0 0.0 0.0] 25 | return m # 在列表尾部追加成员也是列表,所以返回的是个矩阵 26 | 27 | 28 | # 函数 sigmoid,bp神经网络前向传播的激活函数 29 | def sigmoid(x): 30 | return 1.0 / (1.0 + math.exp(-x)) 31 | 32 | 33 | # 函数 sigmoid 的导数,反向传播时使用 34 | def dsigmoid(x): 35 | return x * (1 - x) 36 | 37 | 38 | errors = [] 39 | 40 | 41 | class NN: 42 | """ 三层反向传播神经网络 """ 43 | 44 | def __init__(self, ni, nh, no): 45 | # 输入层、隐藏层、输出层的节点(数) 46 | self.ni = ni + 1 # 输入层增加一个偏差节点。定义一个实例属性self.ni记录输入节点个数 47 | self.nh = nh + 1 # 隐藏层增加一个偏置节点 48 | self.no = no # 输出层个数即为鸢尾花的种类数 49 | 50 | # 激活神经网络的所有节点(向量) 51 | self.ai = [1.0] * self.ni # 输入层神经元的激活项其实就是输入的特征数,这样设计是为了向量化前向传播过程。 52 | self.ah = [ 53 | 1.0] * self.nh # [1.0]是一个列表,列表支持乘法运算,[1.0]*5 的结果是[1.0 1.0 1.0 1.0 1.0 1.0]。偏置节点必定为1,也就是列表中第一个数为1,其他数依次记录隐藏层节点的激活项 54 | self.ao = [1.0] * self.no # 输出层输出的结果为预测该样本属于某一类的概率,概率最大者,则预测为该类 55 | 56 | # 建立权重(矩阵) 57 | self.wi = makeMatrix(self.ni, self.nh) # 定义一个实例属性self.wi记录输入层到隐藏层的映射矩阵 58 | self.wo = makeMatrix(self.nh, self.no) # python中类中可以直接调用全局函数makeMatrix()生成矩阵,默认零矩阵;隐藏层到输出层的映射矩阵。 59 | # 设为随机值,在做线性回归和逻辑回归时,一般将权重都初始化为0;但在神经网络中需要设为随机值,是因为如果权重矩阵为零矩阵的话,那么经过前向传播下一层神经元的激活项均相同 60 | for i in range(self.ni): # 上层循环控制行 61 | for j in range(self.nh): # 下层循环控制列 62 | self.wi[i][j] = rand(-0.2, 0.2) # 调用全局函数rand(),生成区间[-0.2, 0.2)内的随机数 63 | for j in range(self.nh): 64 | for k in range(self.no): 65 | self.wo[j][k] = rand(-2, 2) # 生成区间[-2, 2)内的随机数 66 | 67 | '''前向传播,激活神经网络的所有节点(向量)''' 68 | 69 | def update(self, inputs): 70 | if len(inputs) != self.ni - 1: # 输入的样本特征量数等于神经网络输入层数-1,因为有一个是偏置节点 71 | raise ValueError('与输入层节点数不符!') # 使用raise手工抛出异常,若引发该异常,中断程序 72 | 73 | # 激活输入层 74 | for i in range(self.ni - 1): # 输入层中的偏置节点 = 1,不用激活 75 | self.ai[i] = inputs[i] # 将输入样本的特征量赋值给神经网络输入层的其他节点 76 | 77 | # 激活隐藏层 78 | for j in range(self.nh): # self.nh表示隐藏层的节点数,包括隐藏层的第一个节点,也就是我们人为加的偏置节点,偏置节点恒为1,是不需要激活的;应该是self.nh -1,但原代码也并不影响结果 79 | sum = 0.0 # 激活项a = g(z) z = Θ^T x ;sum相当于z,每次循环归零 80 | for i in range(self.ni): # 通过循环z = Θ^T x ,因为Θ、x均为向量 81 | sum = sum + self.ai[i] * self.wi[i][j] # 〖 Z〗^((2))=Θ^((1)) a^((1)) 82 | self.ah[j] = sigmoid(sum) # a^((2))=g(z^((2))),这里使用sigmoid()函数作为激活函数 83 | 84 | # 激活输出层 85 | for k in range(self.no): 86 | sum = 0.0 87 | for j in range(self.nh): 88 | sum = sum + self.ah[j] * self.wo[j][k] # 〖 Z〗^((3))=Θ^((2)) a^((2)) 89 | self.ao[k] = sigmoid(sum) # a^((3))=g(z^((3))) 90 | 91 | return self.ao[:] # 返回输出值,即为某样本的预测值 92 | 93 | '''反向传播, 计算节点激活项的误差''' 94 | 95 | def backPropagate(self, targets, lr): # targets为某样本实际种类分类,lr为梯度下降算法的学习率 96 | 97 | # 计算输出层的误差 98 | output_deltas = [ 99 | 0.0] * self.no # 记录方向传播的误差;输出层误差容易求,把样本的实际值减去我们当前神经网络预测的值,δ^((3))=〖y-a〗^((3) );但是输出层的误差是由前面层一层一层累加的结果,我们将误差方向传播的过程叫方向传播算法。由算法知:δ^((2))=〖(Θ^((2)))〗^T δ^((3)).*g^' (z^((2))) 100 | for k in range(self.no): 101 | error = targets[k] - self.ao[k] # δ^((3))=〖y-a〗^((3) ),得到输出层的误差 102 | output_deltas[k] = dsigmoid( 103 | self.ao[k]) * error # dsigmoid()函数的功能是求公式中 g^' (z^((2))) 项,而output_deltas记录的是δ^((3)).*g^' (z^((2)))的值 104 | 105 | # 计算隐藏层的误差 106 | hidden_deltas = [0.0] * self.nh # 记录的是δ^((2)).*g^' (z^((1)))的值 107 | for j in range(self.nh): 108 | error = 0.0 109 | for k in range(self.no): 110 | error = error + output_deltas[k] * self.wo[j][k] # 求δ^((2)),隐藏层的误差 111 | hidden_deltas[j] = dsigmoid(self.ah[j]) * error 112 | 113 | # 更新输出层权重 114 | for j in range( 115 | self.nh): # 反向传播算法,求出每个节点的误差后,反向更新权重;由算法知Δ(_ij ^((L)))=Δ(_ij ^((L)))+a(_j ^((L)))δ(_i ^((L+1))) ,而∂/(∂Θ_ij^((L) ) ) J(Θ)=Δ_ij^((L)) (λ=0) λ为正则化系数。代入梯度下降算法中:Θ_ij^((L))=Θ_ij^((L))+α ∂/(∂Θ_ij^((L) ) ) J(Θ)即可更新权重 116 | for k in range(self.no): 117 | change = output_deltas[k] * self.ah[j] # 求 a(_j ^((L)))δ(_i ^((L+1))) 项 118 | self.wo[j][k] = self.wo[j][k] + lr * change # 用于梯度下降算法 119 | 120 | # 更新输入层权重 121 | for i in range(self.ni): # 与上同理 122 | for j in range(self.nh): 123 | change = hidden_deltas[j] * self.ai[i] 124 | self.wi[i][j] = self.wi[i][j] + lr * change 125 | 126 | # 计算误差 127 | error = 0.0 # 每调用一次先归零,不停地进行迭代 128 | error += 0.5 * (targets[k] - self.ao[k]) ** 2 # 神经网络的性能度量,其实就是均方误差少了除以整数,但不影响度量 129 | return error # 返回此时训练集的误差 130 | 131 | # 用测试集来测试训练过后的神经网络,输出准确率 132 | def test(self, patterns): # patterns为测试样本数据 133 | count = 0 # 记录测试样本的实际值与预测值相等的个数 134 | for p in patterns: 135 | target = flowerLables[ 136 | (p[1].index(1))] # p[1].index(1):返回p[1]列表中值为1的序号;而这序号正对应flowerLables字典中的键值。target存储的是样本实际种类类别 137 | result = self.update(p[0]) # 输入测试样本的特征值,返回的是对每种种类预测的概率 138 | index = result.index(max(result)) # 求出result列表中最大数值的序号 139 | print(p[0], ':', target, '->', flowerLables[index]) # 输出测试样本的特征值,实际输出,预测输出 140 | count += (target == flowerLables[ 141 | index]) # 若样本的实际值与预测值相等为真,加1。顺便提一下,其实flowerLables字典完全没有必要使用,我们只要确定p[1].index(1)与index相等即可 142 | accuracy = float(count / len(patterns)) # 求准确率 143 | print('accuracy: %-.9f' % accuracy) 144 | 145 | # 输出训练过后神经网络的权重矩阵 146 | def weights(self): 147 | print('输入层权重:') 148 | for i in range(self.ni): 149 | print() 150 | print('输出层权重:') 151 | for j in range(self.nh): 152 | print(self.wo[j]) 153 | 154 | # 用训练集训练神经网络 155 | def train(self, patterns, iterations=1000, 156 | lr=0.1): # patterns:训练集数据 iterations:迭代次数,默认值为1000;lr: 梯度下降算法中的学习速率(learning rate) 157 | for i in range(iterations): # 这里默认规定了梯度下降算法迭代的次数 158 | error = 0.0 # 记录每次迭代后的误差 159 | for p in patterns: # 将训练集的数据依次喂入神经网络输入层 160 | inputs = p[0] # inputs获取该样本的特征值 161 | targets = p[1] # targets获取该样本的种类类别 162 | self.update(inputs) # 前向传播,激活神经网络每个节点 163 | error = error + self.backPropagate(targets, lr) # 反向传播,算出每个节点的误差,并通过反向传播算法更新权重,算出此时的样本误差 164 | errors.append(error) 165 | if i % 100 == 0: # 方便我们观看样本误差变化情况 166 | print('error: %-.9f' % error) 167 | 168 | return errors 169 | 170 | 171 | def iris(): 172 | data = [] # 建立一个data列表,用来存放样本数据 173 | # 读取数据 174 | raw = pd.read_csv('iris.csv') # pd是pandas模块的重命名,pd.read_cs()函数读取本地文件iris.csv里数据。raw为DataFrame类型 175 | raw_data = raw.values # 将DataFrame类型转化为array类型 176 | raw_feature = raw_data[0:, 0:4] # 用冒号表达式取数,取第1-5列的数,也就是样本的特征值 177 | for i in range(len(raw_feature)): # 将数据保存在列表中,方便后面操作 178 | ele = [] 179 | ele.append(list(raw_feature[i])) # ele列表第一个元素保存该样本特征值 180 | if raw_data[i][4] == 'Iris-setosa': # 用向量表示种类类型,Iris-setosa用[1,0,0]表示 181 | ele.append([1, 0, 0]) # ele列表第二个元素该样本的种类 182 | elif raw_data[i][4] == 'Iris-versicolor': # Iris-versicolor用[0,1,0]表示 183 | ele.append([0, 1, 0]) 184 | else: 185 | ele.append([0, 0, 1]) # Iris-virginica用[0,0,1]表示 186 | data.append(ele) # 将ele列表作为一个元素加入到data列表中 187 | '''ele1=np.array(ele) 188 | cha=ele1.shape[0] 189 | y1 = [] 190 | for i in range(cha): 191 | if ele[i][0] == 1: 192 | y1.append(i) 193 | y2 = [] 194 | for i in range(cha): 195 | if ele[i][1] == 1: 196 | y2.append(i) 197 | y3 = [] 198 | for i in range(cha): 199 | if ele[i][2] == 1: 200 | y3.append(i) 201 | ''' 202 | # 随机排列数据 203 | random.shuffle(data) # 将样本次序随机打乱 204 | training = data[0:100] # 取序号0-100作为训练集 205 | test = data[101:] # 取序号100-150作为测试集 206 | nn = NN(4, 7, 3) # 用nn实例化NN类,同时调用构造函数建立bp神经网络结构 207 | nn.train(training, iterations=200) # 调用类中方法train(),通过反向传播算法训练权重 208 | nn.test(test) # 调用类中方法test(),用测试集来测试训练过后的神经网络 209 | x = np.arange(0, (len(errors))) 210 | plt.figure() 211 | plt.plot(x, errors) 212 | plt.xlabel("iteration") 213 | plt.ylabel("error") 214 | plt.show() 215 | 216 | 217 | # 当.py文件被直接运行时,iris()函数被运行;当.py文件以模块形式被导入时,iris()函数不被运行。可以认为这是程序的入口 218 | if __name__ == '__main__': 219 | iris() 220 | --------------------------------------------------------------------------------