四层BP网络python代码实现

本文详细介绍了使用Python实现的四层BP神经网络,以Iris数据集为例,通过1-100个训练样本和独热编码处理输出。着重探讨了训练过程、误差反向传播算法和可能的优化改进点,如数据集顺序调整和可视化评估。
摘要由CSDN通过智能技术生成

四层BP网络python代码实现,输入节点为4,输出节点为3(独热编码),采用的是iris数据集,1-100为训练集,100-150为测试集,因为数据集本身有序,所以最后测试效果不是很好。第一次写BP代码,也参考了优秀的代码。需要修改的地方还有很多…数据集顺序的修改、可视化、评估等等

import pandas
import numpy as np
import math
import random
import string
import matplotlib as mpl
import matplotlib.pyplot as plt
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder             # 编码
from sklearn.model_selection import train_test_split
import array

#导入数据
iris = pandas.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None)
iris.columns=['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm', 'Species']
arrary = iris.values

size_mapping = {'Iris-virginica': 2,
                'Iris-versicolor': 1,
                'Iris-setosa': 0}
iris['Species'] = iris['Species'].map(size_mapping)
arrary = iris.values

a = arrary[:100, :]   # 训练集
b = arrary[100:, :]   # 测试集
c = arrary[:100, 4]  # 为后面独热编码做准备

#独热编码
def onehot(targets, num_out):
    onehot = np.zeros((num_out, targets.shape[0]))
    for idx, val in enumerate(targets.astype(int)):
        onehot[val, idx] = 1.
    return onehot.T

#生成一个矩阵,大小为m*n,并且设置默认零矩阵
def makematrix(m, n, fill=0.0):
    a = []
    for i in range(m):
        a.append([fill] * n)
    return a


#函数sigmoid(),用tanh
def sigmoid(x):
    return math.tanh(x)


#函数
def derived_sigmoid(x):
    return 1.0 - x ** 2


#构造四层BP网络架构
class BPNN:
    def __init__(self, num_in, num_hidden1, num_hidden2, num_out):
        # 输入层,隐藏层,输出层的节点数
        self.num_in = num_in + 1  # 增加一个偏置结点 4
        self.num_hidden1 = num_hidden1 + 1  # 增加一个偏置结点 4
        self.num_hidden2 = num_hidden2 + 1
        self.num_out = num_out

        # 激活神经网络的所有节点
        self.active_in = [1.0] * self.num_in
        self.active_hidden1 = [1.0] * self.num_hidden1
        self.active_hidden2 = [1.0] * self.num_hidden2
        self.active_out = [1.0] * self.num_out

        # 创建权重矩阵
        self.wight_in = makematrix(self.num_in, self.num_hidden1)
        self.wight_h1h2 = makematrix(self.num_hidden1, self.num_hidden2)
        self.wight_out = makematrix(self.num_hidden2, self.num_out)

        # 对权值矩阵赋初值
        for i in range(self.num_in):
            for j in range(self.num_hidden1):
                self.wight_in[i][j] = np.random.normal(0.0, pow(self.num_hidden1, -0.5))  # 输出num_in行,num_hidden列权重矩阵,随机生成满足正态分布的权重
        for i in range(self.num_hidden1):
            for j in range(self.num_hidden2):
                self.wight_h1h2[i][j] = np.random.normal(0.0, pow(self.num_hidden2, -0.5))
        for i in range(self.num_hidden2):
            for j in range(self.num_out):
                self.wight_out[i][j] = np.random.normal(0.0, pow(self.num_out, -0.5))

        # 最后建立动量因子(矩阵)
        self.ci = makematrix(self.num_in, self.num_hidden1)
        self.ch1h2 = makematrix(self.num_hidden1, self.num_hidden2)
        self.co = makematrix(self.num_hidden2, self.num_out)


        # 信号正向传播

    def update(self, inputs):
        if len(inputs) != self.num_in - 1:
            raise ValueError('与输入层节点数不符')

        # 数据输入输入层
        for i in range(self.num_in - 1):
            # self.active_in[i] = sigmoid(inputs[i])  #或者先在输入层进行数据处理
            self.active_in[i] = inputs[i]  # active_in[]是输入数据的矩阵

        # 数据在隐藏层1的处理
        for i in range(self.num_hidden1):
            sum = 0.0
            for j in range(self.num_in):
                sum = sum + self.active_in[j] * self.wight_in[j][i]
            self.active_hidden1[i] = sigmoid(sum)  # active_hidden[]是处理完输入数据之后存储,作为输出层的输入数据

        # 数据在隐藏层2的处理
        for i in range(self.num_hidden2):
            sum = 0.0
            for j in range(self.num_hidden1):
                sum = sum + self.active_hidden1[j] * self.wight_h1h2[j][i]
            self.active_hidden2[i] = sigmoid(sum)  # active_hidden[]是处理完输入数据之后存储,作为输出层的输入数据

        # 数据在输出层的处理
        for i in range(self.num_out):
            sum = 0.0
            for j in range(self.num_hidden2):
                sum = sum + self.active_hidden2[j] * self.wight_out[j][i]
            self.active_out[i] = sigmoid(sum)  # 与上同理

        return self.active_out[:]


    # 误差反向传播
    def errorbackpropagate(self, targets, lr, m):  # lr是学习率, m是动量因子
        if len(targets) != self.num_out:
            raise ValueError('与输出层节点数不符!')

        # 首先计算输出层的误差
        out_deltas = [0.0] * self.num_out
        for i in range(self.num_out):
            error = targets[i] - self.active_out[i]
            out_deltas[i] = derived_sigmoid(self.active_out[i]) * error

        # 计算隐藏层2的误差
        hidden2_deltas = [0.0] * self.num_hidden2
        for i in range(self.num_hidden2):
            error = 0.0
            for j in range(self.num_out):
                error = error + out_deltas[j] * self.wight_out[i][j]
            hidden2_deltas[i] = derived_sigmoid(self.active_hidden2[i]) * error

        # 计算隐藏层1的误差
        hidden1_deltas = [0.0] * self.num_hidden1
        for i in range(self.num_hidden1):
            error = 0.0
            for j in range(self.num_hidden2):
                error = error + hidden2_deltas[j] * self.wight_h1h2[i][j]
            hidden1_deltas[i] = derived_sigmoid(self.active_hidden1[i]) * error



        # 更新输出层权值
        for i in range(self.num_hidden2):
            for j in range(self.num_out):
                change = out_deltas[j] * self.active_hidden2[i]
                self.wight_out[i][j] = self.wight_out[i][j] + lr * change + m * self.co[i][j]
                self.co[i][j] = change

        # 更新隐藏层间权值
        for i in range(self.num_hidden1):
            for j in range(self.num_hidden2):
                change = hidden2_deltas[j] * self.active_hidden1[i]
                self.wight_h1h2[i][j] = self.wight_h1h2[i][j] + lr * change + m * self.ch1h2[i][j]
                self.ch1h2[i][j] = change

        # 然后更新输入层权值
        for i in range(self.num_in):
            for j in range(self.num_hidden1):
                change = hidden1_deltas[j] * self.active_in[i]
                self.wight_in[i][j] = self.wight_in[i][j] + lr * change + m * self.ci[i][j]
                self.ci[i][j] = change

        # 计算总误差
        error = 0.0
        for i in range(self.num_out):
            error = error + 0.5 * (targets[i] - self.active_out[i]) ** 2
        return error

    # 测试
    def test(self, b):
        for i in range(b.shape[0]):
            print(b[i, 0:4], '->', self.update(b[i, 0:4]))

    # 权重
    def weights(self):
        print("输入层权重")
        for i in range(self.num_in):
            print(self.wight_in[i])
        print("输出层权重")
        for i in range(self.num_hidden2):
            print(self.wight_out[i])

    def train(self, a, itera=10000, lr=0.1, m=0.1):
        for i in range(itera):
            error = 0.0
            for j in range(100):
                inputs = a[j, 0:4]
                d = onehot(c, self.num_out)
                targets = d[j, :]
                self.update(inputs)
                error = error + self.errorbackpropagate(targets, lr, m)
            if i % 100 == 0:
                print('误差 %-.5f' % error)
