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])
結果: