手撕Bp神经网络(python实现+附带案例测试)

代码先放在这啦,理论知识以后再来补充

import numpy as np
import pandas as pd
import time
import matplotlib.pyplot as plt

start = time.time()

class Bp:
    def __init__(self,num_input, num_hidden, num_out, num_sample):
        # 三个参数分别为输入,隐藏,输出层的节点个数
        self.num_input = num_input
        self.num_hidden = num_hidden
        self.num_out = num_out

        # 初始化权重矩阵
        """
        为什么使用rand函数结果全为1
        """
        # 以正态分布初始化各层权重
        self.weight_in = np.random.normal(0.0, num_input ** - 0.5, (num_input, num_hidden))  #第一层的权重
        self.weight_out = np.random.normal(0.0, num_hidden ** - 0.5,(num_hidden, num_out)) #第二层的权重

        # self.weight_in = np.random.rand(num_input, num_hidden)  # 第一层的权重
        # self.weight_out = np.random.rand(num_hidden, num_out) # 第二层的权重
        # self.weight_in = np.ones((num_input, num_hidden))  #第一层的权重
        # self.weight_out = np.ones((num_hidden, num_out)) #第二层的权重
        # print(self.weight_in.shape)

        #初始化偏置项
        # self.b_in = np.random.rand(num_hidden, 1)
        # self.b_out = np.random.rand(num_out, 1)

        self.b_in = np.zeros((num_hidden, 1))
        self.b_out = np.zeros((num_out, 1))

        #初试化各层的激活值
        self.input_activate = np.zeros((num_input, 1))
        self.hidden_activate = np.zeros((num_hidden, 1))
        self.out_activate = np.zeros((num_out, 1))

        #初始化激活后的参数
        self.num_sample = num_sample

    def updata(self, data_input):
        self.input_activate = data_input
        #第一层更新
        # print(self.b_in.shape)
        z_hidden = self.input_activate @ self.weight_in + self.b_in.T
        # print(self.input_activate.shape, self.weight_in.shape)
        # print(z_hidden.shape,self.b_in.shape)
        self.hidden_activate = sigmoid(z_hidden)
        # print(self.u_activate.shape)

        #第二层更新
        z_out = self.hidden_activate @ self.weight_out + self.b_out.T
        self.out_activate = sigmoid(z_out)

        # return sigmoid(z_out)

    def derivate_sigmiod(self,x):
        return (1 - x) * x

    #返回第一次正向传播的误差,即预测值和实际值的差值
    def total_loss(self, target):
        error = target - self.out_activate
        return np.sum(np.power(error, 2)) / self.num_sample

    #反向传播更新参数
    def backPropagate(self, data, target, alpha):
        #求输出层的delta
        out_error = self.out_activate - target
        out_delta = out_error * self.derivate_sigmiod(self.out_activate)
        # print(out_delta)

        #计算隐藏层的delta
        hidden_error = out_delta @ self.weight_out.T
        hidden_delta = hidden_error * self.derivate_sigmiod(self.hidden_activate)

        #更新权重
        self.weight_in -= alpha * data.T @ hidden_delta / self.num_sample  #用平均值
        self.weight_out -= alpha * self.hidden_activate.T @ out_delta / self.num_sample #用平均值
        # print(np.sum(hidden_delta,axis=0).reshape(self.num_hidden,1))
        # print(self.weight_in)
        self.b_in -= alpha * np.mean(hidden_delta,axis=0).reshape(self.num_hidden, 1)
        self.b_out -= alpha * np.mean(out_delta,axis=0).reshape(self.num_out, 1)
        # print(self.b_in)


    def train(self, data_input, target, alpha, iterations):
        total_loss = []
        for iter in range(iterations):
            self.updata(data_input)
            self.backPropagate(data_input,target, alpha)
            loss = self.total_loss(target)
            total_loss.append(loss)
        return total_loss

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

from sklearn.datasets import load_boston
from sklearn.preprocessing import MinMaxScaler
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

# 设置缩放器
scaler = MinMaxScaler(feature_range=(0, 1))

