Javascript实现BP神经网络

北慕城南 提交于 2020-03-20 11:53:23

BP神经网络是一种按照误差逆向传播算法训练的多层前馈神经网络,是目前应用最广泛的神经网络。
BP神经网络误差反向传播神经网络:

  1. 置各权和阈值的初始化
  2. 给定P个训练样本Xp(p=1,2,...,p) 和对应的理想输出Dp(p=1,2,...p)
  3. 信息前向传递:
    计算网络各层的输出
    Javascript实现BP神经网络

4.误差反向传播
Javascript实现BP神经网络
5.修改权和阈值
Javascript实现BP神经网络
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神经网络实现异或逻辑:
Javascript实现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])

结果:
Javascript实现BP神经网络

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!