Python基于K-均值、RLS算法实现RBF神经网络(神经网络与机器学习 第五章 计算机实验)

1、生成数据集

class moon_data_class(object):
    def __init__(self,N,d,r,w):
        self.N=N
        self.w=w
        self.d=d
        self.r=r
        
    def sgn(self,x):
        if(x>0):
            return 1;
        else:
            return -1;
        
    def sig(self,x):
        return 1.0/(1+np.exp(x))
    
        
    def dbmoon(self):
        N1 = 10*self.N
        N = self.N
        r = self.r
        w2 = self.w/2
        d = self.d
        done = True
        data = np.empty(0)
        while done:
            #generate Rectangular data
            tmp_x = 2*(r+w2)*(np.random.random([N1, 1])-0.5)
            tmp_y = (r+w2)*np.random.random([N1, 1])
            tmp = np.concatenate((tmp_x, tmp_y), axis=1)
            tmp_ds = np.sqrt(tmp_x*tmp_x + tmp_y*tmp_y)
            #generate double moon data ---upper
            idx = np.logical_and(tmp_ds > (r-w2), tmp_ds < (r+w2))
            idx = (idx.nonzero())[0]
     
            if data.shape[0] == 0:
                data = tmp.take(idx, axis=0)
            else:
                data = np.concatenate((data, tmp.take(idx, axis=0)), axis=0)
            if data.shape[0] >= N:
                done = False
        #print (data)
        db_moon = data[0:N, :]
        #print (db_moon)
        #generate double moon data ----down
        data_t = np.empty([N, 2])
        data_t[:, 0] = data[0:N, 0] + r
        data_t[:, 1] = -data[0:N, 1] - d
        db_moon = np.concatenate((db_moon, data_t), axis=0)
        return db_moon

2、定义RBF神经网络
2.1 RLS算法
在这里插入图片描述

class RBF_NET:
    def __init__(self,K,input_n,output_n):
        self.K = K
        self.input_n = input_n
        self.output_n = output_n
        self.x =[]
        self.y =[]
        self.k_point = []
        self.weight = [0] *  K
        self.Alpha = np.array([0] *  K)
        self.weight = [0] *  K
        self.weight = np.mat(self.weight).T
        self.center =[0] *  K
        self.Sigma = []

    def k_means(self,input_cells):
        k_count = self.K
        count = len(input_cells)      #点的个数
        x = input_cells[0:count, 0]
        y = input_cells[0:count, 1]
        #随机选择K个点
        k = rd.sample(range(count), k_count)
        
        self.k_point = [[x[i], [y[i]]] for i in k]   #保证有序
        self.k_point.sort()
    
        while True:
            km = [[] for i in range(k_count)]      #存储每个簇的索引
            #遍历所有点
            for i in range(count):
                cp = [x[i], y[i]]                   #当前点
                #计算cp点到所有质心的距离
                _sse = [distance(self.k_point[j], cp) for j in range(k_count)]
                #cp点到那个质心最近
                min_index = _sse.index(min(_sse))   
                #把cp点并入第i簇
                km[min_index].append(i)
            #更换质心
           
            k_new = []
            for i in range(k_count):
                _x = sum([x[j] for j in km[i]]) / len(km[i])
                _y = sum([y[j] for j in km[i]]) / len(km[i])
                k_new.append([_x, _y])
            k_new.sort()        #排序
        
            if (k_new != self.k_point):#一直循环直到聚类中心没有变化
                self.k_point = k_new
            else:
                pl.figure()
                pl.title("N=%d,k=%d  iteration"%(count,k_count))
                for j in range(k_count):
                    pl.plot([x[i] for i in km[j]], [y[i] for i in km[j]], color[j%4])
                    pl.plot(self.k_point[j][0], self.k_point[j][1], dcolor[j%4])
                pl.show()
                self.x =x
                self.y =y
                self.center = self.k_point
                return self.k_point,km
            
    def get_max_distance():
        pass
        
    def get_sigma_cov(self):
        k_count = self.K
        center_array = []
        for j in range(k_count):
           center_array.append([[self.x[i] for i in km[j]], [self.y[i] for i in km[j]]])
        Sigma_Cov = []
        distans_Max = []
        Sigma_Array = []
       
        Sigma = [0]*k_count
        for j in range(k_count):
            distans = []
            for i in range(len(center_array[j][0])):
                temp =  self.Phi(np.array([center_array[j][0][i],center_array[j][1][i]]),np.array(self.center[j]))
                distans.append(temp)
          
            distans = np.array(distans)
            
            temp = np.mean(distans)/np.sqrt(2*self.K)
           
            Sigma[j]=temp
            test = np.array(distans)
            Sigma_Array.append(np.cov(test))
           # Sigma_Cov.append(np.cov(Sigma))
        self.Sigma =np.array(Sigma)
        return Sigma
    
    def train(self,input_cells,labels,batch_size):
        Sigma_Array = self.get_sigma_cov()
        P = np.eye(self.K)*0.01
        # G = np.array([1] *  k_count)
        # self.Alpha = np.array([0] *  self.K)
        for batch in range(batch_size):
            i=0
            for input_data in input_cells:
                
                Phi_Arr = []
                for j in range(k_count):
                
                    temp =  self.Phi(np.array([input_data[0],input_data[1]]),np.array(center[j]))
                    temp1 = self.gaussian(temp,self.Sigma[j])
                    Phi_Arr.append(temp1)
                Phi_Arr = np.mat(Phi_Arr).T

                
                temp_1 = np.dot(P,np.mat(Phi_Arr)) 
                temp_2 = np.dot(temp_1,np.mat(Phi_Arr).T)
                temp_3 = np.dot(temp_2,np.mat(P))
                
                temp_4 = np.dot(Phi_Arr.T, P)
                temp_5 = np.dot(temp_4,Phi_Arr)
                P = P - temp_3/(1+temp_5)
                
                G =  np.dot(P,np.mat(Phi_Arr))         
                alpha = np.mat(labels[i]) - np.dot(self.weight.T,Phi_Arr)
                
                
                self.weight = self.weight + G*alpha
                i += 1
    def predict(self,input_data):
        Phi_Arr = []
        #print("input_data:",input_data)
        for j in range(k_count):
            temp =  self.Phi(input_data,np.array(self.k_point[j]))
            temp1 = self.gaussian(temp,self.Sigma[j])
            Phi_Arr.append(temp1)
        Phi_Arr = np.mat(Phi_Arr).T
                
        out_put = np.dot(self.weight.T,Phi_Arr)
        t = np.tanh(4*out_put[0][0])
        return t
        
    def Phi(self, a, b):
        return norm(a-b)

    def gaussian (self, x, sigma):
        return np.exp(-x**2 / (2 * sigma**2))

