lrn-tfjs-merge-0
TensorFlow.js 学习手册(一)
译者:飞龙
前言
人工智能和机器学习是革命性的技术,可以改变世界,但只有当有开发人员使用良好的 API 来利用这些技术带来的进步时,它们才能实现这一目标。
其中一项进展是在浏览器中运行机器学习模型的能力,赋予应用程序智能行为。
TensorFlow.js 的崛起告诉我,人工智能已经到来。它不再仅仅属于拥有超级计算机的数据科学家;现在,数百万日常使用 JavaScript 编码的开发人员也可以访问它。但存在一个差距。构建模型的工具和技术仍然主要掌握在了那些了解 Python、NumPy、图形处理单元(GPU)、数据科学、特征建模、监督学习、张量等许多奇怪而美妙术语的人手中,你可能并不熟悉!
Gant 在这本书中所做的是直奔主题,教会你需要了解的重要内容,同时让你牢牢地保持在网页开发人员的角色中,使用 JavaScript 和浏览器。他将向你介绍人工智能和机器学习的概念,重点关注它们如何在你关心的平台上使用。
经常听到开发人员问,当想要使用机器学习时,“我在哪里可以找到可以重复使用的东西?我不想成为一个机器学习工程师,只是为了弄清楚这些东西是否适合我!”
Gant 在这本书中回答了这个问题。你将发现可以从 TensorFlow Hub 中获取的预制模型。你还将学习如何站在巨人的肩膀上,从使用数百万数据项和成千上万小时训练构建的模型中选择部分,并看看如何从中学习并将其转移到你自己的模型中。然后,只需将其放入你的页面中,让 JavaScript 来完成剩下的工作!
开发人员问,“我如何在我关心的平台上使用机器学习,而无需进行大量的重新训练?”
这本书深入探讨了这一点——向你展示如何弥合 JavaScript 和使用 TensorFlow 训练的模型之间的差距。从原始数据和张量之间的数据转换到将输出概率解析为文本,这本书将引导你完成与你的网站紧密集成的步骤。
开发人员问我,“我想超越其他人的工作和简单的原型。作为一个网页开发人员,我能做到吗?”
再次强调。当你完成这本书时,你不仅会熟悉使用模型,而且 Gant 会为你提供创建模型所需的所有细节。你将学习如何训练复杂的模型,比如卷积神经网络,以识别图像的内容,并且你将在 JavaScript 中完成所有这些工作。
2020 年 10 月的一项调查显示,全球有 1240 万 JavaScript 开发人员。其他调查显示,全球约有 30 万人从事人工智能工作。凭借 TensorFlow.js 技术和本书中的技能,亲爱的 JavaScript 开发人员,你可以成为让人工智能有意义的一部分。而这本书是一个美妙、美妙的开始。
享受这段旅程!
劳伦斯·莫罗尼
2021 年 3 月
前言
"如果你选择不做决定,你仍然已经做出了选择。"
—Geddy Lee(Rush)
让我们开始吧。
事后诸葛亮。"当比特币价格为 X 时,我应该买一些"或者"如果我在创业公司 Y 变得出名之前申请了就好了"。世界上充满了定义我们的时刻,无论是好是坏。时间永远不会倒流,但它会在我们前行时回响我们年轻时的选择教训。你很幸运有这本书和这个时刻来做决定。
由于人工智能的出现,软件行业的基础正在发生变化。这些变化最终将由那些抓住机会并塑造明天世界的人来决定。机器学习是一次探索新可能性的冒险,当它与 JavaScript 的广泛应用结合在一起时,限制就消失了。
就像我在谈论人工智能时告诉我的听众的那样,"你不是为了到这一步才创造软件而到这一步的"。所以让我们开始吧,看看我们的想象力会带我们去哪里。
为什么选择 TensorFlow.js?
TensorFlow 是市场上最受欢迎的机器学习框架之一。它得到了谷歌顶尖人才的支持,负责为世界上许多最有影响力的公司提供动力。TensorFlow.js 是 TensorFlow 不可战胜的 JavaScript 框架,比所有竞争对手都更好。简而言之,如果你想要一个 JavaScript 框架的强大功能,只有一个选择可以做到。
谁应该阅读这本书?
两个主要人群将享受并从这本书的内容中受益:
JavaScript 开发者
如果你熟悉 JavaScript,但以前从未接触过机器学习,这本书将成为你的向导。它倚重于框架,让你积极参与实用和令人兴奋的创作。通过构建各种项目,你将通过实践经验理解机器学习的基础知识。虽然我们不会回避数学或更深层次的概念,但我们也不会过度复杂化体验。如果你在 JavaScript 中构建网站并想获得新的超能力,请阅读这本书。
人工智能专家
如果你熟悉 TensorFlow 甚至是线性代数的基本原理,这本书将为你提供无数例子,展示如何将你的技能应用到 JavaScript 中。在这里,你将找到各种核心概念在 TensorFlow.js 框架中的展示。这将使你能够将你的广泛知识应用到可以高效存在于客户端浏览器或物联网设备(IoT)等边缘设备上的媒介中。阅读这本书,学习如何将你的创作带到无数设备上,提供丰富的互动体验。
这本书需要一定程度上对现代 JavaScript 的阅读和理解。
书籍概述
在概述这本书时,我意识到我必须做出选择。我可以创建一个旋风般的冒险,涉及到机器学习的各种应用,并用小而具体的例子涉及每一个,或者我可以选择一个单一的路径,讲述概念的不断增长的故事。在征求我的朋友和追随者的意见后,很明显后者是必要的。为了让这本书保持理智并控制在一千页以下,我选择删除任何 JavaScript 框架,专注于一个实用的旅程,探索人工智能的视觉方面。
每一章都以问题和一个特定的挑战结束,供你测试自己的决心。章节挑战部分经过精心设计,以巩固 TensorFlow.js 的教训。
章节
第一章和第二章从核心概念和一个具体示例开始。这种阴阳方法反映了本书的教学风格。每一章都建立在前几章提到的教训、词汇和功能之上。
第三章至第七章让您具备理解和实施现有 AI 工具和数据的视野。您将能够创建令人印象深刻的库,并在由大量数据科学家创建的项目中使用模型。
第八章至第十一章开始让您在 TensorFlow.js 中具有创造力。您将能够在 JavaScript 中训练模型,我坚信这是整本书中最有趣和令人兴奋的部分之一。
第十二章是最后的挑战。最后一章提供了一个顶点项目,让您可以利用本书所提供的一切,并用自己的能力表达出来。
要点
阅读本书后,无论您之前的经验如何,您都将能够在 TensorFlow.js 中找到、实现、调整和创建机器学习模型。您将能够识别网站中机器学习的应用,然后跟进并实现该应用。
本书中使用的约定
本书使用以下印刷约定:
斜体
指示新术语、URL、电子邮件地址、文件名和文件扩展名。
常量宽度
用于程序清单,以及在段落中引用程序元素,如变量或函数名称、数据库、数据类型、环境变量、语句和关键字。
常量宽度粗体
显示应由用户按字面输入的命令或其他文本。
常量宽度斜体
显示应替换为用户提供的值或由上下文确定的值的文本。
提示
此元素表示提示或建议。
注意
此元素表示一般说明。
警告
此元素表示警告或注意。
使用代码示例
补充材料(代码示例、练习等)可在https://github.com/GantMan/learn-tfjs下载。
如果您有技术问题或在使用代码示例时遇到问题,请发送电子邮件至bookquestions@oreilly.com。
本书旨在帮助您完成工作。一般来说,如果本书提供示例代码,您可以在程序和文档中使用它。除非您复制了代码的大部分内容,否则无需联系我们以获得许可。例如,编写一个使用本书中几个代码块的程序不需要许可。销售或分发 O'Reilly 图书中的示例需要许可。通过引用本书回答问题并引用示例代码不需要许可。将本书中大量示例代码合并到产品文档中需要许可。
我们感谢,但通常不要求署名。署名通常包括标题、作者、出版商和 ISBN。例如:“学习 TensorFlow.js by Gant Laborde (O'Reilly)。版权所有 2021 年 Gant Laborde,978-1-492-09079-3。”
如果您认为您使用的代码示例超出了合理使用范围或上述授权,请随时与我们联系permissions@oreilly.com。
致谢
我要感谢编辑、制作人员和 O'Reilly 的员工,在写这本书时与他们合作是一种快乐。
当然,感谢这本书前言作者杰出的劳伦斯·莫罗尼。你一直是我的偶像和启发,我从你那里学到了很多,我将继续在你的机器学习课程和成就的影响下茁壮成长。
这本书的技术审阅者是我有幸合作过的最友好和最彻底的人之一。
劳拉·乌兹卡特吉
你友善和鼓舞人心的反馈让人陶醉。你的直觉帮助使这本书感觉正确。
维舍什·拉维·施里马利
你理解了我所有的笑话。显然你是一个聪明友好的人,以这种方式,你推动我变得更好。我感激你所有的建议和智慧。
杰森·梅斯
我在你被选为这本书的技术编辑之前就认识你了,所以我把你看作是朋友,也是团队合作伙伴,一起让这本书变得更好。你的反馈是细致、聪明且不可替代的。真诚地感谢你。
阿克塞尔·达米安·西罗塔
我可以感受到你在每一点反馈中给予的高度个人支持。你花时间既聪明又善良。你的艺术是这本书的一份礼物。
李·沃里克
你继续审查和挑战我在所有作品中变得更好。这本书是我成就的最新例子,得益于你的洞察力。
米歇尔·克罗宁
我们每次会面我都很享受。你是一种持续的快乐!谢谢你做你自己。你让这本书变得轻松。你是如何做到的,我永远不会知道。
特别感谢弗兰克·冯·霍芬三世,他问了所有正确的问题,并递给我一页又一页手写的反馈笔记(图 P-1)。你的才华和诚实让我在传递强大和鼓舞人心的信息时保持引导。

图 P-1。弗兰克提供了令人赞叹的支持和反馈
最后,感谢我爱的家人,他们尽可能避免打扰我,但也知道何时需要一个好的打断。爱丽西亚,我的爱,你比我更了解我自己。当我需要继续前进时,你给我惊喜的咖啡,当是时候停下来休息时,你给我一杯烈酒。每天,我最好的一面都是因为有你。
第一章:AI 是魔法
“任何足够先进的技术都是不可区分的魔法。”
—亚瑟·克拉克
好吧,AI 并不是真正的魔法。事实上,AI 是超越其他技术的一步,以至于它感觉像魔法。解释一个有效的排序算法是很容易的,但深入研究智能本身会触及第三导轨,将我们全部带入一个全新的技术力量水平。这种指数级的能力提升是通过 TensorFlow.js 的智慧和才能实现的。
科学家和工程师们在 AI 领域已经重新创造了比喻性的轮子,并调整了控制它的机制。当我们在本书中深入研究 AI 时,我们将用 TensorFlow.js 灵活而坚固的框架掌握这些概念,并借此将我们的想法实现在 JavaScript 不断扩展的领域中。是的,JavaScript,世界上最流行的编程语言。
这里提供的概念和定义将为您提供技术射线视野。您将能够穿透首字母缩略词和流行词汇,看到并理解我们周围各个领域中不断出现的 AI 基础设施。AI 和机器学习概念将变得清晰,本章的定义可以作为识别核心原则的参考,这些原则将推动我们在 TensorFlow.js 的学术发展中启程。
我们将:
-
澄清 AI 和智能的领域
-
讨论机器学习的类型
-
回顾和定义常见术语
-
通过 TensorFlow.js 的视角审视概念
让我们开始吧!
提示
如果您已经熟悉 TensorFlow.js 和机器学习术语、哲学和基本应用,您可能希望直接跳转到第二章。
JavaScript 中的 AI 之路
TensorFlow.js,简单来说,是一个处理 JavaScript 中特定 AI 概念的框架。就是这样。幸运的是,您在正确的书籍中,处于历史上正确的时刻。AI 工业革命才刚刚开始。
当计算机出现时,一个拥有计算机的人可以在显著的规模上执行几乎不可能的任务。他们可以破解密码,从大量数据中瞬间提取信息,甚至像与另一个人玩游戏一样。一个人无法做到的事情不仅变得可能,而且变得司空见惯。自数字发明诞生以来,我们的目标一直是赋予计算机更多的能力。作为独立的人类,我们能够做任何事情,但不是所有事情。计算机以一种扩展我们限制的方式使我们获得了新的力量。我们中的许多人花费一生来磨练一些技能,而在这些技能中,甚至更少的人成为我们的专长。我们都在建立一生的成就,我们中的一些人在某一领域成为世界上最优秀的人,这种技能只能通过运气、信息和成千上万天的努力获得...直到现在。
AI 使我们能够跳到队伍的最前面;大胆地建造以前从未建造过的东西。每天我们都看到公司和研究人员一次又一次地迈出计算的飞跃。我们站在一个新行业的入口处,邀请我们参与世界将如何改变的过程。
您掌握着方向盘,驶向下一个大事件,而这本书就是您的方向盘。我们学习 AI 魔法的旅程只会受到您想象力的限制。借助启用 JavaScript 的机器学习,您可以利用摄像头、麦克风、即时更新、位置和其他物理传感器、服务和设备!
我相信你会问,“为什么以前 AI 没有做到这一点?为什么现在这很重要?”要理解这一点,你需要踏上人类对再现智能的探索之旅。
什么是智能?
关于思想的概念,尤其是通向机器智能的道路,可以写成一本又一本的书。就像所有哲学努力一样,关于智能的每一个具体陈述都可以在途中争论。你不需要对一切都有确定的了解,但我们需要了解 AI 的领域,这样我们才能理解我们是如何来到 TensorFlow.js 这本书中的。
诗人和数学家们几个世纪以来一直在说,人类的思想不过是预先存在的概念的组合。生命的出现被认为是一种类似神的设计;我们都只是由元素“制造”而成。希腊神话中有发明之神赫淮斯托斯创造了能行走和行动如士兵般的自动铜制机器人。基本上,这些就是第一批机器人。机器人和智能的概念已经根植于我们的基础,作为古代传说中的终极和神圣的工艺。巨大的活力战士塔洛斯被著名地编程来守护克里特岛。虽然没有实际的铜制机器人,但这个故事为机械的志向提供了动力。数百年来,机械古代一直被认为是通往看似人类“智能”的途径,几个世纪后,我们开始看到生活在模仿艺术。小时候,我记得去我当地的 Chuck E. Cheese,这是美国一家受欢迎的餐厅,为儿童提供动画音乐表演。我记得曾经相信,就在那一刻,每天播放的木偶驱动的电子音乐会是真实的。我被激发了,这种激发驱使科学家追逐智能。这种火花一直存在,通过故事、娱乐,现在又通过科学传递。
随着能够自主工作和智能地工作的机器的概念在历史上不断发展,我们努力定义这些概念实体。学者们继续研究推理和学习,并出版作品,同时保持他们的术语在“机器”和“机器人”的领域内。机械智能的模仿总是受限于速度和电力的缺乏。
智能的概念在数百年来一直固定在人类思想中,远远超出了机械结构的范围,直到最终机器的诞生,计算机。计算机的诞生与大多数机器一样,都是为整个设备的单一目的而生。随着计算机的出现,一个新术语出现了,用来说明智能的不断增长,这在很大程度上反映了人类的智力。术语 AI 代表人工智能,直到 20 世纪 50 年代才被创造出来。随着计算机变得通用,哲学和学科开始结合。模仿智能的概念从神话中跃入科学研究领域。每一种为人类而设计的电子测量设备都成为计算机的新感官器官,也是电子和智能科学的一个令人兴奋的机会。
在相对较短的时间内,我们已经有了与人类交互并模拟人类行为的计算机。对人类活动的模仿提供了一种我们愿意称之为“智能”的形式。人工智能是这些战略行动的总称,无论其复杂程度或技术水平如何。一台可以下井字棋的计算机不必赢才能被归类为 AI。AI 是一个低门槛,不应与人类的一般智能混淆。最简单的代码片段也可以是合法的 AI,而好莱坞电影中的有感情机器的末日也是 AI。
当使用术语 AI 时,它是指来自一种惰性和通常非生物的设备的智能的总称。无论术语的最低门槛是什么,人类,拥有一门研究和一个不断增长的实际用途,都有一个统一的术语和明确的目标。所有被衡量的都被管理,因此人类开始衡量、改进并竞相追求更高级的 AI。
AI 的历史
AI 框架最初非常具体,但今天不再是这样。正如您可能知道或不知道的那样,TensorFlow.js 作为一个框架的概念可以应用于音乐、视频、图像、统计数据以及我们可以收集的任何数据。但并非总是这样。AI 的实现最初是缺乏任何动态能力的特定领域代码。
互联网上有一些笑话流传,称 AI 只是一堆 IF/THEN 语句的集合,而在我看来,它们并不完全错误。正如我们已经提到的,AI 是对自然智能各种模仿的总称。即使是初学者程序员也是通过解决简单的 AI 问题来学习编程,比如Ruby Warrior。这些编程练习教授算法的基础知识,并且需要相对较少的代码。这种简单性的代价是,虽然它仍然是 AI,但它被困在模仿程序员智能的境地。
很长一段时间以来,实施 AI 的主要方法依赖于一个编写 AI 程序的人的技能和哲学,这些技能和哲学直接转化为代码,以便计算机执行指令。数字逻辑正在执行那些传达程序的人的人类逻辑。当然,这是创建 AI 的最大延迟。您需要一个知道如何制造懂得的机器的人,我们受到他们的理解和翻译能力的限制。硬编码的 AI 无法推断超出其指令。这很可能是将任何人类智慧转化为人工智能的最大障碍。如果您想教会机器下棋,您如何教它下棋理论?如果您想告诉程序区分猫和狗,对于幼儿来说是微不足道的事情,您甚至知道从哪里开始编写算法吗?
在 50 年代末和 60 年代初,教师的概念从人类转变为能够阅读原始数据的算法。阿瑟·塞缪尔在一个事件中创造了术语机器学习(ML),这个事件使 AI 摆脱了创作者的实际限制。一个程序可以根据数据增长并掌握程序员无法将其转化为代码或自己从未理解的概念。
利用数据来训练程序的应用或功能是一个令人兴奋的抱负。但在计算机需要整个房间而数据远非数字化的时代,这也是一个不可逾越的要求。几十年过去了,计算机才达到了模拟人类信息和架构能力的关键转折点。
在 2000 年代,机器学习研究人员开始使用图形处理单元(GPU)来绕过“CPU 和内存之间的孤立通道”,即冯·诺伊曼瓶颈。2006 年,杰弗里·辛顿等人利用数据和神经网络(我们将在下一节中介绍的概念)来理解模式,并让计算机读取手写数字。这是一个以前对于普通计算来说太不稳定和不完美的壮举。深度学习能够读取和适应手写的随机性,以正确识别字符的最先进水平超过 98%。在这些发表的论文中,数据作为训练代理的概念从学术界的发表作品跃升到现实。
当 Hinton 陷入制作一个从头开始的学术证明神经网络有效的困境时,“这是什么数字?”问题成为机器学习实践者的一个支柱。这个问题已经成为机器学习框架的关键简单示例之一。TensorFlow.js 有一个演示,可以在不到两分钟的时间内直接在您的浏览器中解决这个问题。借助 TensorFlow.js 的优势,我们可以轻松构建在网站、服务器和设备上无缝运行的高级学习算法。但这些框架实际上在做什么呢?
AI 的最大目标一直是接近甚至超越人类的能力,98%的手写识别准确率正是如此。Hinton 的研究引发了对这些高效机器学习方法的关注,并创造了行业术语如深度神经网络。我们将在下一节详细说明原因,但这是应用机器学习的开始,它开始蓬勃发展,并最终进入了像 TensorFlow.js 这样的机器学习框架。虽然新的基于机器的学习算法不断被创造出来,但一个灵感和术语的来源变得非常清晰。我们可以模拟我们内部的生物系统来创造出一些先进的东西。从历史上看,我们使用自己和我们大脑的皮层(我们大脑的一层)作为结构化训练和智能的灵感来源。
神经网络
深度神经网络的概念始终受到我们人类身体的启发。数字节点(有时称为感知器网络)模拟我们大脑中的神经元,并像我们自己的突触一样激活,以创建一种平衡的思维机制。这就是为什么神经网络被称为神经,因为它模拟了我们大脑的生物化学结构。许多数据科学家厌恶与人脑的类比,但它通常是合适的。通过连接数百万个节点,我们可以构建优雅的深度神经网络,这些网络是用于做出决策的优雅数字机器。
通过增加更多层的神经通路,我们到达了深度学习这个术语。深度学习是一个庞大的层层连接的隐藏节点。您会听到这些节点被称为神经元、人工神经元、单元,甚至感知器。术语的多样性证明了为机器学习做出贡献的广泛科学家的广泛性。
这整个学习领域只是 AI 的一部分。如果您一直在关注,人工智能有一个称为机器学习的子集或分支,在这个集合内,我们有深度学习的概念。深度学习主要是一类推动机器学习的算法,但不是唯一的一种。请参见图 1-1 以获得这些主要术语的视觉表示。

图 1-1. AI 子领域
就像人类一样,通过示例和数据来适当平衡和构建神经元的迭代教学或“训练”被用来。起初,这些神经网络通常是错误和随机的,但随着他们看到一个又一个数据示例,他们的预测能力“学习”。
但我们的大脑并不直接感知世界。就像计算机一样,我们依赖于被组织成连贯数据发送到我们大脑的电信号。对于计算机来说,这些电信号类似于张量,但我们将在第三章中更详细地介绍这一点。TensorFlow.js 体现了研究和科学家们已经确认的所有这些进步。所有这些帮助人体执行的技术都可以包装在一个优化的框架中,这样我们就可以利用几十年来受人体启发的研究。
例如,我们的视觉系统从视网膜开始,使用神经节将光感信息传递到大脑,以激活这些神经元。正如一些人从儿童生物学中记得的那样,我们的视觉中有一些盲点,技术上我们看到的一切都是颠倒的。信号并不是“原样”发送到我们的大脑。这个视觉系统内置了技术,我们在今天的软件中利用了这些技术。
虽然我们都很兴奋地迎接我们的 8K 分辨率电视,你可能认为我们的大脑和视觉仍然超出了现代计算能力,但情况并非总是如此。连接我们眼睛到大脑的视觉信号的神经通道只有大约 10 Mb 的带宽。这相当于上世纪 80 年代初的局域网连接。即使是流媒体宽带连接也需要比这更多的带宽。但我们却能瞬间和迅速地感知一切,对吧?那么这是怎么做到的?我们是如何在这种过时的硬件上获得优越的信号的?答案是我们的视网膜在将数据发送到我们深度连接的神经网络之前对数据进行了压缩和“特征化”。这就是我们开始在计算机上做的事情。
卷积神经网络(CNN)在视觉数据上的工作方式与我们的眼睛和大脑一起压缩和激活我们的神经通路的方式相同。您将在第十章中进一步了解并编写自己的 CNN。我们每天都在了解我们的工作方式,并将这数百万年的进化直接应用于我们的软件。虽然了解这些 CNN 如何工作对您很有好处,但自己编写它们太学术化了。TensorFlow.js 带有您需要处理图像的卷积层。这是利用机器学习框架的基本好处。
你可以花费数年时间阅读和研究使计算机视觉、神经网络和人类有效运作的所有独特技巧和黑客技术。但我们生活在一个这些根源已经有时间生长、分支并最终结果的时代:这些先进的概念是可访问的,并内置在我们周围的服务和设备中。
今天的人工智能
今天我们使用这些最佳实践与人工智能相结合,以增强机器学习。卷积用于边缘检测,对某些区域的关注超过其他区域,甚至为一个单一项目提供多摄像头输入,为我们提供了一个在云机器训练 AI 的光纤服务器农场中的预先处理的数据宝库。
2015 年,AI 算法开始在某些视觉任务中胜过人类。正如你可能在新闻中听说的那样,AI 已经在癌症检测方面超越了人类,甚至在识别法律缺陷方面超过了美国顶级律师。正如数字信息一样,AI 在几秒钟内完成了这些任务,而不是几小时。AI 的“魔力”令人惊叹。
人们一直在寻找将人工智能应用于他们的项目的新颖有趣的方法,甚至创造全新的行业。
AI 已被应用于:
-
生成写作、音乐和视觉方面的新内容
-
推荐有用的内容
-
取代简单的统计模型
-
从数据中推断法则
-
可视化分类器和识别器
所有这些突破都是深度学习的方面。今天我们拥有必要的硬件、软件和数据,可以通过深度机器学习网络实现突破性的变革。每天,社区和《财富》500 强公司都在人工智能领域发布新的数据集、服务和架构突破。
凭借您手头的工具和本书中的知识,您可以轻松地创造以前从未见过的东西,并将其带到网络上。无论是为了娱乐、科学还是财富,您都可以为任何现实世界问题或业务创建一个可扩展的智能解决方案。
如果说目前机器学习的问题是它是一种新的超级能力,而世界是广阔的。我们没有足够的例子来理解在 JavaScript 中拥有人工智能的全部好处。当电池寿命有了显著改善时,它们为更强大的手机和相机等设备带来了一个全新的世界,这些设备可以在单次充电的情况下持续数月。这一突破带来了数年内市场上无数新产品。机器学习不断取得突破,带来了新技术的飞速发展,我们甚至无法澄清或认识到这种洪流的加速。本书将重点介绍具体和抽象的例子,以便您可以使用 TensorFlow.js 应用实用解决方案。
为什么选择 TensorFlow.js?
您有选择。您可以从头开始编写自己的机器学习模型,也可以选择各种编程语言中的任何现有框架。即使在 JavaScript 领域,已经存在竞争框架、示例和选项。是什么使 TensorFlow.js 能够处理和承载今天的人工智能?
重要支持
TensorFlow.js 由 Google 创建和维护。我们将在第二章中更多地介绍这一点,但值得注意的是,世界上一些最优秀的开发人员已经齐心协力使 TensorFlow.js 成为可能。这也意味着,即使没有社区的努力,TensorFlow.js 也能够与最新和最伟大的突破性发展一起工作。
与其他基于 JavaScript 的机器学习库和框架实现不同,TensorFlow.js 支持经过优化和测试的 GPU 加速代码。这种优化传递给您和您的机器学习项目。
在线就绪
大多数机器学习解决方案都限制在一个非常定制的机器上。如果您想要创建一个网站来分享您的突破性技术,人工智能通常被锁在 API 后面。虽然在 Node.js 中运行 TensorFlow.js 是完全可行的,但在浏览器中直接运行 TensorFlow.js 也是可行的。这种无需安装的体验在机器学习领域是罕见的,这使您能够无障碍地分享您的创作。您可以版本化并访问丰富的互动世界。
离线就绪
JavaScript 的另一个好处是它可以在任何地方运行。代码可以保存到用户的设备上,如渐进式 Web 应用程序(PWA)、Electron 或 React Native 应用程序,然后可以在没有任何互联网连接的情况下始终如一地运行。不言而喻的是,与托管的 AI 解决方案相比,这也提供了显著的速度和成本提升。在本书中,您将发现许多完全存在于浏览器中的例子,这些例子可以使您和您的用户免受延迟和托管成本的困扰。
隐私
人工智能可以帮助用户识别疾病、税收异常和其他个人信息。通过互联网发送敏感数据可能存在危险。设备上的结果保留在设备上。甚至可以训练一个人工智能并将结果存储在用户的设备上,而没有任何信息离开浏览器的安全性。
多样性
应用 TensorFlow.js 在机器学习领域和平台上具有强大而广泛的影响。TensorFlow.js 可以利用 Web Assembly 在 CPU 或 GPU 上运行,适用于性能更强大的机器。如今的机器学习 AI 领域的光谱对于新手来说是一个重要而庞大的新术语和复杂性的世界。拥有一个可以处理各种数据的框架是有用的,因为它保持了您的选择。
精通 TensorFlow.js 使您能够将您的技能应用于支持 JavaScript 的各种平台(请参阅图 1-2)。

图 1-2. TensorFlow.js 平台
使用 TensorFlow.js,您可以自由选择、原型设计和部署您的技能到各种领域。为了充分利用您的机器学习自由度,您需要了解一些术语,这些术语可以帮助您进入机器学习领域。
机器学习类型
许多人将机器学习分为三类,但我认为我们需要将所有机器学习视为四个重要元素:
-
监督
-
无监督
-
半监督
-
强化
每个元素都值得写成一本书。接下来的简短定义只是为了让您熟悉这个领域中会听到的术语。
快速定义:监督学习
在这本书中,我们将重点放在最常见的机器学习类别上,即监督机器学习(有时简称为监督学习或简称为监督)。监督机器学习简单地意味着我们对用于训练机器的每个问题都有一个答案。换句话说,我们的数据是有标签的。因此,如果我们试图教会机器区分一张照片是否包含鸟类,我们可以立即根据 AI 的答案是对还是错来评分。就像使用 Scantron 一样,我们有答案。但与 Scantron 不同的是,由于这是概率数学,我们还可以确定答案有多错。
如果 AI 对一张鸟类照片有 90%的确定性,虽然它回答正确,但还可以提高 10%。这突显了 AI 的“训练”方面,即通过即时数据驱动的满足感。
提示
如果你没有成百上千个现成的标记问题和答案,也不用担心。在这本书中,我们要么为您提供标记数据,要么向您展示如何自己生成数据。
快速定义:无监督学习
无监督学习不需要我们有答案。我们只需要问题。无监督机器学习是理想的,因为世界上大多数信息都没有标签。这类机器学习侧重于机器可以从未标记数据中学习和报告的内容。虽然这个主题可能有点令人困惑,但人类每天都在执行它!例如,如果我给你一张我的花园照片,并问你我拥有多少种不同类型的植物,你可以告诉我答案,而不必知道每株植物的属种。这有点类似于我们如何理解自己的世界。很多无监督学习都集中在对大量数据进行分类上。
快速定义:半监督学习
大多数时候,我们并不是在处理 100%未标记的数据。回到之前的花园例子,你可能不知道每株植物的属种,但也不完全无法对植物进行分类为 A 和 B。你可能告诉我,我有十株植物,其中三株是花,七株是草本植物。拥有少量已知标签可以帮助很多,当今的研究在半监督突破方面取得了巨大进展!
您可能听说过术语生成网络或生成对抗网络(GANs)。这些流行的 AI 构造在许多 AI 新闻文章中被提及,并源自半监督学习策略。生成网络是根据我们希望网络创建的示例进行训练的,通过半监督方法,可以构建新的示例。生成网络非常擅长从少量标记数据中创建新内容。流行的 GAN 的例子通常有自己的网站,比如https://thispersondoesnotexist.com,越来越受欢迎,创意人员正在享受半监督输出带来的乐趣。
注意
GAN 在生成新内容方面发挥了重要作用。虽然流行的 GAN 是半监督的,但 GAN 的更深层概念并不局限于半监督网络。人们已经将 GAN 调整为适用于我们定义的每种学习类型。
快速定义:强化学习
解释强化学习最简单的方法是展示它在处理更真实的活动时是必需的,而不是之前的假设构造。
例如,如果我们在下棋时,我开始游戏时移动一个兵,那是一个好动作还是坏动作?或者如果我想让一个机器人把球踢进篮筐,它开始迈步,这是好还是坏?就像对待人类一样,答案取决于结果。这是为了最大奖励而采取的一系列动作,不总是有一个动作会产生一个结果。训练机器人首先迈步或首先看很重要,但可能不如在其他关键时刻所做的事情重要。而这些关键时刻都是由奖励作为强化来驱动的。
如果我要教一个 AI 玩《超级马里奥兄弟》,我想要高分还是快速胜利?奖励教会 AI 什么组合动作是最优化的以实现目标。强化学习(RL)是一个不断发展的领域,经常与其他形式的人工智能结合以培养最大的结果。
信息过载
对于刚提到的机器学习的许多应用,感到惊讶是可以的。在某种程度上,这就是为什么我们需要像 TensorFlow.js 这样的框架。我们甚至无法理解所有这些奇妙系统的用途及其未来几十年的影响!在我们理解这一切的同时,人工智能和机器学习的时代已经到来,我们将成为其中的一部分。监督学习是进入人工智能所有好处的一个很好的第一步。
我们将一起探讨一些最令人兴奋但实用的机器学习用途。在某些方面,我们只会触及表面,而在其他方面,我们将深入探讨它们的工作原理。以下是我们将涵盖的一些广泛类别。这些都是监督学习概念:
-
图像分类
-
自然语言处理(NLP)
-
图像分割
本书的主要目标之一是,虽然你可以理解这些类别的概念,但不会受到限制。我们将倾向于实验和实践科学。有些问题可以通过过度工程解决,而有些问题可以通过数据工程解决。AI 和机器学习的思维是看到、识别和创建新工具的关键。
人工智能无处不在
我们正在进入一个人工智能渗透到一切的世界。我们的手机现在已经加速到深度学习硬件。摄像头正在应用实时人工智能检测,而在撰写本文时,一些汽车正在街上行驶,没有人类驾驶员。
在过去的一年中,我甚至注意到我的电子邮件已经开始自动写作,提供了一个“按 Tab 键完成”选项来完成我的句子。这个功能,比我最初写的任何东西更清晰更简洁,这是一个显著的可见成就,超过了多年来一直在同一个收件箱中保护我们免受垃圾邮件的被遗忘的机器学习 AI。
随着每个机器学习计划的展开,新的平台变得需求量大。我们正在将模型推向边缘设备,如手机、浏览器和硬件。寻找新语言来传承是合理的。很快搜索就会以 JavaScript 为明显选择。
框架提供的一次导览
机器学习是什么样子?以下是一个准确的描述,会让博士生因其简洁而感到不安。
在正常的代码中,人类直接编写代码,计算机读取和解释该代码,或者读取其某种派生形式。现在我们处于一个人类不编写算法的世界,那么实际发生了什么?算法从哪里来?
这只是一个额外的步骤。一个人编写算法的训练器。在框架的帮助下,甚至从头开始,一个人在代码中概述了问题的参数、所需的结构和要学习的数据的位置。现在,机器运行这个程序训练程序,不断地编写一个不断改进的算法作为解决问题的解决方案。在某个时候,您停止这个程序,取出最新的算法结果并使用它。
就是这样!
算法比用于创建它的数据要小得多。数千兆字节的电影和图像可以用来训练一个机器学习解决方案数周,所有这些只是为了创建几兆字节的数据来解决一个非常具体的问题。
最终的算法本质上是一组数字,这些数字平衡了人类程序员所确定的结构。这组数字及其相关的神经图通常被称为模型。
您可能已经在技术文章中看到这些图表,它们被绘制为从左到右的一组节点,就像图 1-3。

图 1-3. 密集连接神经网络的示例
我们的框架 TensorFlow.js 处理了指定模型结构或架构的 API,加载数据,通过我们的机器学习过程传递数据,并最终调整机器以更好地预测下次给定输入的答案。这就是 TensorFlow.js 真正的好处所在。我们只需要担心正确调整框架以解决问题,并保存生成的模型。
什么是模型?
当您在 TensorFlow.js 中创建一个神经网络时,它是所需神经网络的代码表示。该框架为每个神经元智能选择随机值生成一个图。此时,模型的文件大小通常是固定的,但内容会发展。当通过将数据传递给一个未经训练的具有随机值的网络进行预测时,我们得到的答案通常与正确答案相去甚远,就像纯随机机会一样。我们的模型没有经过任何数据训练,所以在工作中表现糟糕。因此,作为开发人员,我们编写的代码是完整的,但未经训练的结果很差。
一旦训练迭代发生了相当长的一段时间,神经网络的权重就会被评估然后调整。速度,通常被称为学习率,会影响结果。在以学习率为步长进行数千次这样的小步骤后,我们开始看到一个不断改进的机器,我们正在设计一个成功概率远远超出原始机器的模型。我们已经摆脱了随机性,收敛于使神经网络工作的数字!分配给给定结构中的神经元的那些数字就是训练好的模型。
TensorFlow.js 知道如何跟踪所有这些数字和计算图,所以我们不必,它还知道如何以适当和可消费的格式存储这些信息。
一旦您获得了这些数字,我们的神经网络模型就可以停止训练,只用来进行预测。在编程术语中,这已经变成了一个简单的函数。数据进去,数据出来。
通过神经网络传递数据看起来很像机会,如图 1-4 所示,但在计算世界中,这是一个平衡概率和排序的精密机器,具有一致和可重复的结果。数据被输入到机器中,然后得到一个概率性的结果。

图 1-4. 一个平衡的网络隐喻
在下一章中,我们将尝试导入并使用一个完全训练好的模型进行预测。我们将利用数小时的训练来在微秒内得到智能分析。
在本书中
本书的结构使您可以将其收起放在度假中,一旦找到您的小天堂,就可以跟着书本阅读,学习概念,并审查答案。图像和截图应该足以解释 TensorFlow.js 的深层原理。
然而,要真正掌握这些概念,您需要超越简单地阅读本书。随着每个概念的展开,您应该编写代码,进行实验,并在实际计算机上测试 TensorFlow.js 的边界。对于那些作为机器学习领域的新手的人来说,重要的是您巩固您第一次看到的术语和工作流程。花时间逐步学习本书中的概念和代码。
相关代码
在整本书中,有可运行的源代码来说明 TensorFlow.js 的课程和功能。在某些情况下提供整个源代码,但在大多数情况下,打印的代码将仅限于重要部分。建议您立即下载与本书相匹配的源代码。即使您计划在示例旁边从头编写代码,您可能会遇到的小配置问题已经在相关代码中得到解决并可引用。
您可以在https://github.com/GantMan/learn-tfjs看到 GitHub 源页面。
如果您对 GitHub 和 Git 不熟悉,可以简单地下载最新的项目源代码的单个 ZIP 文件并引用它。
您可以从https://github.com/GantMan/learn-tfjs/archive/master.zip下载源 ZIP 文件。
源代码结构化以匹配每个章节。您应该能够在具有相同名称的文件夹中找到所有章节资源。在每个章节文件夹中,您将找到最多四个包含课程信息的文件夹。当您运行第一个 TensorFlow.js 代码时,将在第二章中进行审查。现在,请熟悉每个文件夹的目的,以便选择最适合您学习需求的示例代码。
额外文件夹
这个文件夹包含章节中引用的任何额外材料,包括文档或其他参考资料。这些部分的材料是每章的有用文件。
节点文件夹
这个文件夹包含了章节代码的 Node.js 特定实现,用于基于服务器的解决方案。该文件夹可能包含其中几个特定项目。Node.js 项目将安装一些额外的软件包,以简化实验过程。本书的示例项目使用以下内容:
nodemon
Nodemon 是一个实用程序,将监视源中的任何更改并自动重新启动服务器。这样可以保存文件并立即查看其相关更新。
ts-node
TypeScript 有很多选项,最明显的是强类型。然而,为了易于理解,本书专注于 JavaScript 而不是 TypeScript。ts-node模块用于支持 ECMAScript。您可以在这些节点示例中编写现代 JavaScript 语法,通过 TypeScript,代码将正常工作。
这些依赖项在package.json文件中标识。Node.js 示例用于说明使用 TensorFlow.js 的服务器解决方案,通常不需要在浏览器中打开。
要运行这些示例,请使用 Yarn 或 Node Package Manager(NPM)安装依赖项,然后执行启动脚本:
# Install dependencies with NPM
$ npm i
# Run the start script to start the server
$ npm run start
# OR use yarn to install dependencies
$ yarn
# Run the start script to start the server
$ yarn start
启动服务器后,您将在终端中看到任何控制台日志的结果。查看结果后,您可以使用 Ctrl+C 退出服务器。
简单文件夹
这个文件夹将包含没有使用 NPM 的解决方案。所有资源都简单地放在独立的 HTML 文件中进行服务。这绝对是最简单的解决方案,也是最常用的。这个文件夹很可能包含最多的结果。
web 文件夹
如果您熟悉基于客户端的 NPM Web 应用程序,您将会对web文件夹感到舒适。这个文件夹很可能包含其中的几个具体项目。web文件夹示例是使用Parcel.js打包的。这是一个用于 Web 项目的快速多核打包工具。Parcel 提供热模块替换(HMR),因此您可以保存文件并立即看到页面反映您的代码更改,同时还提供友好的错误日志记录和访问 ECMAScript。
要运行这些示例,请使用 Yarn 或 NPM 安装依赖项,然后执行启动脚本:
# Install dependencies with NPM
$ npm i
# Run the start script to start the server
$ npm run start
# OR use yarn to install dependencies
$ yarn
# Run the start script to start the server
$ yarn start
运行打包程序后,将打开一个网页,使用您的默认浏览器访问该项目的本地 URL。
提示
如果项目使用像照片这样的资源,那么该项目的根文件夹中将存在一个credit.txt文件,以正确归功于摄影师和来源。
章节部分
每一章都从确定章节目标开始,然后立即深入讨论。在每一章的末尾,您将看到一个章节挑战,这是一个资源,让您立即应用您刚学到的知识。每个挑战的答案可以在附录 B 中找到。
最后,每一章都以一组发人深省的问题结束,以验证您是否已内化了本章的信息。建议您尽可能通过代码验证答案,但答案也会在附录 A 中提供给您。
常见的 AI/ML 术语
您可能会想,“为什么模型不只是称为函数?模型在编程中已经有了意义,不需要另一个!”事实是这源自机器学习起源的问题。原始数据问题根植于统计学。统计模型将模式识别为样本数据的统计假设,因此我们从这些示例的数学运算中得到的产品是一个机器学习模型。机器学习术语通常会大量反映发明它的科学家的领域和文化。
数据科学伴随着大量的数学术语。我们将在整本书中看到这一主题,并且我们将为每个术语找出原因。有些术语立即就有意义,有些与现有的 JavaScript 和框架术语冲突,有些新术语与其他新术语冲突!命名事物是困难的。我们将尽力以易记的方式解释一些关键术语,并在途中详细说明词源。TensorFlow 和 TensorFlow.js 文档为开发人员提供了大量新词汇。阅读以下机器学习术语,看看您是否能掌握这些基本术语。如果不能,没关系。随着我们的进展,您可以随时回到本章并参考这些定义。
训练
训练是通过让机器学习算法审查数据并改进其数学结构以使其在未来做出更好的预测的过程。
TensorFlow.js 提供了几种方法来训练和监控训练模型,无论是在机器上还是在客户端浏览器上。
例如,“请不要触碰我的电脑,它已经在我的最新的空气弯曲算法上训练了三天。”
训练集
有时被称为“训练数据”,这是您将向算法展示的数据,让它从中学习。你可能会想,“这不就是我们拥有的所有数据吗?”答案是“不是”。
通常,大多数机器学习模型可以从它们以前见过的示例中学习,但测试并不能保证我们的模型可以推广到识别它以前从未见过的数据。重要的是,我们用来训练人工智能的数据要与验证和核实分开。
例如,“我的模型一直将热狗识别为三明治,所以我需要向我的训练集中添加更多照片。”
测试集
为了测试我们的模型是否能够对从未见过的数据进行处理,我们必须保留一些数据进行测试,并且永远不让我们的模型从中学习。这通常被称为“测试集”或“测试数据”。这个集合帮助我们测试我们是否已经创建了一个可以推广到现实世界新问题的东西。测试集通常比训练集要小得多。
例如,“我确保测试集是我们试图训练模型解决的问题的一个很好的代表。”
验证集
即使您还没有达到需要它的水平,这个术语也是很重要的。正如您经常会听到的,训练有时可能需要几小时、几天甚至几周。启动一个长时间运行的过程,只是回来发现您构建了错误的结构,必须重新开始,这有点令人担忧!虽然在本书中我们可能不会遇到任何这些大规模训练的需求,但这些情况可能需要一组数据进行更快的测试。当这与您的训练数据分开时,它是用于验证的“留出法”。基本上,这是一种实践,在让您的模型在昂贵的基础设施上训练或花费更长时间之前,将一小部分训练数据保留下来进行验证测试。这种调整和验证是您的验证集。
有很多方法可以选择、切片、分层甚至折叠您的验证集。这涉及到一种超出本书范围的科学,但当您讨论、阅读和提升自己的大型数据集时,了解这些知识是很有用的。
TensorFlow.js 在训练过程中有整个训练参数,用于识别和绘制验证结果。
例如,“我已经划分了一个小的验证集,在构建模型架构时使用。”
张量
我们将在第三章中详细介绍张量,但值得注意的是,张量是优化的数据结构,允许 GPU 和 Web Assembly 加速巨大的人工智能/机器学习计算集。张量是数据的数值持有者。
例如,“我已经将您的照片转换为灰度张量,以查看我们可以获得什么样的速度提升。”
归一化
归一化是将输入值缩放到更简单领域的操作。当一切都变成数字时,数字的稀疏性和数量的差异可能会导致意想不到的问题。
例如,房屋的大小和房屋中的浴室数量都会影响价格,但它们通常以完全不同的数字单位进行测量。并非所有事物都以相同的度量标准来衡量,虽然人工智能可以适应这些模式中的波动,但一个常见的技巧是简单地将数据缩放到相同的小领域。这样可以让模型更快地训练并更容易地找到模式。
例如,“我已经对房价和浴室数量进行了一些归一化,这样我们的模型可以更快地找到两者之间的模式。”
数据增强
在照片编辑软件中,我们可以拍摄图像并操纵它们,使其看起来像完全不同环境中的同一物体。这种方法有效地创建了一张全新的照片。也许您想要将您的标志放在建筑物的一侧或者压印在名片上。如果我们试图检测您的标志,原始照片和一些编辑过的版本将有助于我们的机器学习训练数据。
通常情况下,我们可以从原始数据中创建符合我们模型目标的新数据。例如,如果我们的模型将被训练来检测人脸,一个人的照片和一个镜像的人的照片都是有效的,而且明显不同的照片!
TensorFlow.js 有专门用于数据增强的库。我们将在本书的后面看到增强的数据。
例如,“我们通过镜像所有南瓜进行了一些数据增强,以扩大我们的训练集。”
特征和特征化
我们之前提到过特征化,当我们谈到眼睛如何将最重要的信息发送到大脑时。我们在机器学习中也是这样做的。如果我们试图制作一个猜测房子价值的 AI,那么我们必须确定哪些输入是有用的,哪些输入是噪音。
房子上的数据不缺乏,从砖块的数量到装饰线。如果你经常看家装电视节目,你会知道识别房子的大小、年龄、浴室数量、厨房最后一次更新的日期和社区是明智的。这些通常是识别房价的关键特征,你会更关心提供给模型这些信息,而不是一些琐碎的东西。特征化是从所有可能的数据中选择这些特征作为输入的过程。
如果我们决定把所有可能的数据都放进去,我们就给了我们的模型找到新模式的机会,但代价是时间和精力。没有理由选择像草叶的数量、房子的气味或正午的自然光线这样的特征,即使我们有这些信息或者我们觉得这对我们很重要。
即使我们选择了我们的特征,仍然会有错误和异常值会减慢实用机器学习模型的训练。有些数据只会让预测模型更成功的指针移动,选择明智的特征会使快速训练的智能 AI。
例如,“我相当确定计算感叹号的数量是检测这些营销邮件的关键特征。”
章节回顾
在这一章中,我们已经掌握了总称 AI 的术语和概念。我们也触及了我们将在本书中涵盖的关键原则。理想情况下,你现在对机器学习中必不可少的术语和结构更有信心了。
复习问题
让我们花点时间确保你完全掌握了我们提到的概念。花点时间回答以下问题:
-
你能给出机器学习的充分定义吗?
-
如果一个人想到了一个机器学习项目的想法,但是他们没有标记的数据,你会推荐什么?
-
什么样的机器学习对打败你最喜欢的视频游戏有用?
-
机器学习是唯一的 AI 形式吗?
-
一个模型是否保存了用于使其工作的所有训练示例数据?
-
机器学习数据是如何分解的?
这些练习的解决方案可以在附录 A 中找到。
¹ 编程语言统计:https://octoverse.github.com
² 人工智能是由约翰·麦卡锡在 1956 年首次学术会议上创造的。
第二章:介绍 TensorFlow.js
“如果你的行动激励他人梦想更多,学习更多,
做更多,成为更多,你就是一个领导者。”
—约翰·昆西·亚当斯
我们已经稍微谈到了 TensorFlow.js 以及它的功能,但我们还没有真正深入探讨像 TensorFlow.js 这样的机器学习框架到底是什么。在本章中,我们将探讨机器学习框架的概念,然后迅速进入编写代码。我知道编写具有某种实际结果的代码很重要,所以在本章中,你最终将让你的计算机运行 TensorFlow.js 并产生结果。
我们将:
-
看看 TensorFlow.js 的概念
-
设置 TensorFlow.js
-
运行一个 TensorFlow.js 模型包
-
深入了解 AI 的工作原理
让我们从我们将使用的框架开始。
你好,TensorFlow.js
考虑到我们之前的章节讨论了古代哲学和机器学习作为一个领域的诞生,你会期望人工智能框架的历史可以追溯到上世纪 60 年代初。然而,人工智能长时间停滞不前,这段时间通常被称为“人工智能寒冬”。人工智能的概念受到怀疑和极端数学计算的困扰,因为当时可用的数据量很小。谁能责怪这些研究人员呢?今天大多数软件开发人员依赖于发布应用程序,而不是从头开始编写支持 GPU 的线性代数和微积分,构建自己的人工智能不应该是例外。幸运的是,由于谷歌 Brain 团队的一些开源贡献,我们有了选择。
当你开始学习机器学习时,会听到很多流行词。TensorFlow、TensorFlow Lite 和 TensorFlow.js 都可能被提到,对于大多数新手来说,这些术语的含义以及为什么会有三个都不清楚。现在,让我们暂时忽略“张量”这个术语,因为你在第一章中已经听过这个词,而且在接下来的章节中你会真正理解它。相反,让我们专注于定义 TensorFlow.js,以便我们可以使用它。
TensorFlow,没有任何额外的“.js”或“Lite”,是谷歌的第一个公开的机器学习框架;谷歌 Brain 团队于 2015 年底发布了它。这个框架专注于用 Python 在云端有效解决谷歌的机器学习问题。谷歌很快意识到将这个流行的框架推广到计算能力有限的物联网和移动设备上会有好处,这就需要对 TensorFlow 进行适应,这就是所谓的 TensorFlow Lite。这一成功的适应为将 TensorFlow 理念推广到其他语言铺平了道路。
你可能可以猜到接下来会发生什么。2018 年初,谷歌宣布了一个由谷歌支持的 JavaScript 导入机器学习框架 TensorFlow 的版本,称为 TensorFlow.js。这一新举措以全新的方式增强了 TensorFlow 的实用性。Daniel Smilkov、Nikhil Thorat 和 Shanqing Cai 是发布 TensorFlow.js 的团队的一部分。在TensorFlow 开发者峰会上,Smilkov 和 Thorat 使用计算机视觉和网络摄像头训练一个模型来控制吃豆人游戏。
正是在这一刻,“仅限 Python”的选项被从流行的人工智能框架选项中移除,神经网络可以有效地穿越 JavaScript 领域。如果你可以运行 JavaScript,你就可以运行由 TensorFlow.js ML 支持的人工智能。
这三种实现今天都是活跃的,并随着它们特定目的的增长。通过将 TensorFlow 扩展到 JavaScript 实现,我们现在可以在节点服务器甚至客户端浏览器中实现 AI/ML。在论文“TensorFlow.js: 用于 Web 和更多的机器学习”中(Daniel Smilkov 等人,2019),他们表示,“TensorFlow.js 使来自庞大 JavaScript 社区的新一代开发人员能够构建和部署机器学习模型,并实现新类的设备上计算。” TensorFlow.js 可以利用广泛的设备平台,同时仍然可以访问 GPU 甚至 Web Assembly。有了 JavaScript,我们的机器学习可以涉足地平线并回来。
值得注意的是,在几项基准测试中,Node 在较低的 CPU 负载下胜过了 Python 3,因此尽管 Python 一直是大多数 AI 的采用语言,JavaScript 作为产品和服务的主要语言平台。
但没有必要删除或推广任何一种语言。TensorFlow 模型基于有向无环图(DAG),这是与语言无关的图,是训练的输出。这些图可以由一种语言训练,然后转换并被完全不同的编程语言消耗。本书的目标是为您提供使用 JavaScript 和 TensorFlow.js 的工具,以便充分利用它们。
利用 TensorFlow.js
对于很多人来说,“学习”有时可能意味着从基础开始,这意味着从数学开始。对于这些人来说,像 TensorFlow 这样的框架和像 TensorFlow.js 这样的实用分支是一个糟糕的开始。在本书中,我们将构建项目,并涉及 TensorFlow.js 框架的基础知识,我们将很少或根本不花时间在底层数学魔法上。
像 TensorFlow 和 TensorFlow.js 这样的框架帮助我们避免涉及的线性代数的具体细节。您不再需要关注前向传播和反向传播这样的术语,以及它们的计算和微积分。相反,我们将专注于像推断和模型训练这样的行业术语。
虽然 TensorFlow.js 可以访问底层 API(如tfjs-core)来对经典问题进行一些基本优化,但这些时刻留给了那些无论手头的框架如何都有坚实基础的学者和高级用户。这本书旨在展示 TensorFlow.js 的强大之处,利用框架的辛勤工作和优化是我们将如何做到这一点。我们让 TensorFlow.js 负责配置和优化我们的代码,以适应各种设备约束和 WebGL API。
我们甚至可能走得太远,将机器学习应用于您可以轻松手工编码的算法,但这通常是大多数人真正理解概念的地方。用机器学习解决您理解的简单问题有助于您推断解决您无法手工编码的高级问题的步骤、逻辑和权衡。
另一方面,一些关于神经元、激活函数和模型初始化的基础知识是不能被忽视的,可能需要一些解释。本书的目标是为您提供理论和实用性的健康平衡。
正如您可能已经推测到的那样,TensorFlow.js 的各种平台意味着没有单一的预设设置。我们可以在本书中在客户端或服务器上运行 TensorFlow.js。然而,我们最隐性的交互选项是充分利用浏览器。因此,我们将在浏览器中执行大部分示例。当然,在适当的情况下,我们仍将涵盖托管节点服务器解决方案的关键方面。这两种工具都有各自的优缺点,我们将在探索 TensorFlow.js 的强大之处时提到。
让我们准备好 TensorFlow.js
与任何流行工具一样,您可能会注意到 TensorFlow.js 包有几种不同版本,以及几个可以访问代码的位置。本书的大部分内容将专注于 TensorFlow.js 最常用和“准备运行”的版本,即浏览器客户端。优化的框架版本是为服务器端制作的。这些版本与 Python 使用相同的底层 C++核心 API 进行通信,但通过 Node.js,这使您能够利用服务器的图形卡或 CPU 的所有性能。TensorFlow.js AI 模型在各种位置运行,并利用各种环境的各种优化(请参见图 2-1)。

图 2-1。TensorFlow.js 的选项
本书中学到的知识可以应用于大多数平台。为了方便起见,我们将覆盖最常见平台的设置过程。如果您不愿意从头开始设置环境,可以直接访问与本书相关的源代码中为您构建的预配置项目,位于https://github.com/GantMan/learn-tfjs。
在浏览器中设置 TensorFlow.js
让我们来看看运行 TensorFlow.js 的最快、最多功能和最简单的方法。要在浏览器中运行 TensorFlow.js,实际上非常容易。我假设您熟悉 JavaScript 的基础知识,并且以前已经将 JavaScript 库导入到现有代码中。TensorFlow.js 支持多种包含方式,因此任何经验的开发人员都可以访问它。如果您熟悉包含 JavaScript 依赖项,您将熟悉这些常见做法。我们可以以两种方式将 TensorFlow.js 导入到页面中:
-
使用 NPM
-
包含脚本标签
使用 NPM
管理网站依赖项的最流行方式之一是使用包管理器。如果您习惯使用 NPM 或 Yarn 构建项目,您可以通过 NPM 注册表访问代码https://oreil.ly/R2lB8。只需在命令行安装依赖项:
# Import with npm
$ npm i @tensorflow/tfjs
# Or Yarn
$ yarn add @tensorflow/tfjs
导入tfjs包后,您可以在 JavaScript 项目中使用以下 ES6 JavaScript 导入代码导入此代码:
import * as tf from '@tensorflow/tfjs';
包含脚本标签
如果网站不使用包管理器,您可以简单地向 HTML 文档添加一个脚本标签。这是您可以在项目中包含 TensorFlow.js 的第二种方式。您可以下载并在本地托管 TensorFlow.js,或者利用内容传送网络(CDN)。我们将把脚本标签指向 CDN 托管的脚本源:
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.7.0/dist/tf.min.js">
</script>
除了跨网站缓存外,CDN 非常快,因为它们利用边缘位置确保全球快速交付。
注意
您可能已经注意到,我已将此代码锁定到特定版本(2.7.0),我强烈建议您在涉及 CDN 的项目中始终这样做。您不希望在网站出现自动破坏性更改的问题。
在 Node 中设置 TensorFlow.js
我们在浏览器中使用的 TensorFlow.js 包与 Node.js 完全兼容,如果您计划仅暂时尝试 Node.js,这是一个很好的解决方案。一个好的规则是,如果您不打算为他人托管实时项目或在大量数据上进行训练,则使用简单的/tfjs而不是/tfjs-node导入。
如果您的目标是超越实验,并在 TensorFlow.js 中实现有效的 Node.js,您应该花一些时间改进您的 Node.js 设置,使用一些这些替代包。有两个更好的 TensorFlow.js 分发版本专门为 Node 和速度构建。它们是tfjs-node和tfjs-node-gpu。请记住,每台开发者机器都是独特的,您的安装和体验可能有所不同。
对于 Node.js,您可能需要在@tensorflow/tfjs-node和@tensorflow/tfjs-node-gpu之间进行选择。如果您的计算机配置了 NVIDIA GPU 并正确设置了 CUDA 软件,您可以使用后者 GPU 加速的软件包。Compute Unified Device Architecture(CUDA)允许通过并行计算平台直接访问 GPU 加速的 NVIDIA 硬件。虽然 GPU 软件包是 TensorFlow.js 选项中绝对最快的,但由于其硬件和软件约束,它也是最不可能准备好并配置好的软件包。目前,我们的示例将在安装tfjs-node上运行,并将可选的 CUDA 配置留给您。
# Import with npm
$ npm i @tensorflow/tfjs-node
# Or Yarn
$ yarn add @tensorflow/tfjs-node
警告
通常,如果您的计算机尚未设置为开发高级 C++库,您可能需要安装一些软件来准备好您的计算机。只有当您希望积极使用tfjs-node或tfjs-node-gpu时,才需要进行这种深入研究。
如果您的 NPM 安装成功,恭喜!您已准备好从此包中导入。如果您已经设置了 Node 来处理 ES6,您可以使用以下代码导入:
import * as tf from '@tensorflow/tfjs-node';
如果您尚未配置 Node.js 软件包以处理 ES6 导入,您仍然可以使用经典的 require 访问代码:
const tf = require('@tensorflow/tfjs-node');
验证 TensorFlow.js 是否正常工作
之前的所有方法都会在您的 JavaScript 代码中提供一个名为tf的变量,这使您可以访问 TensorFlow.js。为了确保我们的导入工作正常,让我们记录导入的 TensorFlow.js 库的版本。
将此代码添加到您的 JavaScript 中,如果在控制台中看到一个版本打印出来,您的导入就可以继续进行了!
console.log(tf.version.tfjs);
运行页面时,我们可以右键单击页面并检查以访问 JavaScript 控制台日志。在那里,我们将找到我们的日志命令的输出,“3.0.0”或您导入的 TensorFlow.js 版本。对于 Node.js 示例,该值将直接在控制台中打印。
警告
在访问tf变量(TensorFlow.js 库)的功能之前,通常需要确保 TensorFlow.js 已经正确加载了后端并准备就绪。上述代码绕过了这个检查,但始终最好运行您的初始代码等待tf.ready()的承诺。
下载并运行这些示例
如第一章中所述,您可以访问本书中的代码。为了确保您不必在每个示例中从头开始设置这些项目,请确保您拥有每个项目的源代码,包括之前显示的简单代码。
从书的存储库中以您喜欢的方式下载项目:https://github.com/GantMan/learn-tfjs。
转到第二章的目录,并确保您可以在您的计算机上运行代码。
运行简单示例
在chapter2/simple/simplest-example中,我们避免使用 NPM,只是从 CDN 中拉取我们的代码。以当前结构化的方式,我们甚至不需要托管网站!我们只需在任何现代浏览器中打开index.html,它就会运行!
在某个时候,我们实际上需要托管这些简单示例,因为我们将访问需要完整 URI 的其他资产。我们可以通过使用一个小型的 Web 服务器来托管文件来轻松实现这一点。我知道的最小的 Web 服务器叫做 Web 服务器,有一个有趣的手绘“200 OK!”标志。在五分钟内,我们就可以在本地服务器上正确提供我们的文件。
您可以在Chrome Web Store 作为扩展上找到 Chrome 的 Web 服务器。在本书中,我们有时会称此插件为“200 OK!”当您将 Web 服务器指向index.html文件时,它将自动为您提供文件,并且所有相邻文件都可以通过其关联的 URL 访问,正如我们将在后续课程中所需的那样。应用程序界面应该看起来像图 2-3。

图 2-3。Chrome 的 Web 服务器 200 OK!对话框
如果您想查看其他选项或想要链接到提到的 Chrome 插件,请查看chapter2/extra/hosting-options.md,找到适合您的选项。当然,如果您发现一个未列出的绝妙选项,请贡献一个拉取请求。
一旦找到一个以您喜欢的方式运行simple-example的服务器,您可以将该服务用于以后的所有简单选项。
运行 NPM web 示例
如果您更熟悉 NPM,此项目的基本 NPM 示例使用 Parcel。Parcel 是最快的应用程序捆绑工具,零配置。它还包括热模块重新加载,以获取实时更新和出色的错误日志记录。
要运行代码,请导航至chapter2/web/web-example并执行 NPM 安装(npm i)。完成后,在package.json中有一个脚本可以启动所有内容。您只需运行启动脚本:
$ npm run start
就是这样!我们将使用这种方法来运行本书中所有基于 NPM 的代码。
运行 Node.js 示例
Node.js 示例与 Parcel NPM 示例一样易于运行。虽然 Node.js 通常没有明确的意见,但本书中的 Node.js 示例将包括一些明确的开发依赖项,以便我们可以使我们的 Node.js 示例代码与浏览器示例保持一致。本书中的代码将充分利用 ECMAScript。我们通过一些转译、文件监视和节点魔法来实现这一点。
为了准备这个示例,请导航至chapter2/node-example并执行 NPM 安装(npm i)。如果遇到任何问题,您可能需要运行npm i -g ts-node nodemon node-gyp来确保您拥有所需的库,以确保我们所有的魔法发生。一旦您的节点包正确放置,您可以随时通过运行启动脚本来启动项目:
$ npm run start
代码通过 TypeScript 转译,并且使用nodemon进行重新加载。如果一切正常运行,您将在运行服务器的控制台/终端中直接看到已安装的 TensorFlow.js 版本。
让我们使用一些真实的 TensorFlow.js
现在我们有了 TensorFlow.js,让我们用它来创造一些史诗般的东西!好吧,这有点简化:如果那么容易,这本书就结束了。仍然有很多东西要学习,但这并不妨碍我们乘坐缆车,以获得高层视角。
TensorFlow.js 有大量预先编写的代码和模型可供我们利用。这些预先编写的库帮助我们获得利用 TensorFlow.js 的好处,而无需完全掌握底层概念。
虽然有很多社区驱动的模型效果很好,但 TensorFlow.js 模型的官方维护列表在 TensorFlow GitHub 上,名称为tfjs-models。为了稳定性,我们将尽可能经常在本书中使用这些模型。您可以在这里查看链接:https://github.com/tensorflow/tfjs-models。
在这次尝试运行实际 TensorFlow.js 模型时,让我们选择一个相对简单的输入和输出。我们将使用 TensorFlow.js 的Toxicity分类器来检查文本输入是否具有侮辱性。
毒性分类器
谷歌提供了几个不同复杂度的“即插即用”模型。其中一个有益的模型被称为毒性模型,这可能是对初学者来说最直接和有用的模型之一。
像所有编程一样,模型将需要特定的输入并提供特定的输出。让我们开始看看这个模型的输入和输出是什么。毒性检测有毒内容,如威胁、侮辱、咒骂和普遍仇恨。由于这些并不一定是互斥的,因此每种违规行为都有自己的概率是很重要的。
毒性模型试图识别给定输入是否符合以下特征的真假概率:
-
身份攻击
-
侮辱
-
淫秽
-
严重毒性
-
性暴力
-
威胁
-
毒性
当您给模型一个字符串时,它会返回一个包含七个对象的数组,用于识别每个特定违规行为的概率预测百分比。百分比表示为两个介于零和一之间的Float32值。
如果一句话肯定不是违规行为,概率将主要分配给Float32数组中的零索引。
例如,[0.7630404233932495, 0.2369595468044281]表示对于这种特定违规行为的预测是 76%不是违规行为,24%可能是违规行为。
对于大多数开发人员来说,这可能是一个“等等,什么!?”的时刻。在我们习惯于真和假的地方得到概率,这有点奇怪,不是吗?但直观地,我们一直知道语言有很多灰色地带。侮辱的确切科学往往取决于个人,甚至是当天!
因此,该模型具有一个额外功能,允许您传递一个阈值,当特定违规行为超过分配的限制时将其识别出来。当检测到超过阈值的侮辱时,match标志将设置为 true。这是一个很好的额外功能,可以帮助您快速映射重大违规行为的结果。选择有效的阈值取决于您的需求和情况。您可以凭直觉行事,但如果需要一些指导,统计学有各种工具供您查阅。阅读有关接收器操作特性(ROC)图的文章,以绘制和选择适合您需求的最佳阈值。
警告
要激活毒性模型,我们将不得不写一些侮辱性的话。以下示例使用基于外表的侮辱。这个侮辱避免使用粗话,但仍然是冒犯性的。这并不针对任何特定人,而是旨在说明 AI 理解和识别有毒评论的能力。
选择一个对人类容易识别但对计算机难以识别的侮辱是很重要的。在文本形式中检测讽刺是困难的,并且一直是计算机科学中的一个主要问题。为了严肃测试这个模型,侮辱应避免使用常见和明显的煽动性措辞。将阈值设置为0.5,在特别狡猾的侮辱上运行毒性模型会产生示例 2-1 中显示的数组。
侮辱输入:“她看起来像一个穴居人,只是远不如智慧!”
示例 2-1。输入句子的完整毒性报告
[{
"label":"identity_attack",
"results":[{
"probabilities":{
"0":0.9935033917427063,
"1":0.006496586836874485
}, "match":false
}]
},{
"label":"insult",
"results":[{
"probabilities":{
"0":0.5021483898162842,
"1":0.4978516101837158
}, "match":false
}]
},{
"label":"obscene",
"results":[{
"probabilities":{
"0":0.9993441700935364,
"1":0.0006558519671671093
}, "match":false
}]
},{
"label":"severe_toxicity",
"results":[{
"probabilities":{
"0":0.9999980926513672,
"1":0.0000018614349528434104
}, "match":false
}]
},{
"label":"sexual_explicit",
"results":[{
"probabilities":{
"0":0.9997043013572693,
"1":0.00029564235592260957
}, "match":false
}]
},{
"label":"threat",
"results":[{
"probabilities":{
"0":0.9989342093467712,
"1":0.0010658185929059982
}, "match":false
}]
},{
"label":"toxicity",
"results":[{
"probabilities":{
"0":0.4567308723926544,
"1":0.543269157409668
}, "match":true
}]
}]
正如您从示例 2-1 中可以看到的,我们在“侮辱”雷达下勉强通过(50.2%错误),但我们被毒性指标扣分,导致"match": true。这相当令人印象深刻,因为我在句子中没有任何明确的冒犯性语言。作为程序员,编写一个算法来捕捉和识别这种有毒的侮辱并不直接,但 AI 经过研究大量标记的侮辱后,被训练来识别有毒语言的复杂模式,这样我们就不必自己做了。
前面的示例使用一个句子的数组作为输入。如果将多个句子作为输入,您的句子索引将直接对应于每个类别的结果索引。
但不要只听我的话;现在轮到您运行代码了。您可以通过以下方式将模型添加到您的网站:
$ npm install @tensorflow-models/toxicity
然后导入库:
import * as toxicity from "@tensorflow-models/toxicity";
或者您可以直接从 CDN 添加脚本。³ 脚本标签的顺序很重要,所以确保在尝试使用模型之前将标签放在页面上:
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/toxicity@1.2.2">
</script>
前面的任何示例都将在一个准备就绪的toxicity变量中提供结果。我们将使用这个变量的load方法来加载 ML 模型的承诺。然后,我们可以利用该模型在一个句子数组上使用classify方法。
以下是加载模型并对三个句子进行分类的示例。这个确切的示例可以在GitHub 上的章节代码的相关部分中以三种不同形式找到。
// minimum positive prediction confidence
// If this isn't passed, the default is 0.85
const threshold = 0.5;
// Load the model // ①
toxicity.load(threshold).then((model) => {
const sentences = [
"You are a poopy head!",
"I like turtles",
"Shut up!"
];
// Ask the model to classify inputs // ②
model.classify(sentences).then((predictions) => {
// semi-pretty-print results
console.log(JSON.stringify(predictions, null, 2)); // ③
});
});
①
模型加载到浏览器中并带有阈值。
②
加载的模型被要求对输入进行分类。
③
使用 JavaScript 对象表示法很好地打印了对象。
注意
如果您在浏览器中运行此代码,您需要查看控制台以查看输出。您可以通过检查页面导航到控制台,或者通常情况下,您可以在 Windows 上按 Control+Shift+J 或在 Mac 上按 Command+Option+J。如果您使用npm start从命令行运行此代码,您应该立即在控制台中看到输出。
多个句子的结果按毒性类别分组。因此,前面的代码尝试根据每个类别识别每个句子。例如,前面的“侮辱”输出应该类似于示例 2-2。
示例 2-2. 侮辱部分结果
...
{
"label": "insult",
"results": [
{
"probabilities": {
"0": 0.05905626341700554,
"1": 0.9409437775611877
},
"match": true
},
{
"probabilities": {
"0": 0.9987999200820923,
"1": 0.0012000907445326447
},
"match": false
},
{
"probabilities": {
"0": 0.029087694361805916,
"1": 0.9709123373031616
},
"match": true
}
]
},
...
哒哒哒!代码运行得很好。每个results索引对应于输入句子索引,并且正确诊断了三个句子中的两个侮辱。
祝贺您运行您的第一个 TensorFlow.js 模型。现在您是 AI 的大师,让我们一起讨论这个库的步骤和基本概念。
加载模型
当我们调用toxicity.load时,您可能会认为模型被加载到内存中,但您只对一半正确。大多数这些库不会在 JavaScript 代码库中提供经过训练的模型。再读一遍那句话。这对于我们的 NPM 开发人员可能有点令人担忧,但对于我们的 CDN 用户来说完全合理。加载方法触发一个网络调用来下载库使用的模型。在某些情况下,加载的模型会针对 JavaScript 所在的环境和设备进行优化。查看图 2-4 中说明的网络日志。

图 2-4. 网络下载请求
警告
尽管毒性 NPM 捆绑包可以被缩小并压缩到仅 2.4 KB,但在使用库时,实际模型文件在网络上有额外的多兆字节负载。
这个毒性库的加载方法需要一个阈值,它将应用于所有后续分类,然后触发一个网络调用来下载实际的模型文件。当模型完全下载时,库会将模型加载到张量优化内存中供使用。
适当评估每个库是很重要的。让我们回顾一些人们在学习更多关于这个库时常问的常见问题。
分类
我们的毒性代码接下来做的事情是运行classify方法。这是我们的输入句子通过模型传递的时刻,我们得到了结果。虽然它看起来就像任何其他 JavaScript 函数一样简单,但这个库实际上隐藏了一些必要的基本处理。
模型中的所有数据都被转换为张量。我们将在第三章中更详细地介绍张量,但重要的是要注意,这种转换对于 AI 至关重要。所有输入字符串都被转换,进行计算,得到的结果是重新转换为普通 JavaScript 基元的张量。
很高兴这个库为我们处理了这个问题。当您完成本书时,您将能够以相同的灵活性包装机器学习模型。您将能够让您的用户对发生在幕后的数据转换的复杂性保持幸福的无知。
在下一章中,我们将深入探讨这种转换。您将完全掌握数据转换为张量以及随之而来的所有数据操作超能力。
自己试试
现在你已经实现了一个模型,很可能你可以实现谷歌提供的其他模型。大多数其他谷歌模型的 GitHub 页面都有 README 文档,解释如何实现每个库。许多实现与我们在毒性中看到的类似。
花点时间浏览现有的模型,让你的想象力发挥得淋漓尽致。你可以立即开始使用这些库进行工作。随着你在本书中的进展,了解这些模型的存在也会很有用。你不仅将更好地理解这些库的能力,还可能想要结合甚至改进这些现有库以满足你的需求。
在下一章中,我们将开始深入挖掘这些包装良好的库隐藏的细节,以便无限释放你的 TensorFlow.js 技能。
章节复习
我们通过几种常见的实践选项为 TensorFlow.js 设置了你的计算机。我们确保我们的机器已经准备好运行 TensorFlow.js,甚至下载并运行了一个打包好的模型来确定文本毒性。
章节挑战:卡车警报!
花点时间尝试一下MobileNet 模型,它可以查看图像并尝试对主要物件进行分类。这个模型可以传递任何 <img>、<video> 或 <canvas> 元素,并返回对该特定图形中所见内容的最有可能预测的数组。
MobileNet 模型已经经过训练,可以对1,000 种可能的物品进行分类,从石墙到垃圾车,甚至是埃及猫。人们已经使用这个库来检测各种有趣的事物。我曾经看到一些代码将网络摄像头连接到 MobileNet 来检测羊驼。
对于这个章节挑战,你的任务是创建一个可以检测卡车的网站。给定一个输入图像,你要识别它是否是一辆卡车。当你从照片中检测到一辆卡车时,执行 alert("检测到卡车!")。默认情况下,MobileNet 包返回前三个检测结果。如果这三个中有任何一个在照片中看到卡车,你的警报应该像图 2-5 中一样通知用户。

图 2-5. 卡车检测器工作
你可以在附录 B 中找到这个挑战的答案。
复习问题
让我们回顾一下你在本章编写的代码中学到的教训。花点时间回答以下问题:
-
常规 TensorFlow 能在浏览器中运行吗?
-
TensorFlow.js 能访问 GPU 吗?
-
运行 TensorFlow.js 是否必须安装 CUDA?
-
如果我在 CDN 上没有指定版本,会发生什么?
-
毒性分类器如何识别违规行为?
-
我们何时会达到毒性的阈值?
-
毒性代码是否包含所有所需的文件?
-
我们是否需要进行任何张量工作来使用这个毒性库?
这些练习的解决方案可以在附录 A 中找到。
¹ TensorFlow 直到 2017 年 2 月 11 日才达到 1.0.0 版本。
² Node 比 Python 案例研究提高了 2 倍:https://oreil.ly/4Jrbu
³ 请注意,此版本已锁定在 1.2.2。
⁴ 毒性模型信息可在https://oreil.ly/Eejyi找到。


浙公网安备 33010602011771号