本文使用synaptic库搭建一个简单的神经网络,并在浏览器中实现训练过程。这个神经网络可以与其他框架相结合来创建一个简单的推荐系统应用程序。由于在浏览器上训练的神经网络将计算任务分发给各个终端设备,大大减轻了服务器的压力。此外,在终端上训练的神经网络也极大地保护了用户的隐私。机器之心对这篇文章做了简单的介绍。所有代码请查看Github项目地址。项目地址:https://github.com/markselby9/ml-in-browser用JS做机器学习?为什么不!1.项目概况我们将构建一个基于人工神经网络的简单网络应用推荐系统。该应用程序包含两个页面,第一页显示书籍,第二页显示电影。用户可以在第一页选择自己感兴趣的书籍,当他点击下一页按钮时,我们实际上可以在后台预测他可能感兴趣的电影。用户选择自己喜欢的电影后,我们向用户展示他的选择结果,以及我们对他的选择的预测。显示的一些屏幕截图如下所示:在第一页选择感兴趣的书在第二页选择感兴趣的电影将选择与预测结果进行比较此应用程序使用Vue.js和ElementUI(Vue.js框架的UI)并使用突触库构建神经网络。有什么好处?本项目的优势可以概括为:我们将模型训练工作转移到前端,而不是后端,这样既减轻了服务器的压力,又将一些计算任务分摊给了很多客户端。由于npm社区提供了许多与神经网络相关的Javascript库,因此这种方法是可行的。我们保护用户的隐私。用户的数据实际上并没有上传到服务器,他们的数据在服务器更新训练模型时是匿名的。2.神经网络简介首先,这里使用的神经网络是最基本的人工神经网络,我们决定只使用用户的选择作为输入输出集。本节使用的图片来自一篇介绍神经网络的博客:https://ujjwalkarn.me/2016/08/09/quick-intro-neural-networks/。本项目涵盖的概念包括:人工神经网络、神经元、层和训练(反向传播)。如果您已经熟悉这些概念,则可以跳过本节。人工神经网络(ANN)是一种受人脑启发的计算模型。它由神经元组成,神经元是神经网络的基本单位。神经元接收来自其他来源的输入,并且每个输入被分配一个权重,该权重根据输入的重要性分配。神经元将激活函数应用于所有输入的加权和,然后给出输出。神经元单层神经网络由若干个神经元组成,如下图所示。神经网络可能包含也可能不包含多个隐藏层,每对相邻层之间都有连接,通常由上述权重表示。一个简单的全连接神经网络的层次结构但是你如何通过适当地权衡这些权重来构建一个神经网络呢?这些权重需要经过训练才能达到神经网络正常工作的要求。假设我们有一个包含1000对输入和对应输出的数据表。我们首先生成0到1之间的随机数来赋予所有权重,然后遍历所有数据对。在每一对输入输出中,我们使用神经网络的激活函数给出计算结果,并与实际输出进行比较。然后我们重新训练网络并使用反向传播算法调整权重。更新反向传播的权重可以通过随机梯度下降来完成,这是一种获得最佳权重值的方法。这里只是简单介绍一下神经网络的原理。更多详情请参考以下链接:https://ujjwalkarn.me/2016/08/09/quick-intro-neural-networks/https://en.wikipedia.org/wiki/Artificial_neural_networkhttps://github.com/cazala/synaptic/wiki/Neural-Networks-101神经网络在浏览器中的实现最近有一些关于在浏览器中实现神经网络的研究,例如:Deeplearnjs:https://github.com/PAIR-code/deeplearnjsConvnetJS:http://cs.stanford.edu/people/karpathy/convnetjs/synaptic.js:http://caza.la/synaptic/我们在这里使用synaptic.js因为对于node.js和浏览器,这都是一个无架构的神经网络库。我们可以通过github存储库中的wiki查看文档:https://github.com/cazala/synaptic/wiki/Architect。我们计划在浏览器中实现所有的神经网络训练和部分激活功能,服务器(使用简单的node.js和express服务器框架)只保留包含网络参数的JSON文件。synaptic.js有一个方便的API,用于将神经网络解析为JSON,并将JSON解析为神经网络实例。该应用程序是使用Vue.js和ElementUI构建的。在创建主要应用程序组件的生命周期中,应用程序从服务器获取模型的JSON文件,并基于JSON文件构建神经网络实例。该模型随后显示20张带有电影信息的卡片,让用户选择他/她感兴趣的项目,在用户完成选择并单击下一步后,网络实例将调用激活函数并给出用户可能想要的书的预测值(基于20本书选项)。同时,该应用程序还呈现了另外20张带有图书信息的卡片供用户选择。用户点击提交按钮后,应用程序将预测的图书清单和实际图书清单呈现给用户,并使用后台新的训练数据反向传播和重新训练模型。再次训练后,新的神经网络将被解析为JSON对象并发送回服务器。下面是代码。服务器使用简单的I/OAPI和Express构建在node.js中。app.post('/getNetwork',(req,res)=>{if(req.body){console.log(req.body);readJSONFromFile((network)=>{//readlocalJSONfileres.send({code:200,network,});},(err)=>{console.log(err.toString());});}});app.post('/setNetwork',(req,res)=>{if(req.body&&req.body.networkJSON){console.log(req.body);const{networkJSON}=req.body;saveJSONToFile(networkJSON,(err)=>{//writetolocalJSONfileif(err){res.send({code:500,err});}else{res.send({code:200,});}});}else{res.send({code:406,})}});app.listen(3000,()=>{console.log('serverstarted');});在客户端。在本文中我们不会深入DOM的细节,我们将只关注组件app.vue下的脚本部分。created(){//fetchthetrainmodelfromserverthisthis.content_data=this.shuffle(book_data);this.loading=true;axios.post('http://localhost:3000/getNetwork').then((response)=>{console.日志(响应);this.loading=false;constnetworkJSON=response.data.network;if(networkJSON&&Object.keys(networkJSON).length>0){this.$message('Receivedneuralnetworkfromserver.');localNetworkInstance=Network.fromJSON(networkJSON);}else{this.$message('Createdanewnetworkinstance.');//创建一个新的网络实例constinputLayer=newLayer(20);consthiddenLayer=newLayer(20);constoutputLayer=newLayer(20);inputLayer.project(hiddenLayer);hiddenLayer.project(outputLayer);localNetworkInstance=newNetwork({input:inputLayer,hidden:[hiddenLayer],output:outputLayer});}}).catch(函数(错误){this.loading=false;console.log(错误);});},以上是我们在应用程序中创建的生命周期(lifecycle)。它尝试从“getNetwork”API获取一个JSON对象:如果它是网络可用的JSON设置,那么它将通过突触的fromJSON方法创建一个本地网络实例;否则,它将创建一个新的网络实例并保存到“localNetworkInstance”变量中间。当用户点击第一页的“下一页”按钮时,我们调用“onClick”函数中的激活函数,将其作为预测结果保存在Vue组件的数据中。然后在用户选择他/她感兴趣的电影后,调用重新训练函数。reTrainByThisUserData(){//通过这个用户的数据重新训练模型if(localNetworkInstance){localNetworkInstance.propagate(learningRate,this.trainingSet.output);//传播网络this.$message('NeuralNetworkretrained!');constsuccessFunc=()=>{console.log('成功');this.$message('SuccessfullysentthenewNeuralNetwork!');};consterrorFunc=(error)=>{console.log('error',error);this.$message(error);};this.loading=true;axios.post('http://localhost:3000/setNetwork',{networkJSON:localNetworkInstance.toJSON()}).then((response)=>{this.loading=false;if(response.data&&response.data.code===200){successFunc();}else{errorFunc(response.data);}}).catch(function(error){errorFunc(error)});}else{this.loading=false;console.log('networkisundefined!');}}再训练过程是一个反向传播过程,使用当前用户的选择作为输入和输出数据对。用户对电影的选择将成为反向传播数据。反向传播后会调整神经网络的权值,将神经网络的新数据上传到服务器并保存。理想情况下,新网络应该更强大:)进一步探索正如许多读者可能已经意识到的那样,与简单的推荐系统相比,我们可以使用这种方法做更多的事情。一些可能改进这个项目的方法包括:更多关于浏览器的信息可以作为输入,比如用户在每张卡片上花费的时间,用户的点击事件和滚动事件等。这些信息可以从前端获取.神经网络可以有更复杂的架构,但要注意不要过拟合。前端项目要考虑规模。目前,构建的文件大小约为1Mb,这在PC上是可以接受的,但对于移动站点来说可能太大了。如果该项目要在移动设备上使用,则应进行优化。这个项目的完整代码,查看参考:https://github.com/markselby9/ml-in-browser/tree/feature/Recommendation_system_in_browser_demo。原文:https://medium.com/@markselby9/neural-network-in-your-browser-3e6fc91709ca)》]点此阅读本作者更多好文