3、训练网络,打印结果

if __name__ == '__main__':
    
    #计算平面两点的欧氏距离
    step=0
    color=['.r','.g','.b','.y']#颜色种类
    dcolor=['*r','*g','*b','*y']#颜色种类
    frames = []
    
    N = 200
    d = -6
    r = 10
    width = 6
        
    data_source = moon_data_class(N, d, r, width)
    data = data_source.dbmoon()
     # x0 = [1 for x in range(1,401)]
    input_cells = np.array([np.reshape(data[0:2*N, 0], len(data)), np.reshape(data[0:2*N, 1], len(data))]).transpose()
        
    labels_pre = [[-1] for y in range(1, 201)]
    labels_pos = [[1] for y in range(1, 201)]
    labels=labels_pre+labels_pos
    
    
    k_count = 20 
    #center,km = k_means(input_cells, k_count)
    """test = Phi(input_cells[1],np.array(center[0]))
    print(test)
    test = distance(input_cells[1],np.array(center[0]))
    print(np.sqrt(test))"""
    count = len(input_cells)
    x = input_cells[0:count, 0]
    y = input_cells[0:count, 1]
    center_array = []
    
    RBF_NET = RBF_NET(k_count,1,1)
    center,km = RBF_NET.k_means(input_cells)
    RBF_NET.get_sigma_cov()
    RBF_NET.train(input_cells,labels,50)
    test_x = []
    test_y = []
    test_p = []
        
    y_p_old = 0
    
    #for x in input_cells:
    #    t =RBF_NET.predict(x)
    #    print(t)
                   
    for x in np.arange(-12.,15.,0.1):
        for y in np.arange(-10.,15.,0.1):
            y_p =RBF_NET.predict(np.array([x, y]))
            if(y_p_old > 0 and y_p[0] < 0):
                test_x.append(x)
                test_y.append(y)
                test_p.append([y_p_old,y_p[0]])
            y_p_old = y_p[0]
    #画决策边界
    plt.plot( test_x, test_y, 'g--')    
    plt.plot(data[0:N, 0], data[0:N, 1], 'r*', data[N:2*N, 0], data[N:2*N, 1], 'b*')
    plt.show() 
    

