Python实现多层感知器MLP(基于双月数据集)

1、加载必要的库,生成数据集


import math
import random
import matplotlib.pyplot as plt
import numpy as np
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、定义激活函数

def rand(a,b):
    return (b-a)* random.random()+a

def sigmoid(x):
    #return np.tanh(-2.0*x)
    return 1.0/(1.0+math.exp(-x))
def sigmoid_derivate(x):
    #return -2.0*(1.0-np.tanh(-2.0*x)*np.tanh(-2.0*x))
    return x*(1-x) #sigmoid函数的导数
def make_matrix(m,n, fill = 0.0):
    mat=[]
    for i in range(m):
        mat.append([fill]*n)

3、定义神经网络

class BP_NET(object):
    def __init__(self):
        self.input_n = 0
        self.hidden_n = 0
        self.output_n = 0
        self.input_cells = []
        self.bias_input_n = []
        self.bias_output = []
        self.hidden_cells = []
        self.output_cells = []
        self.input_weights = []
        self.output_weights = []
        
        self.input_correction = []
        self.output_correction = []
    
    def setup(self, ni,nh,no):
        self.input_n = ni+1#输入层+偏置项
        self.hidden_n = nh
        self.output_n = no
        self.input_cells = [1.0]*self.input_n
        self.hidden_cells = [1.0]*self.hidden_n
        self.output_cells = [1.0]*self.output_n
        
        self.input_weights = make_matrix(self.input_n,self.hidden_n)
        self.output_weights = make_matrix(self.hidden_n,self.output_n)
        
        for i in range(self.input_n):
            for h in range(self.hidden_n):
                self.input_weights[i][h] = rand(-0.2,0.2)
        
        for h in range(self.hidden_n):
            for o in range(self.output_n):
                self.output_weights[h][o] = rand(-2.0,2.0)
        
        self.input_correction = make_matrix(self.input_n , self.hidden_n)
        self.output_correction = make_matrix(self.hidden_n,self.output_n)
                
    def predict(self,inputs):
        for i in range(self.input_n-1):
            self.input_cells[i] = inputs[i]
        
        for j in range(self.hidden_n):
            total = 0.0
            for i in range(self.input_n):
                total += self.input_cells[i] * self.input_weights[i][j]
            self.hidden_cells[j] = sigmoid(total)
            
        for k in range(self.output_n):
            total = 0.0
            for j in range(self.hidden_n):
               total+= self.hidden_cells[j]*self.output_weights[j][k]# + self.bias_output[k]
               
            self.output_cells[k] = sigmoid(total)
        return self.output_cells[:]
    
    def back_propagate(self, case,label,learn,correct):
        #计算得到输出output_cells
        self.predict(case)
        output_deltas = [0.0]*self.output_n
        error = 0.0
        #计算误差 = 期望输出-实际输出
        for o in range(self.output_n):
            error = label[o] - self.output_cells[o] #正确结果和预测结果的误差:0,1,-1
            output_deltas[o]= sigmoid_derivate(self.output_cells[o])*error#误差稳定在0~1内
 
        hidden_deltas = [0.0] * self.hidden_n
        for j in range(self.hidden_n):
            error = 0.0
            for k in range(self.output_n):
                error+= output_deltas[k]*self.output_weights[j][k]
            hidden_deltas[j] = sigmoid_derivate(self.hidden_cells[j])*error 

        for h in range(self.hidden_n):
            for o in range(self.output_n):
                change = output_deltas[o]*self.hidden_cells[h]
                #调整权重:上一层每个节点的权重学习*变化+矫正率
                self.output_weights[h][o] += learn*change 
        #更新输入->隐藏层的权重
        for i in range(self.input_n):
            for h in range(self.hidden_n):
                change = hidden_deltas[h]*self.input_cells[i]
                self.input_weights[i][h] += learn*change 
            
            
        error = 0
        for o in range(len(label)):
            for k in range(self.output_n):
                error+= 0.5*(label[o] - self.output_cells[k])**2
            
        return error
        
    def train(self,cases,labels, limit, learn,correct=0.1):

        for i in range(limit):                
            error  = 0.0
           # learn = le.arn_speed_start /float(i+1)        
            for j in range(len(cases)):
                case = cases[j]
                label = labels[j]  
                         
                error+= self.back_propagate(case, label, learn,correct)
            if((i+1)%500==0):
                print("error:",error)
                
    def test(self): #学习异或

        
        N = 200
        d = -4
        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.0] for y in range(1, 201)]
        labels_pos = [[0.0] for y in range(1, 201)]
        labels=labels_pre+labels_pos
       
        self.setup(2,5,1) #初始化神经网络:输入层,隐藏层,输出层元素个数
        self.train(input_cells,labels,2000,0.05,0.1) #可以更改
       
        test_x = []
        test_y = []
        test_p = []
        
        y_p_old = 0
    
        for x in np.arange(-15.,25.,0.1):

            for y in np.arange(-10.,10.,0.1):
                y_p =self.predict(np.array([x, y]))

                if(y_p_old <0.5 and y_p[0] > 0.5):
                    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()   
                    

