BP神经网络是一种按照误差逆向传播算法训练的多层前馈神经网络,是目前应用最广泛的神经网络。
BP神经网络误差反向传播神经网络:
- 置各权和阈值的初始化
- 给定P个训练样本Xp(p=1,2,...,p) 和对应的理想输出Dp(p=1,2,...p)
- 信息前向传递:
计算网络各层的输出
4.误差反向传播
5.修改权和阈值
6.重复2~5步,直至P个样本都训练一边
7.判断是否满足精度要求。若满足,则停止训练,否则重复第2步。
根据上述流程,编写代码:
class BPNet{
constructor(layernum, n, fn, fd, miu, iter ,eps){
if(!(n instanceof Array)) {
throw '参数错误'
}
if(!n.length == layernum) {
throw '参数错误'
}
this.layernum = layernum
this.n = n
//输出函数
if(!fn) {
this.fn = function (x) {
return 1.0/(1.0 + Math.exp(-x))
}
}else {
this.fn = fn
}
//误差函数
if(!fd) {
this.fd = function(x) {
return x * (1 - x)
}
}else {
this.fd = fd
}
this.w = new Array()//权值矩阵
this.b = new Array() //阈值矩阵
this.miu = miu || 0.5 //学习速率
this.iter = iter || 500 //迭代次数
this.e = 0.0 //误差
this.eps = eps || 0.0001
for(let l = 1; l < this.layernum;l++) {
let item = new Array()
let bitem = new Array()
for(let j = 0;j < n[l]; j++) {
let temp = new Array()
for(let i = 0;i < n[l - 1];i++) {
temp[i] = Math.random()
}
item.push(temp)
bitem.push(Math.random())
}
this.w[l] = item
this.b[l] = bitem
}
}
//预测函数
forward(x) {
let y = new Array()
y[0] = x
for(let l = 1; l < this.layernum;l++) {
y[l] = new Array()
for(let j = 0;j < this.n[l]; j++) {
let u = 0.0
for(let i = 0;i < this.n[l - 1]; i++) {
u = u + this.w[l][j][i] * y[l - 1][i]
}
u = u + this.b[l][j]
y[l][j] = this.fn(u)
}
}
return y
}
//计算误差
calcdelta(d, y) {
let delta = new Array()
let last = new Array()
for(let j = 0;j < this.n[this.layernum - 1];j++){
last[j] = (d[j] - y[this.layernum - 1][j]) * this.fd(y[this.layernum - 1][j])
}
delta[this.layernum - 1] = last
for(let l = this.layernum - 2;l > 0; l--) {
delta[l] = new Array()
for(let j = 0;j < this.n[l]; j++) {
delta[l][j] = 0.0
for(let i = 0; i < this.n[l + 1];i++) {
delta[l][j] += delta[l + 1][i] * this.w[l+1][i][j]
}
delta[l][j] = this.fd(y[l][j])*delta[l][j]
}
}
return delta
}
//调整权值和阈值
update(y, delta) {
for(let l = 0; l < this.layernum;l++) {
for(let j = 0;j < this.n[l];j++) {
for(let i = 0;i < this.n[l - 1];i++) {
this.w[l][j][i] += this.miu * delta[l][j] * y[l-1][i]
this.b[l][j] += this.miu * delta[l][j]
}
}
}
}
//样本训练
train(x, d) {
for(let p = 0;p < this.iter;p++) {
this.e = 0
for(let i = 0;i < x.length;i++) {
let y = this.forward(x[i])
let delta = this.calcdelta(d[i], y)
this.update(y, delta)
let ep = 0.0
let l1 = this.layernum - 1
for(let l = 0;l < this.n[l1];l++) {
ep += (d[i][l] - y[l1][l]) * (d[i][l] - y[l1][l])
}
this.e += ep/2.0
}
if(this.e < this.eps) {
break;
}
}
}
}
使用方式:
用BP神经网络实现异或逻辑:
let x = [[0,0],[0,1],[1,0],[1,1]]//输入样本
let d = [[0],[1],[1],[0]]//理想输出
let bp = new BPNet(3, [2,6,1], undefined, undefined, 0.5, 5000 ,0.0001)
bp.train(x,d)
let y = bp.forward([0, 1])
console.log(y[2][0])
let y2 = bp.forward([0,0])
console.log(y2[2][0])
let y3 = bp.forward([1,1])
console.log(y3[2][0])
let y4 = bp.forward([1, 0])
console.log(y4[2][0])
结果:
来源:51CTO
作者:janwool
链接:https://blog.51cto.com/janwool/2117732