4、运行结果
在这里插入图片描述
在这里插入图片描述
完成代码

# coding:utf-8
import numpy as np
import pylab as pl
import random as rd
import math
import random
import matplotlib.pyplot as plt
import numpy as np
import mpl_toolkits.mplot3d
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from scipy import *
from scipy.linalg import norm, pinv
 
from matplotlib import pyplot as plt
random.seed(0)
class moon_data_class(object):
    def __init__(self,N,d,r,w):
        self.N=N
        self.w=w
      
        self.d=d
        self.r=r
    
   
    def sgn(self,x):
        if(x>0):
            return 1;
        else:
            return -1;
        
    def sig(self,x):
        return 1.0/(1+np.exp(x))
    
    def dbmoon(self):
        N1 = 10*self.N
        N = self.N
        r = self.r
        w2 = self.w/2
        d = self.d
        done = True
        data = np.empty(0)
        while done:
            #generate Rectangular data
            tmp_x = 2*(r+w2)*(np.random.random([N1, 1])-0.5)
            tmp_y = (r+w2)*np.random.random([N1, 1])
            tmp = np.concatenate((tmp_x, tmp_y), axis=1)
            tmp_ds = np.sqrt(tmp_x*tmp_x + tmp_y*tmp_y)
            #generate double moon data ---upper
            idx = np.logical_and(tmp_ds > (r-w2), tmp_ds < (r+w2))
            idx = (idx.nonzero())[0]
     
            if data.shape[0] == 0:
                data = tmp.take(idx, axis=0)
            else:
                data = np.concatenate((data, tmp.take(idx, axis=0)), axis=0)
            if data.shape[0] >= N:
                done = False
        db_moon = data[0:N, :]

        data_t = np.empty([N, 2])
        data_t[:, 0] = data[0:N, 0] + r
        data_t[:, 1] = -data[0:N, 1] - d
        db_moon = np.concatenate((db_moon, data_t), axis=0)
        return db_moon
        