# 实例
def Mytrain():
    a = iris.values
    # 创建神经网络,4个输入节点,X个隐藏层1节点,X个隐藏层2节点,3个输出层节点
    n = BPNN(4, 6, 6, 3)
    # 训练神经网络
    n.train(a)
    n.weights()
    n.test(b)

if __name__ == '__main__':
    Mytrain()

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
下面是一个四层BP神经网络代码示例: ```python # 导入所需的库 import numpy as np # 定义激活函数 def sigmoid(x): return 1 / (1 + np.exp(-x)) # 定义BP神经网络类 class BPNeuralNetwork: def __init__(self, input_dim, hidden_dim1, hidden_dim2, output_dim): self.input_dim = input_dim self.hidden_dim1 = hidden_dim1 self.hidden_dim2 = hidden_dim2 self.output_dim = output_dim # 初始化权重 self.weights1 = np.random.randn(self.input_dim, self.hidden_dim1) self.weights2 = np.random.randn(self.hidden_dim1, self.hidden_dim2) self.weights3 = np.random.randn(self.hidden_dim2, self.output_dim) # 初始化偏置 self.bias1 = np.random.randn(self.hidden_dim1) self.bias2 = np.random.randn(self.hidden_dim2) self.bias3 = np.random.randn(self.output_dim) def forward(self, X): # 前向传播 self.hidden_layer1 = sigmoid(np.dot(X, self.weights1) + self.bias1) self.hidden_layer2 = sigmoid(np.dot(self.hidden_layer1, self.weights2) + self.bias2) self.output_layer = sigmoid(np.dot(self.hidden_layer2, self.weights3) + self.bias3) return self.output_layer def train(self, X, y, learning_rate, epochs): # 训练网络 for epoch in range(epochs): # 前向传播 output = self.forward(X) # 反向传播,计算梯度 error = y - output delta_output = error * output * (1 - output) delta_hidden2 = np.dot(delta_output, self.weights3.T) * self.hidden_layer2 * (1 - self.hidden_layer2) delta_hidden1 = np.dot(delta_hidden2, self.weights2.T) * self.hidden_layer1 * (1 - self.hidden_layer1) # 更新权重和偏置 self.weights3 += learning_rate * np.dot(self.hidden_layer2.T, delta_output) self.weights2 += learning_rate * np.dot(self.hidden_layer1.T, delta_hidden2) self.weights1 += learning_rate * np.dot(X.T, delta_hidden1) self.bias3 += learning_rate * np.sum(delta_output, axis=0) self.bias2 += learning_rate * np.sum(delta_hidden2, axis=0) self.bias1 += learning_rate * np.sum(delta_hidden1, axis=0) # 创建BP神经网络对象 nn = BPNeuralNetwork(input_dim=2, hidden_dim1=4, hidden_dim2=4, output_dim=1) # 定义输入和目标输出 X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) y = np.array([[0], [1], [1], [0]]) # 训练神经网络 nn.train(X, y, learning_rate=0.1, epochs=10000) # 预测 output = nn.forward(X) ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

odd~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值