用JavaScript创建神经网络的有趣教程,一定要让你知道!

640?wx_fmt=gif
作者 | Daniel Simmons
译者 | 王天宇
编辑 | Jane
出品 | AI科技大本营
【导读】本文中作者为初学者解释了如何使用 JavaScript 来搭建一个神经网络。不用担心,这不是一份深入介绍隐藏输入层、激励函数或如何使用 TensorFlow 的复杂教程,而是一次轻松实践。即使你不懂神经网络背后的深入内容,也可以完成这个简单又有趣的实践。
前言
机器学习对我来说是个特别的存在,让我一次又一次觉得,“它实在太酷了,但我不确定接下来我是否会花几个月的时间去学习线性代数和微积分。”
然而,同许多开发者一样,我使用 JavaScript 比较得心应手,也会偶尔找一些用 JS 实现机器学习的例子,但却看到大量文章和帖子控诉 JS 对机器学习来说是极其糟糕的语言,这也是不得不承认的一个事实。
但后来当我发现 Brain.js 时,我被打动了。为什么它被人忽略了这么久?!Brain.js 的文档写得非常清楚,而且易于学习。用了30分钟的入门时间,然后我就搭建并训练了一个神经网络。如果你想直接去 Github 阅读文档,我们在文末给出了地址。

初体验
关于接下来工作的主要步骤包括:

  1. 创建初始文件
  2. 确定你想让神经网络做的工作
  3. 搭建 Brain.js 并考虑好如何处理训练数据和用户输入
  4. 收集训练数据
  5. 运行神经网络
  6. 评估结果

1.初始文件
创建一个新的目录,然后添加一个 index.html 作为样板文件。接下来创建三个 JS 文件:brain.js、training-data.js 和 script.js,当然,index.html 文件下面也需要引入这三个文件。
640?wx_fmt=png
目前做这么多就足够了。
现在我们来看看 Brain.js 的源代码。将所有代码复制并粘贴到你创建的空白 brain.js 文件中,然后点击保存:4个文件中的2个就这样完成了。

Brain.js 源代码:
https://raw.githubusercontent.com/harthur-org/brain.js/master/browser.js

2. “我的目的是什么?”
接下来这个部分很有趣:决定你的机器要学习什么。你可以用这种方式解决不计其数的实际问题,如情感分析或图像识别。我偶然想到一个机器学习应用,把文本作为输入信息进行处理是很有趣的,因为你能随处找到可用作训练的数据,它们有很多潜在的应用场合,所以在这里我们要举一个文本分类问题的例子:
判断一条推文的作者是唐纳德·特朗普还是金·卡戴珊。
这看起来可能不是个用处最广的应用。虽然推文作者识别器还没有强大的吸引点,但 Twitter 对机器学习来说真的是一座宝库。一旦进行过训练,我们的神经网络就可以通过识别推文的内容模式,来辨别一条此前从未见过的推文是出自唐纳德·特朗普还是金·卡戴珊。为了实现这个目的,我们需要提供尽可能多的训练数据,把它们复制并粘贴到我们的 training-data.js 文件中,同时我们也可以试试自己是否能判断一些推文的原作者。

3.设置 & 数据处理
现在我们还需做的工作就是在 script.js 文件中设置 Brain.js,并为我们的 training-data.js 文件提供一些训练数据。但在此之前,让我们先来看看这一切是如何运作的。
设置 Brain.js 是极其简单的,我们在这里不会花费太多时间,但关于如何处理输入数据格式的细节仍需要我们优先处理。我们先看一下文档中的例子,很清晰地展示了这一过程:

 1let net = new brain.NeuralNetwork();
 2
 3
 4net.train([
 5
 6  {
 7
 8    Input: { r0.03g0.7b0.5 },
 9
10    Output: { black1 }
11
12  },{
13
14    Input: { r0.16g0.09b0.2 },
15
16    Output: { black1 }
17
18  },{
19
20    Input: { r0.5b0.5 },
21
22    Output: { black1 }
23
24  }
25
26]);
27
28
29
30let output = net.run({ r1g0.4b0 });

首先,上面的例子是一个可以正常运行的 AI(它会查看给定的颜色,然后告诉你在该颜色上黑色文本和白色文本哪个更易于辨认)。希望可以借此体现 Brain.js 有多易于使用。我们只需先将它实例化,然后进行训练,最后运行,就是这么简单。如果你将训练数据嵌入文件内部,仅仅需要三行代码,是不是很酷!
现在我们讲一下数据的训练。在上面的例子中,除了训练数据的整体格式为 input: {}, output: {},还有两点需要注意。
第一,数据无需统一的长度。如上面代码中的第11行,只传入了 R 和 B 的值,而另两条输入传入了 R、G 和 B 的值。同时,虽然上面的例子把对象作为输入,值得一提的是你也可以使用数组。我之所以特别强调这一点,是因为我们会在该项目中传入长度不等的数组。
第二,这些都不是有效的 RGB 值。如果你真的采用这些值,每一组都会呈现出黑色。这是因为要想让 Brain.js 正常工作,输入值必须在0和1之间。因此,为了能使其正常工作,每个颜色都需要进行处理(只需用一个函数将它除以255,即 RGB 的最大值)。接下来我们也需要做类似的工作。

