欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用js实现一个三层的bp神经网络

程序员文章站 2022-05-22 13:06:44
...

      当我实现了一个简单的bp神经网络后内心很是激动,赶忙实现了三层的神经网络是什么样子的。

网络长这个样子的:
实际上三个输入,两个隐层元,一个输出
用js实现一个三层的bp神经网络

各种参数的说明是这样子的:
用js实现一个三层的bp神经网络
      比起二层网络要多更新很多值。

公式的一些推导长这样子的:
依旧使用梯度下降法:
用js实现一个三层的bp神经网络

最后代码是这样子的:

<html>
<head>
</head>
<body>
    <div class="div"></div>
    <button>开始</button>
    <script src="http://www.numericjs.com/lib/numeric-1.2.6.js" type="text/javascript"></script>
    <script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js" type="text/javascript"></script>
    <script>
        //Initial input/ouput values
        var X = [
            [0, 0, 1],
            [1, 0, 1],
            [0, 1, 0],
            [1, 1, 0]
            ];

        var y = [
        [0],
        [1],
        [0],
        [1]
        ];
    </script>
    <script>
        // test 输出函数
        function print(x){
            if(typeof x === "object"){
                $('.div').before("<p>"+numeric.prettyPrint(x)+"</p>");
            }else{
                $('.div').before("<p>"+x+"</p>");
            }
        }

        // Sigmoid 函数
        function sigmoid(x) {
            return numeric.div(1, numeric.add(1, numeric.exp(numeric.neg(x))));
        }


        // 输入层到隐层的权值
        var syn0;
        // 初始化为 -1~1
        syn0 = numeric.sub(numeric.mul(2, numeric.random([2, 3])), 1);//输入层有三个元,隐层有两个元
        // 隐层的阈值
        var gama;
        // 初始化为 -1~1
        var gama = numeric.sub(numeric.mul(2,numeric.random([2,1])),1);

        // 隐层到输出层的权值
        var syn1;
        // 初始化为 -1~1
        syn1 = numeric.sub(numeric.mul(2,numeric.random([1,2])),1);//输出层有一个元
        // 输出层的阈值
        var sita;
        // 初始化
        sita = numeric.random([1,1]);

        // 学习率
        var engama = 0.1;

        // 隐层第h元的输出函数  
        function output0(x,h){                 // x=[[0,0,1]]这种形式
            var temp = numeric.transpose([syn0[h]]);
            return sigmoid(numeric.sub(numeric.dot(x,temp),gama[h][0]))[0];
        }
        function putput0_toArr(x){
            var q = 2;   //隐层元数量为2
            var h = 0;
            var b =  new Array();
            for(;h<q;h++){
                b.push(output0(x,h));
            }        
            return b;   //b = [[1],[1]]这种形式
        }
        // 输出层的输出函数
        function output1(x){                  // x=[[0,0,1]]这种形式
            b = putput0_toArr(x);
            return sigmoid(numeric.sub(numeric.dot(syn1,b),sita));
        }

        function train_neural(X, y, iteration) {
            //第i代训练
            var i = 0;
            for (; i < iteration; i++) {
                // 第k个训练样本
                var k;
                for( k in X){
                    // 真实输出
                    var yt = output1([X[k]]);
                    // 函数gi的值为
                    var gk = (yt-y[k])*yt*(1-yt);
                    var b = putput0_toArr([X[k]]);  //b = [[1],[1]]这种形式
                    // 参数更新
                        var temp2 = numeric.mul(numeric.transpose(syn1),gk);   //gk * wh
                        var temp3 = numeric.mul(b,numeric.sub(1,b)); //bh * (1 - bh)
                        var temp4 = numeric.mul(temp2,temp3); // [[0],[0]]这种形式  eh
                        syn0 = numeric.sub(syn0,numeric.mul(engama,numeric.dot(temp4,[X[k]])));
                        gama = numeric.add(gama,temp4);

                        var temp1 = numeric.transpose(numeric.mul(gk,b));
                        // 标准误差逆传播
                        syn1 = numeric.sub(syn1,numeric.mul(engama,temp1));   
                        sita = numeric.add(sita,engama * gk);//阈值更新

                }
            } 
        }
        $('button').on('click',function(){
            train_neural(X, y, 10000);
            var k;
            for( k in X){
                print(output1([X[k]]));
            }

        })
    </script>
</body>
</html>

这是一段很头疼的代码,因为js上实现矩阵运算还是比较麻烦的,加上numeric这个js库运用不熟练,让部分代码看起来很奇怪

运行结果是这样子的:
用js实现一个三层的bp神经网络
对训练样本做训练然后输出训练样本的值,也是蛮接近(0,1,0,1)

注:渴望您的交流!