(学习笔记)神经网络--------Numpy实现BP算法实列

应用背景:

根据提供的一个鸢尾花数据集,通过数据集提供的花萼长度、花萼宽度、花瓣长度、花瓣宽度和标签来进行训练,得到一个适宜的权值来判断鸢尾花属于什么品质

算法优化

这里使用python作为主要编程语言进行优化,与一般的写法不同,python除了代码简单可视化以外,还拥有对矩阵算法的优化,使训练数据集的时间大大优化,避免了BP算法训练时间慢的缺点,有时间的话,我会写一个JAVA和C++的BP鸢尾花训练,可以很明显比较出python处理矩阵算法的时间快,代码简单的特点

鸢尾花数据集

在这里插入图片描述
由于鸢尾花数据集是神经网络学习的一个常用数据集,在网上就可以找到很多此数据集链接,有需要的可以联系

BP算法公式推导

BP算法公式推导(无优化)

代码展示

import numpy as np
import pandas as pd

# 格式
flowerLables = {0: 'Iris-setosa',
                1: 'Iris-versicolor',
                2: 'Iris-virginica'}


# 读取数据
def read():
    # 读取csv数据
    csv_data = pd.read_csv(r"./Iris.csv").values
    # 随机打乱数据
    np.random.shuffle(csv_data)
    # 取数据集
    inputs = csv_data[:, 1:5]
    # 获取标签
    targets = csv_data[:, -1]
    # 将标签转码为one-hot形式
    t = []
    for i in range(targets.shape[0]):
        if csv_data[i][-1] == flowerLables[0]:
            t.append([1, 0, 0])
        elif csv_data[i][-1] == flowerLables[1]:
            t.append([0, 1, 0])
        elif csv_data[i][-1] == flowerLables[2]:
            t.append([0, 0, 1])
    targets = np.array(t)
    # 转化格式
    inputs = inputs.astype("float64")
    targets = targets.astype("float64")

    return inputs, targets


class BP:
    # 构造函数
    def __init__(self, ni, nh, no):
        self.ni = ni
        self.nh = nh
        self.no = no

        self.V = (np.random.random([ni + 1, nh]) * 2 - 1) * 0.2
        self.W = (np.random.random([nh + 1, no]) * 2 - 1) * 2

    # 激活函数
    def sigmoid(self, x):
        return 1.0 / (1 + np.exp(-x))

    # 激活函数求导
    def dsigmoid(self, x):
        return x * (1 - x)

    # 正向传播
    def updata(self, inputs):
        # 插入x的偏正值
        inputs = np.column_stack((np.ones([inputs.shape[0], 1]), inputs))
        # 正向传播入隐藏层
        net1 = np.dot(inputs, self.V)
        out1 = self.sigmoid(net1)
        # 插入out1的偏正值
        out1 = np.column_stack((np.ones([out1.shape[0], 1]), out1))
        # 正向传播入输出层
        net2 = np.dot(out1, self.W)
        out2 = self.sigmoid(net2)

        return out1, out2

    # 反向传播
    def backPropage(self, inputs, targets, out1, out2, lr):
        # 计算输出层误差
        out2_delta = (out2 - targets) * self.dsigmoid(out2)
        # 计算W误差
        W_delta = out1.T.dot(out2_delta) * lr
        # 计算隐藏层误差
        out1_delta = out2_delta.dot(self.W.T) * self.dsigmoid(out1)
        # 计算V误差
        inputs = np.column_stack((np.ones([inputs.shape[0], 1]), inputs))
        V_delta = inputs.T.dot(out1_delta[:, 1:]) * lr
        # 更新权值
        self.V = self.V - V_delta
        self.W = self.W - W_delta

    # 训练
    def train(self, inputs, targets):
        # 学习率
        lr = 0.05
        # 迭代次数
        epoch = 20000
        # 训练
        for i in range(epoch):
            # 正向传播
            out1, out2 = self.updata(inputs)
            # 反向传播
            self.backPropage(inputs, targets, out1, out2, lr)

    #测试
    def test(self, inputs, targets):
            #获取测试的值
            out1, out2 = self.updata(inputs)
            #找到测试和实际值的最大数的下标
            result_inputs = out2.argmax(axis=1)
            result_targets = targets.argmax(axis=1)

            count = 0
            for i in range(inputs.shape[0]):
                print(f"数据 {inputs[i]} -> 预测{flowerLables[result_inputs[i]]} 实际{flowerLables[result_targets[i]]}")
                count += (result_targets[i] == result_inputs[i])

            #正确率
            accuracy = float(count / len(inputs))
            print(f'正确率为: {accuracy * 100}%')




# 主函数
def Iris():
    # 获取数据
    inputs, targets = read()
    # 创建算法
    bp = BP(inputs.shape[1], 7, targets.shape[1])
    # 训练(前100个数据)
    bp.train(inputs[:100], targets[:100])
    # 测试(后50个数据)
    bp.test(inputs[:50], targets[:50])


if __name__ == '__main__':
    Iris()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值