1. 程式人生 > >python實現《機器學習》西瓜書習題5.7RBF網路解決異或問題

python實現《機器學習》西瓜書習題5.7RBF網路解決異或問題

致敬: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