class RBF_NET:
    def __init__(self,K,input_n,output_n):
        self.K = K
        self.input_n = input_n
        self.output_n = output_n
        self.x =[]
        self.y =[]
        self.k_point = []
        self.weight = [0] *  K
        self.Alpha = np.array([0] *  K)
        self.weight = [0] *  K
        self.weight = np.mat(self.weight).T
        self.center =[0] *  K
        self.Sigma = []
        #self.weight = np.mat(self.weight).T

    def k_means(self,input_cells):
        k_count = self.K
        count = len(input_cells)      #点的个数
        x = input_cells[0:count, 0]
        y = input_cells[0:count, 1]
        #随机选择K个点
        k = rd.sample(range(count), k_count)
        
        self.k_point = [[x[i], [y[i]]] for i in k]   #保证有序
        self.k_point.sort()
    
        while True:
            km = [[] for i in range(k_count)]      #存储每个簇的索引
            #遍历所有点
            for i in range(count):
                cp = [x[i], y[i]]                   #当前点
                #计算cp点到所有质心的距离
                _sse = [distance(self.k_point[j], cp) for j in range(k_count)]
                #cp点到那个质心最近
                min_index = _sse.index(min(_sse))   
                #把cp点并入第i簇
                km[min_index].append(i)
            #更换质心
           
            k_new = []
            for i in range(k_count):
                _x = sum([x[j] for j in km[i]]) / len(km[i])
                _y = sum([y[j] for j in km[i]]) / len(km[i])
                k_new.append([_x, _y])
            k_new.sort()        #排序
        
            if (k_new != self.k_point):#一直循环直到聚类中心没有变化
                self.k_point = k_new
            else:
                pl.figure()
                pl.title("N=%d,k=%d  iteration"%(count,k_count))
                for j in range(k_count):
                    pl.plot([x[i] for i in km[j]], [y[i] for i in km[j]], color[j%4])
                    pl.plot(self.k_point[j][0], self.k_point[j][1], dcolor[j%4])
                pl.show()
                self.x =x
                self.y =y
                self.center = self.k_point
                return self.k_point,km
            
    def get_max_distance():
        pass
        
    def get_sigma_cov(self):
        k_count = self.K
        center_array = []
        for j in range(k_count):
           center_array.append([[self.x[i] for i in km[j]], [self.y[i] for i in km[j]]])
        Sigma_Cov = []
        distans_Max = []
        Sigma_Array = []
       
        Sigma = [0]*k_count
        for j in range(k_count):
            distans = []
            for i in range(len(center_array[j][0])):
                temp =  self.Phi(np.array([center_array[j][0][i],center_array[j][1][i]]),np.array(self.center[j]))
                distans.append(temp)
          
            distans = np.array(distans)
            
            temp = np.mean(distans)/np.sqrt(2*self.K)
           
            Sigma[j]=temp
            test = np.array(distans)
            Sigma_Array.append(np.cov(test))
           # Sigma_Cov.append(np.cov(Sigma))
        self.Sigma =np.array(Sigma)
        return Sigma
    
    def train(self,input_cells,labels,batch_size):
        Sigma_Array = self.get_sigma_cov()
        P = np.eye(self.K)*0.01
        # G = np.array([1] *  k_count)
        # self.Alpha = np.array([0] *  self.K)
        for batch in range(batch_size):
            i=0
            for input_data in input_cells:
                
                Phi_Arr = []
                for j in range(k_count):
                
                    temp =  self.Phi(np.array([input_data[0],input_data[1]]),np.array(center[j]))
                    temp1 = self.gaussian(temp,self.Sigma[j])
                    Phi_Arr.append(temp1)
                Phi_Arr = np.mat(Phi_Arr).T
                print
                
                temp_1 = np.dot(P,np.mat(Phi_Arr)) 
                temp_2 = np.dot(temp_1,np.mat(Phi_Arr).T)
                temp_3 = np.dot(temp_2,np.mat(P))
                
                temp_4 = np.dot(Phi_Arr.T, P)
                temp_5 = np.dot(temp_4,Phi_Arr)
                P = P - temp_3/(1+temp_5)
                
                G =  np.dot(P,np.mat(Phi_Arr))         
                alpha = np.mat(labels[i]) - np.dot(self.weight.T,Phi_Arr)
                
                
                self.weight = self.weight + G*alpha
                i += 1
    def predict(self,input_data):
        Phi_Arr = []
        #print("input_data:",input_data)
        for j in range(k_count):
            temp =  self.Phi(input_data,np.array(self.k_point[j]))
            temp1 = self.gaussian(temp,self.Sigma[j])
            Phi_Arr.append(temp1)
        Phi_Arr = np.mat(Phi_Arr).T
                
        out_put = np.dot(self.weight.T,Phi_Arr)
        t = np.tanh(4*out_put[0][0])
        return t
        
    def Phi(self, a, b):
        return norm(a-b)

    def gaussian (self, x, sigma):
        return np.exp(-x**2 / (2 * sigma**2))
    
if __name__ == '__main__':
    
    #计算平面两点的欧氏距离
    step=0
    color=['.r','.g','.b','.y']#颜色种类
    dcolor=['*r','*g','*b','*y']#颜色种类
    frames = []
    
    N = 200
    d = -6
    r = 10
    width = 6
        
    data_source = moon_data_class(N, d, r, width)
    data = data_source.dbmoon()
 
    input_cells = np.array([np.reshape(data[0:2*N, 0], len(data)), np.reshape(data[0:2*N, 1], len(data))]).transpose()
        
    labels_pre = [[-1] for y in range(1, 201)]
    labels_pos = [[1] for y in range(1, 201)]
    labels=labels_pre+labels_pos

    k_count = 20 

    count = len(input_cells)
    x = input_cells[0:count, 0]
    y = input_cells[0:count, 1]
    center_array = []
    
    RBF_NET = RBF_NET(k_count,1,1)
    center,km = RBF_NET.k_means(input_cells)
    RBF_NET.get_sigma_cov()
    RBF_NET.train(input_cells,labels,50)
    test_x = []
    test_y = []
    test_p = []
        
    y_p_old = 0
         
    for x in np.arange(-12.,15.,0.1):
        for y in np.arange(-10.,15.,0.1):
            y_p =RBF_NET.predict(np.array([x, y]))
            if(y_p_old > 0 and y_p[0] < 0):
                test_x.append(x)
                test_y.append(y)
                test_p.append([y_p_old,y_p[0]])
            y_p_old = y_p[0]
    #画决策边界
    plt.plot( test_x, test_y, 'g--')    
    plt.plot(data[0:N, 0], data[0:N, 1], 'r*', data[N:2*N, 0], data[N:2*N, 1], 'b*')
    plt.show() 
  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值