BP三层神经网络Python实现代码

BP三层神经网络实现代码

# 神经网络类
class neuralNetwork():

    # 初始化
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        self.inodes = inputnodes   # 输入层节点
        self.hnodes = hiddennodes  # 隐藏层节点
        self.onodes = outputnodes  # 输出层节点
        self.lr = learningrate    # 学习率
        # 三层 神经网络, 权重 数值 (初始值, 随机设置, 【-1, 1】)
        self.wih = (np.random.rand(self.hnodes, self.inodes) - 0.5)  # 输入层和隐藏 的权重矩阵  大小:hnodes * inodes
        self.who = (np.random.rand(self.onodes, self.hnodes) - 0.5)  # 隐层层和输出层 权重矩阵 大小:onodes * hnodes

        # # 权重设置 另外方式; 使用 正态概率分布的方式采样;
        # # 1 使用输入层的节点数的开放作为正太分布的标准方差
        # self.wih = (np.random.normal(0.0, pow(self.inodes, -0.5)))
        # self.who = (np.random.normal(0.0, pow(self.hnodes, -0.5)))
        #
        # # 2 使用下一层的节点数的开方作为正太分布的标准方差
        # self.wih = (np.random.normal(0.0, pow(self.hnodes, -0.5)))
        # self.who = (np.random.normal(0.0, pow(self.onodes, -0.5)))

        # 定义激活函数
        self.activation_function = lambda x: scipy.special.expit(x)  # 使用了S函数

    # 输入数据, 输入数据对应的目标数据
    def train(self, inputs_list, targets_list):
        # 将 其 转化为 二维数组
        inputs = np.array(inputs_list, ndmin=2).T
        targets = np.array(targets_list, ndmin=2).T

        hidden_inputs = np.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)

        final_inputs = np.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)  # 一次前馈信号 最终输出结果

        # 基于输出 计算误差, 改进权重
        # 误差 是 预期目标输出 - 计算得到的输出
        output_errors = targets - final_outputs
        # 得到 隐藏层的误差
        hidden_errors = np.dot(self.who.T, output_errors)  # 隐藏层和输出层 之间权重矩阵的转置 * 输出误差
        # 更新 隐藏层 和 输出层 之间的权重矩阵
        self.who += self.lr * np.dot((output_errors * final_outputs * (1 - final_outputs)), np.transpose(hidden_outputs))

        # 更新 输入层 和 隐藏层 之间的权重矩阵
        self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1 - hidden_outputs)), np.transpose(inputs))

        pass

    # 查询 神经网络; inputs_list: 输入数据; 即进行预测,返回一次预测结果
    def query(self, inputs_list):
        # 将输入list 转化为 2维数组; T:转置
        inputs = np.array(inputs_list, ndmin=2).T
        # 计算 隐层层的输入,
        hidden_inputs = np.dot(self.wih, inputs)
        # 隐藏层输出信号, 是经过S函数运算后的
        hidden_outputs = self.activation_function(hidden_inputs)

        # 计算 输出层的 输入和输出结果
        final_inputs = np.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        return final_outputs  # 返回的使 输出层输出的值

    # 封装成 fit(), predict 这种形式
    def fit(self, trains_list, targets_list):
        for index in range(len(trains_list)):
            # 数据 归一化 放在外面
            # scaled_input = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01  # 数据归一化 [0.01, 1]
            # 将 标签 对应的 形成 节点数长度的一维数组
            targets = np.zeros(self.onodes) + 0.01  # 期望输入【真实标签值】
            targets[int(targets_list[index])] = 0.99  # 对应标签值 设置为 最大值 0.99; 神经网络 阈值函数 值域在(0, 1)
            self.train(trains_list[index], targets)  # 一行数据训练一次

    # 预测函数, 返回预测的标签值
    def predict(self, test_data_list):
        pred_label_list = []
        for raw in test_data_list:
            outputs = self.query(raw)
            label = np.argmax(outputs)
            pred_label_list.append(label)
        pred_label_list = np.asarray(pred_label_list)
        return pred_label_list

 测试代码如下:

import numpy as np
import math
import matplotlib.pyplot as plt
import scipy.special
import pprint
from sklearn import metrics
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号


# 读取小文件 一次读取所有的行
def read_csv_file(filename):
    data_file = open(filename, 'r')
    data_list = data_file.readlines()
    data_file.close()
    return data_list


def show_digital_image(image_array):
    # cmap 设置 图像色彩; Greys:灰色
    plt.imshow(image_array, cmap="Greys", interpolation="None")
    plt.show()

# 符合 Sklearn 库的形式代码
def neural_main1():
    input_nodes = 784
    hidden_nodes = 100
    output_nodes = 10
    learning_rate = 0.3
    n = neuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate)
    filename = r".\mini_dataset\mnist_train_100.csv"
    all_train_filename = r"./mini_dataset/mnist_train.csv"
    train_data_list = read_csv_file(all_train_filename)
    test_filename = r"./mini_dataset/mnist_test_10.csv"
    all_test_filename = r"./mini_dataset/mnist_test.csv"
    test_data_list = read_csv_file(all_test_filename)
    x_train = []
    y_train = []
    x_test = []
    y_test = []
    # 进行 数据归一化; BP神经网络 训练数据和测试数据都要进行数据归一化
    for raw in train_data_list:
        raw = raw.split(",")
        x_train.append((np.asfarray(raw[1:]) / 255.0 * 0.99) + 0.01) # 数据归一化
        y_train.append(int(raw[0]))

    for raw in test_data_list:
        raw = raw.split(",")
        x_test.append((np.asfarray(raw[1:]) / 255.0 * 0.99) + 0.01)
        y_test.append(int(raw[0]))

    x_train = np.asarray(x_train)
    y_train = np.asarray(y_train)
    x_test = np.asarray(x_test)
    y_test = np.asarray(y_test)

    n.fit(x_train, y_train)
    prd_list = n.predict(x_test)
    accu = metrics.accuracy_score(y_test, prd_list)
    print("预测精度: {}".format(accu))
    return prd_list  # 返回的是预测标签
    # 将数据归一化

使用的MNIST数据集文件如下:

https://download.csdn.net/download/qq_23944915/10823451

https://download.csdn.net/download/qq_23944915/10823451

猜你喜欢

转载自blog.csdn.net/qq_23944915/article/details/84728749