deeplearn.js科研之路(一)

【写在最前】

转发请注明原地址~

要读博了,得做研究了,不能成天想着JavaScript接私活了,就让我用另一种方式来爱你吧~

deeplearn.js本身并没有什么特别的东西,基本就是Numpy和Tensorflow两套API。

从基础开始接触深度学习,这几天一直在手写推导公式,暂时喘口气,把最早接触deeplearn.js的这个全连接拟合异或的实验记录下来。

以前没有接触过tensorflow,好在官方文档给的很清晰,好在有个玩得转tensorflow的女朋友。这次的实验应该是非常非常简单,甚至简陋,甚至甚至丑陋了,只用了一些矩阵运算。后面会慢慢地按tensorflow的架构来搭网络做实验搞研究,一些不重要的内容也会记录在blog里。

本篇文章不包含任何全连接网络的基础知识,只有deeplearn.js实现全连接网络拟合异或的实现,基础知识网上大把大把。也不包含任何对API的说明,官网上有API文档的。如果有疑问可以发消息给我~

本次实验少一点点东西...就是隐藏层到输出层的bias。

还处于学习阶段,还差得远呢

github展示页(可以进去直接体验直接控制台写代码玩哦):https://knimet.github.io/my-research-with-deeplearn.js/xor.html

github工程地址:https://github.com/knimet/my-research-with-deeplearn.js

【任务】全连接网络拟合XOR。

【思路】

实验设计的全连接网络,输入层3节点,1个包含3节点的隐藏层,输出层1节点。

【实现】

首先按官网指导引入文件

<script src="https://unpkg.com/deeplearn"></script>
开启严格模式,搭建基础环境。

var dl = deeplearn;
var math = new dl.NDArrayMathCPU();

定义实验数据。输入的第三个数据恒为1,为bias准备的。

const data = [dl.Array2D.new([3,1],[0,0,1]),dl.Array2D.new([3,1],[0,1,1]),dl.Array2D.new([3,1],[1,0,1]),dl.Array2D.new([3,1],[1,1,1])];
const label = dl.Array1D.new([0,1,1,0]);

激活函数使用sigmoid函数,基础环境中math.sigmoid()已定义。

定义学习速率

const n = dl.Scalar.new(0.1);
定义权重矩阵,也就是要训练的部分。wih是输入层到隐藏层的3*3权重矩阵,who是隐藏层到输出层的1*3权重矩阵。

var wih = dl.Array2D.rand([3,3],Math.random); 
var who = dl.Array2D.rand([1,3],Math.random); 
定义初始的输出,用于启动训练。我定义的初始输出为[0,0,0,0],这样可以让循环继续下去。

var output = dl.Array1D.new([0,0,0,0]);
定义loss函数,误差平方和。

function loss(output){ //计算loss,认为误差平方和小于0.01为合格
    let result = math.subtract(label,output);
    return math.dotProduct(result,result).getValues();
}

定义c记录迭代次数。

var c = 0;
开始训练。

while( loss(output) > 0.01 ){//误差平方和小于0.01为合格
        c++;
        if(c % 100 ==0){ //每100轮打印一次loss
            document.write("第"+c+"轮的loss值为"+loss(output)+"<br>");
            
        }
        data.forEach(function(value,index,array){ //对每个样本进行训练
            //前向计算
            var outih = math.sigmoid(math.matMul(wih,value));//3*1,3*3的权重矩阵和3*1的输入矩阵相乘,得到隐藏层值
            
            //console.log("隐藏层计算结果为"+outih.getValues());
            var out = math.sigmoid(math.matMul(who,outih));//1*1,1*3的权重矩阵和3*1的隐藏层值相乘,得到输出结果
            //console.log("输出为"+out.getValues());
            //反向传播调整权重
            var y = out.getValues(); //得到输出层的值
            var t = label.getValues()[index]; //得到label值,也就是目标值
            if(y != t){ 
                //console.log("输出结果和label不同,开始BP");
                //计算误差
                var deltay = y * (1-y) * (t-y); //输出层误差
                let deltaihp1 = math.subtract(dl.Scalar.new(1),outih);
                let deltaihp2 = math.multiply(outih , deltaihp1);
                let deltaihp3 = math.multiply(dl.Scalar.new(deltay),deltaihp2);
                let deltaihp4 = math.multiply(deltaihp3 , math.transpose(who)); //隐藏层误差

                //console.log("开始调整权重");
                var wihp1 = math.matMul(deltaihp4,math.transpose(value)); //这一步写了草稿才确定写法是正确的
                var wihp2 = math.multiply(n,wihp1);
                wih = math.add(wih,wihp2);//更新输入到隐藏层的权重矩阵
                who = math.add(who,math.multiply(dl.Scalar.new(deltay),math.transpose(outih)));//更新隐藏层到输出层的权重矩阵

                //前向计算,更新本轮输出
                var outih = math.sigmoid(math.matMul(wih,value));//3*1
                var out = math.sigmoid(math.matMul(who,outih));//1*1
                output.set(out.getValues(),index);
            }
        })
    }

训练结束后,打印训练后的结果到屏幕上。

document.write("计算结果为<br>");
data.forEach(function(value,index,array){ //对每个样本
    var outih = math.sigmoid(math.matMul(wih,value));//3*1
    var out = math.sigmoid(math.matMul(who,outih));//1*1
    var v = value.getValues();
    document.write(v[0]+"异或"+v[1]+"="+out.getValues()+"<br>");
})

【体验】

权重初值,隐藏层节点数对训练次数影响非常非常大~文章开始留下的github展示页,多刷新几次就能体验到权重初值对训练次数的影响。

【THE END】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值