使用 SKLearn 估算器、本地 Jupyter 笔记本和终端在 AWS 上部署 Scikit-Learn 模型
关于如何从本地设备在 AWS 上部署 scikit-learn 模型的分步教程。
从 Wikipedia.com(scikit-learn)和 aws.amazon.com 检索到的徽标。
亚马逊网络服务(AWS)是目前数据科学和机器学习专业人士最需要的云平台。鉴于此,本机器学习部署系列的第一批博客文章将概述如何在 AWS 上以多种不同的方式部署各种模型。
本系列其他帖子:
我们将涉及的第一个 AWS 部署将是一个简单的 Scikit-learn 模型的部署,该模型完全从一个人的本地计算机使用 AWS 预构建 Scikit-learn 估计器来完成。
在我们深入研究这些步骤之前,理解 AWS Sagemaker 如何训练和部署模型的基本概念很重要。如果你不熟悉 Docker,我推荐在这里阅读他们的概述文档。不涉及太多细节,AWS 本质上使用 Docker 容器来存储模型的配置,训练模型,并最终部署模型。通过将 ML 模型封装在 Docker 容器中,AWS 能够同时为通用 ML 框架提供一组预配置的 Docker 映像,同时还允许完全定制。
幸运的是,在 2018 年,AWS 将 Scikit-learn 添加到其支持的框架列表中。因此,我们可以使用预配置的 Docker 容器快速部署我们的模型。正如您将在下面看到的,我们将创建一个训练脚本,并使用 AWS Scikit-learn 估计器在容器内执行它。所以,事不宜迟,让我们开始吧。
你可以在我为这个博客系列开始的回购中找到这篇文章的代码。
第一步:账户设置
在开始之前,我们必须设置一个 AWS 帐户。如果您已经有一个 AWS 帐户,那么您可以跳到下一步。否则,让我们为你注册 AWS 和他们的 175(并且持续增长)服务。首先,导航到这一页创建你的免费 AWS 账户并获得 12 个月的免费层访问(这足以完成本文中的代码)。
步骤 2: AWS CLI 和 Pip 包
一旦您注册了 AWS,我们还需要下载 AWS 命令行界面(CLI ),这样我们就可以在本地设备上使用我们的 AWS 帐户。AWS 很好地解释了如何安装 , 配置,使用他们的 CLI。
我们还需要安装几个 python SDKs,以便在 python 脚本中访问 AWS。具体来说,我们将需要 Boto3 来处理数据上传,并需要 Sagemaker 来创建我们的 Scikit-learn 估算器。运行下面的 pip 命令来安装它们。
pip install boto3
pip install sagemaker
步骤 3:数据设置
为了专注于模型的部署,并避免陷入数据清理和模型调整的困境,我们将在 Iris 数据集上训练一个简单的逻辑回归模型。您可以在此下载数据集并将其保存到您的本地设备。
一旦我们部署了模型,我们将使用下面的代码块从数据集中提取一些样本来测试 API 调用,并将数据保存到两个名为 train.csv 和 deploy_test.csv 的新文件中。
注意:我们不考虑 ML 训练/测试集指南。在实践中,您应该总是将您的数据分成一个训练/测试集。然而,对于本教程,我们只是专注于部署模型,并将通过在最后调用 API 来检查模型如何预测我们在deploy _ test . CSV中保存的几个点。
为了让 AWS Sagemaker 在训练模型时访问这些数据,我们必须通过创建一个新的简单存储服务(S3)桶并将我们的训练数据添加到其中,将数据上传到我们的 AWS 帐户。为此,我们将使用上面安装的 boto3 SDK 在指定区域创建一个 S3 桶,然后将我们的 train.csv 文件保存在该桶的 train/ 文件夹中。 点击这里了解更多关于 S3 的信息。
注意:为了让 Sagemaker 访问数据,S3 存储桶和 Sagemaker 会话需要在同一个区域。鉴于 Sagemaker 仅在某些地区可用,请务必从这里列出的地区中为您的 S3 桶选择一个地区。
为了再次检查以上脚本是否正常工作,您可以导航到 AWS S3 控制台,登录,并查看我们在上面创建的 bucket 是否在那里。如果有了,我们就可以继续工作,创建我们的模型了!
第四步:模型脚本
为了使用 Scikit-learn Sagemaker SDK 将模型部署到 AWS,我们首先必须创建一个脚本,告诉 Sagemaker 如何训练和部署我们的模型。虽然比创建我们自己的 Docker 容器来部署我们的模型要简单得多,但是 SDK 确实要求我们坚持相当严格的准则。
首先,我们将导入我们需要的所有包,并创建几个字典来将目标标签从文本转换成数字,反之亦然。
在这些导入之后,我们需要将训练步骤包装在 main 函数中。我们还将在最后添加一行来保存模型。SKLearn Sagemaker SDK 将运行这个 main 函数,根据我们推送到上面的 S3 存储桶的数据训练一个模型,然后保存这个模型,以便以后我们想要部署它时可以使用它。
main 函数是唯一必需的函数。然而,我们有能力修改一些额外的函数,这些函数决定了模型在部署后如何处理 API 调用。这些可选功能是:
****model _ fn:***指定从何处以及如何加载正在部署的模型。
***input _ fn:***将发送到部署模型的请求体格式化为可以馈入模型的格式。 ***predict _ fn:***使用 model_fn 加载的部署模型和 input_fn 格式化的数据进行预测。 ***output _ fn:**将 predict_fn 做出的预测重新格式化为最终的格式,作为 API 调用的响应返回。
下面的要点显示了我们模型的这些可选函数。每个函数上面的注释提供了关于每个函数的更多信息。关于这些函数及其默认行为的更多信息,请参见这里的。
步骤 5:创建 IAM Sagemaker 角色
不幸的是,当我说我们将在本地计算机上完成所有这些工作时,我撒了一个谎。如果您还没有 Sagemaker IAM 角色,我们需要导航到 AWS IAM 控制台并创建一个新角色。首先点击这里并登录。您应该会看到如下所示的屏幕:
AWS 选择 IAM 角色页
从这里,选择 Sagemaker 作为服务,并按下下一步。
通过选择下一页跳过下两页,直到您看到以下屏幕:
AWS 创建 IAM 角色名页
在此页面中,在点击创建角色之前,只需创建自己的角色名称 和(可选)角色描述。请务必记住您为您的角色命名的名称,因为我们将在下一步中用到它!*
第六步:部署模型
艰苦的工作完成后,让我们来部署您的模型。幸运的是,使用 AWS SKLearn 类,这只需要几行代码。只需确保 入口点 路径指向我们在步骤 4 中保存的脚本,并且 角色 变量是您在步骤 5 中创建的角色名称 。在这个片段中,我们还为模型和部署的端点指定了 instance_types。instance_type 指定了我们希望 AWS 为我们的服务分配多少计算能力。显然,功率越大,成本越高,所以对于这个例子,我们使用小实例。查看这里的以获得所有可用的 Sagemaker 实例类型的列表。*
注意:SKLearn()构造函数有许多可选参数,您可以添加这些参数来配置 Scikit-learn framework_version、超参数等。点击 此处 了解更多信息。
第七步:测试终点
为了测试端点,我们将 feed send 一个请求,其中包含我们在步骤 3 中保存到 deploy_test.csv 的数据样本。为了向部署的端点发送请求,我们首先需要将我们的测试样本转换成模型可以解析的格式(即,可以由我们在 aws_sklearn_main.py 中定义的 input_fn 函数解释的格式)。由于我们将模型配置为理解具有多个样本的请求,其中每个样本的特征由“,”分隔,每个单独的样本由“|”分隔,因此我们将 request_body 格式化为如下格式:
*'147,6.5,3.0,5.2,2.0|148,6.2,3.4,5.4,2.3|149,5.9,3.0,5.1,1.8'*
在这里,我们使用 boto3 创建一个 Sagemaker 会话,它将允许我们与部署的模型进行交互。为了调用我们的 Sagemaker 端点,我们使用了 invoke_endpoint 函数。对于这个函数,我们必须指定一个端点、一个内容类型和一个主体。还有一些可选参数,你可以在这里阅读更多关于的内容。在我们的例子中,我们将传递在上一步中输出的端点、content_type 'text/csv '和一个格式类似于上面的字符串。最后,一旦我们运行了这个方法并收到了响应,我们就在响应的正文中下标并读取返回的内容。
如果预期的响应与模型实际返回的相匹配,那么您已经成功地在 AWS 上训练和部署了一个有效的 Scikit-learn 模型!
步骤 8:清理资源
为了避免任何 AWS 费用,请务必清理您的资源。您可以通过取消步骤 6 中最后一行的注释并运行它来快速终止模型的端点。
*aws_sklearn_predictor.delete_endpoint()*
虽然这将删除端点,但要完全清除您在本教程中使用的所有资源的 AWS 帐户,请完成以下操作。
- 打开制袋机控制台
- 在**推理下的侧栏菜单中,**删除在模型*、端点和端点配置选项卡上创建的资源。*
- 打开 S3 控制台并删除我们创建的桶。
- 打开 IAM 控制台,删除我们创建的角色。
- 打开 Cloudwatch 控制台,删除所有/aws/sagemaker 日志。
回顾
总的来说,虽然学习曲线有点高,但一旦您能够在 AWS 服务中导航并理解 Sagemaker 原则,AWS SKLearn 估计器就成为快速部署 Scikit-learn 模型的一个不可思议的工具。
好处:
- 需要很少的配置,但有很多可用的
- 过多的文件
- 只需几行代码就可以部署模型
缺点
- 巨大的初始学习曲线
- 需要理解和使用的几个 AWS 服务
- 文档可能很难找到
本系列其他博文:
使用 TensorFlow.js 将简单的机器学习模型部署到 WebApp 中
你好,今天,你要构建一个简单的 WebApp,可以识别数字。看看下面的演示。
请在您的浏览器或手机中尝试一下:
https://carlos-aguayo.github.io/tfjs.html
TensorFlow.js 的美妙之处在于,您可以使用 Keras 或 TensorFlow 在 Python 中训练机器学习模型,并使用 TensorFlow.js 将其部署在浏览器上。无需外部服务来运行您的查询。
数字识别 WebApp
这个有趣而简单的应用程序让你画一个一位数,它使用简单的机器学习工具识别它。
如果你想直接看的话,下面是完整的代码:
让我们开始吧;这些是构建这个演示所需的成分和步骤。
配料和步骤:
- 培训用数据
- 培训环境
- 预处理数据
- 机器学习
- 将 Keras 模型转换为 Tensorflow.js
- HTML5 画布
- 把一切都连接起来
培训用数据
任何机器学习模型都需要高质量的数据。我们将使用 MNIST 数据集,这是一个手写数字的数据集。
约瑟夫·斯泰潘[ CC BY-SA
在这个数据集中,有 60,000 幅图像,所有图像的灰度都是 28 x 28 像素,像素值从 0 到 255。
有关加载和查看 MNIST 数据集的信息,请参见下面的代码片段。
培训环境
Google Colab 允许你在浏览器中编写和执行 Python。
Colab 是一个非常方便的 Jupyter Notebook Python 平台,预装了您需要的大部分 Python 机器学习库,这是一种让您快速启动并运行 ML 项目的便捷方法。
此外,它让您可以免费访问 GPU/CPU。
数据预处理
来自 MNIST 的数据需要进行一个小的预处理:
- 规范化输入:数据带有从 0 到 255 的值,我们应该将它们规范化为从 0 到 1 的范围。
- 一键编码输出。
# Normalize Inputs from 0–255 to 0–1**x_train = x_train / 255****x_test = x_test / 255**# One-Hot Encode outputs**y_train = np_utils.to_categorical(y_train)****y_test = np_utils.to_categorical(y_test)**num_classes = 10
机器学习
我们终于准备好做一些机器学习了。我们可以从一个非常简单的模型开始。我们将使用一个简单的神经网络,只有一个隐藏层。这个简单的模型足以获得 98%的准确率。
x_train_simple = x_train.reshape(60000, 28 * 28).astype(‘float32’)x_test_simple = x_test.reshape(10000, 28 * 28).astype(‘float32’)model = Sequential()**model.add(Dense(28 * 28, input_dim=28 * 28, activation=’relu’))****model.add(Dense(num_classes, activation=’softmax’))**model.compile(loss=’categorical_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])model.fit(x_train_simple, y_train, validation_data=(x_test_simple, y_test), epochs=30, batch_size=200, verbose=2)
如果你想变得花哨,你可以尝试一个深度学习模型。有了它,你可以把准确率提高到 99%。
x_train_deep_model = x_train.reshape((60000, 28, 28, 1)).astype(‘float32’)x_test_deep_model = x_test.reshape((10000, 28, 28, 1)).astype(‘float32’)deep_model = Sequential()**deep_model.add(Conv2D(30, (5, 5), input_shape=(28, 28, 1), activation=’relu’))****deep_model.add(MaxPooling2D())****deep_model.add(Conv2D(15, (3, 3), activation=’relu’))****deep_model.add(MaxPooling2D())****deep_model.add(Dropout(0.2))**deep_model.add(Flatten())deep_model.add(Dense(128, activation=’relu’))deep_model.add(Dense(50, activation=’relu’))deep_model.add(Dense(num_classes, activation=’softmax’))deep_model.compile(loss=’categorical_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])deep_model.fit(x_train_deep_model, y_train, validation_data=(x_test_deep_model, y_test), epochs=30, batch_size=200, verbose=2)
将 Keras 模型转换为 Tensorflow.js
现在我们有了一个训练好的模型,我们需要转换它,以便可以在 TensorFlow.js 中使用它。
首先,我们需要将模型保存到 HDF5 模型中。
model.save(“model.h5”)
之后,您可以通过点击左侧导航中的文件夹图标来访问保存的文件。
有几种方法可以转换模型。笔记本中的一个简单例子是这样的:
!pip install tensorflowjs!tensorflowjs_converter --input_format keras ‘/content/model.h5’ ‘/content/model’
/content/model.h5 是输入,输出保存在/content/model 文件夹中。
TensorFlow.js 需要指向 JSON 文件( model.json ),需要一个名为“ group1-shard1of1.bin ”的兄弟文件。你需要这两份文件。下载这两个文件。
HTML5 画布
让我们有一个简单的 HTML 页面,它使用 HTML5 Canvas 组件让我们在上面绘图。姑且称这个文件为“tfjs.html”。
核心绘图代码来自本网站:
使用 HTML5 Canvas 组件,我们可以将鼠标事件挂钩到画布中。
canvas.addEventListener('mousedown', function(e) {
context.moveTo(mouse.x, mouse.y);
context.beginPath();
canvas.addEventListener('mousemove', onPaint, false);
}, false);var onPaint = function() {
context.lineTo(mouse.x, mouse.y);
context.stroke();
};
然后,我们添加触摸事件,使其在移动设备上工作。
添加触摸动作以禁用滚动。这个代码的灵感来自于这个网站。
一旦我们可以绘制,让我们在鼠标抬起时获取图像。我们将把它缩小到 28 乘 28 像素,以便它与训练好的模型相匹配。
canvas.addEventListener('**mouseup**', function() {
$('#number').html('<img id="spinner" src="spinner.gif"/>');
canvas.removeEventListener('mousemove', onPaint, false);
**var img = new Image();
img.onload = function() {
context.drawImage(img, 0, 0, 28, 28);** data = context.getImageData(0, 0, 28, 28).data; var input = [];
for(var i = 0; i < data.length; i += 4) {
input.push(data[i + 2] / 255);
}
predict(input);
**};
img.src = canvas.toDataURL('image/png');** }, false);
然后,我们获取数据,将它保存在一个“输入”数组中,并将其传递给一个预测函数,我们将在后面定义该函数。
canvas.addEventListener('mouseup', function() {
$('#number').html('<img id="spinner" src="spinner.gif"/>');
canvas.removeEventListener('mousemove', onPaint, false);
var img = new Image();
img.onload = function() {
context.drawImage(img, 0, 0, 28, 28);
**data = context.getImageData(0, 0, 28, 28).data;
var input = [];
for(var i = 0; i < data.length; i += 4) {
input.push(data[i + 2] / 255);
}
predict(input);** };
img.src = canvas.toDataURL('image/png');
}, false);
数据是一个 1D 数组,其值为 RGBA 值。我们的模型只取 0 到 1 的值(或者从 255 的灰度中取 0)。假设我们正在画布上绘制 B lue,我们可以将数组分成四块,每隔一个元素取一个。
RG**B**ARG**B**ARG**...**
01**2**345**6**789...
把所有东西都挂起来
最后,让我们加载 TensorFlow.js 并运行预测。
<script src=”https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.5.2/dist/tf.min.js"></script>
你应该已经下载了文件 model.json 和 group1-shard1of1.bin ,并将它们保存到一个名为 model 的文件夹中,这个文件夹与你保存 HTML 文件的文件夹相同。
加载后,我们可以通过简单地执行以下操作来加载训练好的模型:
**tf.loadLayersModel**(‘**model/model.json**’).then(function(model) {
window.model = model;
});
鼠标一放,一旦我们有了数据,我们就可以把它输入到模型中:
**window.model.predict**([tf.tensor(**input**).reshape([1, 28, 28, 1])]).array().then(function(scores){
scores = scores[0];
predicted = scores.indexOf(Math.max(...scores));
$('#number').html(predicted);
});
在本地测试很简单,并且可以很容易地设置一个 HTTP 服务器来用 Python 进行测试:
python3 -m http.server 8080
如果你想用手机测试,你可以利用这个叫做 ngrok 的漂亮工具。
$ ngrok http 8080
这就打开了一个可以通过手机访问的 URL 的通道。
一旦你对结果感到满意,你就可以将你的 HTML 部署到一个虚拟主机站点。一个简单的地方就是 Github。如果你从未用 Github 创建过静态网站,你需要创建一个名为“{username}.github.io”的资源库。例如,我的存储库是:
https://github.com/carlos-aguayo/carlos-aguayo.github.io
然后,您可以通过以下方式访问它:
https://carlos-aguayo.github.io/tfjs.html
结论
请注意,我们可以多么轻松地在 Google Colab 中训练模型,导出训练好的模型,并在 JavaScript 中查询它,而无需离开浏览器!
我是 Appian 的软件开发总监兼机器学习工程师。我在 Appian 工作了 15 年,我一直很开心。如果你想知道我们是如何制作软件的,请给我发消息,让我们的客户开心!
为 Python 部署简单的 UI
Streamlit 共享:Python 项目的游戏规则改变者
瑞安·莫尔顿在 Unsplash 上的照片
使用 Streamlit 为 Python 项目创建用户界面是无缝的,Streamlit 是一个相对较新的基于浏览器的 Python 框架,允许您优雅地展示项目,而无需编写任何 HTML、CSS 或 Javascript 代码。
现在,通过 Streamlit Sharing,你可以免费部署你的项目,而不需要启动服务器或使用任何云服务,如 Heroku。
背景
在之前的文章中,我们构建了一个简单的迷宫求解器应用。简而言之,它允许用户上传一个迷宫的图像,并显示一个解决方案。用于促进用户交互的一些 Streamlit 功能包括:
滑块
文件上传和复选框:
要更深入地了解该应用如何实现 Streamlit 特性,请访问:
Streamlit:一个基于浏览器的 Python UI,不需要 HTML/CSS/JS
towardsdatascience.com](/building-a-simple-ui-for-python-fd0e5f2a2d8b)
部署
Streamlit 最近推出了 Streamlit 共享服务,以促进 Streamlit 项目的部署。使用该服务需要几个快速步骤。
1。创建一个 requirements.txt
您可以在项目环境中使用以下命令来创建它:
pip freeze > requirements.txt
2.将您的项目推送到 GitHub
为您的项目创建一个公共存储库,并确保提交 requirements.txt 以及任何项目文件。
如果你没有使用过 Github,这里有一个关于创建资源库的初级读本。
3.请求访问简化共享
虽然这项服务仍处于早期阶段,但你可以在这里申请访问。不到 24 小时,我就获得了 Streamlit 团队的访问权限。
收到访问邮件后,使用当前 GitHub 帐户登录 share.streamlit.io。
4.部署
登录后,点击“新建应用”并输入存储库信息。
注意:如果您的 python 依赖项需要操作系统级别的包,您可能需要将 packages.txt 文件添加到您的存储库中。例如,将 OpenCV Python 库与 Streamlit 一起使用需要主机服务器安装 ffmpeg。
在本课中,我们使用 Streamlit 共享免费快速部署了一个 Python 项目。你可以在这里查看最终部署的应用以及 Github 上的所有源代码。
要了解更多关于迷宫求解器背后的算法,或者如何使用 Streamlit 用很少几行 Python 代码创建友好的 web 界面,请查看本系列的第一部分和第二部分。
使用 Dijkstra 的算法和 OpenCV
towardsdatascience.com](/solving-mazes-with-python-f7a412f2493f) [## 为 Python 构建一个简单的 UI
Streamlit:一个基于浏览器的 Python UI,不需要 HTML/CSS/JS
towardsdatascience.com](/building-a-simple-ui-for-python-fd0e5f2a2d8b)
轻松将 TensorFlow 模型部署到生产环境中。
使用 TensorFlow 服务将深度学习模型部署到生产中。
学习使用 TensorFlow 服务将 TensorFlow 模型逐步部署到生产中。
您使用 Tensorflow 创建了一个深度学习模型,对模型进行了微调以获得更好的准确性和精确度,现在想要将您的模型部署到生产中,供用户使用它来进行预测。
将您的模型投入生产的最佳方式是什么?
快速、灵活地部署 TensorFlow 深度学习模型的方法是使用高性能和高度可扩展的服务系统——tensor flow 服务
TensorFlow 服务使您能够
- 轻松管理您的模型的多个版本,如实验版或稳定版。
- 保持您的服务器架构和 API 不变
- 动态发现 TensorFlow 流模型的新版本,并使用一致的 API 结构gRPC(远程过程协议)为其服务。
- 所有客户通过集中模型位置进行推理的一致体验
tensor flow 服务的哪些组件使部署到生产变得容易?
张量流服务架构
TF 服务的主要组成部分包括
- Servables:Servable 是一个底层对象,客户端使用它来执行计算或推理。TensorFlow 服务将深度学习模型表示为一个或多个服务对象。
- 加载器 : 管理服务程序的生命周期,因为服务程序不能管理自己的生命周期。加载器**标准化用于加载和卸载服务的 API,**独立于特定的学习算法。
- Source : 寻找并提供 servable,然后为 servable 的每个版本提供一个 Loader 实例。
- 管理者 : 管理服务对象的整个生命周期:加载服务对象,服务服务对象,卸载服务对象。
- TensorFlow Core:通过将加载程序和可服务程序作为不透明对象来管理可服务程序的生命周期和指标
假设您有一个模型的两个不同版本,版本 1 和版本 2。
- 客户端通过显式地指定模型的版本或者仅仅请求模型的最新版本来进行 API 调用。
- 管理器监听源代码,并跟踪 Servable 的所有版本;然后,它应用已配置的版本策略来确定应该加载或卸载哪个版本的模型,然后让我们加载适当的版本。
- 加载器包含加载 Servable 的所有元数据。
- 源插件将为 Servable 的每个版本创建一个 Loader 实例。
- 源对管理器进行回调,通知加载器的期望版本被加载,并将其提供给客户端。
- 每当源检测到 Servable 的新版本时,它会创建一个加载器,指向磁盘上的 Servable。
如何在 Windows 10 上部署使用 Tensorflow 服务的深度学习模型?
对于 Windows 10,我们将使用 TensorFlow 服务图像。
第一步:安装 Docker App
步骤 2:提取 TensorFlow 服务图像
**docker pull tensorflow/serving**
一旦你有了张量流服务图像
- 端口 8500 对 gRPC 开放
- 端口 8501 是为 REST API 公开的
- 可选环境变量
**MODEL_NAME**
(默认为model
) - 可选环境变量
**MODEL_BASE_PATH**
(默认为/models
)
步骤 3:创建并训练模型
这里,我从张量流数据集中提取了 MNIST 数据集
#Importing required libraries
**import os
import json
import tempfile
import requests
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds**#Loading MNIST train and test dataset
#as_supervised=True, will return tuple instead of a dictionary for image and label
**(ds_train, ds_test), ds_info = tfds.load("mnist", split=['train','test'], with_info=True, as_supervised=True)**#to select the 'image' and 'label' using indexing coverting train and test dataset to a numpy array
**array = np.vstack(tfds.as_numpy(ds_train))
X_train = np.array(list(map(lambda x: x[0], array)))
y_train = np.array(list(map(lambda x: x[1], array)))
X_test = np.array(list(map(lambda x: x[0], array)))
y_test = np.array(list(map(lambda x: x[1], array)))**#setting batch_size and epochs
**epoch=10
batch_size=128**#Creating input data pipeline for train and test dataset
# Function to normalize the images**def normalize_image(image, label):
#Normalizes images from uint8` to float32
return tf.cast(image, tf.float32) / 255., label**# Input data pipeline for test dataset
#Normalize the image using map function then cache and shuffle the #train dataset
# Create a batch of the training dataset and then prefecth for #overlapiing image preprocessing(producer) and model execution work #(consumer)**ds_train = ds_train.map(
normalize_img, num_parallel_calls=tf.data.experimental.AUTOTUNE)
ds_train = ds_train.cache()
ds_train = ds_train.shuffle(ds_info.splits['train'].num_examples)
ds_train = ds_train.batch(batch_size)
ds_train = ds_train.prefetch(tf.data.experimental.AUTOTUNE)**# Input data pipeline for test dataset (No need to shuffle the test #dataset)
**ds_test = ds_test.map(
normalize_image, num_parallel_calls=tf.data.experimental.AUTOTUNE)
ds_test = ds_test.batch(batch_size)
ds_test = ds_test.cache()
ds_test = ds_test.prefetch(tf.data.experimental.AUTOTUNE)**# Build the model
**model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28, 1)),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense(196, activation='softmax')
])**#Compile the model
**model.compile(
loss='sparse_categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(0.001),
metrics=['accuracy'],)**#Fit the model
**model.fit(
ds_train,
epochs=epoch,
validation_data=ds_test,
verbose=2)**
第四步:保存模型
通过将 save_format 指定为“tf”将模型保存到协议缓冲文件中。
**MODEL_DIR='tf_model'
version = "1"
export_path = os.path.join(MODEL_DIR, str(version))**#Save the model
**model.save(export_path, save_format="tf")
print('\nexport_path = {}'.format(export_path))
!dir {export_path}**
当我们保存模型的一个版本时,我们可以看到包含文件的以下目录:
- Saved_model.pb :包含一个或多个模型的序列化图形定义,以及作为 MetaGraphDef 协议缓冲区的模型元数据。权重和变量存储在单独的检查点文件中。
- 变量:保存标准训练检查点的文件
您可以使用saved _ model _ CLI命令检查模型。
**!saved_model_cli show --dir {export_path} --all**
步骤 5:使用 Tensorflow 服务为模型提供服务
打开 Windows Powershell 并执行以下命令来启动 TensorFlow 服务容器,以便使用 REST API 端口为 TensorFlow 模型提供服务。
**docker run -p 8501:8501 --mount type=bind,source=C:\TF_serving\tf_model,target=/models/mnist/ -e MODEL_NAME=mnist -t tensorflow/serving**
用 Docker 成功服务 TensorFlow 模型。
- 使用-p 打开端口 8501 为模型提供服务
- Mount 将绑定模型基路径,该路径应该是保存模型的容器位置的绝对路径。
- 通过指定 MODEL_NAME,客户端将用来调用的模型的名称
- 使用-t 选项分配一个伪终端“tensorflow/serving”
docker run 命令的输出
步骤 6:请求模型预测一个 REST
我们将创建一个 JSON 对象来传递预测数据。
#Create JSON Object
**data = json.dumps({“signature_name”: “serving_default”, “instances”: X_test[:20].tolist()})**
请求模型的 predict 方法作为对服务器的 REST 端点的 POST。
**headers = {"content-type": "application/json"}
json_response = requests.post('**[**http://localhost:8501/v1/models/mnist:predict'**](http://localhost:8501/v1/models/mnist:predict')**, data=data, headers=headers)****predictions = json.loads(json_response.text)['predictions']**
检验预测的准确性
**pred=[ np.argmax(predictions[p]) for p in range(len(predictions)) ]
print("Predictions: ",pred)
print("Actual: ",y_test[:20].tolist())**
在下一篇文章中,我们将探索不同的模型服务器配置。
结论:
TensorFlow 服务是一种快速、灵活、高度可扩展且易于使用的方式,使用一致的 gRPC 或 REST APIs 为您的生产模型提供服务。
参考资料:
TensorFlow 服务是一个灵活、高性能的机器学习模型服务系统,专为生产…
www.tensorflow.org](https://www.tensorflow.org/tfx/guide/serving)
https://www . tensor flow . org/tfx/tutorials/serving/rest _ simple # make _ rest _ requests
在 Python 中部署文本分类模型
一个端到端的机器学习项目
学习使用 Dash 和 Heroku 部署基于机器学习的应用程序
本文是我介绍开发一个机器学习项目的整个过程的系列文章的最后一篇。如果你还没有看过前面两篇文章,我强烈建议你在这里做,在这里做。
该项目包括创建一个实时 web 应用程序**,该应用程序从几家报纸收集数据,并显示新闻文章中讨论的不同主题的摘要。**
这是通过监督机器学习分类模型实现的,该模型能够预测给定新闻文章的类别,通过 web 抓取方法从报纸上获取最新新闻,通过交互式 web 应用向用户显示获取的结果。
正如我在本系列的第篇文章中解释的那样,我写这些文章的原因是因为我注意到,大多数时候,互联网、书籍或文献上发布的关于数据科学的内容都集中在以下方面:我们有一个带标签的数据集,我们训练模型以获得性能指标。这意味着数据标签或模型部署等关键概念被忽略。
然而,事实证明,机器学习和数据科学旨在解决问题和提供有用的信息。所以,拥有一个 99%准确率的模型却不知道如何利用它,会让我们意识到我们已经失去了时间。
这就是为什么在这一系列帖子中,我试图从头到尾涵盖从头构建一个对最终用户有用的机器学习应用程序的所有必要步骤,并为他们提供有价值的见解或信息。
所以,这个项目的整个开发过程被分成了三个不同的岗位:
GitHub 回购可以在这里找到。它包括所有的代码和一个完整的报告。
在第一篇文章中,我们用 Python 开发了文本分类模型,它允许我们获得某篇新闻文章文本,并以整体良好的准确性预测其类别。
在第二篇文章中,我们创建了一个脚本,从不同的报纸上搜集最新的新闻文章并存储文本。
在这篇文章中,我们将把所有的部分放在一起,并部署我们的机器学习模型,以便它可以为最终用户提供有用的、方便的和实时洞察。我们将遵循以下步骤:
- 部署前的考虑事项
- Dash web 应用程序的创建
- 与 Heroku 一起部署
- 最后的想法
部署前的考虑事项
数据
此时,我们已经使用包含 2004 年至 2005 年新闻文章的数据集训练了一个机器学习模型。我们现在的目的是将该模型应用于实时、当前数据。
很容易理解,这可能是我们的 web 应用程序的第一个限制,我们将通过一个简单的例子来了解它:假设我们运行我们的 web 应用程序,并尝试对一篇谈论 iPhone 11 新发布的文章进行分类,并关注其令人惊叹的最先进的功能,如视网膜显示屏、5G 网络支持等…
如果我们回顾 2004 年,最畅销的手机之一是这个:
因此,我们在当前数据中发现的许多术语很可能在 2004 年甚至还不存在,因此也不存在于我们的数据集中。
例如,这是我们样本中一篇文章的摘录:
成千上万的人排了几个小时的队,只为买到运送给零售商的 20 万台 PSP 中的一台。这款掌上游戏机可以玩游戏、听音乐和看电影,明年将在欧洲和北美上市。尽管需求旺盛,索尼表示不会增加计划在年底前发货的 50 万台 PSP 的库存。
你们中的一些人甚至不会记得这个便携式游戏机!
我希望这能让下面的陈述变得简单明了:我们用于训练的数据和我们将在部署后输入模型的数据越相似,就越好。
如果两个阶段的数据不相似,我们将解决所谓的数据不匹配问题。而且,虽然我知道这听起来可能太明显了,但在实践中,我见过很多没有考虑这个问题的模型,这可能导致实时数据的性能非常差,即使我们有一个非常好的训练数据,并因此导致一个无用的应用。
我们如何解决这个问题?在训练我们的模型时,我们应该通过花费大量时间创建特征或者通过超参数调整来获得更高的精度吗?你猜对了:没有。解决这个问题的唯一方法是使用更新的语料库来训练模型。这里没有神奇的机器学习可以提供。
特性
为了将我们的原始文本文章转换为可以输入到机器学习模型中的数字,我们首先通过几个步骤清理文本:删除停用词、词条分类等。之后,我们应用了一个 TF-IDF 矢量化功能将文本转换为数字特征。
因此,当我们部署了我们的应用程序并从报纸上获取了新的文本时,我们将需要转换原始文本**,就像我们转换**一样。
例如,我们使用了 NLTK 中预先构建的停用词向量。这意味着当我们运行我们的 web 应用程序时,我们将需要以某种方式获得这个向量,以便可以删除这些单词。
关于 TF-IDF 矢量化,我们在这里有一个重要的观点:正如我们在第一篇文章中看到的,这个矢量化工具为文档 *d、*中的术语 t 计算该术语在该文档中的频率以及逆文档频率,这表示该术语是否在语料库中出现了很多(因此它是一个常用术语)或者没有出现(并且它是一个不常用术语,因此它有点“重要”)。
来源:自己创作
需要注意的是,我们所指的这个语料库是训练语料库。这意味着,当从 web 抓取过程中获取一篇新闻文章时,将只在该文章中计算术语频率,但将在训练语料库中计算逆文档频率。
因此,正如与最新 iPhone 相关的现代单词所发生的那样,如果我们从我们的实时数据中获得一个不在训练语料库中的单词,我们将无法计算 TF-IDF 分数。它将被忽略。我们再次看到了数据不匹配问题的重要性。
环境
我们一会儿会谈到它,但基本上我们的 web 应用程序将包含一个 python 脚本,它将被执行并向我们提供结果。因此,正如 NLTK 停用词向量所发生的那样,我们将需要创建一个环境,在这个环境中,脚本可以被执行,并且拥有所有可用的必要依赖项:从基本库(sklearn、numpy 等等)到训练模型、TF-IDF 向量器等等…
用户体验
最后,我们需要关注用户体验。因此,举个例子,如果我们花了 2 分钟从某份报纸上抓取最新的 5 篇文章,我们可能不应该把它作为用户的一个选项。
一旦我们总结了部署模型时需要考虑的所有事情,很明显,只关注在训练集中获得良好的准确性而不考虑所有这些因素会导致我们成为无用的 web 应用程序。
讨论完这些问题后,我们将看看如何用 Dash 创建应用程序,并用 Heroku 部署它。Dash 和 Heroku 有非常好的文档,所以我不会在这里花太多时间讨论技术细节。任何人都可以在几个小时内学会这两种方法,我认为我们一直在讨论的方法学问题更有价值。
Dash web 应用程序的创建
Dash 是一个用于构建 web 应用程序的高效 Python 框架。它是基于 Flask、Plotly.js 和 React.js 编写的,使用起来非常简单,但效果惊人。在 Dash 网页上有一个非常好的教程,它涵盖了从零开始创建一个 web 应用程序,解释了每一个步骤:安装、布局(定义了我们的应用程序的外观)、回调(定义了“发生的事情”)以及一些高级概念,这些概念将让我们按照我们想要的那样构建应用程序。
为了创建 web 应用程序的代码,我们可以在本地执行它,应用程序将显示在浏览器中。通过这种方式,我们可以在部署应用程序之前进行简单的更改并构建我们想要的应用程序。
我的 web 应用程序下的代码可以在这里找到。
在我们准备好代码之后,最后一步是部署应用程序。
与 Heroku 一起部署
有许多平台允许我们部署 web 应用程序。两个好的是 Dash Enterprise 和 Heroku。我使用 Heroku 是因为你可以免费部署一个应用程序(有一些限制),花很少的钱你就可以得到一个全功能的服务器。
同样,Heroku 有一个非常好的教程,可以在这里找到。它一步一步地涵盖了部署应用程序所需的所有内容。
对于这个项目,我通过 anaconda 在 Windows 中部署了这个应用程序。我遵循的步骤是:
# after signing in to Heroku and opening the anaconda prompt
# we create a new folder
$ mkdir dash-app-lnclass
$ cd dash-app-lnclass# initialize the folder with git
$ git init
之后,我们创建一个环境文件( environment.yml ),在这个文件中我们将指出我们将需要的依赖项:
name: dash_app_lnclass #Environment name
dependencies:
- python=3.6
- pip:
- dash
- dash-renderer
- dash-core-components
- dash-html-components
- dash-table
- plotly
- gunicorn # for app deployment
- nltk
- scikit-learn
- beautifulsoup4
- requests
- pandas
- numpy
- lxml
并激活环境:
$ conda env create
$ activate dash_app_lnclass
然后,我们用 app.py,requirements.txt 和一个 Procfile: 初始化这个文件夹
# the procfile must contain the following line of code
web: gunicorn app:server# to create the requirements.txt file, we run the following:
$ pip freeze > requirements.txt
最后,由于我们将使用 nltk 下载(用于停用词和其他功能)和 pickles,我们需要添加 nltk.txt 文件和 Pickles 文件夹。
最后,我们初始化 Heroku,将文件添加到 Git 并部署:
$ heroku create lnclass # change my-dash-app to a unique name
$ git add . # add all files to git
$ git commit -m 'Comment'
$ git push heroku master # deploy code to heroku
$ heroku ps:scale web=1 # run the app with a 1 heroku "dyno"
详细说明可以在这里找到。
一旦我们完成了所有的步骤,我们现在就可以使用我们的 web 应用程序了!可以在这个 链接 中找到。
请注意,此应用程序尚未进行定期维护,因此您可能会遇到一些错误。
最终想法
所以这一系列的文章就告一段落了。我们已经介绍了创建基于机器学习的应用程序的整个过程,从获取训练数据到创建和部署应用程序。我希望它是有用的,并且阐明了面对一个新项目时需要考虑的所有步骤和注意事项。我在这三篇文章中展示了我的想法和建议,它们可以用几个段落来概括:
永远不要忘记你正在追求的目标:机器学习模型确实很棒,但最终,如果它们不能提供一些实用性,它们就毫无价值。因此,重要的是要始终牢记我们为用户提供的是什么工具。
另外,不失去项目的端到端视野也是极为有利的。例如,当我们处于模型训练阶段时,我们需要记住这一步之前的事情,例如当部署应用程序时,数据将如何避免数据不匹配。
希望这些文章是有用的,如果你有任何问题,不要犹豫与我联系!
在 2.0 中使用 TensorFlow Serving + Docker 部署文本分类器
在本教程中,我们使用一个接受原始字符串进行推理的 API 端点来简化模型预测。我们还对模型签名进行了实验,以获得更加可定制的有效负载。
马库斯·温克勒在 Unsplash 上的照片
这里是GitHub repo的全部代码。
大约一年前,我写了Deploy a Keras Model for Text Classification 使用 tensor flow Serving在 TensorFlow 1.X 中部署文本分类器。x 更容易使用,我很难找到我需要的文档,特别是关于部署和迁移 TensorFlow 服务的已弃用的 V1 功能。
我已经收集了我的知识,并将通过一个玩具示例演示模型部署。
如果这是你第一次用 TensorFlow 2。x,我建议学习这个课程来构建、训练和部署模型。
本课程的重点是利用 TensorFlow 2.x 和 Keras 的灵活性和“易用性”来构建、培训和…
click.linksynergy.com](https://click.linksynergy.com/link?id=J2RDo*Rlzkk&offerid=759505.12488204614&type=2&murl=https%3A%2F%2Fwww.coursera.org%2Flearn%2Fintro-tensorflow)
在 TF 1 中,文本预处理是一场噩梦。X …
Sebastian Herrmann 在 Unsplash 上拍摄的照片
特别是 2。x 引入了几个新功能,使得使用文本模型变得更加容易。1 的最大痛点之一。x 是如何处理矢量化层。要求消费者应用程序为我的推理 API 提供向量输入并不总是可行的。
因此,创建了许多丑陋的变通方法来允许模型接受原始字符串。点击这里查看我的标记化/截断/填充回退。
在许多情况下,预测端点必须包装在另一个端点中,以处理预处理步骤。这造成了一种令人讨厌的情况,即预处理逻辑位于两个不同的地方:用于训练模型的模块和将客户机的原始文本转换成向量的包装器。
让我们看看如何在 2.X 中解决这个问题。*
目标:创建一个 API 端点,该端点以原始字符串的形式接受电影评论,并返回评论为正面的概率
这是一个标准的情绪分析任务。为了确保我们构建的解决方案是端到端的:
- 服务端点将负责预处理原始字符串,并为模型对其进行矢量化
- 除了 TensorFlow 服务,我们不会使用任何其他框架
如果你想更进一步,有很多关于将 TensorFlow 模型部署到云平台(如 GCP 或 AWS)的课程和资源。
* [## 基于 GCP tensor flow 的端到端机器学习
由谷歌云提供。在本专业的第一门课程中,我们将回顾机器中涵盖的内容…
click.linksynergy.com](https://click.linksynergy.com/link?id=J2RDo*Rlzkk&offerid=759505.13223275109&type=2&murl=https%3A%2F%2Fwww.coursera.org%2Flearn%2Fend-to-end-ml-tensorflow-gcp)
属国
我建议分叉或克隆我的 GitHub repo 并从那里开始跟进。
本文对每个步骤进行了更详细的解释。如果您只是想让一些东西启动并运行起来,那么可以按照我的 README.md 中的说明来做。README.md 包括如何训练和服务模型的细节。
数据集:IMDB 电影评论
乔恩·泰森在 Unsplash 上的照片
该数据集包含 25,000 条用于训练的高度极性电影评论,以及另外 25,000 条用于测试的评论。每条影评都标注为 0(负面情绪)或 1(正面情绪)。关于数据集的更多信息可以在这里找到。
我们将训练一个二元分类器来预测给定电影评论是正面的概率。
代码
我将在一个ModelTrainer
类中组织我的大部分代码,该类处理模型的端到端训练和部署。让我们一步一步来。
依赖关系
首先,我们加载将要使用的库。我还定义了一个logger
来跟踪培训过程中的重要事件。在较大的项目中,日志记录通常比打印语句更受青睐,因为它更容易跟踪(更容易看到日志来自哪里)、可配置并且更容易存储。
模特教练班
我在这里将模型架构参数定义为属性。在一个更复杂的项目中,将它们移动到一个配置文件中可能更有意义。下面是每个属性所指内容的快速分类:
embed_size
:每个令牌嵌入的维度max_features
:你词汇量的最大值epochs
:训练集的迭代次数batch_size
:一次处理的观察次数max_len
:每次观察的令牌数;较短的长度将被填充,而较长的长度将被截断
稍后我们将讨论tf_model_wrapper
属性。
获取数据
在这个类中,我定义了一个名为fetch_data
的方法,它将通过编程从tensorflow_datasets
下载训练和测试数据。这种下载数据集的方法效率很低。数据集不会保存在任何地方,每次执行脚本时都需要重新加载。
矢量化图层
这是获取原始字符串并将其转换为与我们的模型架构兼容的矢量化输出的层。我们还在这一层中构建了预处理步骤,以便在矢量化之前对原始文本进行预处理。
预处理在custom_preprocessing
方法中定义。我们在这里做三件事:
- 将文本转换为小写
- 在我们的影评中经常出现的脱衣
<br />
- 去除标点符号
在init_vectorize_layer
中返回的TextVectorization
对象将返回一个完全适合的层,该层适应于所提供的文本(这是来自我们的训练数据的电影评论)。除了自定义预处理功能,我们还定义了最大令牌数、输出序列长度和输出模式。
初始化模型
首先,我们创建vectorize_layer
并定义输入类型(单个字符串)。我们通过矢量化层传递原始输入,然后将输出传递给模型架构的其余部分。
我已经把一个简单的 RNN 和一个双向 GRU 层放在了一起。出于说明发球的目的,我没有花太多时间来完善这个模型。我敢肯定,找到一个针对该数据集实现更好结果的模型架构并不困难。
训练模型
我们在train
方法中做的第一件事是使用fetch_data
加载训练数据。在这个玩具示例中,我们将不会加载测试数据,因为我们跳过了模型评估。模型评估非常重要,在更实际的场景中不应该被忽略。
我们使用init_model
方法初始化模型,并通过train_examples
来拟合我们的矢量化图层。接下来是在训练数据上拟合模型。
在这个要点的第 4 行,我们最终通过创建一个新的TFModel
类的实例来定义我们的tf_model_wrapper
对象。该对象的目的是将签名合并到服务模型中。
我将在这里绕道谈论模型签名,以及为什么您可能想要合并它们。
模型签名
TensorFlow 文档上的这个页面解释了签名用于提供“识别函数输入和输出的一般支持,并且可以在构建 SavedModel 时指定”。
签名定义需要指定:
inputs
作为字符串到 TensorInfo 的映射。
outputs
作为字符串到 TensorInfo 的映射。
method_name
(对应加载工具/系统中支持的方法名)。
通过定制输入,我们可以在推理之前加入额外的预处理步骤。通过定制输出,我们可以定制来自服务模型的有效负载。
在本例中,我们将创建一个签名,以便在预测中包含一些有用的元数据。
创建支持签名的包装器
我们将创建一个TFModel
作为模型的包装器。初始化时,TFModel
对象将接受一个tf.keras.Model
并将它保存为一个model
属性。这个初始化步骤非常灵活,可以用来传递额外的参数。
我们使用@tf.function
装饰器定义了一个prediction
方法。这个装饰器将函数转换成可调用的张量流图。input_signature
参数指定将提供给签名的形状和数据类型。这个方法的输出成为我们服务模型时的输出。
我们的服务模型有效载荷将有两个字段:一个包含模型输出的prediction
字段和一个硬编码的description
字段。
对于我们的用例,模型输出相当直观,不完全需要description
。然而,当类标签不清楚或者额外的元数据可能有帮助时,这就变成了一个有用的指示器。
我们还想传递哪些元数据?
世界是你的!这里有一些想法可能会让你以后的生活更轻松。
可听度和再现性
考虑添加有助于调查和重现特定预测的元数据。
- 用于训练该模型的数据集是什么?
- 如果我想在我的机器上重建这个模型,我可以在哪里找到模型资产?
- 用于训练模型的代码在哪里?使用了什么版本的代码(即 Git SHA/pull 请求编号)来训练模型?
解释
你的模型的最终消费者可能不是熟悉机器学习的人。在没有任何解释的情况下传递类别概率和相应标签的列表可能会令人困惑。考虑通过顶部预测和相关概率。
使用
有时,输出反映您的预期用途可能会有所帮助。也许你有一个不同型号的标量输出的阈值?您可以使用元数据来明确您的预期用途。*
部署模型
部署步骤非常简单。我们将模型保存到本地目录,并将serving_default
签名定义为来自我们tf_model_wrapper.
的prediction
方法
实际上拯救了什么?
该模型被序列化为 SavedModel 对象,可用于推理。在此过程中,整个 TensorFlow 会话被导出为包含在单个目录中的语言不可知格式。
该目录具有以下结构:
*assets/
assets.extra/
variables/
variables.data-?????-of-?????
variables.index
saved_model.pb*
- saved_model.pb 定义数据流结构
- 资产是包含所有辅助模型文件的子目录
- assets.extra 是包含由其他库生成的资源的子目录
- 变量是一个子目录,包含用于恢复模型的权重
指定模型版本
默认情况下,TensorFlow 服务将始终为您的模型提供最新版本。“最新”版本是从 SavedModel 目录名推断出来的。对于这个例子,我根据训练时的整数时间戳命名了 SavedModel 目录,因此总是提供最新的模型。
为模型服务
确保您在此步骤之前训练了模型。可以通过在克隆的 repo 的根目录下运行python -m classifier.train
来训练模型。这将运行上述代码。
是时候为模特服务了!确保为这一步安装了 Docker。
- 使用
docker pull tensorflow/serving
获取 TensorFlow 服务图像的最新版本 - 在您克隆 GitHub repo 的根目录中,根据 SavedModel 文件的路径创建一个环境变量。如果你按照自述文件上的说明,这将是
export ModelPath=”$(pwd)/classifier”
- 启动服务器并为 REST API 端点公开端口 8501:
*docker run -t --rm -p 8501:8501 \
-v "$ModelPath/saved_models:/models/sentiment_analysis" \
-e MODEL_NAME=sentiment_analysis \
tensorflow/serving*
会出现一堆日志。每个日志中的第一个字符将指示进程的状态。
- E =错误
- W =警告
- I =信息
下面是最初几行可能的样子。
*docker run -t --rm -p 8501:8501 -v "$ModelPath/:/models/sentiment_analysis" -e MODEL_NAME=sentiment_analysistensorflow/servingI tensorflow_serving/model_servers/server.cc:82] Building single TensorFlow model file config: model_name: sentiment_analysis model_base_path: /models/sentiment_analysis
I tensorflow_serving/model_servers/server_core.cc:461] Adding/updating models.*
*如果每个日志都以 **I、*开头,那么恭喜您——该模型已经成功提供了!
***注意:*让日志淹没你的终端可能有点烦人。使用分离模式,所以它不会这样做。下面命令的唯一区别是增加了一个-d
标志。
*docker run -t -d --rm -p 8501:8501 \
-v "$ModelPath/saved_models:/models/sentiment_analysis" \
-e MODEL_NAME=sentiment_analysis \
tensorflow/serving*
有用的 Docker 命令
这里有两个有用的 Docker 命令,在使用模型服务器时可能会派上用场:
docker ps
-显示哪些 Docker 容器正在运行;这对于获取容器 id 以便进一步操作非常有用docker kill [container id]
-如果您构建了错误的模型,您可以终止当前容器来释放端口并重启服务器
发布请求
既然我们的模型服务器已经在本地机器上启动并运行,我们就可以发送一个示例 POST 请求了。POST 请求可以通过 curl 发送,这是一个用于在服务器之间传输数据的简单工具,也可以通过 Python 中的request
库发送。
样本卷曲命令:
我们通过了“史上最差电影”的评论。
*curl -d '{"inputs":{"review": ["worst movie EVER"]}}' \
-X POST http://localhost:8501/v1/models/sentiment_analysis:predict*
对应输出:
不出所料,“史上最差电影”被认为不太可能是正面评价。
*{ "outputs": { "prediction": [[ 0.091893291 ]], "description": "prediction ranges from 0 (negative) to 1 (positive)" } }*
这次到此为止。希望这篇文章对你有帮助!快乐大厦。
参考
- https://keras . io/examples/NLP/text _ class ification _ from _ scratch/
- https://www.tensorflow.org/api_docs
感谢您的阅读!
通过 Medium 关注我的最新动态。😃
作为一个业余爱好项目,我还在www.dscrashcourse.com建立了一套全面的免费数据科学课程和练习题。
再次感谢您的阅读!📕
使用 Flask 部署已训练的 ML 模型
端到端 ML 项目教程系列的第 2 部分
继我上一篇关于端到端机器学习项目教程的文章之后,我们讨论了构建一个健壮的 ML 模型的主要任务,这篇文章为你提供了一个在 web 上部署 ML 模型的简单快速的解决方案。
这是我们在这里开始的端到端 ML 油耗项目的最后一项任务。
部署应用程序需要什么?
为了部署任何经过训练的模型,您需要以下内容:
- 准备部署的已训练模型 —将模型保存到文件中,以供 web 服务进一步加载和使用。
- 一个 web 服务——为你的模型在实践中的使用提供一个目的。对于我们的燃料消耗模型,它可以使用车辆配置来预测其效率。我们将使用 Flask 来开发这项服务。
- 云服务提供商——你需要特殊的云服务器来部署应用程序,为了简单起见,我们将使用 Heroku(数据工程系列将涵盖 AWS 和 GCP)来完成这一任务。
让我们从逐一查看这些流程开始。
保存训练好的模型
一旦您有足够的信心将经过培训和测试的模型带入生产就绪环境,第一步就是将它保存到. h5 或。使用类似于pickle
的库来绑定文件。
确保您的环境中安装了pickle
。
接下来,让我们导入模块并将模型转储到一个.bin
文件中:
import pickle##dump the model into a file
with open("model.bin", 'wb') as f_out:
pickle.dump(final_model, f_out) # write final_model in .bin file
f_out.close() # close the file
这将把您的模型保存在您当前的工作目录中,除非您指定一些其他的路径。
是时候测试我们是否能够使用该文件加载我们的模型并进行预测了,我们将使用相同的(如 prev blog 中所定义的)车辆配置:
##vehicle config
vehicle_config = {
'Cylinders': [4, 6, 8],
'Displacement': [155.0, 160.0, 165.5],
'Horsepower': [93.0, 130.0, 98.0],
'Weight': [2500.0, 3150.0, 2600.0],
'Acceleration': [15.0, 14.0, 16.0],
'Model Year': [81, 80, 78],
'Origin': [3, 2, 1]
}
让我们从文件中加载模型:
*##loading the model from the saved file*
**with** open('model.bin', 'rb') **as** f_in:
model = pickle.load(f_in)
在vehicle_config
上做预测
##defined in prev_blog
predict_mpg(vehicle_config, model)##output: array([34.83333333, 18.50666667, 20.56333333])
输出与我们之前使用final_model
预测的一样。
开发网络服务
下一步是将这个模型打包到一个 web 服务中,当通过 POST 请求获得数据时,该服务会返回 MPG(英里/加仑)预测作为响应。
我使用的是 Flask web 框架,这是一个常用的用 Python 开发 web 服务的轻量级框架。在我看来,这可能是实现 web 服务最简单的方法。
Flask 只需要很少的代码就可以让您入门,并且您不需要担心处理 HTTP 请求和响应的复杂性。
以下是步骤:
- 为您的 flask 应用程序创建一个新目录。
- 使用 pip 设置安装了依赖项的专用环境。
- 安装以下软件包:
pandas
numpy
sklearn
flask
gunicorn
seaborn
下一步是激活这个环境,并开始开发一个简单的端点来测试应用程序:
创建一个新的文件,main.py
,并导入烧瓶模块:
from flask import Flask
通过实例化 Flask 类来创建 Flask 应用程序:
##creating a flask app and naming it "app"
app = Flask('app')
创建一个路由和与之对应的函数,该函数将返回一个简单的字符串:
[@app](http://twitter.com/app).route('/test', methods=['GET'])
def test():
return 'Pinging Model Application!!'
上面的代码利用了 decorator——一种高级的 python 特性。你可以在这里阅读更多关于装饰者的信息。我们不需要对装饰者有很深的理解,只需要在test()
函数上添加一个装饰者@app.route
就可以将 web 服务地址分配给那个函数。
现在,要运行应用程序,我们需要最后这段代码:
if __name__ == ‘__main__’:
app.run(debug=True, host=’0.0.0.0', port=9696)
run 方法启动我们的 flask 应用程序服务。这 3 个参数指定:
debug=True
—当应用程序遇到任何代码变化时,自动重启应用程序host=’0.0.0.0'
—公开 web 服务port=9696
—我们用来访问应用程序的端口
现在,在你的终端运行main.py
python main.py
在浏览器中打开 URLhttp://0 . 0 . 0 . 0:9696/test将在网页上打印响应字符串:
现在,应用程序正在运行,让我们来运行模型:
创建一个新目录model_files
来存储所有与模型相关的代码。
在这个目录中,创建一个 ml_model.py 文件,该文件将包含数据准备代码和我们在这里编写的预测函数。
复制并粘贴您在第一部分中导入的库和预处理/转换函数。该文件应该如下所示:
在同一个目录中,也放置您保存的model.bin
文件。
现在,在main.py
中,我们将导入 predict_mpg 函数来进行预测,但是要这样做,我们需要创建一个空的__init__.py
文件来告诉 Python 这个目录是一个包。
您的目录应该有这样的树:
接下来,定义将接受来自 HTTP POST 请求的vehicle_config
并使用模型和predict_mpg()
方法返回预测的predict/
路由。
在您的 main.py 中,第一次导入:
import pickle
from flask import Flask, request, jsonify
from model_files.ml_model import predict_mpg
然后添加predict
路线和相应的功能:
- 这里,我们将只接受函数的 POST 请求,因此我们在装饰器中有
methods=[‘POST’]
。 - 首先,我们使用
get_json()
方法从请求中获取数据(vehicle_config ),并将其存储在变量 vehicle 中。 - 然后,我们从
model_files
文件夹中的文件将训练好的模型加载到模型变量中。 - 现在,我们通过调用 predict_mpg 函数并传递
vehicle
和model
来进行预测。 - 我们为预测变量中返回的数组创建一个 JSON 响应,并将这个 JSON 作为方法响应返回。
我们可以使用 Postman 或requests
包来测试这个路由,启动运行 main.py 的服务器,然后在您的笔记本中,添加以下代码来发送带有vehicle_config
的 POST 请求:
import requestsurl = “[http://localhost:9696/predict](http://localhost:9696/predict)"
r = requests.post(url, json = vehicle_config)
r.text.strip()##output: '{"mpg_predictions":[34.60333333333333,19.32333333333333,14.893333333333333]}'
太好了!现在,到了最后一部分,当部署在远程服务器上时,同样的功能应该工作。
在 Heroku 上部署应用程序
要在 Heroku 上部署这个 flask 应用程序,您需要遵循以下非常简单的步骤:
- 在主目录中创建一个
Procfile
——它包含在服务器上运行应用程序的命令。 - 在 Procfile 中添加以下内容:
web: gunicorn wsgi:app
我们使用 gunicorn(之前安装的)来部署应用程序:
Gunicorn 是一个用于 WSGI 应用程序的纯 Python HTTP 服务器。它允许您通过在一个 dyno 中运行多个 Python 进程来同时运行任何 Python 应用程序。它提供了性能、灵活性和配置简单性的完美平衡。
3.创建一个wsgi.py
文件并添加:
##importing the app from main file
from main import appif __name__ == “__main__”:
app.run()
确保从main.py
中删除运行代码。
4.将所有 python 依赖关系写入 requirements.txt:
你可以使用pip freeze > requirements.txt
或者简单地把上面提到的包列表+你的应用程序正在使用的任何其他包。
5.使用终端,
- 初始化一个空的 git 存储库,
- 将文件添加到临时区域
- 将文件提交到本地存储库:
$ git init
$ git add .
$ git commit -m "Initial Commit"
6.创建 Heroku 帐户如果您还没有,请登录 Heroku CLI:
heroku login
弹出页面时批准从浏览器登录:
7.创建烧瓶应用程序:
heroku create <name of your app>
我把它命名为mpg-flask-app
。它将创建一个 flask 应用程序,并会给我们一个应用程序将被部署的 URL。
8.最后,将所有代码推送到 Heroku remote:
$ git push heroku master
瞧啊。您的 web 服务现在已经部署在 https://mpg-flask-app.herokuapp.com/predict 的上了。
同样,通过发送相同的车辆配置,使用request
包测试端点:
这样,您就拥有了构建更复杂的 ML 应用程序所需的所有主要技能。
这个项目可以参考我的 GitHub 资源库:
70 年代和 80 年代车辆油耗预测的端到端机器学习项目。GitHub 是超过 50 个…
github.com](https://github.com/dswh/fuel-consumption-end-to-end-ml)
你可以和我一起开发整个项目:
下一步!
这仍然是一个简单的项目,在接下来的步骤中,我建议你使用一个更复杂的数据集,也许可以选择一个分类问题并重复这些任务直到部署。
数据科学与 Harshit —我的 YouTube 频道
但是如果你不想等待,这里是我的 YouTube 频道上的完整教程系列(播放列表),你可以在这个项目上跟随我。
通过这个渠道,我计划推出几个覆盖整个数据科学领域的系列。以下是你应该订阅频道的原因:
- 这些系列将涵盖每个主题和子主题的所有必需/要求的高质量教程,如数据科学的 Python 基础。
- 解释了为什么我们在 ML 和深度学习中这样做的数学和推导。
- 与谷歌、微软、亚马逊等公司的数据科学家和工程师以及大数据驱动型公司的首席执行官的播客。
- 项目和说明实施到目前为止所学的主题。了解新的认证、训练营以及破解这些认证的资源,例如 Google 举办的 TensorFlow 开发者证书考试。
使用 OpenVINO 部署 AI Edge 应用程序
在我之前的文章中,我已经讨论了 OpenVINO 工具包的基础,OpenVINO 的模型优化器和推理机。在这篇文章中,我们将探索:-
- 计算机视觉模型的类型。
- OpenVINO 的预训练模型。
- 下载预先训练好的模型。
- 使用预先训练的模型部署 Edge 应用程序。
图片:来源
计算机视觉模型的类型
有不同类型的计算机视觉模型用于各种目的。但是三个主要的计算机视觉模型是:-
- 分类
- 目标检测
- 分割
分类模型识别给定图像或图像中对象的“类别”。分类可以是二元的,即“是”或“否”,或者成千上万的类别,如人、苹果、汽车、猫等…有几种分类模型,如 ResNet、DenseNet、Inception 等…
对象检测模型用于确定图像中存在的对象,并且经常在检测到的对象周围绘制边界框。它们还使用分类来识别边界框内对象的类别。您还可以设置边界框的阈值,以便拒绝低阈值检测。RCNN、Fast-RCNN、YOLO 等。是对象检测模型的一些例子。
分割模型在给定图像中执行逐像素分类。有两种不同类型的分段-语义分段和实例分段。在语义分割中,属于同一类的所有对象被认为是相同的,而在实例分割中,每个对象被认为是不同的,即使它属于同一类。例如,如果在一幅图像中有五个人,语义分割模型将把他们都视为相同,而在实例分割模型中,他们都将被不同地对待。优信网、DRN 等…
OpenVINO 中的预训练模型
预训练模型,顾名思义,是已经被训练得具有高精度甚至尖端精度的模型。训练深度学习模型需要大量的时间和计算能力。虽然,创建自己的模型并通过微调超参数(隐藏层数、学习率、激活函数等)来训练它是令人兴奋的。)以达到更高的精度。但是,这需要几个小时的工作。
通过使用预先训练的模型,我们避免了大规模数据收集和长时间高成本培训的需要。了解如何预处理输入和处理网络输出后,您可以将这些内容直接插入到您自己的应用程序中。
OpenVINO 在模型动物园里有很多预先训练好的模型。模型动物园有自由模型集和公共模型集,自由模型集包含已转换为中间表示的预训练模型。xml 和。bin)使用模型优化器。这些模型可以直接用于推理机。公共模型集包含预先训练的模型,但是这些模型不会被转换为中间表示。
下载预先训练的模型
在本文中,我将从开放模型动物园加载“车辆-属性-识别-障碍-0039”模型。
要下载预先训练的模型,请遵循以下步骤(在命令提示符/终端中键入命令):-
- 导航到模型下载器目录
对于 Linux:-
cd /opt/intel/openvino/deployment_tools/open_model_zoo/tools/model_downloader
对于 Windows:-
cd C:/Program Files (x86)/IntelSWTools/openvinodeployment_tools/open_model_zoo/tools/model_downloader
我在上面的命令中使用了默认的安装目录,如果您的安装目录不同,那么请导航到适当的目录。
2.运行下载程序. py
下载器 Python 文件需要一些参数,您可以使用“-h”参数来查看可用的参数。
python downloader.py -h
让我们下载模型,
python downloader.py --name vehicle-attributes-recognition-barrier-0039 --precisions -FP32 --output_dir /home/pretrained_models
- —名称 →型号名称。
- —精度 →型号精度(FP16、FP32 或 INT8)。
- — output_dir →保存模型的路径。
成功下载模型后,导航到下载模型的路径,您将找到。xml“和”。bin "文件的模型。
请参考文档以了解关于该模型的更多细节(输入和输出)。
部署边缘应用
现在,由于我们已经下载了预训练模型,让我们在 Edge 应用程序中部署它。
让我们创建一个文件“inference.py”来定义和使用推理引擎。在我的上一篇文章中,关于推理引擎,我已经使用了不同的函数,但是这里我将定义一个类。
from openvino.inference_engine import IENetwork, IECore**class** Network:
**def** __init__(self):
self.plugin = None
self.network = None
self.input_blob = None
self.exec_network = None
self.infer_request = None **def** load_model(self):
self.plugin = IECore()
self.network = IENetwork(model='path_to_xml', weights='path_to_bin')
### Defining CPU Extension path
CPU_EXT_PATH= "/opt/intel/openvino/deployment_tools/inference_engine/lib/intel64/ libcpu_extension_sse4.so" ### Adding CPU Extension
plugin.add_extension(CPU_EXT_PATH,"CPU") ### Get the supported layers of the network
supported_layers = plugin.query_network(network=network, device_name="CPU") ### Finding unsupported layers
unsupported_layers = [l **for** l **in** network.layers.keys() **if** l **not** **in** supported_layers] ### Checking for unsupported layers
**if** len(unsupported_layers) != 0:
print("Unsupported layers found")
print(unsupported_layers)
exit(1) ### Loading the network
self.exec_network = self.plugin.load_network(self.network,"CPU") self.input_blob = next(iter(self.network.inputs))
print("MODEL LOADED SUCCESSFULLY!!!) **def** get_input_shape(self):
return self.network.inputs[self.input_blob].shape **def** synchronous_inference(self,image):
self.exec_network.infer({self.input_blob: image}) **def** extract_output(self):
return self.exec_network.requests[0].outputs
别糊涂了!我会解释每一个功能。
- init(self):
它是类网络的构造器,在那里我初始化了类的数据成员。
- load_model(self):
顾名思义,它用于加载模型(预训练),在这个函数中我们:-
▹声明了一个 iecore 对象。
▹声明了一个 ienetwork 对象。
▹加载了模型 xml 和 bin 文件。
▹检查了不受支持的层
▹在 iecore 对象中加载 ienetwork 对象。
- 获取 _ 输入 _ 形状(自身):
返回模型所需的输入形状
- 同步 _ 推论(自我,形象):
对输入图像执行同步推理
- 提取 _ 输出(自我):
推理完成后返回模型的输出。
这就是“推论. py”,现在让我们创建一个文件“main.py”。
import cv2
import numpy as np
from inference import Network def preprocessing(image,height,width): ### Resize the Image
image = cv2.resize(image,(width,height)) ### Add color channel first
image = image.transpose((2,0,1)) ### Add Batch Size
image = np.reshape((image,(1,3,height,width))
return image
- 使用 OpenCV 的 resize()调整图像大小时,应该先给出宽度,再给出高度。
- 根据文档,模型首先读取通道,然后读取图像尺寸,但是 OpenCV 首先读取图像尺寸,然后读取通道,所以我使用了 transpose(),首先带来颜色通道。
- 该模型将输入作为(batch_size,color_channels,height,width ),因此我们对图像进行整形,以给出为 1 的“batch_size”。
def main():
### Read the image
image = cv2.imread('path_to_image') ### Declare a Network Object
plugin = Network() ### Input shape required by model
input_shape = plugin.get_input_shape() height = input_shape[2]
width = input_shape[3] ### Preprocess the input
p_image = preprocessing(image,height,width) ### Perform Synchronous Inference
plugin.synchronous_inference(p_image) ### Extract the output
results = plugin.extract_output()
根据文档,模型的输出(结果)是一个字典,其中包含以下信息
- “颜色”,形状:[1,7,1,1] —七种颜色类别的 Softmax 输出[白色、灰色、黄色、红色、绿色、蓝色、黑色]
- “类型”,形状:[1,4,1,1] —跨四个类型类别[轿车、公共汽车、卡车、货车]的 Softmax 输出
由于它是 softmax 输出,我们需要将最大值的索引与颜色和类型进行映射。
color = ['white','grey','yellow','red','green','blue','black']
vehicle = ['car','bus','truck','van'] ### Finding out the color and type
result_color = str(color[np.argmax(results['color'])])
result_type = str(vehicle[np.argmax(results['type'])])### Add details to image
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 1
col = (0, 255,0) #BGR
thickness = 2
color_text= 'color: '+result_color
type_text = 'vehicle: '+result_type
cv2.putText(image,color_text,(50,50), font, font_scale, col, thickness, cv2.LINE_AA)
cv2.putText(image,type_text,(50,75), font, font_scale, col, thickness, cv2.LINE_AA) ### Save the image
cv2.imwrite('path/vehicle.png',image)if __name__=="__main__":
main()
我尝试了两辆车,得到了以下输出:-
来源:作者
好了,大家都到齐了。我希望现在你已经对如何使用 OpenVINO 部署 AI edge 应用程序有了正确的理解。OpenVINO 为多种应用提供了各种预训练模型。尝试实现 OpenVINO model zoo 中可用的不同预训练模型,并创建自己的 edge 应用程序。非常感谢您阅读我的文章。
使用 Python 部署影像分类 Web 应用程序
如何使用 Streamlit 和 Heroku 部署您的机器学习模型
图片来源: Unsplash
毫无疑问,做一个数据科学和机器学习项目,从收集数据开始,处理数据,可视化关于数据的见解,并开发一个机器学习模型来完成预测任务,是一件有趣的事情。更有趣和可行的是,我们可以在本地机器上完成所有这些步骤,然后就可以完成了。
然而,如果其他人可以利用我们的机器学习模型来做有趣和酷的事情,这不是很棒吗?当我们的模型可以进入其他人的手中,他们可以从中做有用的东西时,机器学习的真正魔力就来了。
创建一个 web 应用程序是解决方案之一,这样其他人就可以利用我们的机器学习模型。幸运的是,现在创建一个 web 应用程序非常简单。
如果您正在使用 Python,您可以使用 Streamlit 库在本地机器上创建一个简单的机器学习 web 应用程序。要部署 web 应用程序,使其可供其他人访问,那么我们可以使用 Heroku 或其他云平台。在本文中,我将一步一步向您展示如何使用 Python、Streamlit 和 Heroku 创建自己的简单图像分类 web 应用程序。
如果您还没有安装 Streamlit,您可以通过在提示符下运行以下 pip 命令来安装它。
pip install streamlit
图像分类数据
对于这个图像分类示例,将使用 Laurence Moroney 创建的石头-纸-剪刀数据集。你可以在他的网站上下载数据。总之,石头-纸-剪刀是一个合成的数据集,它包含人们形成石头、纸或剪刀形状的手。总共有 2520 幅训练图像和 372 幅测试图像。
下面是合成图像数据的预览图:
先睹为快石头剪刀布数据集的训练图像
总的来说,本文将涵盖三个步骤:
- 创建第一个 Python 文件来加载数据、构建模型并最终训练模型。
- 创建第二个 Python 文件来加载模型和构建 web 应用程序。
- 使用 Heroku 部署 web 应用程序。
加载数据、构建模型和训练模型
首先,下载训练集和测试集,并将其保存到您选择的目录中。接下来,您需要解压缩它们。将有两个文件夹,一个称为*‘RPS’用于训练图像,另一个称为‘RPS-test-set’*用于测试图像。之后创建一个名为rps_model.py
的 Python 文件来加载数据,建立机器学习模型,训练模型。
加载数据
在构建模型之前,您需要首先使用os
库指定本地机器中训练集文件夹和测试集文件夹的路径。
import ostrain_dir = os.path.join('directory/to/your/rps/')
test_dir = os.path.join('directory/to/your/rps-test-set/')
接下来,我们可以使用 TensorFlow 库中的图像生成器来生成训练集和测试集,并自动标记数据。使用 image generator 的另一个优点是,我们可以“即时”进行数据扩充,通过缩放、旋转或移动训练图像来增加训练集的数量。此外,我们可以将训练集的某一部分拆分为验证集,以比较模型的性能。
from tensorflow.keras.preprocessing.image import ImageDataGenerator def image_gen_w_aug(train_parent_directory, test_parent_directory):
train_datagen = ImageDataGenerator(rescale=1/255,
rotation_range = 30,
zoom_range = 0.2,
width_shift_range=0.1,
height_shift_range=0.1,
validation_split = 0.15)
test_datagen = ImageDataGenerator(rescale=1/255)
train_generator = train_datagen.flow_from_directory(train_parent_directory,
target_size = (75,75),
batch_size = 214,
class_mode = 'categorical',
subset='training')
val_generator = train_datagen.flow_from_directory(train_parent_directory,
target_size = (75,75),
batch_size = 37,
class_mode = 'categorical',
subset = 'validation')
test_generator = test_datagen.flow_from_directory(test_parent_directory,
target_size=(75,75),
batch_size = 37,
class_mode = 'categorical') return train_generator, val_generator, test_generator
在创建了上面的函数之后,现在您可以调用该函数,并使用您之前定义的train_dir
和test_dir
变量传递参数。
train_generator, validation_generator, test_generator = image_gen_w_aug(train_dir, test_dir)
而到了这一步,就已经加载好数据了!
建立机器学习模型
作为一个机器学习模型,如果你愿意,你可以建立自己的 CNN 模型。但在本文中,迁移学习法将被应用。使用来自 ImageNet 的具有预训练权重的 InceptionV3 模型。
但是,由于这个模型非常深,所以使用的模型将一直到称为mixed_5
的层,并且直到这一层的所有权重都是固定的,以加快训练时间。从该图层开始,模型将被展平以连接到密集图层,然后连接到最终的密集输出。mixed_5
之后的所有重量都是可训练的。
from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras.layers import Flatten, Dense, Dropoutdef model_output_for_TL (pre_trained_model, last_output): x = Flatten()(last_output)
# Dense hidden layer
x = Dense(512, activation='relu')(x)
x = Dropout(0.2)(x)
# Output neuron.
x = Dense(3, activation='softmax')(x)
model = Model(pre_trained_model.input, x)
return modelpre_trained_model = InceptionV3(input_shape = (75, 75, 3),
include_top = False,
weights = 'imagenet')for layer in pre_trained_model.layers:
layer.trainable = Falselast_layer = pre_trained_model.get_layer('mixed5')
last_output = last_layer.output
model_TL = model_output_for_TL(pre_trained_model, last_output)
如果您还没有导入 InceptionV3 模型,下载该模型需要几分钟时间。
在这一步,您已经建立了模型!接下来,我们需要训练模型。
训练并保存机器学习模型
现在是我们训练模型的时候了。在训练模型之前,首先需要编译模型。在本文中,优化器将是 Adam,因为我们有一个分类问题,那么我们应该使用分类交叉熵作为损失。对于指标,我们将使用准确性。
编译完模型后,现在我们可以训练模型了。模型训练完成后,我们需要保存训练好的模型。然后,在与 Python 文件相同的目录中,您应该有一个名为“my_model.hdf5”的新 hdf5 文件。
model_TL.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])history_TL = model_TL.fit(
train_generator,
steps_per_epoch=10,
epochs=20,
verbose=1,
validation_data = validation_generator)tf.keras.models.save_model(model_TL,'my_model.hdf5')
现在你已经完成了建模过程。您可以保存并关闭 Python 文件。
创建 Streamlit Web 应用程序
要用 Streamlit 创建一个 web 应用程序,我们需要做的第一件事是创建一个新的 Python 文件,姑且称之为rps_app.py
。在这个 Python 文件中,首先我们需要加载之前保存的训练模型。
import tensorflow as tfmodel = tf.keras.models.load_model('my_model.hdf5')
下一步是编写一个标题和任何其他你想放入你的 web 应用程序的文本。要写标题,只需使用 Streamlit 的write
属性,然后在文本前加上#
。要写一个简单的文本,我们也可以使用write
的方法,然后在不添加#
的情况下继续你的文本
要让用户将自己的图像上传到您的 web 应用程序,只需使用 Streamlit 库中的file_uploader
属性。有关 Streamlit 上其他可用选项的更多详细信息,您可以在 Streamlit API 文档页面 查看。
import streamlit as stst.write("""
# Rock-Paper-Scissor Hand Sign Prediction
"""
)st.write("This is a simple image classification web app to predict rock-paper-scissor hand sign")file = st.file_uploader("Please upload an image file", type=["jpg", "png"])
下一个重要步骤是处理用户上传的图像。该处理步骤包括将图像调整到与训练和验证图像相同的大小。调整图像大小后,加载的模型应该预测该图像属于哪个类别。
import cv2
from PIL import Image, ImageOps
import numpy as npdef import_and_predict(image_data, model):
size = (150,150)
image = ImageOps.fit(image_data, size, Image.ANTIALIAS)
image = np.asarray(image)
img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
img_resize = (cv2.resize(img, dsize=(75, 75), interpolation=cv2.INTER_CUBIC))/255.
img_reshape = img_resize[np.newaxis,...]
prediction = model.predict(img_reshape)
return predictionif file is None:
st.text("Please upload an image file")
else:
image = Image.open(file)
st.image(image, use_column_width=True)
prediction = import_and_predict(image, model)
if np.argmax(prediction) == 0:
st.write("It is a paper!")
elif np.argmax(prediction) == 1:
st.write("It is a rock!")
else:
st.write("It is a scissor!")
st.text("Probability (0: Paper, 1: Rock, 2: Scissor")
st.write(prediction)
之后,您需要将 Python 文件保存在与之前的 Python 文件相同的目录中。
我们现在基本上都准备好了!要检查我们的 web 应用程序的外观,请打开提示符,然后导航到 Python 文件的工作目录。在工作目录中,您可以键入以下命令:
streamlit run rps_app.py
现在,您将从提示中看到,您可以在本地主机上检查您的 web 应用程序。如果你再等一会儿,在你运行你的 Streamlit 应用程序后,一个新的窗口将会马上打开。下面是简单图像分类 web app 的截图。
使用 Heroku 部署您的 Web 应用程序
到目前为止,您已经在本地计算机上构建了 web 应用程序。为了让其他人能够使用你的网络应用,你可以使用 Heroku。
用于部署的附加文件
在部署 web 应用程序之前,除了我们为构建应用程序而创建的 Python 文件之外,我们还需要创建另外三个文件。这三个文件是:
- requirements.txt: 这是我们需要创建的文本文件,用来告诉 Heroku 安装部署我们的机器学习模型所需的必要 Python 包。在本教程中,我们使用了四个 Python 库来构建应用程序:numpy、streamlit、tensorflow 和 pillow。因此,我们需要在这个文本文件中指定这些库的相关版本。
tensorflow==2.0.0
streamlit==0.62.0
numpy==1.16.5
pillow==6.2.0
如果您不确定您正在使用的 Python 库的版本,您可以在您的 Python 环境中使用’***_ _ version _ _ '***属性,或者在 conda 提示符中键入’conda list '。
- setup.sh: 这个文件是处理我们在 Heroku 上的应用的服务器和端口号所必需的。
mkdir -p ~/.streamlit/ echo "\
[server]\n\
port = $PORT\n\
enableCORS = false\n\
headless = true\n\
\n\
" > ~/.streamlit/config.toml
- Procfile: 这是你的配置文件,用来告诉 Heroku 如何以及执行哪些文件。
web: sh setup.sh && streamlit run rps_app.py
现在已经有了这三个文件,将它们放在与 Python 文件相同的目录中。
接下来,让我们跳到 Heroku。
创建您的 Heroku 帐户
如果你已经有了 Heroku 账号,可以跳过这一步。如果你还没有,那么你可以直接去 Heroku 。在那里你会发现一个“*注册”*按钮,点击该按钮并填写必要的信息。之后,你需要用你的电子邮件确认你的新 Heroku 账户。
用 Heroku Git 部署您的 ML 模型
创建好 Heroku 账号后,接下来需要做的事情就是安装 Heroku CLI (命令行界面)。接下来,打开命令提示符,键入以下命令。
heroku login
该命令将引导您使用 Heroku 帐户登录。
接下来,使用命令提示符移动到应用程序文件的目录。在应用程序文件的目录中,键入以下命令。
heroku create your_app_name
您可以根据自己的喜好更改your_app_name
作为应用名称。接下来,您需要通过键入以下命令来启动一个空的 git 存储库。
git init
接下来,您希望将所有应用程序文件提交到刚刚创建的空存储库中。为此,您可以键入git add .
命令,然后您需要通过键入commit
和push
命令来推送它们,如下所示。
git add .
git commit -m "your message"
git push heroku master
现在,您的应用程序文件将通过 Heroku Git 部署到 Heroku,在该过程完成后,您将看到您的 web 应用程序的 URL,可以通过互联网访问。您的 web 应用程序 URL 的格式类似于your _ app _ name . heroku app . com .
下面是一个用 Heroku 部署的简单 web 应用程序的例子。
就是这样!您的影像分类 web 应用程序已部署!
如果想看本教程中 web app 的代码或者其他必要的文件,可以在我的 GitHub 上看到。
使用 JavaScript 部署图像分类器
推断图像分类模型的另一种方式是通过直接部署在静态网站或节点 web 应用中来减少推断时间。
图片来源:novasush.com
使用机器学习模型可能会很有趣。你必须确保你已经设置了硬件和软件优化的管道,然后你的模型就可以投入生产了。但是有时用 image 对后端进行 HTTP 调用,然后在前端返回结果可能是一项单调乏味的工作。如果您使用的是重型模型,并且您的服务器配置较低,那么会有很多限制,比如后期推断。
这就是为什么他们说模型部署是数据科学领域 80%的工作。
金钱大劫案教授说 |来源:imgflip.com
用 JavaScript 进行机器学习
TensorFlow.js ,这是一个开源库,您可以使用 Javascript 和高级层 API,完全在浏览器中定义、训练和运行机器学习模型。如果您是刚接触 ML 的 Javascript 开发人员,TensorFlow.js 是开始学习的好方法。JavaScript 是一种客户端脚本语言,在浏览器中完全在客户端运行机器学习程序会带来新的机会,如交互式 ML。
我们开始吧
我已经在 Keras 上训练了一个简单的猫和狗的分类器。想自己培养模特可以参考我的笔记本档案。我们将使用 tensorflowjs_converter 工具将 Keras (.h5)权重转换为 tfjs 格式。
tensorflowjs_converter 附带了 tensorflowjs python 库,我们来安装吧。
pip install tensorflowjs
使用 tensorflow.js 转换器将保存的 Keras 模型转换为 JSON 格式。(假设重量模型的名称. h5)
创建一个目录来存储转换后的权重并提及其路径(jsweights)
tensorflowjs_converter --input_format=keras ./model.h5 ./jsweights
如果你做的没错,你现在应该有一个名为model.json
的 JSON 文件和各种.bin
文件,比如group1-shard1of10.bin
。.bin
文件的数量将取决于您的模型的大小:您的模型越大,的数量就越大。bin 文件。这个model.json
文件包含了你的模型和的架构。bin 文件将包含模型的重量。
来源:https://novasush.com/blog/images/js_in_action.jpg
让我们开始吧
我们需要创建一个 js 文件,其中包含用于加载模型和从给定图像进行推断的代码。
确保您在文件中为加载model.json
设置了正确的位置。此外,预测函数和模型加载函数应该是异步的。
//classifier.js
var model;
var predResult = document.getElementById("result");
async function initialize() {
model = await tf.loadLayersModel('/weights/catsvsdogs/model.json');
}async function predict() {
// action for the submit buttonlet image = document.getElementById("img")
let tensorImg = tf.browser.fromPixels(image).resizeNearestNeighbor([150, 150]).toFloat().expandDims();
prediction = await model.predict(tensorImg).data();if (prediction[0] === 0) {
predResult.innerHTML = "I think it's a cat";} else if (prediction[0] === 1) {
predResult.innerHTML = "I think it's a dog";} else {
predResult.innerHTML = "This is Something else";
}
}
initialize();
在你的 Html 文件中设置一个图片路径。把路径换成你要预测的图像就行了。你只需要给出一个相对的图像路径。
<img src="./images/courage.jpg">
将这个文件和 tensorflowjs CDN 链接添加到您的 HTML 文件中的</body>
标签之后。
<script src="[https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js](https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js)"> </script>
<script src="/classifier.js"></script>
一旦我们的设置完全就绪,我们就可以加载我们的 Html 页面并检查预测。
注意事项
即使所有的文件都是静态的,我们的 Html 文件仍然需要一个服务器来加载 model.json 文件。就像托管网页一样。最简单的方法是使用 python HTTP 服务器模块,它可以作为静态网页的托管服务器。最好的部分是,我们不需要安装任何额外的库来加载 HTTP 模块。另外,你也可以使用 apache 或 Nginx 这样的托管服务器。对于 windows 用户来说,WAMP 服务器也很有用。
可以使用以下命令在 Html 文件目录中启动 Python HTTP server。
python3 -m http.server
运行上述命令后,您将获得以下输出:
Serving HTTP on 0.0.0.0 port 8000 ([http://0.0.0.0:8000/](http://0.0.0.0:8000/)) ...
在浏览器中打开 URL,查看通过 js 权重预测的图像输出。
这里是我的模型的输出
来源:novasush.com
亲自尝试
这是我这个项目的 GitHub 回购链接。尝试训练和转换重量,然后自己在网站上部署。
JavaScript 中的猫狗分类器训练一个 Keras 分类器并保存其权重安装 tensorflowjs python 库使用…
github.com](https://github.com/novasush/image-classifier-in-javascript)
这是所有的乡亲
再见| novasush.com
参考
[1] Tensorflow.js
[2] 转换器工具的 Tensorflowjs python 库
[3] 猫狗图像分类教程来自 TensorFlow 官方网站
【4】加菲猫人物参考为猫。
勇敢懦弱的狗(我的最爱)
[5] 金钱大劫案人物
和几杯咖啡😉
部署 NLP Web 应用程序:棘手的问题
你是否已经建立了一个很酷的 NLP 模型,并试图部署到 web 上,以便向你的朋友和家人展示你有多酷?如果是这样,那么这篇文章可能会让你感兴趣!
在游戏的这个阶段,你已经完成了 Jupyter,你正在使用你的 Flask 应用程序向人们展示你的模型是多么的平庸。你的应用程序看起来很简单,但在本地可以正常工作。
你现在可能处于这样一个阶段,你已经浪费了无数个小时试图用 Google App Engine 进行部署,结果却放弃了,并开始在 Heroku 上投入无数个小时。这两种解决方案基本上都应该是一行代码,但它们并不适合您。
您最终在 Procfile 中正确地设置了端口,但却遇到了新的障碍。该应用程序将顺利部署,但不会启动,并将抛出 H10 或 H13 错误。“应用崩溃”。本地一切都正常,您已经正确设置了端口,并验证了确实有 Dynos 启动并运行。
您现在已经调试了整个过程,并且您意识到 pickle 文件中有可疑之处。你为什么要加载 pickle 文件?因为这是你保存矢量器和模型的方法。
鉴于这是一个 NLP 应用程序,您至少有一个 pickle 用于您的矢量器(因为您需要对输入文本进行矢量化),至少有一个 pickle 用于您的模型(因为您需要基于来自矢量器的矢量进行预测)。
你开始尝试。你把它拆下来,在没有腌渍文件附带的功能的情况下运行,它就工作了。很好。看来你已经把问题隔离了。pickle 文件一定太大了,或者 pickle 文件可能有某种问题。
到目前为止,您已经通过简单地上传静态文件夹中的 pickle 文件进行了部署。尽管当您在本地运行它时这样做是可行的,但是您决定将它们全部放入 s3 桶中,并在启动时从那里访问它们。
H10 应用程序崩溃
几个小时的调试之后,您发现罪魁祸首实际上只是经过腌制的矢量器。
因为您使用了定制的预处理器和记号赋予器,所以当您加载 pickle 矢量器时,您必须在加载 pickle 的模块中使用这两个函数。
正如用户blckknight在 StackOverflow ( link )上比我更优雅地解释的那样:“Pickle 不转储实际的代码类和函数,只转储它们的名字。它包含了每个定义模块的名字,所以它可以再次找到它们。如果您转储在作为脚本运行的模块中定义的类,它将转储名称__main__
作为模块名称,因为这是 Python 使用的主模块名称(如if __name__ == "__main__"
样板代码所示)。”
这很有道理,但你已经知道这一点,因为你在最初构建应用程序时已经处理过这个问题。当问题最初出现时,由于 IDE 中更好的错误追溯,您无需任何谷歌搜索就能进行调试。因此,在主应用程序模块中已经有了预处理程序和标记器函数。为什么这他妈的又成问题了?
我不清楚具体是如何和为什么,但我清楚的是你的主文件——你运行 Flask 应用程序的那个——不是 Heroku 服务器作为 main 运行的。这意味着当你加载你的 pickled 矢量器时,它会寻找类 main。我的 _ 预处理器,它找不到。
现在,解决方案非常简单,在上面提到的论坛帖子中有概述:重新拾取矢量器,但这次是通过导入预处理器,并且从一个可访问的位置将标记器函数从文件中取出。
现在
您可能会注意到,当您处理这些不同的文件时,模型将占用大约 50Kb,然而,您的矢量器可能会占用大约 500Mb。只是重申一下:您的矢量器可能是 500Mb +!这是疯狂的,将挫败任何部署这种模式的企图。
我在 BrainStation 的一位导师的帮助下找到了下一个技巧,在此之前,我尝试了几天不同的部署方法,最终建立了我自己的 Linux 服务器。事实证明,与大多数代码相关的问题一样,解决方案实际上一直摆在我面前。
在所选矢量器(在我的例子中是 tfidf)的文档页面上的一个小部分中,有一个小注释,说明默认情况下,由于某种不为人知的原因,fit 矢量器将所有停用词(在这种情况下,不仅是常规停用词,实际上还有所有未包含在矢量化中的标记)作为属性存储。
完整注释声明:“酸洗时,stop_words_
属性会变大并增加模型尺寸。此属性仅用于自检,可以使用 delattr 安全删除,或者在酸洗前设置为 None。
在我的例子中,如上所述,完整的 pickle 文件大约有 500Mb。由于没有逻辑原因而作为属性存储的无用令牌列表被删除后,它下降到大约 200Kb。那是 3 个数量级。
这是一个很小的腌渍错误案例,但我希望它能帮助人们不像我一样用头撞墙几个小时。
#泡菜# TFIDF # Heroku #烧瓶#NLP
使用 Kubernetes 部署 BERT
谷歌云平台,Docker,微服务,NLP
伯特:形象信用
**简介 **
BERT 是 Google 广泛使用的 NLP 模型。2019 年被认为是 BERT 年,取代了大多数生产系统。BERT 使用基于自我关注的方法,该模型本身由变压器块组成,变压器块是一系列自我关注层。与基于 RNN 的序列对序列模型相比,BERT 证明了自我注意的使用导致了更优越的性能,特别是在 Stanford 问答数据集(SQUAD)上。我们已经跳过了所有的理论细节,如 RNN,LSTM 模型,自我关注,因为它们在吴恩达课程和博客文章s herehere(作者 Jay Alammar)的课程中会讲到。另一个很棒的帖子提供了基于 BERT 的主要模型。请注意,注意力机制最初被应用于改善基于 RNN 的序列对序列模型的性能。Lilian Weng 也发表了一篇关于注意力机制的概述,她在其中解释了 transformer 架构。特别是键、值和查询概念,其中键和值相当于编码器输出,即存储器,而查询是解码器输出,然而,作为原始论文,它们是位抽象的,并且作用于所有字。ukasz Kaiser 解释了为什么它们更有效和高效的原因
从实现的角度来看,BERT 是一个拥有 1.1 亿或更多参数的大型模型,从头开始训练非常具有挑战性,正如 Google 的博客中所强调的。它需要有效的计算能力,模型结构必须仔细编程以避免错误。因此,为了使 BERT 模型易于使用,谷歌开源了它的实现,它可以在大约 30 分钟内微调到各种任务。一个例子是情绪分析任务,正如这里的所解释的。限制参数数量的研究工作正在进行中。然而,微调 BERT 也是广泛使用的方法。
目标
这篇文章的目标是部署一个经过训练的 BERT 模型,作为一个微服务,对流媒体 tweets 进行情感分析。这个简单的例子揭示了为 ML 开发微服务的关键挑战。目标是涵盖强调训练和部署 ML 模型的高级工具需求的关键概念。这篇文章中涉及的主要任务是
- 流数据(tweets)的数据预处理:就 ETL 而言,真实世界的系统要复杂得多
- 使用经过训练(微调)的 BERT 模型进行推理
训练模型需要额外的考虑,以供审查和保留。这些将在另一篇文章中讨论。
我们的架构如下
采用的技术有(通过相关的 python API)
- 伯特,张量流,张量流服务,雷迪斯,
- 容器:Docker 容器和用于编排的 kubernetes
Docker 和 kubernetes 的背景信息
我们将开发微服务,使用容器部署它们,并使用 K8S 来管理这些容器。简而言之,容器是将代码和依赖项打包在一起独立运行的抽象。如果你不熟悉容器,请查看 docker 网站获取更多信息和教程。Kubernetes (K8S)由 Google 开发,用于管理多个容器,它可以在本地计算集群或云上运行。所有主要的云提供商都支持 Kubernetes。这篇文章需要的主要 Kubernetes 概念如下
#Create deployment/pods
kubectl create -f tensorflowServing.yaml #Delete deployment/pods
kubectl delete -f tensorflowServing.yaml#Check pods and service
kubectl get pods
kubectl get svc#Check persistance volume and persistance volume cliam
kubectl get pv
kubectl get pvc
这里的和这里的提供了对这些概念的快速概述,而 youtube 的播放列表提供了对这些概念的更详细的阐述。微软也开发了好的资源来开始 K8S。谷歌提供的资源是广泛的,最初可能有点令人不知所措。一旦你对 K8S 的概念有了概念,并尝试“你好世界”这里。它涵盖了流程,我们需要遵循相同的流程,几次!!!
文档中提到的过程如下
- 将您的应用程序打包成 Docker 映像
- 在您的机器上本地运行容器(可选)
- 将图像上传到注册表
- 创建一个容器集群
- 将您的应用部署到集群
- 通过服务向集群外部公开您的应用
- 扩展您的部署
回到我们的微服务
- 我们的第一个微服务使用 tensorflow-serving 和经过训练的保存模型运行 BERT,允许我们使用客户端执行推理
- 第二个微服务使用 gRPC 客户端通过“请求”BERT 来执行情感分析,并将其发布到 Redis 发布/订阅频道
如果你正在使用 GCP,我们假设你已经在你的机器上安装了 gcloud,kubectl 并连接到名为“kubernetes”的项目,更多信息请参见这里。对于其他设置,我们假设存在等效性。
我们首先通过命令行创建并连接到 GCP 的 kubernetes 集群
创建
**gcloud** beta container — project “kubernetes” clusters create “standard-cluster-1” — zone “us-central1-a” — no-enable-basic-auth — cluster-version “1.13.11-gke.14” — machine-type “n1-standard-1” — image-type “COS” — disk-type “pd-standard” — disk-size “100” — scopes “https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" — num-nodes “3” — enable-cloud-logging — enable-cloud-monitoring — enable-ip-alias — network “projects/kubernetes/global/networks/default” — subnetwork “projects/kubernetes/regions/us-central1/subnetworks/default” — default-max-pods-per-node “110” — addons HorizontalPodAutoscaling,HttpLoadBalancing — enable-autoupgrade — enable-autorepair
连接
**gcloud** container clusters get-credentials standard-cluster-1 — zone us-central1-a — project kubernetes
对于数据存储,我们使用谷歌云磁盘,模型是存储在一个单独的位置
**gcloud** beta compute disks create redis-disk-gce — project=kubernetes — type=pd-standard — size=100GB — zone=us-central1-a — physical-block-size=4096
我们在这个设置中使用 redis 在微服务之间进行通信。Redis 被用作发布/订阅消息传递。有必要在集群上运行健壮的 redis 微服务。我们可能面临的一个问题是万一 redis 崩溃。Kubernetes 能够检测崩溃并创建一个新的容器,即 redis 实例来维护服务。然而,当重新创建容器时,新容器可能具有不同的状态。因此,为了避免这种情况,我们使用了持久性磁盘(一个专用的存储磁盘),它通过使用持久性卷声明将这个存储链接到我们的 Redis 容器。这是一个非常简单的设置,在企业级别,要实现扩展,我们需要使用有状态集合。关于它的详细讨论可以在这里找到,而示例 redis 配置可以在这里找到。
在我们的设置中,有一个 redis 实例,我们使用 google 云盘通过 yaml 文件创建一个持久性卷和持久性卷声明。我们通过 redis 容器中的持久性卷声明的方式在 make use storage 中使用这些,如 ymal 文件中所概述的。我们还通过 kubernetes 服务向外部世界公开 redis。
服务张量流模型
通过使用 tensorflow 服务 API,在 kubernetes 中服务 tensorflow 模型非常简单。这些步骤如下
- 从张量流图中收集输入(“sinputs”)和输出(“soutput”)变量的列表
- 在保存模型之前创建预测签名
- 使用保存模型格式保存模型
我们将训练好的模型复制到 tensorflow 服务 docker 映像,使用我们的模型创建新的 docker 映像,并上传到容器注册表,使用此处列出的流程。我们的 docker 映像是 gcr.io/kubernetes-258108/bert.的我们通过 kubenetes 部署来部署这个映像。我们还创建了 kubernetes 服务。
注意:使用通过“kubectl”获得的服务 IP 地址,让我们的集群之外的客户端发出请求。为了避免使用 IP 地址,需要使用 kube-dns 发现服务,这是有据可查的,这里有一个 python 示例。因为我们已经为 bert 推断客户端配置了服务,并且可以使用服务名“bertservice:8500 ”,所以 8500 是端口,因为我们是在集群中发出请求的。
在客户端发出请求的关键代码组件如下,它们基于 google client 示例。
推理客户端可用的完整示例如下。它由 Tweepy 流监听器组成,用于订阅 tweets 主题和 redis sub/pub 消息服务
Bert 推理客户端使用 gRPC 请求客户端
我们使用一个docker 文件将这个客户端打包在 docker 容器中,并部署在我们的 kubernetes 集群上
要为 python 容器创建的 docker 文件
现在,我们可以通过连接到 redis pods 或使用 python 订阅者,通过 kubectl 来观察带有情感的流推文
***kubectl exec -it redis-pod-name redis-cli
127.0.0.1:6379> SUBSCRIBE STREAM***
注意:我们不使用 GPU 进行推理,因此标准 N1 计算资源上的 gRPC 请求需要大约 12 秒(对于 20 个批处理大小)
关闭思绪
我们能够在 GCP 集群上部署此设置 3 天,没有发生任何事件。这展示了 ML 的容器和简单应用程序的威力,并且可以很快部署。然而,在现实世界中,情况完全不同。例如,ETL 可能是一项非常复杂的任务,可能需要 rabbit-MQ、Kafka 或 Apache beam 等高级技术来集成来自其他来源的数据。我们可能需要重新培训和重新部署 ML 模型。这些在另一篇博文中有所涉及。结合起来,这些应该提供开发微服务的介绍,并强调对其他技术的需求,如 Kubeflow、Apache Airflow、Seldon、helm charts,用于使用 kubernetes 基础设施开发 ML 应用程序。我们还没有讨论如何使用 Kubernetes 扩展我们的微服务。一种方法是利用复制集,但根据我们需要的任务和规模,可能会有一些考虑。例如,OpenAI 在最近的博客帖子中记录了将 kubernetes 扩展到 2500 个节点的挑战。
git 回购:这项工作可以在这里找到
在 Heroku 上部署 Dash 或 Flask web 应用程序。简易 CI/CD。
在笔记本电脑上开发 python web 应用非常棒。让每个人都能接触到它更令人满意。今天,我们将了解如何在 GitHub 的 Heroku 平台上轻松部署 python web 应用程序。
首先,我们将把我上一篇文章中构建的动画散点图转换成一个基本的 Dash 应用程序,然后我们将评估 CI/CD 概念,最后,我们将从这个 GitHub repo 在 Heroku 上部署应用程序。
情节动画散点图
构建应用程序
Dash 是构建在 Flask 和 Plotly 之上的 Python 框架,旨在制作数据驱动的 web 应用。多亏了 plotly,它提供了一些基本的图表,如直方图和饼状图,它还附带了许多高度可参数化的控件,如下拉菜单、复选框、日期滑块等等。
让我们从创建一个只有一个标题的非常基本的应用程序并运行它开始。
Dash 的“Hello World”脚本
把标题改成“你好,世界!”,我们会在这里找到最基本的 dash 应用程序。对于了解 Flask 的人来说,直到现在看起来都很像。
基本 Dash 应用程序—渲染界面
让我们用散点图来填充空白页。由于本文的目的是 Heroku 部署,我们将假设数据准备已经完成,并使用pickle
模块存储在dictionnary
中。如果你对此感到好奇,这里有一些有用的资源:
App 的基本结构
现在我们有了一个漂亮的标题,关于疫情的指标,以及生动的散点图。
仪表板应用
注意:这个应用程序并不旨在展示 Dash 及其回调函数的强大功能。这是一个非常基本的应用程序,主要用于演示如何在 GitHub 的 Heroku 上进行部署。
既然我们已经准备好了应用程序,我们就可以部署它了。为了做到这一点,我们将使用 Heroku 平台,但是让我们从发现集成和持续部署的概念开始。
CI/CD
这是什么意思?您可能听说过 GitLab CI/CD、Circle CI、Travis CI 或任何其他包含这些字母的工具。但这意味着什么呢?
CI/CD ,或持续集成/交付和持续部署,专注于小增量变更的快速发布和整个开发过程中自动化的使用。在 DevOps 的核心,CI/CD 工具是其成功的关键。以下是这些概念的一些定义。
使用 Github 和 Heroku 的 CI 管道
**持续集成:**使用 CI,开发人员尽可能频繁地将他们的代码变更合并到回购的主分支中。一旦变更得到验证,就会运行自动化的构建和测试流程来验证变更的准确性。在开发周期中尽可能早地发现缺陷。测试自动化是持续集成的关键,以确保在集成到主分支时,新的提交不会破坏应用程序。
连续交付:它是 CI 的一个扩展,软件的设计、配置和参数化的方式使得它可以在任何时候自动投入生产。
持续部署:它比持续交付更进一步,通过每次变更自动协调应用程序向客户的部署。通过加速客户反馈循环,收益是巨大的——在软件质量、项目期限、结果和开发成本方面。
赫罗库
Heroku 是一个云平台即服务(PaaS),为 web 应用部署提供服务器。它支持 Python 中的几种技术,提供 CI/CD 服务,并有一个“免费和爱好”计划,这使它成为一个非常方便的工具,可以与客户和朋友分享您的 POCs 或其他个人项目。
Heroku 运行时:从你的代码到你的最终用户(来自 Heroku 网站)
如前所述,我们将使用 CI/CD: 我们将把我们的应用部署映射到 GitHub repo 主分支上的任何推送。这意味着小的修改应该在另一个分支上完成(例如develop
分支)。当修改被批准后,我们将把develop
分公司合并到master
分公司。此操作将触发 Heroku,并根据您的新代码运行应用程序的新构建/部署。
先决条件
当 Heroku 检查您的回购协议时,它会自动检测使用的技术(在我们的例子中是 Python)。但是,要运行应用程序,需要遵循一些说明:
- 您需要从
app.py
文件运行您的应用程序,并且该文件需要位于 repo 的根目录下。任何其他尝试都将导致以下消息和部署崩溃。
使用 index.py 而不是 app.py 作为主文件会导致崩溃
- 你需要使用 Procfile,它会被 Heroku 查找。它是一个单行文件,必须命名为
Procfile
,包含启动网络服务器web: gunicorn app:server.
的指令 - 如果您为您的项目使用了任何库,您应该在一个
requirements.txt
文件中指定它们。Heroku 在每次构建开始时运行一个pip install -r requirements.txt
。如果任何使用的包不在该文件中,部署将会崩溃。为了确保您不会忘记任何包,您可以在项目的根目录下使用 Linux 命令pip freeze > requirements.txt
,它将生成包含所有需要信息的文件。 - 重要提示:除了你的库之外,你还必须在你的需求文件中添加
gunicorn
包。 - 当然,应用程序的代码需要没有错误!
既然您已经为项目的部署做好了准备,让我们开始最终的部分部署吧!
首次部署
下面是实例化应用程序的持续部署并实现其首次发布的步骤。
- 注册并登录 Heroku 。当它完成后,你将登陆到你的个人仪表盘,现在是空的。
- 点击右上角的“新建”按钮和“创建新应用程序”
- 您现在可以输入您的应用程序名称。它会自动告诉你它是否可用。由于“covid”和各种“covid19”、“新冠肺炎”或“covid_19”已经被占用,我在这里选择“新冠肺炎-世界地图”。您还可以选择您的应用程序将托管的地区:美国或欧洲。通常的选择是从你的用户中选择最接近的;)!
- 点击“创建应用程序”进入下一个屏幕,并关联您的回购。
- 无需为单个应用程序添加管道
- 是时候选择部署方法了。Heroku 提供了一个 CLI(命令行界面)工具,用于从您的终端设置部署。但是我们想从界面配置它,然后选择“连接到 GitHub”
- 由于这是第一次,您需要登录您的 GitHub 帐户。
- 然后,您可以选择 repo to 并单击 connect。几秒钟后,您将能够选择与持续部署相关联的分支。最佳实践是选择
master
分支。 - 选中“部署前等待配置项通过”选项,然后单击“启用自动部署”。
- 当更新您的分支时,它现在将运行新的构建和部署。您还可以选择要立即部署的分支。
神奇的事情发生了:几秒钟后,构建和部署就完成了。你可以连接你的应用!
附加说明
- 现在,每当您通过推送提交或合并请求来更新您的主分支时,应用程序都会重新构建!
- 有时部署过程会失败。这并不有趣,但它确实发生了。你有两个工具来帮助你:日志和控制台。你可以在 Heroku 的应用程序页面点击右上角的按钮**“更多”来访问它们。通过日志,您可以了解失败的原因和原因,但如果您仍然不明白为什么您的应用程序不能正确运行,您可以通过控制台进入虚拟机来检查您的文件。**
- 现在,你已经订阅了 Heroku 免费计划。这足以满足我们的需求,但是有一个限制:几个小时不使用应用程序之后,服务器将关闭。这不是一个真正的问题,尽管这意味着下一个用户使用它时,他必须等待服务器启动,并且第一次加载可能会稍长一些。如果你知道你需要展示你的作品,提前几分钟查看网址是个好主意,这样可以避免这种延迟效应。
结论
您已经在 Heroku 上部署了您的第一个 dash 应用程序,现在只要您修改了代码,只需将您的代码推送到 GitHub,您就可以让全球的任何人都可以看到它。我希望你喜欢它!现在轮到您在 Heroku 上部署基本的(甚至复杂的)web 应用程序了!
下一次我们将探索如何使用 Docker-Compose 通过 Docker 部署 dash 应用程序!敬请期待:)
提醒一下,GitHub 上有完整的代码。此外,您可能已经注意到了 logzero 包在代码中的使用!我真的很喜欢这个软件包及其在控制台中彩色打印报表的能力。我建议你看看并阅读这篇文章,在这篇文章中我解释了为什么你应该在你的 DS 项目中使用它。
使用 AWS 为机器学习部署仪表板
包含 AWS CloudFormation 模板和代码示例。
我们都在努力开发有用的机器学习模型。在花费大量精力进行数据准备和模型开发之后,我们希望我们的模型能够对商业和更广阔的世界产生积极的影响。尽管成功取决于模型性能,但以清晰有效的方式传达模型预测同样重要。大多数机器学习应用程序都可以从拥有仪表板界面中受益。
拥有仪表板有什么好处?
仪表板是一个图形用户界面,显示与特定业务目标或流程相关的信息,这也可以包括机器学习模型预测。对于终端用户来说,使用可视内容通常要容易得多,而且根据定义,仪表板是可视的。与表格数据不同,肉眼可以快速识别出模型预测中的趋势、异常值和其他模式。一些机器学习任务本质上是可视的(例如物体检测),而其他任务可以用图表(例如时间序列预测)和地图(例如空间-时间预测)来显示。甚至可以为简单的分类任务创建引人注目的仪表板视觉效果,只需以不同的方式汇总预测即可。有了设计良好的仪表板,最终用户可以做出更明智、更快速的决策。
让用户能够通过仪表板与模型及其预测进行交互,通常会增加对模型的信任,并导致模型的更广泛采用。除此之外,仪表板是当今企业中非常常见的使用模式,这种熟悉感鼓励了进一步的采用。即使最终产品中没有使用仪表板,它们也是在开发周期早期收集反馈的宝贵工具。
图 1:使用该解决方案部署的示例仪表板。
应该使用什么仪表板服务或工具?
随着仪表板的流行,有大量的服务和工具可供选择也就不足为奇了。选择合适的工作将取决于你的具体要求,但有两大类。
- 托管仪表盘服务:如亚马逊 QuickSight 和 Kibana 。
- 自定义仪表盘工具:如流线型、面板和仪表盘。
一般来说,如果您需要数据库集成、用户管理和可扩展性,并且可视化选项足以满足您的特定使用情形,您应该选择托管仪表板服务。当您需要额外的定制级别(在视觉和用户界面上)时,您应该选择定制仪表板工具。
我们的例子使用了 Streamlit,因为它简单、灵活,并与各种各样的可视化工具集成,如牛郎星、散景和 Plotly 。不过,和往常一样,也有权衡。定制仪表板工具的部署可能比托管服务工具更复杂,因为您需要处理数据库集成、用户管理和可扩展性。
部署的解决方案是什么?
在这篇文章中,我们将对这个问题给出一个全面的回答,并深入探讨一些可能被忽略的重要细节。我们将首先考虑在 Amazon EC2 上部署我们的定制仪表板。添加一些额外的需求(比如安全性、身份验证和可伸缩性),然后我们讨论一个更全面的仪表板部署架构。
不仅仅是理论,我们还包括了一个用于仪表板开发和部署的可定制解决方案。一个 AWS CloudFormation 模板被共享,这样你只需点击几下鼠标就可以在你自己的 AWS 账户中创建所有需要的资源。您可以选择部署两个示例仪表板应用程序之一:“纽约市的优步皮卡”(一个独立的示例)和“ DistilGPT-2 文本生成”(一个与机器学习模型交互的示例)。所有代码都是可定制的。我们已经采用了集装箱化的方法(使用 Docker),因此您可以将该解决方案与一系列定制的仪表板工具一起使用。
🐙:点击这里查看 GitHub 上的代码
🚀:点击此处启动 AWS CloudFormation 堆栈
最小方法
简化 AWS 上的 it 部署的最简单的方法之一是使用亚马逊 EC2 。您可以在 Amazon EC2 实例(即 AWS 云中的虚拟服务器)上部署您的仪表板,并让仪表板用户连接到该实例。如果你需要为你的仪表板使用深度学习模型,你可以在 GPU 实例上使用 AWS 深度学习 AMI 。在 Amazon EC2 上部署时,您应该问自己以下问题:
谁可以访问应用程序,如何将访问权限限制在特定的个人?敏感通信是否被 HTTPS 加密了?如果服务器崩溃会发生什么?谁将在实例上安装错误修复和安全更新?如果用户数量随着时间的推移大幅上升和下降,会发生什么情况?该实例能处理高峰流量吗?模型和应用程序的更新呢?这样的例子不胜枚举。
因此,尽管这种方法在架构上很简单,但是根据您的用例,有许多因素会使事情变得更复杂。我们现在来看一种替代方法,它使用许多其他 AWS 服务来帮助我们实现全功能部署。
综合方案
在这种方法中,我们有 3 个中央 AWS 服务: Amazon SageMaker 、 Amazon ECS 和 Amazon Cognito 。Amazon SageMaker 是为无缝模型训练和部署而设计的,它也非常适合仪表板开发。亚马逊 ECR 和 ECS 是集装箱部署的完美补充。Amazon Cognito 专门从事简单安全的身份验证。结合这些 AWS 服务,我们最终得到了图 2 所示的架构。然后我们将直接进入细节。
图 2:使用的 AWS 组件的架构。其中一些是可选的。
使用亚马逊 SageMaker
当涉及到构建、训练和部署机器学习模型时,亚马逊 SageMaker 简化了体验。几分钟之内,您就可以旋转 Jupyter 笔记本电脑,并开始在专用和完全托管的基础架构上部署模型。开箱即用,您可以访问许多预构建的 Conda 环境和 Docker 容器。在“DistilGPT-2 文本生成”示例中,预构建的 PyTorch Docker 容器用于在 ml.c5.xlarge 实例上部署来自 transformers 的 DistilGPT-2 模型。Amazon SageMaker 然后提供了一个简单的 HTTP 端点来与部署的模型进行交互。我们的示例应用程序使用[invoke_endpoint](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker-runtime.html?highlight=invoke_endpoint#SageMakerRuntime.Client.invoke_endpoint)
方法(来自[boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)
)来调用文本生成模型。
import boto3
import jsondata = {
'text': 'In a shocking finding',
'parameters': {
'min_length': 100,
'max_length': 200
}
}sagemaker_client = boto3.client('sagemaker-runtime')response = sagemaker_client.invoke_endpoint(
EndpointName='text-generation',
ContentType="application/json",
Accept="application/json",
Body=json.dumps(data)
)body_str = response['Body'].read().decode("utf-8")
body = json.loads(body_str)print(body['text'])
# In a shocking finding, scientist discovers a herd of unicorns...
Amazon SageMaker 也可以用于仪表板开发。部署模型后,可以直接在笔记本实例上构建和测试仪表板。为了简化应用程序部署,采用了容器化的方法,但是在编辑文件时,您仍然可以获得实时重新加载的所有好处(由于有了本地卷挂载)。当在 Amazon SageMaker 笔记本实例上运行 dashboard 容器时,您可以通过以下经过身份验证的 URL 上的 jupyter-server-proxy 来访问它:
[https://{NOTEBOOK_URL}/proxy/8501/](https://sagemaker-dashboards-for-ml2-notebook.notebook.us-west-2.sagemaker.aws/proxy/8501/)
当你在 Amazon SageMaker 上完成应用程序开发后,你可以将你的容器推送到Amazon Elastic Container Registry(ECR)。与 Docker Hub 类似,它为您的 Docker 图像提供了一个存储库,但它将图像保存在您的 AWS 帐户中,以获得额外的安全性和可靠性。
docker tag {IMAGE_NAME} {DASHBOARD_ECR_REPOSITORY_URL}:latest
docker push {DASHBOARD_ECR_REPOSITORY_URL}:latest
使用亚马逊 ECS
您的 dashboard Docker 图像现在在 Amazon ECR 上,但是应用程序实际上还没有运行。亚马逊弹性容器服务 (ECS)是运行 Docker 容器的全托管服务。您不需要供应或管理服务器,您只需定义需要运行的任务并指定任务所需的资源。我们的示例 任务定义声明 dashboard Docker 容器应该使用单个 vCPU 和 2GB 内存运行。我们的示例 服务同时运行并维护任务定义的指定数量的实例。因此,为了提高可用性,您可以使用 AWS CLI 将服务的期望任务计数设置为 2:
aws ecs update-service \
--cluster {DASHBOARD_ECS_CLUSTER} \
--service {DASHBOARD_ECR_SERVICE} \
--desired-count 2
使用 Amazon ECS 服务的一个主要优点是,它不断地监控任务的健康状况,并替换由于任何原因而失败或停止的任务。亚马逊 ECS 服务还可以自动扩展任务数量(即自动增加或减少),以应对高峰时期的高需求,并在低利用率期间降低成本。我们的示例解决方案还包括一个应用负载平衡器,它在任务间分配流量,与Amazon Certificate Manager(针对 HTTPS)集成,并通过 Amazon Cognito 认证流量。
使用亚马逊认知
当您的仪表板的内容是私有的时,Amazon Cognito 可用于限制某一组用户的访问。尽管该组件是可选的,但在解决方案中默认情况下是启用的。您可以与社交和企业身份提供商(如谷歌、脸书、亚马逊和微软 Active Directory)集成,但该解决方案会创建自己的用户池,其中包含特定于应用程序的帐户。您只需要在堆栈创建过程中提供一个电子邮件地址来接收临时登录凭证。
图 3: Amazon Cognito 登录
当 Amazon Cognito 身份验证启用时,您将在首次尝试访问应用程序时看到托管登录页面。使用临时登录凭据,然后输入该帐户的新密码。成功登录后,您将能够看到您的仪表板。
摘要
有时,机器学习的仪表板可以直接从您的开发机器上展示。但是,当您需要与世界其他地方(或您的公司内部)共享您的仪表板时,就需要一种健壮且安全的方法。
我们走过了一个可以帮助解决这个问题的解决方案:Amazon SageMaker 用于简化机器学习模型部署,Amazon ECR 和 ECS 用于运行和维护仪表板服务器,Amazon Cognito 用于控制仪表板访问。AWS CloudFormation 可用于在您自己的 AWS 帐户中自动创建解决方案的所有 AWS 资源,然后您可以根据需要定制解决方案。
🐙:点击这里查看 GitHub 上的代码
🚀:点击此处启动 AWS CloudFormation 堆栈