BP算法为深度学习中参数更新的重要角色,一般基于loss对参数的偏导进行更新。

一些根据均方误差,每层默认激活函数sigmoid(不同激活函数,则更新公式不一样)

假设网络如图所示:

则更新公式为:

以上列举了最后2层的参数更新方式,第一层的更新公式类似,即上一层的误差来自于下一层所有的神经元,e的更新就是不断建立在旧的e上(这里g可以当做初始的e)

下面上代码:

1,BP算法

# 手写BP算法
import numpy as np # 先更新参数,再继续传播
# layers:包括从输入层到输出层,每层参数为:连接权重w,阈值b,输出y。类型为np.array
# 对于输入层,w和b随便是啥,反正不用,只需y即原始输入
# 基于激活函数sigmoid
# loss为均方误差
def bp(layers,labels,lr=0.001):
# 翻转layers,反向传播
reversed_layers=layers[::-1]
# 输出层
output_w,output_b,output_y=reversed_layers[0]
g=np.array([output_y[j]*(1-output_y[j])*(labels[j]-output_y[j]) for j in range(len(labels))])
# 最后一层更新较为特殊,先进行更新
delta_w=np.empty(shape=(output_w.shape[0],output_w.shape[1]))
# 上一层输出y
last_y=reversed_layers[1][2]
for h in range(output_w.shape[0]):
for j in range(output_w.shape[1]):
delta_w[h,j]=lr*g[j]*last_y[h]
delta_b=-lr*g
new_w=output_w+delta_w
new_b=output_b+delta_b
reversed_layers[0][0]=new_w
reversed_layers[0][1]=new_b # 从倒数第二层到第二层进行更新,每次取3层进行计算,由公式知,需用到上一层输出即下一层权重
for i in range(1,len(reversed_layers)-1):
# 下一层w
next_w=reversed_layers[i-1][0]
out_w,out_b,out_y=reversed_layers[i]
# 上一层y
last_y=reversed_layers[i+1][2]
# 更新辅助量,意思即上一层每个神经元的误差都由下一层所有神经元的误差反向传播,体现在这里内循环
e=np.empty(shape=(len(out_b),1))
for h in range(len(out_b)):
temp=0
for j in range(next_w.shape[1]):
temp+=next_w[h,j]*g[j]
e[h]=out_y[h]*(1-out_y[h])*temp
delta_w=np.empty(shape=(out_w.shape[0],out_w.shape[1]))
for h in range(out_w.shape[0]):
for j in range(out_w.shape[1]):
delta_w[h,j]=lr*e[j]*last_y[h]
delta_b=-lr*e
out_new_w=out_w+delta_w
out_new_b=out_b+delta_b
reversed_layers[i][0]=out_new_w
reversed_layers[i][1]=out_new_b
g=np.copy(e)
return layers

以上假设每个神经元的输出为一个实数y值

2,构建测试

构建平面上的点(x,y),将y是否大于0作为划分,进行训练。只使用了一层网络,sigmoid激活

X=[]
Y=[]
for i in range(-100,100):
for j in range(-100,100):
X.append([[i],[j]])
if j>=0:
Y.append([1])
else:
Y.append([0])
X=np.array(X)
Y=np.array(Y)

3,划分训练,验证集

indexs=np.random.choice(range(40000),size=30000)

