您已使用 TensorFlow.js 创建了自定义机器学习模型,但现在需要将其托管在某处,以便在您选择的网站上使用。在这方面,有多种方案可供选择,但今天我们要介绍一下若选用 Firebase Hosting 会有多简单。Firebase Hosting 还可提供一些额外的好处,例如版本控制、通过安全连接提供模型,等等。
您将构建的内容
在此 Codelab 中,您将创建一个完整的端到端系统,该系统能够托管和运行保存的自定义 TensorFlow.js 模型及其相关资源,如 HTML、CSS 和 JavaScript。我们将构建一个非常简单的轻量级模型(该模型可在提供某个输入值后预测一个数值输出值,即在知道房屋面积后预测其价格),并将其通过 Firebase Hosting 托管,以便大规模使用。
您将学习的内容
- 如何以正确的格式保存自定义 TensorFlow.js 模型
- 如何设置要用于托管的 Firebase 帐号
- 如何将您的资源部署到 Firebase Hosting
- 如何部署模型的新版本。
请注意:此 Codelab 重点介绍如何构建一个经过自定义训练的模型并将其托管以用于部署,而不是介绍如何打造完美模型架构,因此我们将利用一个简单的例子快速带过机器学习模型本身的创建过程。无论您最终创建的是哪种模型,其原则都是相同的。
与我们分享您的成果
如果您使用此内容做了一些很酷的作品,请告诉我们!我们很期待看到您的创作。
在社交媒体上使用 #MadeWithTFJS 标签通知我们,为您的项目争取在我们的 TensorFlow 博客甚至 Show & Tells 等活动中特推的机会。
Firebase Hosting 可为您的 Web 应用、静态/动态内容和微服务提供快速、安全的生产级托管服务
您只需一个命令,便可快速部署 Web 应用并向全球 CDN(内容分发网络)提供内容,确保您的内容几乎在任何地方都能以低延迟分发。您还可以将 Firebase Hosting 与 Firebase Cloud Functions 或 Cloud Run 搭配使用,以便构建和托管微服务,不过,这些内容超出了此 Codelab 的讨论范围。
Firebase Hosting 关键功能
- 通过安全的连接提供内容 - 新型网站是很安全的。为了访问客户端的传感器,网站经常必须通过安全环境分发。Firebase Hosting 中内置了零配置的 SSL,因此始终能够为托管的所有文件安全地分发内容。
- 利用身份验证支持,托管静态和动态内容以及微服务,以便只有已登录用户才能加载/查看这些文件(如果需要)。
- 快速分发内容 - 您上传的每个文件都会缓存在遍布全球的 CDN 边缘的 SSD 上。无论您的用户身处何处,内容都可快速分发。
- 只需一个命令即可部署新版本 - 利用 Firebase 命令行界面,只需几秒钟即可启动并运行您的应用。
- 一键回滚 - 快速部署十分有用,而能够撤消错误更是锦上添花。Firebase Hosting 利用一键回滚提供完整的版本控制和管理功能。
无论您是在部署一个简单的应用着陆页,还是部署复杂的渐进式 Web 应用 (PWA),Firebase Hosting 均为您提供专为部署和管理网站和应用而特别开发的基础架构、功能和工具。
默认情况下,每个 Firebase 项目均在 web.app 和 firebaseapp.com 网域上拥有免费的子网域。这两个网站提供相同的已部署的内容和配置。如果需要,您还可以将自己的域名关联到由 Firebase 托管的网站。
实施步骤
- 设置项目
- 安装并配置 Firebase 命令行界面
- 部署您的网站
- 关联到 Firebase Web 应用以进行性能监控(可选)
但在此之前,我们需要用来部署的机器学习模型和 Web 应用,来创建一个吧!
在本练习中,我们将构建一个非常简单的预测数值的机器学习模型。我们将使用机器学习技术,在得到了一间虚构的房屋的面积后预测其价格,仅作说明之用。对本次演示,我们只是将房屋的面积乘以 1000,以获得对其训练数据的预测值,但机器学习需要自行学习这一规律。
在现实中,您可能会选择使用真实的数据,这些数据之间的关系更复杂(例如,对于小户型,其价格可能只是面积的 500 倍,但在面积超过某个阈值之后,价格可能会逐渐上涨为面积的 1000 倍),并且您可能需要更高级的模型来学习预测这些值的最佳方式。
我们今天将创建的模型(线性回归)可用于预测其他许多事物(前提是提供足够多的真实世界数据),并且可以轻松上手上面的假设使用情形。但是,今天我们讲的重点是如何保存和部署模型,而不是针对特定使用情形设计和优化模型。开始吧!
训练和测试数据
所有机器学习模型都从获取一些示例训练数据开始,我们可以使用这些数据训练模型,以便能够预测未来的值。通常,您可以从数据库、文件夹、CSV 或更多来源中获得此类数据,但这里我们直接以 JavaScript 将 20 个示例硬编码为数组,如下所示。我们建议您立即将代码复制到您喜欢的编码环境中(例如 Glitch.com),或者如果您能在本地主机上运行服务器,也可以在本地的文本编辑器中复制此代码。
model.js
// House square footage.
const data = [800, 850, 900, 950, 980, 1000, 1050, 1075, 1100, 1150, 1200, 1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000];
// Estimated dollar cost of house for each piece of data above (1000x square footage).
const answers = [800000, 850000, 900000, 950000, 980000, 1000000, 1050000, 1075000, 1100000, 1150000, 1200000, 1250000 , 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000];
// Testing data separate from training data.
const dataTest = [886, 1225, 500];
const answersTest = [886000, 1225000, 500000];
您可以看到,对于每个数据,我们都有相应的答案值,也是未来将尝试预测的值(您可以将这些值想象为一个简单的二维图表上的 x 和 y 值)。
因此,对于输入值 800,我们预期生成约为 800000 美元的输出答案。如果使用值 900,系统应会输出 900000 美元,依此类推。实质上就是输入值乘以 1000。然而,机器学习模型不知道 1000 * N 这一简单关系,它必须通过我们提供的示例自行学习。
注意我们如何使一些测试数据与训练数据完全分开。这样,我们就能评估经过训练的模型,看看它对之前从未见过的数据有怎样的表现。
我们将使用以下 HTML 加载此脚本以及 TensorFlow.js 库:
train.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Training Model</title>
<meta charset="utf-8">
</head>
<body>
<!-- Import TensorFlow.js library -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>
<!-- Import our JS code to train the model -->
<script src="/model.js" defer></script>
</body>
</html>
训练模型
接下来,需要将以下代码添加到上述现有 JS 代码的文件末尾处,以便训练模型。
我们添加了备注以供参考,但如前所述,此 Codelab 主要是介绍如何利用已保存的模型并将其托管。如果您想进一步了解模型创建,请参阅本文末尾处链接的更多 Codelab。您现在可以将代码复制并粘贴到您的项目中。
model.js
// Create Tensor representations of our vanilla JS arrays above
// so can be used to train our model.
const trainTensors = {
data: tf.tensor2d(data, [data.length, 1]),
answer: tf.tensor2d(answers, [answers.length, 1])
};
const testTensors = {
data: tf.tensor2d(dataTest, [dataTest.length, 1]),
answer: tf.tensor2d(answersTest, [answersTest.length, 1])
};
// Now actually create and define model architecture.
const model = tf.sequential();
// We will use one dense layer with 1 neuron and an input of
// a single value.
model.add(tf.layers.dense({inputShape: [1], units: 1}));
// Choose a learning rate that is suitable for the data we are using.
const LEARNING_RATE = 0.0001;
train();
async function train() {
// Compile the model with the defined learning rate and specify
// our loss function to use.
model.compile({
optimizer: tf.train.sgd(LEARNING_RATE),
loss: 'meanAbsoluteError'
});
// Finally do the training itself over 500 iterations of the data.
// As we have so little training data we use batch size of 1.
// We also set for the data to be shuffled each time we try
// and learn from it.
let results = await model.fit(trainTensors.data, trainTensors.answer, {epochs: 500, batchSize: 1, shuffle: true});
// Once trained we can evaluate the model.
evaluate();
}
async function evaluate(stuff) {
// Predict answer for a single piece of data.
model.predict(tf.tensor2d([[768]])).print();
}
使用上述代码,我们能够训练一个可根据输入值来预测输出值的模型。运行上述代码后,对于输入值 768,我们得到了 768073 这一预测值,该值输出在浏览器的开发者控制台中(如果尚未打开此控制台,按 F12 可将其打开)。鉴于我们给出的示例是输出为输入的 1000 倍,此模型对于房价预测得很不错。注意:您得到的预测的值可能会略有不同,这是正常情况。
如果我们对其性能满意,那么现在只需将模型保存到磁盘,以便将其上传到 Firebase Hosting。
保存模型
将以下代码添加到上述评估函数的末尾(在 model.predict 之后),我们可以在完成训练后将生成的模型直接从网络浏览器导出,并保存到磁盘,这样我们就可以将其托管在某处并在未来使用,而不必在每次加载此网页时重新训练该模型。
model.js
await model.save('downloads://my-model');
现在,如果您访问 train.html 并运行此页面,它应该会训练模型(可能需要几秒钟),然后在完成训练时提示下载经过训练的结果模型。
登录 Firebase 并选择一个项目
如果您是第一次使用 Firebase,请用您的 Google 帐号注册,很方便。只需访问 https://firebase.google.com/,然后登录您想要使用的常规 Google 帐号。重定向到首页后,点击页面右上角的“转至控制台”:
重定向到控制台后,您应该会看到类似于以下所示的着陆页:
只需按照所示方法点击“添加项目”,即可创建一个新的 Firebase 项目,为您的项目指定一个独特的名称,接受条款,然后点击“继续”。
接下来,系统会询问您是否要为项目添加分析功能。如果您希望获得此类分析数据,可以启用此选项并点击“继续”,如下所示:
如果一切顺利,您会看到一个显示已创建项目的问候页面,如下所示:
棒极了!我们设置了一个项目。点击“继续”可前往新创建的项目的控制台。让此页面保持打开状态以供后用,但目前我们必须安装一些工具。
安装并连接 CLI
Firebase 以 Node NPM 软件包的形式提供,您可以通过命令行界面 (CLI) 安装和使用,便于您轻松地将本地文件和文件夹部署到 Firebase Hosting。在今天的教程中,我们将使用 Linux 环境,但如果您使用的是 Windows 或 Mac,则可以按照此处的说明在设备上设置 CLI 工具。
不过,在 Linux 上,如果尚未安装 NPM 和 Node.js,请首先在终端窗口中使用以下 3 个命令进行安装(如果使用其他环境,则按照这些说明进行操作):
命令行终端:
sudo apt update
命令行终端:
sudo apt install nodejs
命令行终端:
sudo apt install npm
现在,安装 Node.js 和 NPM 以后,只需在终端窗口中运行以下命令,即可安装 Firebase 命令行工具:
命令行终端:
sudo npm install -g firebase-tools
太好了!现在,我们可以将此 Firebase 项目连接到系统,以便向其推送文件及执行更多操作。
登录 Firebase
运行以下命令,使用您的 Google 帐号登录 Firebase:
命令行终端:
firebase login
系统会要求您授予对以下 Google Firebase 帐号的访问权限:
允许此操作,然后您最终应该看到命令行工具成功连接到 Firebase 帐号:
关闭窗口,然后返回到您先前输入内容的命令行终端,在此终端中应该可以接受新的命令(如下所示,屏幕截图中隐藏了所有私密信息):
恭喜!现在,我们可以将文件从本地机器推送到创建的项目中了。
初始化项目以部署到 Firebase Hosting
如需将本地文件夹连接到您的 Firebase 项目,请从本地项目的根目录(部署时要上传的文件所在的文件夹)运行以下命令。
命令行终端:
firebase init
执行此命令时,请按照终端中的说明完成设置,如下所示:
在这里,我们只需按键盘上的向下箭头选择 Hosting,按空格键选择,然后按 Enter 键即可确认。
现在,我们可以选择之前创建的现有项目来使用:
在“use an existing project”处按下 Enter 键,然后使用向下箭头键将其选中,如下所示:
最后,按下 Enter 键使用该项目,并在弹出的最终屏幕中接受默认值,然后对于是否配置为单页应用 (configure as single page application) 的问题输入“No”:
这样,如果需要,您就可以托管多个 HTML 网页。
现在,初始化已完成,您会看到系统已创建了一个 firebase.json 文件和一个“public”文件夹,就在我们执行以上命令的目录中。
现在,我们只需将要部署的文件移到创建的“public”文件夹,就可以进行部署了!我们现在就来进行这一操作。
加载已保存的模型
首先,确保将之前的 Codelab 中保存的机器学习模型复制到我们刚刚使用 Firebase 创建的“public”文件夹中。只需将您保存的文件拖放到此文件夹即可,如下所示:
您还会注意到 Firebase 为我们创建了 index.html 和 404.html 文件。接下来,在您的机器上使用常用的文本编辑器修改 index.html,添加自定义代码,如下所示:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello World - TensorFlow.js</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import the webpage's stylesheet -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>TensorFlow.js Hello World</h1>
<p>Check the console (Press F12) to see predictions!</p>
<!-- Import TensorFlow.js library -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>
<!-- Import the page's JavaScript to do some stuff -->
<script src="script.js" defer></script>
</body>
</html>
在上面的 index.html 新代码中,我们指定了一个样式表,以便稍后为页面添加样式(如果需要这样做),同时指定了 script.js,来托管为了使用 TensorFlow.js 保存的模型而需要编写的代码。
现在,我们来创建这些文件并按照以下说明填充它们,令其实现某些功能:
style.css
/** Leave blank for now **/
script.js
// Load our saved model from current directory (which will be
// hosted via Firebase Hosting)
async function predict() {
// Relative URL provided for my-model.json.
const model = await tf.loadLayersModel('my-model.json');
// Once model is loaded, let's try using it to make a prediction!
// Print to developer console for now.
model.predict(tf.tensor2d([[1337]])).print();
}
predict();
如果已经正确执行了上述步骤,您现在应该会在我们创建的“public”文件夹中看到以下已修改的文件:
现在,我们只需部署文件,即可检查它是否有效。
上线
返回您在本地机器的 Firebase 项目文件夹(此文件夹包含上述的“public”文件夹以及 Firebase init 文件)中打开的终端窗口。
只需输入以下内容即可部署“public”文件夹的文件:
命令行终端:
firebase deploy
让终端命令完成,此时应该会成功完成一个版本,并返回可以使用的网址:
在上面的示例中,用于查看部署的最终网址是:
https://tensorflow-js-demo.web.app(但您的网址中使用的将是您创建的项目的名称)。
在网络浏览器中打开此网址,看看该网址能否正常使用;如果成功,您打开的网页的开发者控制台中应会显示类似以下的内容(按 F12 可打开开发者控制台)。
您可以看到,该页面在已部署的网域上加载。对于 1337 平方英尺,我们能看到模型的预测值为 1336999.25 美元,这是个相当好的估计值,因为此值应当是平方英尺数的 1000 倍。如果开发一个良好的用户界面来调用该模型,我们当然可以运行任意次预测,而这完全以 JavaScript 运行,从而确保您的查询是私密的并且安全无虞。
您的模型现已部署并托管,接下来您就可以与全世界的任何人分享此网站,他们就能在自己的机器上使用此应用了。显然,您可能想要添加更好的界面,让应用的观感更好,但这超出了本教程的范围。在一键部署且无需任何安装工作的机器学习技术的支持下,Web 应用的发展是无限的。我们鼓励您思考其他可受益于浏览器机器学习模型的情况。
监控使用情况
除了您可以添加到网站代码中的任何 Google 分析功能外,Firebase 还通过您项目的控制台提供版本控制和使用量统计功能。部署后,您将看到类似如下所示的内容,可根据需要随时进行检查:
您可以看到,默认情况下,您在免费层级每月可享受 10GB 带宽来用于托管文件。如果您的网站较受欢迎,您可能需要添加一个结算帐号,以便在给定月份内使用超出这一数量的带宽。您可以在此查看适合较大规模项目的 Firebase 收费方案。如果您的模型不大并且使用量低,此原型的大多数不经常使用的用户可能不会超过免费级层提供的配额,但随着您发展业务或创意,在承诺使用付费方案之前,通过此处测试和检查它是否满足您的需求是一个不错的方法。
恭喜,您已使用 TensorFlow.js 与 Firebase 迈出了第一步,构建并部署自定义的机器学习模型,并可与全世界分享该模型。想象一下,您可以使用这一强大、可扩容并且可直接用于生产用例的方法创建的所有其他应用。由于 Firebase 可随着需求自动扩缩,因此无论是 10 名还是 10000 名用户使用此模型,它都能正常运行。
如果您更改了任何文件,只需像以前一样使用 Firebase 部署命令重新部署应用,并确保清除浏览器缓存,以保证在下次加载此页面时获得的是文件的新版本。如果您打开了开发者工具,可以在执行测试时在网络标签页中强制执行此操作,通过选中标签页顶部附近的“disable cache”复选框来简化操作。
回顾
在此 Codelab 中,我们完成了以下内容:
- 从零开始定义并训练一个自定义 TensorFlow.js 模型来预测房价。
- 在您的开发机器上注册、配置和安装 Firebase 和 Firebase CLI 工具。
- 部署并启动了可加载我们从第 1 步中训练的模型的正常运行网站,并将其用于一个可供任何人在任何地方且满足任何规模需求的真实 Web 应用。
后续步骤
现在,您已拥有一个良好的起点,就拓展此机器学习模型部署样板而言,您还能想出什么创意?
我们期待您将此模型与您自己的数据结合使用。想一想您居住或工作的行业或地区。您如何训练这些数据,以做出未来可能对您(或其他人)有用的预测?房地产并非唯一的例子,我们鼓励您将此代码应用于自己的挑战。编程愉快!
记得使用 #MadeWithTFJS 标签(点击此链接可查看别人开发了什么,寻找灵感)通知我们,争取在我们的社交媒体呈现甚至参与我们未来的 TensorFlow 活动的机会。我们希望看到您的作品,当然,如果您有任何反馈或问题,可以与此 Codelab 的作者联系。