python手推多层感知机(BP网络实现)

一.概念及应用

多层感知机(Multi Layer Perceptron, MLP)是由多个感知机层全连接组成的前馈神经网络,BP网络是指连接权调整采用了反向传播(Back Propagation)学习算法的前馈网络,可实现从输入到输出的非线性映射。
BP网络由前向传播与反向传播两个过程组成,前向传播是指由输入值预测输出值的过程,反向传播是指各输出层反向计算对损失函数的梯度进而迭代权重的过程。
BP网络可用于分类和回归问题,在回归问题中损失函数选取rmse等,在分类问题中损失函数选取交叉熵等,在输出层二分类问题选择sigmoid函数层进行映射,多分类问题选择softmax函数层进行映射。

二.python实现

导入所需库

import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

数据准备与切分

X, ytrue = make_classification(n_samples=100, random_state=1)
X=np.hstack((X,np.ones([X.shape[0], 1])))#增加一列bias
X_train, X_test, y_train, y_test = train_test_split(X, ytrue,
                                                    random_state=1)

前期准备函数

def sigmoid(z):
    return 1 / (1.0 + np.exp(-np.clip(z,-100,10000)))
def sigmoid_Derivative(h):
    return  h*(1.0-h)#对应位置元素进行相乘,计算y的方差h(1-h)

BP类实现

整体思路:分别定义各层系数矩阵,向前传播计算输出值a,输入作为输出进行迭代;向后传播迭代参数

'''{param:
            ni:input数据维数
            nl:隐藏层数量(3)
            nh:每层隐藏层包含神经元数量(列表形式存储)[2,3,4]
            no:输出类别数}
'''

class BP:
    #初始化神经网络
    def _init_(self,ni,nl,nh,no):
        self.input=ni
        self.hidden=nh
        self.output=no
        self.layer=nl
        #系数矩阵,列表存储第几层,size[i,]表示前一层输入神经元(bias+1),size[,i]表示后一层输出神经元(bias不需输出) 
        self.weight=[np.random.random(size=(i+1,o)) for i,o in zip([self.input]+self.hidden,self.hidden+[self.output]) ]  
        #神经元存储输入输出
        self.cell_pre=[np.ones((pre+1,1)) for pre in [self.input]+self.hidden]   

    #前馈神经网络
    def forward(self,x):
        self.cell_pre[0]=x.reshape((len(x),1))
        for i in range(len(self.cell_pre)-1):
            z=self.weight[i].T@self.cell_pre[i]
            o_new=sigmoid(z)
            self.cell_pre[i+1][:-1,0]=o_new.reshape(1,len( self.cell_pre[i+1][:-1,0]))#bias只输入不输出
        self.out_pre=sigmoid(self.weight[-1].T@self.cell_pre[-1])
        return self.cell_pre,self.weight
    #反向传播,根据链式法则计算,损失函数为交叉熵,先计算损失函数对输出层的梯度,而后向后传播
    def backward_propagate(self,x,y,alpha):
        out=self.forward(x)     
        #最后一层
#         sigma=(self.out_pre-y)*sigmoid_Derivative(self.out_pre[-1]) 损失函数为rmse
        sigma=self.out_pre-y
        self.weight[-1]-=alpha*(self.cell_pre[-1]@sigma)
        for j in range(1,len(self.cell_pre)):
            sigma=((self.weight[-j][:-1,]*sigmoid_Derivative(self.cell_pre[-j])[:-1,]))@sigma #bias项连接drop
            self.weight[-j-1]-=self.cell_pre[-j-1]@sigma.T
        return self.weight
    def train(self,cases,label,limit,alpha):
        for l in range(limit):
#             print('iterition:',l)
            for k in range(0,len(cases)):#训练方法采用随机梯度下降进行计算
                x = cases[k]
                y = label[k]
                self.weight=self.backward_propagate(x,y,alpha)
        return self.weight
    def predict(self,cases):
        out=sigmoid(cases@self.weight[0])
        out=np.hstack((out,np.ones([out.shape[0],1])))
        for i in range(1,len(self.weight)):            
            out=sigmoid(out@self.weight[i])        
            if i !=len(self.weight)-1:
                out=np.hstack((out,np.ones([out.shape[0],1])))
        return np.round(out)       

调用

t=BP()
ni,nl,nh,no=20,4,[2,3,4,5],1
t._init_(ni,nl,nh,no)
w=t.train(X_train,y_train,500,0.01)
t.predict(X_train)

https://www.cnblogs.com/Finley/p/5946000.html
https://baike.baidu.com/item/%E5%89%8D%E9%A6%88%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/7580523?fr=aladdin

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值