Python3实现BP神经网络

主要是实现了这位大佬的代码,顺便加了一些自己的理解http://www.cnblogs.com/Finley/p/5946000.html

import math
import random
random.seed(0)
def rand(a,b): #随机函数
    return (b-a)*random.random()+a

def make_matrix(m,n,fill=0.0):#创建一个指定大小的矩阵
    mat = []
    for i in range(m):
        mat.append([fill]*n)
    return mat

#定义sigmoid函数和它的导数
def sigmoid(x):
    return 1.0/(1.0+math.exp(-x))
def sigmoid_derivate(x):
    return x*(1-x) #sigmoid函数的导数

class BPNeuralNetwork:
    def __init__(self):#初始化变量
        self.input_n = 0
        self.hidden_n = 0
        self.output_n = 0
        self.input_cells = []
        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) #由输入层第i个元素到隐藏层第j个元素的边权为随机值

        for h in range(self.hidden_n):
            for o in range(self.output_n):
                self.output_weights[h][o] = rand(-2.0, 2.0) #由隐藏层第i个元素到输出层第j个元素的边权为随机值
        #保存校正矩阵,为了以后误差做调整
        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] #n个样本从0~n-1
        #计算隐藏层的输出,每个节点最终的输出值就是权值*节点值的加权和
        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]
            # 此处为何是先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.output_cells[k] = sigmoid(total) #获取输出层每个元素的值
        return self.output_cells[:]  #最后输出层的结果返回

    #反向传播算法:调用预测函数,根据反向传播获取权重后前向预测,将结果与实际结果返回比较误差
    def back_propagate(self,case,label,learn,correct):
        #对输入样本做预测
        self.predict(case) #对实例进行预测
        output_deltas = [0.0]*self.output_n #初始化矩阵
        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 h in range(self.hidden_n):
            error = 0.0
            for o in range(self.output_n):
                error+=output_deltas[o]*self.output_weights[h][o]
            hidden_deltas[h] = sigmoid_derivate(self.hidden_cells[h])*error
        #反向传播算法求W
        #更新隐藏层->输出权重
        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 + correct*self.output_correction[h][o]
        #更新输入->隐藏层的权重
        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 + correct*self.input_correction[i][h]
                self.input_correction[i][h] =  change
        #获取全局误差
        error = 0.0
        for o in range(len(label)):
            error = 0.5*(label[o]-self.output_cells[o])**2 #平方误差函数
        return error

    def train(self,cases,labels,limit=10000,learn=0.05,correct=0.1):
        for i in range(limit): #设置迭代次数
            error = 0.0
            for j in range(len(cases)):#对输入层进行访问
                label = labels[j]
                case = cases[j]
                error+=self.back_propagate(case,label,learn,correct) #样例,标签,学习率,正确阈值

    def test(self): #学习异或
        cases = [
            [0, 0],
            [0, 1],
            [1, 0],
            [1, 1],
        ] #测试样例
        labels = [[0], [1], [1], [0]] #标签
        self.setup(2,5,1) #初始化神经网络:输入层,隐藏层,输出层元素个数
        self.train(cases,labels,10000,0.05,0.1) #可以更改
        for case in  cases:
            print(self.predict(case))

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


  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
当然可以,BP神经网络是目前应用广泛的一种神经网络。以下是一个简单的Python代码实现BP神经网络的示例: ```python import numpy as np # 定义sigmoid函数 def sigmoid(x): return 1.0/(1.0+np.exp(-x)) # 定义BP神经网络类 class BPNN: # 初始化 def __init__(self, input_dim, hidden_dim, output_dim): self.input_dim = input_dim self.hidden_dim = hidden_dim self.output_dim = output_dim self.W1 = np.random.randn(input_dim,hidden_dim) self.b1 = np.random.randn(hidden_dim) self.W2 = np.random.randn(hidden_dim,output_dim) self.b2 = np.random.randn(output_dim) # 前向传播 def forward(self, X): net_hidden = np.dot(X, self.W1) + self.b1 output_hidden = sigmoid(net_hidden) net_output = np.dot(output_hidden, self.W2) + self.b2 output = sigmoid(net_output) return output, output_hidden # 反向传播 def backward(self, X, Y, output, output_hidden, lr): error_output = (Y - output) * output * (1 - output) error_hidden = np.dot(error_output, self.W2.T) * output_hidden * (1 - output_hidden) self.W2 += lr * np.dot(output_hidden.T, error_output) self.b2 += lr * np.sum(error_output, axis=0) self.W1 += lr * np.dot(X.T, error_hidden) self.b1 += lr * np.sum(error_hidden, axis=0) # 训练 def train(self, X, Y, lr, epochs): for i in range(epochs): output, output_hidden = self.forward(X) self.backward(X, Y, output, output_hidden, lr) # 预测 def predict(self, X): output, _ = self.forward(X) return output ``` 以上代码实现了一个简单的三层BP神经网络,采用sigmoid函数作为激活函数,提供了初始化权重和偏差、前向传播、反向传播、训练等方法。你可以通过实例化`BPNN`类,传入输入层、隐藏层、输出层的维度,来构建一个BP神经网络。然后,通过传入训练数据和标签,设定学习率和迭代次数,来训练该神经网络。最后,可以通过调用`BPNN`的`predict()`方法,传入测试数据,来进行预测。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kelisita

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值