3.1 编码
因此,如果我们想让神经网络把推文(例如:字符串)作为输入,我们需要用一个类似的函数将它们进行处理(即下面提到的 encode()方法),它会把每个字符转化为0和1之间的值,并存入数组中。幸运的是,JavaScript 有一个原生方法 charCodeAt(),它可以将任何字符转化成 ASCII 码。所以我们会采取这种方式,把结果除以 EASCII 的最大值255,该操作可以保证我们得到的值均小于1。

3.2 处理训练数据
我们会将训练数据以纯文本的形式进行存储,而最终喂给 AI 的数据是编码后的数据。因此我们需要另一个函数(即下面所说的 processTrainingData()方法),该函数会对我们的训练数据执行上文提到的编码处理,有选择地将文本转化成编码字符,然后返回可以完美配合 Brain.js 的训练数据的数组。
那么到这儿的代码如下(这部分代码都将写入 ‘script.js’ 文件):


1let trainedNet;
2
3
4
5function encode(arg{
6
7   return arg.split().map(x => (x.charCodeAt(0) / 255));
8
9}
10
11
12
13function processTrainingData(data{
14
15   return data.map(d => {
16
17       return {
18
19           input: encode(d.input),
20
21           output: d.output
22
23       }
24
25   })
26
27}
28
29
30
31function train(data{
32
33   let net = new brain.NeuralNetwork();
34
35   net.train(processTrainingData(data));
36
37   trainedNet = net.toFunction();
38
39   console.log(‘Finished training…’);
40
41};
42
43
44
45function execute(input{
46
47   let results = trainedNet(encode(input));
48
49   let output;
50
51   results.trump > results.kardashian ? output = ‘Trump’ : output = ‘Kardashian’;
52
53   return output;
54
55}
56
57
58
59train(trainingData);
 
这里要强调一个上述文档例子中未涉及的函数,那就是 train(),该函数可将训练好的神经网络存入全局变量 trainedNet 中。这一操作便于我们每次使用神经网络时无需重新训练。一旦神经网络被训练好并存入变量中,我们就可以像调用函数一样直接调用网络,并将编码后的数据传入 AI 中(如上面 execute() 函数中的第 45 行代码)。

4.训练
最后就是有关我们的训练数据了。就像我在上面提到的,我们将推文存储为文本的形式,然后紧接着把它们编码成数值,这一操作可以让你在复制粘贴训练数据时方便很多。无需担心格式问题,直接在文本中粘贴新的一行就好了。

 1const trainingData = [
 2
 3   {
 4
 5       input"Inside Chi's nursery",
 6
 7       output: { kardashian1 }
 8
 9   },{
10
11       input"Why I dyed my hair pink",
12
13       output: { kardashian1 }
14
15   },{
16
17       input"Feeling Blue (wearing @kkwbeauty powder contour in medium & dark contour kit as eye shadow, & a new lip coming soon)",
18
19       output: { kardashian1 }
20
21   },{
22
23       input"I will be interviewed by @JudgeJeanine on @FoxNews at 9:00 P.M. Enjoy!",
24
25       output: { trump1 }
26
27   },{
28
29       input"Dem Memo: FBI did not disclose who the clients were - the Clinton Campaign and the DNC. Wow!",
30
31       output: { trump1 }
32
33   },{
34
35       input"Thank you to the great men and women of the United States @SecretService for a job well done!",
36
37       output: { trump1 }
38
39   }
40
41]

把这段代码写进 ‘training-data.js’ 文件,我们就大功告成了!
注意:上面的代码示例中,只展示了每个人的3条样本,但实际上我分别引入了10条;我只是不想占用太多篇幅。当然,你提供的训练数据量越大,神经网络的精度也会越高,所以试着改变引入的数据量,来看看对结果有哪些影响吧。

5.执行
现在,就可以运行这个训练好的神经网络了。你只需在 ‘script.js’ 文件的最下面加上一行调用 execute() 的代码,然后传入一条特朗普或卡戴珊的推文;记得使用 console.log。这里有一则卡戴珊的推文,这条推文不在我的训练数据中:

1console.log(execute("These aren't real. Kanye would never write Yeezy on the side"));

接下来在本地打开你的 index.html 页面,查看控制台:
640?wx_fmt=png
就是这样,神经网络正确辨别了一条之前从未见过的、来自卡戴珊的推文,确定度达到了80%.
现在我们再用一条特朗普的推文试试:

1console.log(execute("Whether we are Republican or Democrat, we must now focus on strengthening Background Checks!"));

结果如下:
640?wx_fmt=png

6.评估
现在你已经有一个可以训练任何文本的神经网络了!你可以使用它轻松辨别一封邮件或公司在线评价的情感及态度,识别垃圾邮件,将博客文章分类,判别一则消息是否紧急等等,这一点非常有趣,这个神经网络可以用在很多类似根据所写内容判断作者的任务中。
即使你不想另外创建一个由机器学习驱动的全新工具,这次实践对你来说也是一份宝贵的开发经验。也许什么时候它将会派上用场,甚至可能在未来为你开拓新的机遇。

原文链接:
https://itnext.io/you-can-build-a-neural-network-in-javascript-even-if-you-dont-really-understand-neural-networks-e63e12713a3
Brain.js 文档:
https://github.com/BrainJS/brain.js
GitHub地址:
https://github.com/lordpoint/neural-network-author-classifierhttps://github.com/BrainJS/brain.js

——完——

发表评论

电子邮件地址不会被公开。 必填项已用*标注