def boston():
    print("这是波士顿房价预测:")
    # ****************波士顿的房价预测****************************
    boston = load_boston()

    df = pd.DataFrame(boston['data'], columns=boston['feature_names'])
    df['target'] = boston['target']
    df = scaler.fit_transform(df)


    df, df_test = train_test_split(df,test_size=0.1)
    input = df[:, 0:-1]
    target = df[:, -1].reshape(-1, 1)

    # print(input.shape, target)
    n = 1
    # 对数据进行预测
    model = Bp(13, 69, 1, 5)
    loss = model.train(input,target,0.02,2000 * n)
    model.updata(df_test[:,0:-1])

    plt.plot(np.arange(2000 * n), loss, label="boston")
    plt.legend()
    plt.show()

    print("实际值:\n", df_test[0:5,-1].reshape(-1,1))
    print("预测值:\n", model.out_activate[0:5,:])

def cancer():
    print("这是乳腺癌预测:")
    # *******************乳腺癌的预测*******************************
    cancer_data = load_breast_cancer()

    df1 = pd.DataFrame(cancer_data['data'], columns=cancer_data['feature_names'])
    df1['tagert'] = cancer_data['target']

    df1 = scaler.fit_transform(df1)
    # 划分数据集
    df1, df1_test = train_test_split(df1,test_size=0.1)

    input1 = df1[:, 0:-1]
    # print(input1.shape)
    target1 = df1[:, -1].reshape(-1, 1)

    # print(target1)
    n1 = 1   # 在这调迭代次数呀
    model = Bp(30, 90, 1, 5)
    loss = model.train(input1,target1,0.01,2000 * n1)
    model.updata(df1_test[:,0:-1])

    plt.plot(np.arange(2000 * n1), loss, label="cancer")
    plt.legend()
    plt.show()

    print("实际值:\n", df1_test[0:5,-1].reshape(-1,1))
    print("预测值:\n", model.out_activate[0:5,:])

# ******************************************************
boston()
cancer()

end = time.time()
print("用时:{0}秒".format(end - start))

# 绘制不同学习率下的机器学习曲线
# alpha_list = [0.01, 0.05, 0.08, 0.1,0.3,0.5,0.8,1]
# fig, ax = plt.subplots()
# for alpha in alpha_list:
#     model = Bp(13, 69, 1, 506)
#     total_loss = model.train(df_scaler, target_scaler, alpha, 2000)
#     ax.plot(np.arange(2000), total_loss, label=alpha)
#     ax.legend()
# plt.show()

# df_scaler = np.array([[1,2,5],[1,3,4],[1, 6, 2],[1, 5, 1],[1, 8, 4]])
# target_scaler = np.array([[0],[1],[1],[0],[1]])

# df_scaler = np.array([[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0]])
# target_scaler = np.array([[0],[0.2],[0.4],[0.6],[0.8]])


经典卷积神经网络是指使用numpy纯写的卷积神经网络代码,该代码可以帮助理解卷积神经网络的原理。它不使用任何神经网络框架,适合那些有意愿深入理解卷积神经网络底层的人群。这个代码相对简单,但是通过研究它,可以充分理解卷积神经网络的工作原理。 卷积神经网络(CNN)是一种常用于图像处理和识别的深度学习模型。它通过卷积层、池化层和全连接层等组成,实现了对图像特征的提取和分类。在卷积神经网络中,卷积层通过滤波器(卷积核)对输入图像进行卷积操作,以提取图像的局部特征。池化层则通过降采样的方式,减少特征图的尺寸,同时保留重要的特征信息。全连接层将特征图转化为一维向量,并通过神经网络的计算得出最终的分类结果。 通过经典卷积神经网络的代码,我们可以更加深入地了解卷积神经网络的计算过程。该代码中的全连接层实际上就是指上述提到的全连接神经网络,它将最后一次卷积操作的输出作为输入,并通过神经网络的计算产生最终的输出结果。 总之,经典卷积神经网络可以帮助我们更好地理解卷积神经网络的原理和计算过程。通过研究这个代码,我们可以深入了解卷积操作、池化操作和全连接操作在卷积神经网络中的应用,从而更好地应用和设计卷积神经网络模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值