经过一个多月的努力,终于完成了BP网络,参考的资料为:

1、Training feed-forward networks with the Marquardt algorithm

2、The Levenberg-Marquardt method for nonlinear least squares curve-fitting problems

3、Neural Network Design

4、http://deeplearning.stanford.edu/wiki/index.php/UFLDL%E6%95%99%E7%A8%8B 中介绍的神经网络部分

以下给出Python脚本:

import numpy as np
from math import exp, pow
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import sys
import copy
from scipy.linalg import norm, pinv
class Layer:
def __init__(self,w, b, neure_number, transfer_function, layer_index):
self.transfer_function = transfer_function
self.neure_number = neure_number
self.layer_index = layer_index
self.w = w
self.b = b class NetStruct:
def __init__(self, x, y, hidden_layers, activ_fun_list, performance_function = 'mse'):
if len(hidden_layers) == len(activ_fun_list):
activ_fun_list.append('line')
self.active_fun_list = activ_fun_list
self.performance_function = performance_function
x = np.array(x)
y = np.array(y)
if(x.shape[1] != y.shape[1]):
print 'The dimension of x and y are not same.'
sys.exit()
self.x = x
self.y = y
input_eles = self.x.shape[0]
output_eles = self.y.shape[0]
tmp = []
tmp.append(input_eles)
tmp.extend(hidden_layers)
tmp.append(output_eles)
self.hidden_layers = np.array(tmp)
self.layer_num = len(self.hidden_layers)
self.layers = []
for i in range(0, len(self.hidden_layers)): if i == 0:
self.layers.append(Layer([],[],\
self.hidden_layers[i], 'none', i))
continue
f = self.hidden_layers[i - 1]
s = self.hidden_layers[i]
self.layers.append(Layer(np.random.randn(s, f),np.random.randn(s, 1),\
self.hidden_layers[i], activ_fun_list[i-1], i)) class Train:
def __init__(self, net_struct, mu = 1e-3, beta = 10, iteration = 100, tol = 0.1):
self.net_struct = net_struct
self.mu = mu
self.beta = beta
self.iteration = iteration
self.tol = tol
def train(self, method = 'lm'):
if(method == 'lm'):
self.lm()
def sim(self, x):
self.net_struct.x = x
self.forward()
layer_num = len(self.net_struct.layers)
predict = self.net_struct.layers[layer_num - 1].output_val
return predict
def actFun(self, z, activ_type = 'sigm'):
if activ_type == 'sigm':
f = 1.0 / (1.0 + np.exp(-z))
elif activ_type == 'tanh':
f = (np.exp(z) + np.exp(-z)) / (np.exp(z) + np.exp(-z))
elif activ_type == 'radb':
f = np.exp(-z * z)
elif activ_type == 'line':
f = z
return f
def actFunGrad(self, z, activ_type = 'sigm'):
if activ_type == 'sigm':
grad = self.actFun(z, activ_type) * (1.0 - self.actFun(z, activ_type))
elif activ_type == 'tanh':
grad = 1.0 - self.actFun(z, activ_type) * self.actFun(z, activ_type)
elif activ_type == 'radb':
grad = -2.0 * z * self.actFun(z, activ_type)
elif activ_type == 'line':
m = z.shape[0]
n = z.shape[1]
grad = np.ones((m, n))
return grad
def forward(self):
layer_num = len(self.net_struct.layers)
for i in range(0, layer_num):
if i == 0:
curr_layer = self.net_struct.layers[i]
curr_layer.input_val = self.net_struct.x
curr_layer.output_val = self.net_struct.x
continue
before_layer = self.net_struct.layers[i - 1]
curr_layer = self.net_struct.layers[i]
curr_layer.input_val = curr_layer.w.dot(before_layer.output_val) + curr_layer.b
curr_layer.output_val = self.actFun(curr_layer.input_val,
self.net_struct.active_fun_list[i - 1])
def backward(self):
layer_num = len(self.net_struct.layers)
last_layer = self.net_struct.layers[layer_num - 1]
last_layer.error = -self.actFunGrad(last_layer.input_val,
self.net_struct.active_fun_list[layer_num - 2])
layer_index = range(1, layer_num - 1)
layer_index.reverse()
for i in layer_index:
curr_layer = self.net_struct.layers[i]
curr_layer.error = (last_layer.w.transpose().dot(last_layer.error)) \
* self.actFunGrad(curr_layer.input_val,self.net_struct.active_fun_list[i - 1])
last_layer = curr_layer
def parDeriv(self):
layer_num = len(self.net_struct.layers)
for i in range(1, layer_num):
befor_layer = self.net_struct.layers[i - 1]
befor_input_val = befor_layer.output_val.transpose()
curr_layer = self.net_struct.layers[i]
curr_error = curr_layer.error
curr_error = curr_error.reshape(curr_error.shape[0]*curr_error.shape[1], 1, order='F')
row = curr_error.shape[0]
col = befor_input_val.shape[1]
a = np.zeros((row, col))
num = befor_input_val.shape[0]
neure_number = curr_layer.neure_number
for i in range(0, num):
a[neure_number*i:neure_number*i + neure_number,:] = \
np.repeat([befor_input_val[i,:]],neure_number,axis = 0)
tmp_w_par_deriv = curr_error * a
curr_layer.w_par_deriv = np.zeros((num, befor_layer.neure_number * curr_layer.neure_number))
for i in range(0, num):
tmp = tmp_w_par_deriv[neure_number*i:neure_number*i + neure_number,:]
tmp = tmp.reshape(tmp.shape[0] * tmp.shape[1], order='C')
curr_layer.w_par_deriv[i, :] = tmp
curr_layer.b_par_deriv = curr_layer.error.transpose()
def jacobian(self):
layers = self.net_struct.hidden_layers
row = self.net_struct.x.shape[1]
col = 0
for i in range(0, len(layers) - 1):
col = col + layers[i] * layers[i + 1] + layers[i + 1]
j = np.zeros((row, col))
layer_num = len(self.net_struct.layers)
index = 0
for i in range(1, layer_num):
curr_layer = self.net_struct.layers[i]
w_col = curr_layer.w_par_deriv.shape[1]
b_col = curr_layer.b_par_deriv.shape[1]
j[:, index : index + w_col] = curr_layer.w_par_deriv
index = index + w_col
j[:, index : index + b_col] = curr_layer.b_par_deriv
index = index + b_col
return j
def gradCheck(self):
W1 = self.net_struct.layers[1].w
b1 = self.net_struct.layers[1].b
n = self.net_struct.layers[1].neure_number
W2 = self.net_struct.layers[2].w
b2 = self.net_struct.layers[2].b
x = self.net_struct.x
p = []
p.extend(W1.reshape(1,W1.shape[0]*W1.shape[1],order = 'C')[0])
p.extend(b1.reshape(1,b1.shape[0]*b1.shape[1],order = 'C')[0])
p.extend(W2.reshape(1,W2.shape[0]*W2.shape[1],order = 'C')[0])
p.extend(b2.reshape(1,b2.shape[0]*b2.shape[1],order = 'C')[0])
old_p = p
jac = []
for i in range(0, x.shape[1]):
xi = np.array([x[:,i]])
xi = xi.transpose()
ji = []
for j in range(0, len(p)):
W1 = np.array(p[0:2*n]).reshape(n,2,order='C')
b1 = np.array(p[2*n:2*n+n]).reshape(n,1,order='C')
W2 = np.array(p[3*n:4*n]).reshape(1,n,order='C')
b2 = np.array(p[4*n:4*n+1]).reshape(1,1,order='C') z2 = W1.dot(xi) + b1
a2 = self.actFun(z2)
z3 = W2.dot(a2) + b2
h1 = self.actFun(z3)
p[j] = p[j] + 0.00001
W1 = np.array(p[0:2*n]).reshape(n,2,order='C')
b1 = np.array(p[2*n:2*n+n]).reshape(n,1,order='C')
W2 = np.array(p[3*n:4*n]).reshape(1,n,order='C')
b2 = np.array(p[4*n:4*n+1]).reshape(1,1,order='C') z2 = W1.dot(xi) + b1
a2 = self.actFun(z2)
z3 = W2.dot(a2) + b2
h = self.actFun(z3)
g = (h[0][0]-h1[0][0])/0.00001
ji.append(g)
jac.append(ji)
p = old_p
return jac
def jjje(self):
layer_number = self.net_struct.layer_num
e = self.net_struct.y - \
self.net_struct.layers[layer_number - 1].output_val
e = e.transpose()
j = self.jacobian()
#check gradient
#j1 = -np.array(self.gradCheck())
#jk = j.reshape(1,j.shape[0]*j.shape[1])
#jk1 = j1.reshape(1,j1.shape[0]*j1.shape[1])
#plt.plot(jk[0])
#plt.plot(jk1[0],'.')
#plt.show()
jj = j.transpose().dot(j)
je = -j.transpose().dot(e)
return[jj, je]
def lm(self):
mu = self.mu
beta = self.beta
iteration = self.iteration
tol = self.tol
y = self.net_struct.y
self.forward()
pred = self.net_struct.layers[self.net_struct.layer_num - 1].output_val
pref = self.perfermance(y, pred)
for i in range(0, iteration):
print 'iter:',i, 'error:', pref
#1) step 1:
if(pref < tol):
break
#2) step 2:
self.backward()
self.parDeriv()
[jj, je] = self.jjje()
while(1):
#3) step 3:
A = jj + mu * np.diag(np.ones(jj.shape[0]))
delta_w_b = pinv(A).dot(je)
#4) step 4:
old_net_struct = copy.deepcopy(self.net_struct)
self.updataNetStruct(delta_w_b)
self.forward()
pred1 = self.net_struct.layers[self.net_struct.layer_num - 1].output_val
pref1 = self.perfermance(y, pred1)
if (pref1 < pref):
mu = mu / beta
pref = pref1
break
mu = mu * beta
self.net_struct = copy.deepcopy(old_net_struct)
def updataNetStruct(self, delta_w_b):
layer_number = self.net_struct.layer_num
index = 0
for i in range(1, layer_number):
before_layer = self.net_struct.layers[i - 1]
curr_layer = self.net_struct.layers[i]
w_num = before_layer.neure_number * curr_layer.neure_number
b_num = curr_layer.neure_number
w = delta_w_b[index : index + w_num]
w = w.reshape(curr_layer.neure_number, before_layer.neure_number, order='C')
index = index + w_num
b = delta_w_b[index : index + b_num]
index = index + b_num
curr_layer.w += w
curr_layer.b += b
def perfermance(self, y, pred):
error = y - pred
return norm(error) / len(y)
def plotSamples(self, n = 40):
x = np.array([np.linspace(0, 3, n)])
x = x.repeat(n, axis = 0)
y = x.transpose()
z = np.zeros((n, n))
for i in range(0, x.shape[0]):
for j in range(0, x.shape[1]):
z[i][j] = self.sampleFun(x[i][j], y[i][j])
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(x, y, z, cmap='autumn', cstride=2, rstride=2)
ax.set_xlabel("X-Label")
ax.set_ylabel("Y-Label")
ax.set_zlabel("Z-Label")
plt.show()
def sinSamples(n):
x = np.array([np.linspace(-0.5, 0.5, n)])
#x = x.repeat(n, axis = 0)
y = x + 0.2
z = np.zeros((n, 1))
for i in range(0, x.shape[1]):
z[i] = np.sin(x[0][i] * y[0][i])
X = np.zeros((n, 2))
n = 0
for xi, yi in zip(x.transpose(), y.transpose()):
X[n][0] = xi
X[n][1] = yi
n = n + 1
return X,z
def peaksSamples(n):
x = np.array([np.linspace(-3, 3, n)])
x = x.repeat(n, axis = 0)
y = x.transpose()
z = np.zeros((n, n))
for i in range(0, x.shape[0]):
for j in range(0, x.shape[1]):
z[i][j] = sampleFun(x[i][j], y[i][j])
X = np.zeros((n*n, 2))
x_list = x.reshape(n*n,1 )
y_list = y.reshape(n*n,1)
z_list = z.reshape(n*n,1)
n = 0
for xi, yi in zip(x_list, y_list):
X[n][0] = xi
X[n][1] = yi
n = n + 1 return X,z_list.transpose()
def sampleFun(x, y):
z = 3*pow((1-x),2) * exp(-(pow(x,2)) - pow((y+1),2)) \
- 10*(x/5 - pow(x, 3) - pow(y, 5)) * exp(-pow(x, 2) - pow(y, 2)) \
- 1/3*exp(-pow((x+1), 2) - pow(y, 2))
return z
if __name__ == '__main__': hidden_layers = [10,10] #设置网络层数,共两层,每层10个神经元
activ_fun_list = ['sigm','sigm']#设置隐层的激活函数类型,可以设置为tanh,radb,tanh,line类型,如果不显式的设置最后一层为line [X, z] = peaksSamples(20) #产生训练数据点
X = X.transpose()
bp = NetStruct(X, z, hidden_layers, activ_fun_list) #初始化网络信息
tr = Train(bp) #初始化训练网络的类
tr.train() #训练
[XX, z0] = peaksSamples(40) #产生测试数据
XX = XX.transpose()
z1 = tr.sim(XX) #用训练好的神经网络预测数据,z1为预测结果 fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z0[0]) #真值
ax.plot(z1[0],'r.') #预测值
plt.legend((r'real data', r'predict data'))
plt.show()

