python手写简单BP神经网络(一个隐含层)

BP神经网络(不调库)

首先设定数据集(我设置的是50*50):

import numpy as np
# x为50行50列(-1,1)的随机浮点数
np.random.seed(1)
X = 2*np.random.random((50,50))-1
# y为50行1列的只含0,1的矩阵
y = np.random.randint(0,2,(50,1))

然后随机初始化权值w(我没有加偏置b,也可以添加):

np.random.seed(2)
w0_1 = np.random.randn(50,100)*0.1

np.random.seed(3)
w1_2= np.random.randn(100,1)*0.1

激活函数与激活函数的一阶导:

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

# 激活函数的一阶导
def sigmoid_f(net):
    return sigmoid(net)*(1-sigmoid(net))

前向传播(输入信号的正向传递):

#0-1层
# 净输入net并激活
result=[]
Net=[]
for q in range(len(X)):
    m=[]
    Nett=[]
    for i in range(len(w0_1.T)):
        net=0.0
        for j in range(len(X[q])):
            net+=X[q][j]*w0_1.T[i][j] # 净输入net
        num=sigmoid(net) # 激活
        Nett.append(net)
        m.append(num)
    Net.append(Nett)
    result.append(m)

#1-2层
# 净输入net1并激活
result1=[]
Net1=[]
for q in range(len(result)):
    net1=0.0
    for j in range(len(result[q])):
        net1+=result[q][j]*w1_2[j][0] # 净输入net
    Net1.append(net1)
    num1=sigmoid(net1) # 激活
    result1.append(num1)

在这里插入图片描述
输出层误差:
在这里插入图片描述

# 输出层误差
E=0.0
for i in range(len(y)):
    E+=(y[i][0]-result1[i])**2
totalE=E/2
totalE

输出层误差的局部梯度

# grant=(y-result1)*sigmoid_f(net)

grants=[]
for i in range(len(y)):
    grant=(y[i][0]-result1[i])*sigmoid_f(Net1[i])
    grants.append(grant)

输出层权值对误差E的影响

# 学习率learn
learn=0.001

# 将列表result转置
result_T=[[ y[x] for y in result ] for x in range(len(result[0]))]

# 更新w1_2
for q in range(len(result_T)):
    for k in range(len(result_T[q])):
        w1_2[q][0]=w1_2[q][0]-learn*grants[k]*result_T[q][k]

输出层误差的关于隐含层的净输入的局部梯度
在这里插入图片描述

#  grants_0=grants*w1_2*sigmoid_f(net)
grants_0=[]
for k in range(len(Net[0])):
    for i in range(len(y)):
        grant_0=0.0
        for j in range(len(w1_2)):
            grant_0+=grants[i]*w1_2[j]
        grant_0 *=sigmoid_f(Net[i][k])
    grants_0.append(grant_0)

更新w0_1:

# 更新w0-1
for k in range(len(X)):
    for i in range(len(w0_1)):
        for j in range(len(w0_1[i])):
            w0_1[i][j] = w0_1[i][j]-learn*grants_0[j][0]*X[k][i]

输出层的权值调整:
在这里插入图片描述
隐含层的权值调整:
在这里插入图片描述
其中:
在这里插入图片描述
完整代码(学习率为0.01,迭代500次):

import numpy as np
import matplotlib.pyplot as plt


def get_data():
    # x为50行50列(-1,1)的随机浮点数
    np.random.seed(1)
    X = 2 * np.random.random((50, 50)) - 1
    # y为501列的只含01的矩阵
    y = np.random.randint(0, 2, (50, 1))
    return X,y


def init_w():
    np.random.seed(2)
    w0_1 = np.random.randn(50, 100) * 0.1
    # 随机初始化1-2层权值100*1
    np.random.seed(3)
    w1_2 = np.random.randn(100, 1) * 0.1
    return w0_1,w1_2


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


# 激活函数的一阶导
def sigmoid_f(net):
    return sigmoid(net)*(1-sigmoid(net))


#0-1层
# 净输入net并激活
def forward0_1(X,w0_1):
    result = []
    Net = []
    for q in range(len(X)):
        m = []
        Nett = []
        for i in range(len(w0_1.T)):
            net = 0.0
            for j in range(len(X[q])):
                net += X[q][j] * w0_1.T[i][j]  # 净输入net
            num = sigmoid(net)  # 激活
            Nett.append(net)
            m.append(num)
        Net.append(Nett)
        result.append(m)

    return Net,result