if __name__ == '__main__':
    nn = BP_NET()
    nn.test()

4、运行结果
在这里插入图片描述

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
function main() InDim=2; % 样本输入维数 OutDim=3; % 样本输出维数 % figure % colordef(gcf,'white') % echo off % clc % axis([-2,2,-2,2]) % axis on % grid % xlabel('Input x'); % ylabel('Input y'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % line([-1 1],[1 1]) % line([1 -1],[1 0]) % line([-1 -1],[0 1]) % line([-1 1],[-0.5 -0.5]) % line([-1 1],[-1.5 -1.5]) % line([1 1],[-0.5 -1.5]) % line([-1 -1],[-0.5 -1.5]) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % hold on % sj=plot([-1 1],[1 1],[1 -1],[1 0],[-1 -1],[0 1]); % hold on % set(sj,'Color','r','LineWidth',4); % js=plot([-1 1],[-0.5 -0.5],'b',[-1 1],[-1.5 -1.5],'b',[1 1],... % [-0.5 -1.5],'b',[-1 -1],[-0.5 -1.5],'b'); % hold on % set(js,'Color','b','LineWidth',4); %hold off figure colordef(gcf,'white') echo off clc axis([-2,2,-2,2]) axis on grid xlabel('Input x'); ylabel('Input y'); hold on sj=plot([-1 1],[1 1],[1 -1],[1 0],[-1 -1],[0 1]); hold on js=plot([-1 1],[-0.5 -0.5],'b',[-1 1],[-1.5 -1.5],'b',[1 1],... [-0.5 -1.5],'b',[-1 -1],[-0.5 -1.5],'b'); hold on set(sj,'Color','r','LineWidth',4); set(js,'Color','b','LineWidth',4); hold on SamNum=400; % 训练样本数 rand('state', sum(100*clock)) SamIn=(rand(2,SamNum)-0.5)*4; % 产生随机样本输入 % 根据目标函数获得训练样本输入输出,并绘制样本 SamOut=[]; for i=1:SamNum Sam=SamIn(:,i); x=Sam(1,1); y=Sam(2,1); if((x>-1)&(x<1))==1 if((y>x/2+1/2)&(y<1))==1 plot(x,y,'k+') class=[0 1 0]'; elseif((y<-0.5)&(y>-1.5))==1 plot(x,y,'ks') class=[0 0 1]'; else plot(x,y,'ko') class=[1 0 0]'; end else plot(x,y,'ko') class=[1 0 0]'; end SamOut=[SamOut class]; end HiddenUnitNum=10; % 隐节点数 MaxEpochs=10000; % 最大训练次数 lr=0.1; % 学习率 E0=0.1; % 目标误差 W1=0.2*rand(HiddenUnitNum,InDim)-0.1; % 输入层到隐层的初始权值 B1=0.2*rand(HiddenUnitNum,1)-0.1; % 隐节点初始偏移 W2=0.2*rand(OutDim,HiddenUnitNum)-0.1; % 隐层到输出层的初始权值 B2=0.2*rand(OutDim,1)-0.1; % 输出层初始偏移 W1Ex=[W1 B1]; % 输入层到隐层的初始权值扩展, 10*3 W2Ex=[W2 B2]; % 隐层到输出层的初始权值, 3*11 SamInEx=[SamIn' ones(SamNum,1)]'; % 样本输入扩展, 3*200 ErrHistory=[]; % 用于记录每次权值调整后的训练误差 for i=1:MaxEpochs % 正向传播计算网络输出 HiddenOut=logsig(W1Ex*SamInEx); HiddenOutEx=[HiddenOut' ones(SamNum, 1)]'; NetworkOut=logsig(W2Ex*HiddenOutEx); % 停止学习判断 Error=SamOut-NetworkOut; SSE=sumsqr(Error); fprintf('Times: %7.0f',i); fprintf(' SSE: .4f\n\n',SSE); % 记录每次权值调整后的训练误差 ErrHistory=[ErrHistory SSE]; if SSE<E0, break, end % 计算反向传播误差 Delta2=Error.*NetworkOut.*(1-NetworkOut); Delta1=W2'*Delta2.*HiddenOut.*(1-HiddenOut); % 计算权值调节量 dW2Ex=Delta2*HiddenOutEx'; dW1Ex=Delta1*SamInEx'; % 权值调节 W1Ex=W1Ex+lr*dW1Ex; W2Ex=W2Ex+lr*dW2Ex; % 分离隐层到输出层的权值,以便后面使用(见 % 计算反向传播误差 之第二行132) W2=W2Ex(:,1:HiddenUnitNum); end W1=W1Ex(:,1:InDim); B1=W1Ex(:,InDim+1); % W2=W2Ex(:,1:HiddenUnitNum); B2=W2Ex(:,1+HiddenUnitNum); % 绘制学习误差曲线 figure hold on grid [xx,Num]=size(ErrHistory); er111=plot(1:Num,ErrHistory,'k-'); set(er111,'Color','b','LineWidth',1.5); % 根据目标函数获得训练样本输入输出,并绘制样本 TestSamNum=10000; % 测试样本数 %rand('state', sum(100*clock)); TestSamIn=(rand(2,TestSamNum)-0.3)*4; % 产生随机样本输入 TestHiddenOut=logsig(W1*TestSamIn+repmat(B1,1,TestSamNum)); TestNetworkOut=logsig(W2*TestHiddenOut+repmat(B2,1,TestSamNum)); [Val,NNClass]=max(TestNetworkOut); TestTargetOut=[]; for i=1:TestSamNum Sam=TestSamIn(:,i); x=Sam(1,1); y=Sam(2,1); if((x>-1)&(x<1))==1 if((y>x/2+1/2)&(y<1))==1 TestTargetOut=[TestTargetOut 2]; elseif((y<-0.5)&(y>-1.5))==1 TestTargetOut=[TestTargetOut 3]; else TestTargetOut=[TestTargetOut 1]; end else TestTargetOut=[TestTargetOut 1]; end end %显示计算结果 NNC1Flag=abs(NNClass-1)<0.1; NNC2Flag=abs(NNClass-2)<0.1; NNC3Flag=abs(NNClass-3)<0.1; TargetC1Flag=abs(TestTargetOut-1)<0.1; TargetC2Flag=abs(TestTargetOut-2)<0.1; TargetC3Flag=abs(TestTargetOut-3)<0.1; Target_C1_num=sum(TargetC1Flag); Target_C2_num=sum(TargetC2Flag); Target_C3_num=sum(TargetC3Flag); Test_C1_num=sum(NNC1Flag); Test_C2_num=sum(NNC2Flag); Test_C3_num=sum(NNC3Flag); Test_C1_C1=1.0*NNC1Flag*TargetC1Flag'; Test_C1_C2=1.0*NNC1Flag*TargetC2Flag'; Test_C1_C3=1.0*NNC1Flag*TargetC3Flag'; Test_C2_C1=1.0*NNC2Flag*TargetC1Flag'; Test_C2_C2=1.0*NNC2Flag*TargetC2Flag'; Test_C2_C3=1.0*NNC2Flag*TargetC3Flag'; Test_C3_C1=1.0*NNC3Flag*TargetC1Flag'; Test_C3_C2=1.0*NNC3Flag*TargetC2Flag'; Test_C3_C3=1.0*NNC3Flag*TargetC3Flag'; Test_Correct=(Test_C1_C1+Test_C2_C2+Test_C3_C3)/TestSamNum; % 输出格式设计 disp('///////////////////////////////////////////////////////////'); fprintf('\n'); disp(' 测试报告'); fprintf('\n'); fprintf('测试样本总数: %7.0f\n\n',TestSamNum); fprintf('第一类样本数: %7.0f\n',Target_C1_num); fprintf('第二类样本数: %7.0f\n',Target_C2_num); fprintf('第三类样本数: %7.0f\n\n',Target_C3_num); disp('= = = = = = = = = = = = = = = = = = = = = = = = = = = '); fprintf('\n'); fprintf('第一类样本分布(C1=%4.0f)\n',Test_C1_num); fprintf(' C11=%4.0f',Test_C1_C1); fprintf(' C12=%4.0f',Test_C1_C2); fprintf(' C13=%4.0f\n\n',Test_C1_C3); fprintf('第二类样本分布(C2=%3.0f)\n',Test_C2_num); fprintf(' C21=%4.0f',Test_C2_C1); fprintf(' C22=%4.0f',Test_C2_C2); fprintf(' C23=%4.0f\n\n',Test_C2_C3); fprintf('第三类样本分布(C3=%3.0f)\n',Test_C3_num); fprintf(' C31=%4.0f',Test_C3_C1); fprintf(' C32=%4.0f',Test_C3_C2); fprintf(' C33=%4.0f\n\n',Test_C3_C3); fprintf('正确率:%6.4f\n\n',Test_Correct); disp('///////////////////////////////////////////////////////////'); fprintf('\n\n');
多层感知器(Multilayer Perceptron,MLP)是一种常用的神经网络模型,可以用来解决分类和回归问题。它由输入层、隐藏层和输出层组成,每一层都由多个神经元组成,相邻层之间的神经元之间有连接权重。 使用Python实现多层感知器模型的方法如下: 1. 导入所需的库:首先需要导入NumPy库用于数值计算,以及scikit-learn库用于数据预处理。 ```python import numpy as np from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split ``` 2. 准备数据:将原始数据集划分为训练集和测试集,并进行特征缩放。 ```python X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) ``` 3. 初始化权重和偏置:定义一个随机初始化权重和偏置的函数。 ```python def initialize_parameters(layer_dims): parameters = {} for l in range(1, len(layer_dims)): parameters['W' + str(l)] = np.random.randn(layer_dims[l], layer_dims[l-1]) * 0.01 parameters['b' + str(l)] = np.zeros((layer_dims[l], 1)) return parameters parameters = initialize_parameters(layer_dims) ``` 4. 前向传播:定义前向传播函数,计算神经网络的输出。 ```python def forward_propagation(X, parameters): A = X caches = [] for l in range(1, L): Z = np.dot(parameters['W' + str(l)], A) + parameters['b' + str(l)] A = relu(Z) cache = (Z, A) caches.append(cache) ZL = np.dot(parameters['W' + str(L)], A) + parameters['b' + str(L)] AL = sigmoid(ZL) return AL, caches AL, caches = forward_propagation(X_train, parameters) ``` 5. 计算损失:根据神经网络的输出和真实标签计算损失函数。 ```python def compute_cost(AL, Y): m = Y.shape[1] cost = (-1/m) * np.sum(np.multiply(Y, np.log(AL)) + np.multiply(1-Y, np.log(1-AL))) return cost cost = compute_cost(AL, y_train) ``` 6. 反向传播:定义反向传播函数,计算梯度并更新参数。 ```python def backward_propagation(AL, Y, caches): grads = {} dZL = AL - Y dW = (1/m) * np.dot(dZL, A_prev.T) db = (1/m) * np.sum(dZL, axis=1, keepdims=True) dA_prev = np.dot(W.T, dZ) grads['dW'] = dW grads['db'] = db return grads grads = backward_propagation(AL, y_train, caches) ``` 7. 参数更新:根据梯度和学习率更新参数。 ```python def update_parameters(parameters, grads, learning_rate): for l in range(1, L): parameters['W' + str(l)] -= learning_rate * grads['dW' + str(l)] parameters['b' + str(l)] -= learning_rate * grads['db' + str(l)] return parameters parameters = update_parameters(parameters, grads, learning_rate) ``` 8. 模型训练:将上述步骤整合到一个函数中,循环迭代多次进行模型训练。 ```python def model(X, Y, learning_rate, num_iterations): parameters = initialize_parameters(layer_dims) for i in range(num_iterations): AL, caches = forward_propagation(X, parameters) cost = compute_cost(AL, Y) grads = backward_propagation(AL, Y, caches) parameters = update_parameters(parameters, grads, learning_rate) return parameters parameters = model(X_train, y_train, learning_rate, num_iterations) ``` 以上就是使用Python实现多层感知器MLP)模型的主要步骤。根据具体数据集和问题,可能需要进行参数调优和模型评估等进一步步骤。在实际应用中,还可以使用其他性能更好的库(如TensorFlow、Keras)来实现多层感知器模型。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值