以上代码计算的结果如下图,由于初始值等原因的影响偶尔收敛效果会变差,不过大多数时候都可以收敛到下图的结果,以后再改进,欢迎指正。

基于Levenberg-Marquardt训练算法的BP网络Python实现的更多相关文章

  1. 基于Opencv自带BP网络的车标简易识别

    代码地址如下:http://www.demodashi.com/demo/12966.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + 演示效果 1.准备工作 1.1 训练集和测 ...

  2. 关于BP网络的一些总结

    背景 前段时间,用过一些模型如vgg,lexnet,用于做监督学习训练,顺带深入的学习了一下相关模型的结构&原理,对于它的反向传播算法记忆比较深刻, 就自己的理解来描述一下BP网络. 关于BP ...

  3. 基于ReliefF和K-means算法的医学应用实例

    基于ReliefF和K-means算法的医学应用实例 数据挖掘方法的提出,让人们有能力最终认识数据的真正价值,即蕴藏在数据中的信息和知识.数据挖掘 (DataMiriing),指的是从大型数据库或数据 ...

  4. 从头推导与实现 BP 网络

    从头推导与实现 BP 网络 回归模型 目标 学习 \(y = 2x\) 模型 单隐层.单节点的 BP 神经网络 策略 Mean Square Error 均方误差 \[ MSE = \frac{1}{ ...

  5. 神经网络和误差逆传播算法(BP)

    本人弱学校的CS 渣硕一枚,在找工作的时候,发现好多公司都对深度学习有要求,尤其是CNN和RNN,好吧,啥也不说了,拿过来好好看看.以前看习西瓜书的时候神经网络这块就是一个看的很模糊的块,包括台大的视 ...

  6. 传统神经网络ANN训练算法总结

    传统神经网络ANN训练算法总结 学习/训练算法分类 神经网络类型的不同,对应了不同类型的训练/学习算法.因而根据神经网络的分类,总结起来,传统神经网络的学习算法也可以主要分为以下三类: 1)前馈型神经 ...

  7. 我对BP网络的简单的理解

    最近在学习tf的神经网络算法,十多年没有学习过数学了,本来高中数学的基础,已经彻底还给数学老师了.所以我把各种函数.公式和推导当做黑盒子来用,理解他们能做到什么效果,至于他们是如何做到的,暂时不去深究 ...

  8. BP网络中的反向传播

    本文的主要参考:How the backpropagation algorithm works 下面是BP网络的参数结构示意图 首先定义第l层网络第j个神经元的输出(activation) 为了表示简 ...

  9. 感知机算法及BP神经网络

    简介:感知机在1957年就已经提出,可以说是最为古老的分类方法之一了.是很多算法的鼻祖,比如说BP神经网络.虽然在今天看来它的分类模型在很多数时候泛化能力不强,但是它的原理却值得好好研究.先学好感知机 ...

随机推荐

  1. java设计模式之一工厂模式

    简单工厂模式是java设计模式中最简单的设计模式之一: 工厂模式是最常用的设计模式之一. 工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模 ...

  2. 腾讯云安装openvz,高速搭建測试环境

    CSDN送了腾讯云的測试资格,准备拿来作为cici的软件公布首页,想在上面做个demo,无奈没有设备环境,于是想要用openvz来虚拟一些vps: 第一步:选择腾讯云的os模板,centos6.3 第 ...

  3. Android注入事件的三种方法比较

    方法1:使用内部APIs 该方法和其他所有内部没有向外正式公布的APIs一样存在它自己的风险.原理是通过获得WindowManager的一个实例来访问injectKeyEvent/injectPoin ...

  4. MySQL安装指南

    近期领导突然说要用MySQL,我立刻当天晚上就研究了一下. http://www.mysql.com/这是官网,还好能够訪问.好多年前已经被oracle收购.分为企业版和社区版: MySQL Ente ...

  5. SQL点滴7—使用SQL Server的attach功能出现错误及解决方法

    原文:SQL点滴7-使用SQL Server的attach功能出现错误及解决方法 今天用SQL Server 2008的attach功能附加一个数据库,出了点问题,提示的错误是: Unable to ...

  6. idea中output log4j中文乱码

    1.设置tomcat中的VM optins:-Dfile.encofing=UTF-8 2.idea安装目录bin文件夹中idea.exe.vmoptions.idea64.exe.vmoptions ...

  7. 使用jquery.form异步提交注意jquery.validate需要手动添加验证

    使用jquery.form.js异步提时,即使jquery.validate验证失败也会提交的所以加个$("form").valid()来判断是否通过验证: $("#fo ...

  8. IS_EER分析

    下面我们就来具体分析一下这段代码,看看内核中的巧妙设计思路. 要想明白IS_ERR(),首先理解要内核空间.所有的驱动程序都是运行在内核空间,内核空间虽然很大,但总是有限的,而在这有限的空间中,其最后 ...

  9. mvc项目如何在IIS7.5

    mvc项目如何在IIS7.5上发布的 1.在vs中打开你要发布的项目,右键属性找到发布 2.弹出发布web对话框,选择<新建配置文件...> 在弹出的对话框中输入一个配置文件名称,后确定 ...

  10. ORACLE表建立自增列

    create tablespace studentDBdatafile 'E:\datafiles_1.dbf' size 10m; create user Huang_Ying_Boidentifi ...