# 1-2层
# 净输入net1并激活
def forward1_2(result,w1_2):
    result1 = []
    Net1 = []
    for q in range(len(result)):
        net1 = 0.0
        for j in range(len(result[q])):
            net1 += result[q][j] * w1_2[j][0]  # 净输入net
        Net1.append(net1)
        num1 = sigmoid(net1)  # 激活
        result1.append(num1)

    return Net1,result1


# 输出层误差
def coss(y,result1):
    E = 0.0
    for i in range(len(y)):
        E += (y[i][0] - result1[i]) ** 2
    totalE = E / 2

    return totalE


# 输出层误差的局部梯度
# grant=(y-result1)*sigmoid_f(net)
def get_grants(y,result1,Net1):
    grants = []
    for i in range(len(y)):
        grant = (y[i][0] - result1[i]) * sigmoid_f(Net1[i])
        grants.append(grant)

    return grants


def upgrade_w1_2(result,w1_2,learn,grants):
    # 将列表result转置
    result_T = [[y[x] for y in result] for x in range(len(result[0]))]

    # 更新w1_2
    for q in range(len(result_T)):
        for k in range(len(result_T[q])):
            w1_2[q][0] = w1_2[q][0] + learn * grants[k] * result_T[q][k]

    return w1_2


# 输出层误差的关于隐含层的净输入的局部梯度 grants_0=grants*w1_2*sigmoid_f(net)
def get_grants_0(Net,y,w1_2,grants):
    grants_0 = []
    for k in range(len(Net[0])):
        for i in range(len(y)):
            gra = 0.0
            for j in range(len(w1_2)):
                gra += grants[i] * w1_2[j]
            gra *= sigmoid_f(Net[i][k])
        grants_0.append(gra)

    return grants_0


def upgrade_w0_1(X,w0_1,learn,grants_0):
    for k in range(len(X)):
        for i in range(len(w0_1)):
            for j in range(len(w0_1[i])):
                w0_1[i][j] = w0_1[i][j] + learn * grants_0[j][0] * X[k][i]

    return w0_1


# 准确率
def accuracy(result1,y):
    T=0
    for i in range(len(result1)):
        if result1[i]>0.5:
            if y[i]==1:
                T +=1
        else:
            if y[i]==0:
                T +=1

    return T/len(y)


# 召回率
def recall(result1,y):
    TP = 0
    P = 0
    for i in range(len(result1)):
        if result1[i]>0.5:
            if y[i]==1:
                TP +=1

    for j in y:
        if j[0]==1:
            P+=1
    return TP/P


if __name__ == '__main__':
    learn=0.01
    X,y=get_data()
    w0_1, w1_2 = init_w()
    Total=[]
    Accuracy=[]
    Recall=[]

    for i in range(500):
        Net, result=forward0_1(X,w0_1)
        Net1, result1 = forward1_2(result,w1_2)
        totalE = coss(y,result1)
        grants=get_grants(y,result1,Net1)
        w1_2=upgrade_w1_2(result,w1_2,learn,grants)
        grants_0=get_grants_0(Net,y,w1_2,grants)
        w0_1 = upgrade_w0_1(X,w0_1,learn,grants_0)

        Total.append(totalE)
        Accuracy.append(accuracy(result1,y))
        Recall.append(recall(result1,y))

        print("第"+str(i)+"次:")
        print("误差:",totalE)
        print("准确率:",accuracy(result1,y))
        print("召回率:",recall(result1,y))

    plt.subplot(221)
    plt.plot(range(len(Total)),Total)
    plt.ylabel('coss', fontsize=16)
    plt.xlabel('count', fontsize=16)

    plt.subplot(222)
    plt.plot(range(len(Accuracy)),Accuracy)
    plt.ylabel('Accuracy', fontsize=16)
    plt.xlabel('count', fontsize=16)

    plt.subplot(223)
    plt.plot(range(len(Recall)),Recall)
    plt.ylabel('Recall', fontsize=16)
    plt.xlabel('count', fontsize=16)

    plt.show()

运行结果(coss为损失误差,Accuracy为准确率,Recall为召回率,count为迭代次数):
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值