三层BP神经网络实现

数据集:鸢尾花数据

iris.csv 

 

 附上数据集:链接:https://pan.baidu.com/s/1OwpiKGctr1QDFeP42dR2Bw 
提取码:htgl

 实现

 读取iris.csv文件处理

def get_iris():
    name = ['f1', 'f2', 'f3', 'f4', 'y']
    data = pd.read_csv('iris.csv', encoding='ascii', names=name)

    data = data.replace('Iris-setosa', 0)
    data = data.replace('Iris-versicolor', 1)
    data = data.replace('Iris-virginica', 2)
    data['y'].astype(int)
    print(data.dtypes)
    raw_data = data.to_numpy()
    y = np.zeros([len(raw_data), 3])
    x = np.zeros([len(raw_data), 4])

    for i in range(len(raw_data)):
        x[i, :] = raw_data[i, :4]
        if raw_data[i, 4] == 0:
            y[i, :] = np.array([1, 0, 0])
        elif raw_data[i, 4] == 1:
            y[i, :] = np.array([0, 1, 0])
        else:
            y[i, :] = np.array([0, 0, 1])

    return x,y

这里我将类别Iris-setosa的鸢尾花 表示成[1,0,0],类别为Iris-versicolor的鸢尾花表示成[0,1,0],类别为Iris-virginica的鸢尾花表示成[0,0,1]。

神经网络:

import numpy as np
import pandas as pd
import os

from BP.test import get_iris


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


def make_matrix(m, n, fill=0.0):
    return np.full([m, n], fill)


def sigmoid(x):
    return 1.0 / (1.0 + np.math.exp(-x))


def sigmoid_derivative(x):
    return x * (1 - x)


class BPNN:
    def __init__(self, input_num, hidden_num, output_num):
        self.input_num = input_num + 1
        self.hidden_num = hidden_num + 1
        self.output_num = output_num

        self._active_in = np.ones(self.input_num)

        self._active_hidden = np.ones(self.hidden_num)
        self._active_out = np.ones(self.output_num)

        # 创建权重矩阵
        self.weight_in = make_matrix(self.input_num, self.hidden_num)
        self.weight_out = make_matrix(self.hidden_num, self.output_num)

        # 对权值矩阵随机初始化初值
        for i in range(self.input_num):
            for j in range(self.hidden_num - 1):
                self.weight_in[i][j] = rand(-0.2, 0.2)
        for i in range(self.hidden_num):
            for j in range(self.output_num):
                self.weight_out[i][j] = rand(-0.2, 0.2)

        # 误差
        self._output_deltas = np.zeros(self.output_num)

        self._hidden_deltas = np.zeros(self.hidden_num)

        # 最后建立动量因子(矩阵)
        self.ci = make_matrix(self.input_num, self.hidden_num)
        self.co = make_matrix(self.hidden_num, self.output_num)

    def forward_propagation(self, input):

        assert len(input) == self.input_num - 1, "error"
        for i in range(self.input_num - 1):
            self._active_in[i] = input[i]

        for j in range(self.hidden_num - 1):  # 最后一个是偏执段元?
            sum = 0.
            for i in range(self.input_num):
                sum += self._active_in[i] * self.weight_in[i][j]
            self._active_hidden[j] = sigmoid(sum)

        for k in range(self.output_num):
            sum = 0.
            for j in range(self.hidden_num):
                sum += self._active_hidden[j] * self.weight_out[j][k]
            self._active_out[k] = sigmoid(sum)
        return self._active_out[:]

    def backward_propagation(self, label, learning_rate=0.1, m=0.1):

        # 计算输出层的误差

        # for k in range(self.output_num):
        #     self._output_deltas[k]=(self._active_out[k]-label[k])*sigmoid_derivative(self._active_out[k])
        # print(self._output_deltas)

        self._output_deltas = (label - self._active_out) * sigmoid_derivative(self._active_out)

        # 计算隐藏层的误差
        for i in range(self.hidden_num - 1):
            error = 0.
            for j in range(self.output_num):
                error += self.weight_out[i][j] * self._output_deltas[j]
            self._hidden_deltas[i] = error * sigmoid_derivative(self._active_hidden[i])
        i = self.hidden_num - 1
        for j in range(self.output_num):
            error += 1 * self._output_deltas[j]
        self._hidden_deltas[i] = error * sigmoid_derivative(self._active_hidden[i])

        # self._hidden_deltas = ((self.weight_out).dot(self._output_deltas) * sigmoid_derivative(self._active_hidden)).flatten()

        # 更新输出层权值

        for j in range(self.hidden_num - 1):
            for k in range(self.output_num):
                change = (self._output_deltas[k] * self._active_hidden[j])
                self.weight_out[j][k] += learning_rate * change + m * self.co[j][k]
                self.co[j][k] = change
        j = self.hidden_num - 1
        for k in range(self.output_num):
            self.weight_out[j][k] += learning_rate * self._output_deltas[k] + m * self.co[j][k]
            self.co[j][k] = self._output_deltas[k]
        # print(self.weight_out)
        # 更新输入层权值

        for i in range(self.input_num - 1):
            for j in range(self.hidden_num - 1):
                change = (self._hidden_deltas[j] * self._active_in[i])
                self.weight_in[i][j] += learning_rate * change + m * self.ci[i][j]
                self.ci[i][j] = change
        i = self.input_num - 1
        for j in range(self.hidden_num - 1):
            self.weight_in[i][j] += learning_rate * self._hidden_deltas[j] + m * self.ci[i][j]
            self.ci[i][j] = self._hidden_deltas[j]
        # print(self.weight_in)

        error = 0.0
        for o in range(len(label)):
            error += 0.5 * (label[o] - self._active_out[o]) ** 2
        return error

   
    def test(self, label, target):
        for i in range(len(label)):
            print(target[i], '->', self.forward_propagation(label[i]))

    def weights(self):
        print("输入层权重")
        for i in range(self.input_num):
            print(self.weight_in[i])
        print("输出层权重")
        for i in range(self.hidden_num):
            print(self.weight_out[i])

    def train(self, label, target, itera=10000, lr=0.01, m=0.1):
        for i in range(itera):
            error = 0.0
            for j in range(len(label)):
                inputs = label[j]
                targets = target[j]
                self.forward_propagation(inputs)
                error = error + self.backward_propagation(targets, lr, m)
            if i % 100 == 0:
                print('误差 %-.5f' % error)


def demo():
    x, y = get_iris()
    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(x, y, random_state=10)
    # 创建神经网络,4个输入节点,10个隐藏层节点,3个输出层节点
    n = BPNN(4, 10, 3)
    # 训练神经网络
    n.train(X_train, y_train)
    # 测试神经网络
    n.test(X_test, y_test)
    # 查阅权重值
    n.weights()


if __name__ == '__main__':
    demo()

运行结果

 

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值