x_train=np.array([X[i] for i in indexs])
y_train=np.array([Y[i] for i in indexs]) x_val=np.array([X[i] for i in np.setdiff1d(range(40000),indexs))
y_val=np.array([Y[i] for i in np.setdiff1d(range(40000),indexs))

4,训练。这里只对所有样本训练了一轮。使用随机初始化的w和b,每个样本都会改变w和b

# 使用sigmoid激活函数
def output(input_x,w,b):
res=0
t=np.matmul(np.transpose(w),input_x)-b
return 1./(1+np.power(np.e,-t)) w1=np.random.normal(size=(2,1))
b1=np.array([[0]])
for i in range(len(x_train)):
y0=x_train[i]
l=y_train[i]
input_layers=[]
w0,b0=(0,0)
input_layers.append([w0,b0,y0])
input_layers.append([w1,b1,output(y0,w1,b1)])
input_layers=bp(input_layers,l)
w1=input_layers[1][0]
b1=input_layers[1][1] # w: [[0.11213777]
# [1.67425498]]
# b: [[0.0001581]]
print('w: ',w1)
print('b: ',b1)

5,验证。从分出的验证集选取部分验证即可

for xx in x_val[:50]:
print(xx.reshape((2,)),output(xx,w1,b1).reshape((1,)))

验证结果如下:

[63 68] [1.]
[-100 -99] [1.39636722e-77]
[-100 -98] [7.44936654e-77]
[63 69] [1.]
[-100 -96] [2.12011171e-75]
[-100 -94] [6.03390049e-74]
[-100 -93] [3.21897678e-73]
[63 74] [1.]
[-100 -91] [9.16130293e-72]
[63 75] [1.]
[63 76] [1.]
[63 77] [1.]
[63 78] [1.]
[-100 -86] [3.95872874e-68]
[-100 -85] [2.11191018e-67]
[63 79] [1.]
[-100 -83] [6.01055872e-66]
[-100 -82] [3.20652436e-65]
[63 82] [1.]
[-100 -80] [9.12586299e-64]
[-100 -79] [4.86848285e-63]
[63 83] [1.]
[-100 -77] [1.38558459e-61]
[-100 -76] [7.39184317e-61]
[63 89] [1.]
[-100 -74] [2.10374039e-59]
[63 91] [1.]
[-100 -72] [5.98730724e-58]
[-100 -71] [3.19412012e-57]
[-100 -70] [1.70400531e-56]
[-100 -69] [9.09056014e-56]
[-100 -68] [4.84964942e-55]
[-100 -67] [2.58720025e-54]
[-100 -66] [1.38022454e-53]
[63 99] [1.]
[-100 -64] [3.92815978e-52]
[-100 -63] [2.09560219e-51]
[ 64 -100] [2.53988133e-70]
[-100 -61] [5.9641457e-50]
[ 64 -97] [3.85631522e-68]
[ 64 -96] [2.05727442e-67]
[-100 -58] [9.05539386e-48]
[ 64 -90] [4.74253371e-63]
[ 64 -89] [2.53005596e-62]
[ 64 -87] [7.20061393e-61]
[-100 -52] [2.08749548e-43]
[ 64 -84] [1.09327301e-58]
[-100 -50] [5.94107377e-42]
[ 95 -13] [1.49260907e-05]
[-100 -45] [2.56722211e-38]

6,总结:可以看出,这50个验证样本上都没问题,虽然想到的测试方案有点low,但一时找不到啥好数据。由此验证BP算法的正确性。如有可疑或不足之处,敬请告知。

手写BP(反向传播)算法的更多相关文章

  1. 机器学习 —— 基础整理(七)前馈神经网络的BP反向传播算法步骤整理

    这里把按 [1] 推导的BP算法(Backpropagation)步骤整理一下.突然想整理这个的原因是知乎上看到了一个帅呆了的求矩阵微分的方法(也就是 [2]),不得不感叹作者的功力.[1] 中直接使 ...

  2. 【深度学习】BP反向传播算法Python简单实现

    转载:火烫火烫的 个人觉得BP反向传播是深度学习的一个基础,所以很有必要把反向传播算法好好学一下 得益于一步一步弄懂反向传播的例子这篇文章,给出一个例子来说明反向传播 不过是英文的,如果你感觉不好阅读 ...

  3. 手推机器学习公式(一) —— BP 反向传播算法

    方便起见,本文仅以三层的神经网络举例. f(⋅):表示激励函数 xi:表示输入层: yj:表示中间的隐层: yj=f(netj) netj=∑i=0nvijxi ok:表示输出层,dk 则表示期望输出 ...

  4. BP反向传播算法的工作原理How the backpropagation algorithm works

    In the last chapter we saw how neural networks can learn their weights and biases using the gradient ...

  5. 神经网络训练中的Tricks之高效BP(反向传播算法)

    神经网络训练中的Tricks之高效BP(反向传播算法) 神经网络训练中的Tricks之高效BP(反向传播算法) zouxy09@qq.com http://blog.csdn.net/zouxy09 ...

  6. 深度神经网络(DNN)反向传播算法(BP)

    在深度神经网络(DNN)模型与前向传播算法中,我们对DNN的模型和前向传播算法做了总结,这里我们更进一步,对DNN的反向传播算法(Back Propagation,BP)做一个总结. 1. DNN反向 ...

  7. 神经网络之反向传播算法(BP)公式推导(超详细)

    反向传播算法详细推导 反向传播(英语:Backpropagation,缩写为BP)是"误差反向传播"的简称,是一种与最优化方法(如梯度下降法)结合使用的,用来训练人工神经网络的常见 ...

  8. 稀疏自动编码之反向传播算法(BP)

    假设给定m个训练样本的训练集,用梯度下降法训练一个神经网络,对于单个训练样本(x,y),定义该样本的损失函数: 那么整个训练集的损失函数定义如下: 第一项是所有样本的方差的均值.第二项是一个归一化项( ...

  9. 【机器学习】反向传播算法 BP

    知识回顾 1:首先引入一些便于稍后讨论的新标记方法: 假设神经网络的训练样本有m个,每个包含一组输入x和一组输出信号y,L表示神经网络的层数,S表示每层输入的神经元的个数,SL代表最后一层中处理的单元 ...

随机推荐

  1. C# out关键字

    在c#中"out"关键字可以通过参数一次返回多个值. using System; namespace ConsoleApplication1 { internal class Pr ...

  2. wx小程序知识点(八)

    八.小程序的优劣势 优势:   ① 不需要下载 ② 打开速度快 ③ 开发成本低 ④ 安卓上可以添加在桌面,与原生 App 相似 ⑤ 小程序的发布审查流程比较严格,安全保障 劣势:   ① 页面大小不能 ...

  3. PHP 下载+安装

    1.官网下载 官网地址:http://PHP.net/ 地址:http://download.csdn.NET/detail/anndy_/9494632 官网手册:https://secure.ph ...

  4. C语言写数据库(一)

    /*** connect.c ***/ #include<stdio.h> #include<stdlib.h> #include"mysql.h" int ...

  5. supsplk 服务器被植入木马 挖矿 cpu使用 700%

    最近emr集群跑任务的时候总出现 task failed ,优化sql,调提交任务参数都没解决,最后再我排查时候,发现一个从节点的cpu使用800% 经过一些列排查,发现是被注入木马了, #被人种下的 ...

  6. python学习之路(4)

    使用list和tuple Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: >& ...

  7. 分布式-信息方式-ActiveMQ示例

    实战 代码如下: 信息生产者 package test.mq.helloword; import javax.jms.Connection; import javax.jms.ConnectionFa ...

  8. C++入门经典-例5.14-丢失的内存,关于内存泄漏

    1:代码如下: // 5.14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...

  9. TCP定时器 之 重传定时器

    注:这部分还没有完全分析透彻,先在此记录,后面回顾的时候再进行补充: 启动定时器: (1) 之前发送的数据段已经得到确认,新发出一个数据段之后设定: (2) 新建连接发送syn之后设定: (3) PM ...

  10. 使用OMF特性

    Oracle 的OMF全称"Oracle managed file",关于这个概念的参考请自行查阅Oracle官方文档"Using Oracle-Managed File ...