1 引言
自从 Alpha Go 打败了李世石,大家对深度学习的体感更加的强烈,人工智能也越来越多的出现在大家的生活之中。很多人也会谈论,程序员什么时候会被人工智能给替代?与其慌张,在人工智能的潮流下,不断学习新的人工智能相关技术,武装自己,才是硬道理。 本文介绍了如何使用Synaptic.js 创建简单的神经网络,解决异或运算的问题。
2 内容概要
神经网络中的神经元和突触
对神经网络有所了解的人都知道,神经网络就是构建类似人脑的神经系统,在人脑的神经系统中,存在一种非常重要的细胞,叫神经元。在神经网络中,你可以把神经元理解为一个函数,它接受一些输入返回一些输出结果,其中Sigmoid 神经元是一种非常常用的神经元,这种神经元以 Sigmoid 函数 作为激活函数。Sigmoid 函数接受任意的数值,输出 0
到 1
之间的值,大家可以看看常见的几种 Sigmoid 函数的函数曲线。
知道了 Sigmoid 函数了,我们可以看一个具体的 Sigmoid 神经元 例子。
在这个例子中 7
和 3
是权重参数,-2
是偏差,最左边的 1
和 0
是 输入层 中的两个节点,通过如下的计算,得到了一个 隐藏层 节点 5
。
然后将节点 5
输入到一个 Sigmoid 函数,得到一个 输出层 节点 1
。
如何构建神经网络
有了神经元,将所有的神经元连接起来,就构建了一个 神经网络。如下图,神经元间的箭头,可以理解为是一种 “突触”。
完成神经网络的构建了,你可以用来识别手写数字、垃圾邮件判断等众多领域。当然就像上面的例子,好的模型依赖于正确的权重 和 偏差的选择。在实际工作中,每次完成神经网络的训练,我们都会拿训练的结果来对测试样式进行预测,得到算法的准确率,然后尝试选择更好的权重和偏差,期望达到更好的准确度,这个学习的过程称为反向传播。通过大量的学习后,最终才会得到更好的预测准确率。
代码实现
下面附上代码的实现。
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
});
// train the network - learn XOR
var 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]);
}
简单而言,运行 myNetwork.activate([0,0])
时,[0, 0]
是输入值,它对应的异或运算的结果是 false, 也就是 0
。 这个是前向的传播,所以称为 激活 网络,每次前向传播之后,我们需要做一次反向传播来更新权重和偏差。
反向传播就是通过这行代码来做的: myNetwork.propagate(learningRate, [0])
,其中 learningRate
是告诉神经网络如何调整权重的常量,第二个参数 [0]
是异或运算的结果。
经过 20000 次学习,我们得到如下的结果:
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]
对运算结果取最近的整数,我们就可以得到正确异或运算的结果。
3 精读
读原文的时候,大家可能主要对反向传播如何修正权重和偏差会有所疑问,作者给出的引文A Step by Step Backpropagation Example — by Matt Mazur 很详细的解释了整个过程。
方便大家理解,我以上面的异或运算的例子,简单的分析一下整个过程。其中我们选取的激活函数是:Logistic 函数。
当我们输[0, 0]
时,我们选取一些任意的权重和偏差,计算过程如下:
为了方便后续的推到,我们可以通过一些符号来简单的描述一下h1
和最终记过output
计算的过程:
计算得到结果 o
后,我们可以通过平方误差函数
来计算误差。我们在上面的运算中得到的 output = 0.73673
, 目标值是对 [0,0]
取异或运算的值,也就是: target = 0
,带入上面的公式得到的误差值为: 0.271385
。
到这里我们进行反向传播的过程,也就是说我们需要确认新的参数: w1
, w2
, w3
, w4
, w5
, w6
, b1
, b2
.
我们先计算新的 w5
,这里是通过计算误差函数相对于w5
的偏导来得到新的参数的,我们可以通过下面的链式求导来计算偏导。
得到 w5
对应的偏导后,我们通过下面的公式来计算新的w5
参数:
其中, 0.3
就是我们在代码中设置的 learningRate
的值。 重复上面相似的过程,我们可以计算其他参数的值,这里就不再累述。
4. 总结
本文介绍了使用Synaptic.js 创建简单的神经网络,解决异或运算的问题过程,也对反向传播的过程进行了简单的解释。文中实现神经网络的代码非常简单,包行注释也不超过 30 行,但是只会代码会有点囫囵吞枣的感觉,大家可以参考文章中给的引文,了解更多的算法原理。
相关资料
1. A Step by Step Backpropagation Example — by Matt Mazur
2. Hackers Guide to Neural Nets — by Andrej Karpathy
3. NeuralNetworksAndDeepLarning — by Michael Nielsen
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=17583,转载请注明出处。
评论0