当前位置: 首页 > 科技观察

如何用30行JavaScript代码写出一个神经网络异或运算符

时间:2023-03-15 23:51:34 科技观察

配置环境,安装合适的库,下载数据集……有时候学习深度学习的前期工作是很挫败的,如果只是为了大家现在试试看,在我们都在谈论的深度学习中做这些麻烦的事情似乎很不值得。但幸运的是,我们也有一些更简单的方式来体验深度学习。近日,编程学习平台Scrimba的联合创始人PerHaraldBorgen在Medium上发布了一篇仅用30行JavaScript代码创建神经网络的教程,使用的工具只有Node.js、Synaptic.js和浏览器。.此外,作者还制作了交互式Scrimba教程,可以帮助您理解复杂的概念。Synaptic.js:https://synaptic.juancazala.comNode.js:https://nodejs.orgScrimba教程:https://scrimba.com/casts/cast-1980Synaptic.js允许您使用Node.js和浏览器进行深度学习。在本文中,我将介绍如何使用Synaptic.js创建和训练神经网络。//创建网络const{Layer,Network}=window.synaptic;varinputLayer=newLayer(2);varhiddenLayer=newLayer(3);varoutputLayer=newLayer(1);inputLayer.project(hiddenLayer);hiddenLayer.project(outputLayer);varmyNetwork=newNetwork({input:inputLayer,hidden:[hiddenLayer],output:outputLayer});//训练网络-学习异或运算varlearningRate=.3;for(vari=0;i<20000;i++){//0,0=>0myNetwork.activate([0,0]);myNetwork.propagate(learningRate,[0]);//0,1=>1myNetwork.activate([0,1]);myNetwork.propagate(learningRate,[1]);//1,0=>1myNetwork.activate([1,0]);myNetwork.propagate(learningRate,[1]);//1,1=>0myNetwork.activate([1,1]);myNetwork.propagate(learningRate,[0]);}//测试网络console.log(myNetwork.activate([0,0]));//[0.015020775950893527]console.log(myNetwork.activate([0,1]));//[0.9815816381088985]console.log(myNetwork.activate([1,0]));//[0.9871822457132193]console.log(myNetwork.activate([1,1]));//[0.012950087641929467]我们将创建最简单的神经网络:一个可以执行异或运算的网络。这就是上面这个网络的所有代码,但在我们深入研究代码之前,让我们先了解一下神经网络的基础知识。神经元和突触神经网络的基本构建块是神经元。神经元就像一个接受多个输入并可以获得输出的函数。有许多类型的神经元。我们的网络将使用sigmoid神经元,它可以取任何数字并将其压缩在0和1之间。下图是一个sigmoid神经元。它的输入为5,输出为1。称为突触的箭头将神经元连接到网络中的其他层。那么,红色数字5从何而来?就是左边三个突触的总和,我们来剖析一下。在最左边我们可以看到两个值和一个所谓的偏置值。这两个值分别是1和0,用绿色表示。偏差值为-2,以棕色表示。首先,将两个输入乘以它们的权重,即蓝色数字7和3。***我们将这两个值与偏置相加得到红色5。这就是这个人工神经元的输入。由于这是一个sigmoid神经元,它将压缩0到1之间的任何值,因此可以将此输出压缩为1。如果将这些神经元连接到一个网络中,就会得到一个神经网络。通过突触相互连接的神经元可以向前传播它们的输入以获得输出,如下图所示:训练神经网络的目的是让它泛化,例如识别手写数字或垃圾邮件。实现良好的泛化需要为整个网络找到合适的权重和偏置值,就像我们上面例子中的蓝色和棕色数字。在训练神经网络时,您只需向它展示大量示例(例如手写数字)并要求它预测正确答案。每次预测后,您计算预测的错误程度,并调整其权重和偏差,使网络在下一轮预测中更正确一些。这种学习过程称为反向传播。重复此操作几千次,您的网络将很快变得擅长泛化。本教程不会解释反向传播的具体技术细节,但如果您有兴趣,可以参考以下文章:反向传播的分步示例:http://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/神经网络黑客指南:http://karpathy.github.io/neuralnets/神经网络和深度学习:http://neuralnetworksanddeeplearning.com/chap1.html代码现在你知道了基础知识,让我们开始写代码吧!首先我们需要创建图层。我们可以在synaptic中使用新的Layer()函数。传递给这个函数的数字表示每层应该有多少个神经元。如果你不知道什么是层,你可以查看上面提到的交互式教程。常量{层,网络}=window.synaptic;varinputLayer=newLayer(2);varhiddenLayer=newLayer(3);varoutputLayer=newLayer(1);接下来,我们将这些层连接在一起并实例化一个新网络,如下所示:);hiddenLayer.project(outputLayer);varmyNetwork=newNetwork({input:inputLayer,hidden:[hiddenLayer],output:outputLayer});所以,这是一个“2-layer-3-layer-1”网络,可以如下图所示:现在训练这个网络://trainthenetwork-learnXORvarlearningRate=.3;for(vari=0;i<20000;i++){//0,0=>0myNetwork.activate([0,0]);myNetwork.propagate(learningRate,[0]);//0,1=>1myNetwork.activate([0,1]);myNetwork.propagate(learningRate,[1]);//1,0=>1myNetwork.activate([1,0]);myNetwork.propagate(learningRate,[1]);//1,1=>0myNetwork.activate([1,1]);myNetwork.propagate(learningRate,[0]);}这里我们运行网络20000次。每次我们进行4次前向和反向传播,为网络提供4组可能的输入:[0,0][0,1][1,0][1,1]。首先我们执行myNetwork.activate([0,0]),其中[0,0]是我们发送到网络的数据点。这就是前向传播,也称为激活网络。在每次前向传播之后,我们需要执行反向传播,网络更新其权重和偏差。反向传播是通过这行代码完成的:myNetwork.propagate(learningRate,[0]),其中learningRate是一个常数,给出了网络每次调整其权重的量。第二个参数0是给定输入[0,0]的正确输出。然后网络将它的预测与正确的标签进行比较,看看它有多正确。然后网络使用这个比较作为基础来纠正它自己的权重和偏差,以便它的下一个猜测更正确一些。重复此过程20000次后,我们可以使用所有四种可能的输入来检查网络的学习情况:->[0.015020775950893527]console.log(myNetwork.activate([0,1]));->[0.9815816381088985]console.log(myNetwork.activate([1,0]));->[0.9871822457132193]console.log(myNetwork.activate([1,1]));->[0.012950087641929467]如果我们将值舍入到最接近的整数,我们将得到正确的异或结果。这个做完了。虽然这只是触及了神经网络的皮毛,但足以帮助您进一步探索Synaptic并继续学习。https://github.com/cazala/synaptic/wiki包含更多好的教程。原文:https://medium.freecodecamp.org/how-to-create-a-neural-network-in-javascript-in-only-30-lines-of-code-343dafc50d49【本文为专栏《心oftheMachine》,微信公众号《机器之心(id:almosthuman2014)》】点此查看作者更多好文