姓名:闫伟 学号:15020150038
转载自:https://zhuanlan.zhihu.com/p/49928060
【嵌牛导读】:如今神经网络已经深入到生活的许多方面,而最近几年基于js的神经网络也逐渐火了起来。
【嵌牛鼻子】:Synaptic.js node.js 神经网络
【嵌牛提问】:如何用js来搭建神经网络
【嵌牛正文】:
我们先看看神经网络的基本知识。
神经元和突触
搭建神经网络的第一个部分就是神经元。神经元就像一个函数,获取一些输入,返回一个输出。
神经元有很多种类型,我们本文搭建的神经网络使用 Sigmoid 神经元,不管给它什么输入,都会输出 0-1 之间的值。
下图的圆圈表示的就是一个 Sigmoid 神经元,它的输入是 5,输出为 1。图中的箭头就是我们所说的“突触”,它会将神经元和神经网络中的其它层连接在一起。
那么为什么是红色数字 5?因为它是连接到神经元的 3 个突触的总和,即左侧的 3 个箭头。我们挨个解释。
在最左侧,我们可以看到两个值和一个偏差值相加,绿色数字 1 和 0 为两个值,棕色数字 -2 为偏差值。
首先,两个输入和它们的权重相乘,权重是蓝色数字 7 和 3。
最后,我们将它们相加后得到 5,即红色数字。这就是我们的神经元的输入。
因为是 Sigmoid 神经元,它会将任何输入压缩为 0 到 1 之间的数值,所以输出会被压缩为 1.
如果你将这些神经元连接在一起,就会得到一个神经网络。通过这些由突触相连的神经元,神经网络从输入到输出来正向传播。如下图所示:
神经网络的目标是经过训练后完成泛化工作,比如识别手写字或垃圾邮件。神经网络中具有合适的权重和偏差(就是前面所举例子中的蓝色和棕色数字),是它能否具有良好的泛化能力的关键。
在训练神经网络时,我们只需像它展示大量的数据样本,比如手写字,让神经网络预测正确的答案。
每次预测后,我们会计算预测的误差,然后调整权重和偏差,让神经网络下一次预测时更接近正确答案。这个学习过程就叫做“反向传播”。这项操作经过几千次后,神经网络就会变得非常善于泛化。
代码
了解了基本的神经网络知识后,我们开始编写代码。第一样工作就是创建网络层,我们使用 Synaptic 中的 new layer() 函数完成这一步。传递到函数中的数字表示每一层应该有多少个神经元。
const { Layer, Network } = window.synaptic;var inputLayer = new Layer(2);var hiddenLayer = new Layer(3);var outputLayer = new Layer(1);
接着我们将这些网络层相连,实例化一个新的神经网络,像这样:
inputLayer.project(hiddenLayer);hiddenLayer.project(outputLayer);var myNetwork = new Network({ input: inputLayer, hidden: [hiddenLayer], output: outputLayer});
那么这是一个 2-3-1 网络,可视化后如下所示:
现在我们训练神经网络:
// train the network - learn XORvar learningRate = .3;for (var i = 0; i < 20000; i++) { // 0,0 => 0 myNetwork.activate([0,0]); myNetwork.propagate(learningRate, [0]); // 0,1 => 1 myNetwork.activate([0,1]); myNetwork.propagate(learningRate, [1]); // 1,0 => 1 myNetwork.activate([1,0]); myNetwork.propagate(learningRate, [1]); // 1,1 => 0 myNetwork.activate([1,1]); myNetwork.propagate(learningRate, [0]);}
这里我们将神经网络运行 2 万次,每次正向和反向传播 4 次,向神经网络传入 4 个可能值:[0,0] [0,1] [1,0] [1,1]。
我们首先执行 myNetwork.activate([0,0]),其中 [0,0] 是我们发到神经网络中的数据点。这就是正向传播,也叫激活神经网络。在每次正向传播之后,我们需要做一个反向传播,其中神经网络会更新它自身的权重和偏差。
反向传播用这行代码完成:myNetwork.propagate(learningRate, [0]),其中 learningRate 是一个常量,会告诉神经网络每次调整权重的幅度。第二个参数 0 表示跟定输入 [0,0] 的正确输出。
然后神经网络会将它自己的预测和正确标签进行比较,得知它的预测是对还是错。
神经网络利用这种比较作为偏差来纠正它自己的权重和偏差值,这样下一次它就能猜得更准确些。
将这个过程完成 2 万次后,我们就可以用全部 4 个可能输入激活神经网络,检查它的学习效果:
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]
如果我们将这些值四舍五入为最接近整数的值,就会得到 XOR 方程的正确答案。
就是这些,虽然本文只谈了些神经网络的皮毛知识,但是应该能足以帮你开始用 JavaScript 搭建神经网络,探索机器学习。可以看看 Synaptic 的页面,上面有很多不错的教程.