python實現《機器學習》西瓜書習題5.7RBF網路解決異或問題
阿新 • • 發佈:2018-12-30
致敬:https://blog.csdn.net/Snoopy_Yuan/article/details/71024046
RBF首先是確定神經元中心點ci,對於異或,訓練集和驗證集構造0 1取值的二維資料,四個0-1點即為中心點。
然後根據103頁公式計算w和β,代入徑向基函式作為輸出
訓練10次後錯誤率已經是0,畢竟RBF是能以任意精度逼近任意連續函式的,異或麻麻地啦
主函式XOR_RBF.py
import numpy as np # train set X_trn = np.random.randint(0, 2, (100, 2)) #生成int隨機數 >=0且<2 y_trn = np.logical_xor(X_trn[:, 0], X_trn[:, 1]) # test set X_tst = np.random.randint(0, 2, (100, 2)) y_tst = np.logical_xor(X_tst[:, 0], X_tst[:, 1]) ''' implementation of RBF network ''' from RBF_BP import * # 神經元中心ci,因為隨機數在0和1取值,隨機取樣的中心點應該是如下四個 centers = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) # construct the network rbf_nn = RBP_network() # initial a BP network class rbf_nn.CreateNN(4, centers, learningrate=0.05) # build the network structure # parameter training e = [] for i in range(10): err, err_k = rbf_nn.TrainRBF(X_trn, y_trn) e.append(err) ''' model testing ''' y_pred = rbf_nn.Batch_Pred(X_tst); count = 0 for i in range(len(y_pred)): if y_pred[i] >= 0.5: y_pred[i] = True else: y_pred[i] = False if y_pred[i] == y_tst[i]: count += 1 tst_err = 1 - count / len(y_tst) print("test error rate: %.3f" % tst_err)
負責訓練的RBF_BP.py
class RBP_network: ''' the definition of BP network class ''' def __init__(self): ''' initial variables ''' # node number each layer # input neuron number equals to input variables' number self.h_n = 0 # output layer contains only one neuron # output value for each layer self.b = [] # hidden layer self.y = 0.0 # output # parameters (w, b, c) self.w = [] # weight of the link between hidden neuron and output neuron self.beta = [] # scale index of Gaussian-RBF self.c = [] # center of Gaussian-RBF] # initial the learning rate self.lr = 0.05 def CreateNN(self, nh, centers, learningrate): ''' build a RBF network structure and initial parameters @param nh : the neuron number of in layer @param centers: matrix [h_n * i_n] the center parameters object to hidden layer neurons @param learningrate: learning rate of gradient algorithm ''' # dependent packages import numpy as np # assignment of hidden neuron number self.h_n = nh # initial value of output for each layer self.b = np.zeros(self.h_n) # self.y = 0.0 # initial centers self.c = centers # initial weights for each link (random initialization) self.w = np.zeros(self.h_n) self.beta = np.zeros(self.h_n) for h in range(self.h_n): self.w[h] = rand(0, 1) self.beta[h] = rand(0, 1) # initial learning rate self.lr = learningrate def Pred(self, x): ''' predict process through the network @param x: array, input array for input layer @param y: float, output of the network ''' self.y = 0.0 # activate hidden layer and calculating output for h in range(self.h_n): self.b[h] = RBF(x, self.beta[h], self.c[h]) self.y += self.w[h] * self.b[h] return self.y def Batch_Pred(self, X): ''' predict process through the network for batch data @param x: array, data set for input layer @param y: array, output of the networks ''' y_pred = [] # activate hidden layer and calculating output for i in range(len(X)): y_pred.append(self.Pred(X[i])) return y_pred def BackPropagateRBF(self, x, y): ''' the implementation of special BP algorithm on one slide of sample for RBF network @param x, y: array and float, input and output of the data sample ''' # dependent packages import numpy as np # get current network output self.Pred(x) # calculate the gradient for hidden layer g = np.zeros(self.h_n) for h in range(self.h_n): g[h] = (self.y - y) * self.b[h] # updating the parameter for h in range(self.h_n): self.beta[h] += self.lr * g[h] * self.w[h] * np.linalg.norm(x - self.c[h], 2) self.w[h] -= self.lr * g[h] def TrainRBF(self, data_in, data_out): ''' BP training for RBF network @param data_in, data_out: @return e: accumulated error @return e_k: error array based on each step ''' e_k = [] for k in range(len(data_in)): x = data_in[k] y = data_out[k] self.BackPropagateRBF(x, y) # error in train set for each step y_delta2 = (self.y - y) ** 2 e_k.append(y_delta2 / 2) # total error of training e = sum(e_k) / len(e_k) return e, e_k def RBF(x, beta, c): ''' the definition of radial basis function (RBF) @param x: array, input variable @param beta: float, scale index @param c: array. center ''' # dependent packages from numpy.linalg import norm return norm(x - c, 2) #計算範數,2範數也就是歐氏距離 def rand(a, b): ''' the definition of random function @param a,b: the upper and lower limitation of the random value ''' # dependent packages from random import random return (b - a) * random() + a