admin管理员组

文章数量:1645531

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

DETR:使用变压器的端到端对象检测和 Python 实现

原文:https://towardsdatascience/detr-end-to-end-object-detection-with-transformers-and-implementation-of-python-8f195015c94d

变压器架构的使用不仅在速度方面提供了优势,而且在一些特定类型的对象检测问题方面也提供了优势

在脸书的研究团队发表的“DETR:用变形金刚进行端到端的物体检测”论文中,最新的变形金刚技术被用于物体检测问题。这种算法比传统的目标识别技术有许多优点。通过使用这种算法,在本文的后面阶段已经用 python 解决了一个示例对象检测问题。

托古列夫的 Unsplash

通过在目标检测问题中使用不同的方法,已经产生了许多解决方法。在第一种方法中,存在由用于检测目标对象的分类和回归阶段组成的两阶段架构。在第一阶段,使用选择性搜索或区域提议网(RPN)来生成区域提议。之后,执行分类和回归过程。R-CNN、快速 R-CNN 和更快 R-CNN 是该架构最知名的算法。虽然这些算法的准确率很高(特别是对于微小的物体),但在速度上并没有达到理想的水平。在另一种方法中,目标检测在单个阶段中完成。这种方法不使用选择性搜索或 RPN。存在用于对象检测过程的单个神经网络模型。虽然这是一种比第一种方法快得多的技术,但它在检测小尺寸物体方面的性能相对较差。

2020 年,脸书研究团队在一篇名为“利用变压器进行端到端物体检测”的文章中介绍了一种新技术。据宣布,一种新的对象检测模型是使用变压器架构创建的,变压器架构通常用于 NLP(自然语言处理)解决方案。

图一。DETR 模式— 来源

DETR 架构基本上由三层组成(图 1)。

  • CNN 层用于从图像(主干)中提取特征
  • 变压器中的编码器-解码器结构
  • 涉及在预测对象和真实对象之间执行二分匹配的集合损失函数

在第一阶段,通过主干层从图像中提取特征图。可以使用许多不同的模型,例如 RestNet-50 或 ResNet-101。以这种方式,二维结构信息被保留。在接下来的阶段中,数据被展平,因此我们得到一个一维结构。在位置编码之后,它被传送到编码器-解码器机制。最后,每个输出被转发到前馈网络。最后一层由 3 个节点组成。在使用 Relu 激活函数的情况下,获得预测对象的归一化中心坐标以及对象的预测高度和宽度值。当在节点中使用 softmax 激活函数时,预测相关对象的类别。因此,不需要非最大抑制(NMS)。

抑制(NMS):它是物体识别算法的基本课题之一。在模型的预测期间,可以用多于一帧来估计目标对象。这些框架有些可能是倾斜的,有些可能太大。对于 NMS,在这些类型的帧中选择最合适的一个。联合值的交集用于此过程。

图 2 算法中使用的变压器架构— 来源

在位置编码部分,根据元素在数组中的位置重新创建每个元素(或 NLP 世界中的标记)的向量。因此,同一个字在数组中的不同位置可以有不同的向量。

在编码器层,执行高维特征矩阵到低维特征矩阵的缩减。它由每个编码器层中的多头自关注、规格化器和前馈网络模块组成。

在解码器层,有多头自关注,规范和前馈网络模块一样,编码器。n 个对象查询被转换为输出嵌入。在下一阶段,使用前馈网络执行最终估计过程。

注:由于将对变压器架构进行更全面的研究,因此这些章节很短。然而,如果您想获得有关变压器的更多详细信息,您可以访问相关文章https://arxiv/abs/1706.03762

变压器架构的使用不仅在速度方面,而且在对象检测问题的某些特定类型的问题方面提供了很大的优势。通过这种架构,根据对象检测算法的图像内容进行预测。因此,在图像中上下文很重要的情况下,使用这种方法可以获得更高的成功。当递归神经网络用于对象检测项目时,已经看到精度较低并且模型运行较慢。因为操作是连续的。由于这些操作是从变压器架构中并行执行的,因此我们得到了一个更快的模型。

Python 项目

项目中使用的数据集已经从 Kaggle 下载。这里可以访问。数据集在 Kaggle 上获得了麻省理工学院的许可。如果你想得到详细的信息,你可以使用这个链接。

图三。来自 Kaggle 的样本数据集— 来源

在这个数据集中有不同类型的小麦(图 3)。本项目旨在正确检测这些小麦类型。存储库用于轻松完成训练和预测过程(https://github/ademakdogan/plant_detector)。下载数据集时,可以在图 4 中看到原始的标记数据。

图 4。原始标记数据

首先,这种标记结构应该根据存储库进行更改。由于这种改变,csv 文件中的列名应该分别为 image_name、page_width、page_height、x、y、width、height、labels 。csv 文件的转换版本可以在图 5 中看到。

图五。转换的数据

这里应该注意的是,图像名称及其扩展名被写在图像名称列中。事实上,这个存储库可以很容易地用于所有对象检测项目,其中可用数据可以以这种格式进行更改。编写一个只将数据转换为上述格式的转换器就足够了。

1-数据准备

获得的数据必须适应 DETR 算法。以下代码可用于此目的。

对于培训:

*python data_preparation.py -c /Users/.../converted_train.csv -i True*

用于测试:

*python data_preparation.py -c /Users/.../converted_test.csv -i False*

运行名为 data_preparation 的 python 脚本后,在名为 /data/json_files 的文件夹下创建了 custom_train.jsoncustom_test.json 文件。如果在文件的创建中没有问题,则开始训练阶段。

2-培训

训练也可以简单地用下面的代码来完成。在开始训练之前,可以根据需要更改 config.json 文件中的参数。

*python train.py -n <train_image_folder_path> -t <test_image_folder_path>*

作为训练过程的结果,获得了以下结果。

平均精度(AP)@[IoU = 0.50:0.95 | area = all | maxDets = 100]= 0.326
平均精度(AP)@[IoU = 0.50 | area = all | maxDets = 100]= 0.766
平均精度(AP)@[IoU = 0.75 | area = all | maxDets = 100]= 0.229
平均精度(AP)@[IoU = 0.56 = 0.410
平均召回率(AR)@[IoU = 0.50:0.95 | area = all | maxDets = 1]= 0.020
平均召回率(AR)@[IoU = 0.50:0.95 | area = all | maxDets = 10]= 0.161
平均召回率(AR)@[IoU = 0.50:0.95 | area = all | maxDets = 100]= 0.465

当分析结果时,可以清楚地看到,由于 epoch 低,成功率不是很高。很明显,当 config.json 中的 max_steps 参数增加时,将获得更高的精度。但是,根据硬件功率的不同,训练时间将会增加。培训也可以通过 docker 完成。

*make docker*

使用上面的命令在项目的主目录中创建了一个新的 docker 映像。默认情况下,这个 docker 图像的名称是“detr”。如果希望更改图像名称,可以使用 makefile。自动完成必要的安装后,使用以下命令开始培训过程。

*make docker_run v=<full_path_of_the_project> n=<train_image_folder_path> t=<test_image_folder_path>*

这个过程的结果是,在 model 文件夹下创建了一个名为 model.ckpt 的模型文件。之后,使用该模型执行预测过程。

3-预测

使用作为训练结果获得的模型,可以创建许多不同的预测场景。以下命令可用于项目中的预测用法示例。

*python prediction.py -p /Users/..../test/sample.jpg*

结果如下图所示。

图六。示例图像预测

结论

本文分析了基于变压器(DETR)的端到端目标检测方法,并与其他目标检测方法进行了比较。给出了关于构成该体系结构的各层的一般信息。第一阶段使用 ResNet 架构提取特征。在第二层中,在使用二分匹配技术计算损失值之后,将变换层用于编解码机制。DETR 速度很快,因为它具有并行处理能力,并且不使用锚盒和 NMS 等限制性技术。此外,在图像中的内容很重要的情况下,它比其他对象检测架构更强大。为了给这种情况树立一个榜样,用全球小麦检测数据集做了一个样本项目。要检测的对象通常是相互关联的;因此,尽管历元数量很少,该模型也能够进行检测。

示例项目使用了 Python。代码是共享的,因此这个架构可以更容易地使用。这些代码可在 https://github/ademakdogan/plant_detector 的https://github/ademakdogan/plant_detector获得。从 Kaggle 下载的数据集 (MIT-licensed)用于我们的示例项目。本项目对数据预处理、训练和预测阶段进行了详细说明。

不同的对象检测算法将在以后的文章中详细讨论。

****Github:https://github/ademakdogan

****领英:https://www.linkedin/in/adem-akdo%C4%9Fan-948334177/

参考

[1]尼古拉·卡里翁、弗朗西斯科·马萨、加布里埃尔·西纳伊夫、尼古拉·乌苏尼尔、亚历山大·基里洛夫、谢尔盖·扎戈鲁科。利用变压器进行端到端目标检测。2020

[2]https://github/facebookresearch/detr

[3]曹希鹏,彭远,,冯,牛昆.CF-DETR:用于端到端物体检测的粗到细转换器。2022

用 4 个简单的步骤开发一个对话式人工智能机器人

原文:https://towardsdatascience/develop-a-conversational-ai-bot-in-4-simple-steps-1b57e98372e2

了解如何使用 PyTorch transformers、FastAPI 和 Docker 创建聊天机器人

图片由作者提供。

目录

  1. 介绍
  2. 步骤 1:利用预先训练的模型
  3. 步骤 2:构建后端
  4. 步骤 3:构建前端
  5. 第四步:用 Docker 打包 app
  6. 结论
  7. 参考

介绍

对话式 AI 聊天机器人无疑是目前最先进的聊天机器人。这种聊天机器人混合使用自然语言处理(NLP)和人工智能(AI)来理解用户的意图,并提供个性化的响应。

使用专有数据训练(或微调)这种模型,使公司能够直接通过聊天窗口向客户提供提交保险索赔、升级数据计划、更改航班等多种方式。

在本帖中,我们将讨论:

  1. 如何使用预先训练好的 PyTorch 模型构建聊天机器人;
  2. 如何使用 FastAPI 和 Jinja 与模型对话;
  3. 如何使用 Docker 部署我们的定制模型?

步骤 1:利用预先训练的模型

让我们首先安装必要的 Python 包来构建和测试我们的新聊天机器人。

pip install --no-cache-dir transformers[torch] uvicorn fastapi jinja2 python-multipart

对于我们的聊天机器人,我们将使用来自微软的预先训练好的DialoGPT-large模型。为了加载这个模型,我们可以简单地对transformers中的AutoTokenizerAutoModelForCausalLM类使用from_pretrained方法。

要调用模型,我们需要:
1。encode用户消息使用tokenizer
2。generate使用model对象的机器人响应;
3。decode使用tokenizer的响应。

将下面的片段复制并粘贴到终端或笔记本电池上进行测试。

如果上面所有的库都安装正确,那么这段代码应该运行时不会出现错误或警告。如果是这样,应该会返回以下消息:

I'm good, you?

现在我们知道模型工作得很好,让我们将这两个片段包装在一个可重用的类中。

上面的代码片段有两个方法,一个用于加载模型(load_model),另一个用于在用户给定消息的情况下从机器人那里获得回复(get_reply)。注意,我们扩展了get_reply方法来考虑过去的聊天历史。此外,为了提高对话的一致性,我们调整了模型的top_ktop_ptemperature

你可以在这里找到完整的文件: chatbot/app/model.py

步骤 2:构建后端

既然我们已经理清了 chatbot 模型,下一步就是通过标准的 HTTP 方法使这个模型可用。为此,我们将在 FastAPI 应用程序中包装模型。

因为我们只对给定用户消息的模型的响应感兴趣,所以我们只需要实现一个端点(/)来获得来自聊天机器人的回复。

注意,我们在上面的 FastAPI 端点中使用了Form语法。当我们实现前端时,使用Form类型的理由将变得更加明显。要测试上面的代码片段,请运行以下代码:

如果一切顺利,您应该会得到下面的 JSON。

{'message': "I'm good, you?"}

你可以在这里找到完整的文件: chatbot/app/main.py

步骤 3:构建前端

我们的前端将由用户和机器人之间的简单对话组成,类似于 WhatsApp 或 Messenger。

我们将根据麻省理工学院的许可改编 bootsnipp 大学提供的 pablocorezzola 的原创作品,而不是从头开始构建对话。这里使用的用户和机器人头像图标是从 flaticon 免费获得的(在代码中的图标旁边和这个 post)⁴⁵.的末尾提供了对作者的鸣谢

对于这个应用程序,请确保您下载了CSS文件。你将不需要HTMLJS文件。在下面的结构中添加CSS文件,一个空的index.html和头像图标。

static/
  styles.css
  avatar_user.png
  avatar_bot.pngtemplates/
  index.html

在编辑模式下打开index.html文件,粘贴以下内容。这里有两条重要的线:

  • 第 8 行:将styles.css文件添加到 FastAPI 应用程序中;
  • 第 15 行:允许我们使用jinja TemplateResponse注入用户和机器人生成的必要对话框。

为此,我们还需要将下面的代码片段添加到我们的 FastAPI 应用程序中。

  • 第 5 行:允许 FastAPI 应用程序显示/static文件夹中的任何文件;
  • 第 9 行:告诉 Jinja 模板index.html文件在哪里。

最后,我们需要修改 FastAPI 端点来呈现对话框 HTML,而不是之前的 JSON 消息。该对话框将用于使用 Jinja 替换templates/index.html中的{{ chat|safe }}占位符。

为此,用下面的代码片段替换前面的端点(/)。

注意build_html_chat()函数还没有定义。该函数接受 3 个参数:

  • is_me:布尔定义给定消息是来自用户还是机器人;
  • text:用户/机器人消息;
  • time:处理消息的时间。

因为这个函数只是一个标准的 HTML 代码块,所以我不会在本文中涉及它。而是可以从以下链接(以及完整的前端脚本)获取:chatbot/app/html _ utils . py;聊天机器人/app/templates/index.html

第四步:用 Docker 打包 app

最后一步是用 Docker 打包我们的新应用。这一步将允许我们在本地、专用服务器或云上部署我们的应用程序,而不需要任何额外的工作。

让我们从定义最终的应用程序结构开始,如下所示。因为我们还没有定义Dockerfile,所以简单地创建一个空白文件。

app/
  static/
    styles.css
    avatar_user.png
    avatar_bot.png
  templates/
    index.html
  main.py
  model.py
  html_utils.py
Dockerfile

Dockerfile必须包括:

  • 我们在步骤 1 中安装的 Python 库;
  • 上面列出的后端和前端app/文件;
  • 启动容器时将调用的入口点文件(main.py)。

要构建和运行容器,只需在终端上键入以下内容:

docker build . -t chatbot && \
  docker run -p 8000:8000 chatbot

如果 Docker buildrun命令按预期执行,以下输出应该是清楚的:

INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

要测试 Docker 容器,请在您最喜欢的浏览器中打开一个新标签,并键入 http://0.0.0.0:8000/ 。然后,键入“嗨”。“你好吗,”在文本框中。

交叉手指,希望几秒钟后,您会看到两条消息。第一个是你刚刚输入的,第二个是机器人的回复。

用户输入“嗨”后,聊天机器人应用程序完成的例子。“你好吗,”

构建和运行这个应用程序所需的所有文件都可以在这里找到 main/chatbot/app

结论

智能聊天机器人的革命已经到来。这种高度复杂和强大的模型允许多个公司以方便和可扩展的方式提供不同的服务。

在这篇文章中,我介绍了构建你自己的聊天机器人的基本思想,从模型创建到后端和前端。请注意,这只是一个简单的例子,说明了如何实现一个简单的对话机器人,而不应该被用于任何超过说明。

如果你想知道更多关于如何以无服务器的方式部署这样的应用,看看我过去的文章"用 Amazon Lambda 和 API Gateway 构建无服务器 API"⁶"和"使用 AWS Lambda 和 EventBridge 部署" remindme " Reddit bot" ⁷.

加入我的邮件列表,我一发布新内容,你就能收到新内容!

如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑报名成为一名媒体成员。每月 5 美元,让你可以无限制地访问 Python、机器学习和数据科学文章。如果你使用我的链接注册,我会赚一小笔佣金,不需要你额外付费。

https://andrefsr.medium/membership

参考

[1]张等著《对话:会话回应生成的大规模生成性预训练》(2020),arXiv

[2]拥抱脸团队,“一个最先进的大规模预训练反应生成模型(dialog pt)”
https://huggingface.co/microsoft/DialoGPT-large

[3]pablocrezzola,“简单聊天”:Bootstrap 3.0 片段——在麻省理工学院许可下发布https://bootsnipp/snippets/y8e4W

[4] Freepick, Bot 免费图标【https://www.flaticon/free-icon/bot_1786548?】
term = bot % 20 avatar&page = 1&position = 1&page = 1&position = 1&related _ id = 1786548&origin = search

【5】自由选择,男人自由图标【https://www.flaticon/premium-icon/man_2202112?】
term =头像&page = 1&position = 2&page = 1&position = 2&related _ id = 2202112&origin = search

6 a .里贝罗。“用亚马逊 Lambda 和 API 网关构建无服务器 API
https://towardsdatascience . com/Build-a-server less-API-with-Amazon-Lambda-and-API-Gateway-DFD 688510436

7 a .里贝罗。“使用 AWS Lambda 和 EventBridge 部署一个“RemindMe”Reddit Bot
https://towardsdatascience . com/build-a-q-a-app-with-py torch-CB 599480 e29

开发和部署无服务器事件驱动的机器学习应用程序

原文:https://towardsdatascience/develop-and-deploy-serverless-event-driven-applications-using-zappa-flask-and-aws-f39b817a9937

如何使用 Zappa、Python、Flask 和 AWS 创建托管机器学习模型的应用编程接口(API)

目录:

1.无服务器介绍

2。AWS
3 上的 IAM 权限。开发烧瓶应用程序
4。用 Zappa
5 展开。用密钥保护 API

1.介绍

随着全球各地的公司开始扩大其数据科学和机器学习能力,通过无服务器计算部署端点的过程在最近几个月出现了大幅增长。根据最近一篇关于 DataDog [1]的文章,大多数云提供商(AWS、GCP 等)的无服务器架构正在被超过 50%的客户主流采用。尽管这种适应性的重大变化有多种驱动因素和原因,但在本文开始时,有一点很重要,即虽然无服务器计算可能是许多应用程序的最佳解决方案,但它肯定不是所有应用程序的最佳解决方案。记住这一点,让我们仔细看看无服务器方法的一些关键优势。

关注业务逻辑——“关注什么,而不是如何”

随着数据科学家开始处理他们的项目,他们经常面临如何将他们的应用程序部署到云的难题,这迫使他们有时更多地关注部署过程,而不是模型本身的开发。无服务器计算的最大优势之一是它的易用性,我们将在本章后面看到。

图 1——该图显示了对业务逻辑的关注增加,而对架构的关注减少的趋势。(图片由作者提供)

高效、可扩展且强大—“可扩展性始终是关键”

无服务器基础架构的另一个巨大优势是能够以“随用随付”的方式按需扩展和缩减。提供商处理几乎所有与可伸缩性相关的项目,并管理所需的资源。然而,这是以限制对特定运行时设置的访问为代价的。如图 2 所示,根据需要扩展和缩减的能力也大大有助于节省成本。我们在这里可以看到,传统的可伸缩性是逐步增加的,而无服务器的可伸缩性更加线性。

图 2 —展示无服务器计算相对于传统方法的可扩展性的图表(图片由作者提供)

方便且易于部署

相对于全服务器架构,无服务器架构提供了许多优势。最大的优势之一是在部署基础架构和之后进行管理时的易用性。Zappa 可以使用 CloudFormation 来处理这两个项目,cloud formation 本质上是 IaC(基础设施即代码)。记住这一点,让我们开始吧!

2.AWS 上的 IAM 权限

在开始使用 Zappa 之前,让我们先在 AWS 中按顺序获取权限。首先,在 AWS 中导航到 IAM,单击用户组,并创建一个新组。我们可以称这个群为“zappa_group”。

图 AWS 的 IAM 菜单。(作者截图)

创建组后,单击“添加权限”,然后单击“创建内联策略”。

图 AWS 的 IAM 下拉菜单。(作者截图)

单击 JSON 选项卡,并向其中添加以下策略:

这个策略将使 Zappa 能够创建基础设施,并相应地为您标记它。请注意,您需要将 AWS_ACCOUNT_NUMBER 更改为您各自的号码。您可以通过单击屏幕右上角的用户名在下拉选项卡中找到它。

现在导航到“用户”并创建一个新用户。我们可以称这个用户为“zappa_user”。如果你觉得更有创意,请随意更改名称!将用户添加到您创建的组中,以赋予用户适当的权限。完成后,请务必记下访问密钥和密码。

导航到您的终端命令行,并添加您的密钥。您可以使用 vim 在本地编辑 aws 密钥文件:

vim ~/.aws/credentials

进入编辑器后,单击“I”插入新内容,并添加您的密钥。如果您已经有一个名为 default 的配置文件,我建议您创建一个名为“zappa”的新配置文件:

[zappa] 
aws_access_key_id = ADD_KEY_HERE 
aws_secret_access_key = ADD_SECRET_HERE

至此,我们已经完成了 AWS 上的权限,现在可以把注意力转移到 Zappa 上了。

3.开发烧瓶应用程序

现在我们有了一些关于无服务器方法的背景知识,让我们继续准备一个 Flask 应用程序。我们的目标是使用 scikit-learn 训练一个简单的机器学习模型,保存工件,并将其加载到 Flask API 中。

我们可以从创建一个新目录开始,输入目录:

mkdir sklearn-zappa-ml-with-preprocessingcd sklearn-zappa-ml-with-preprocessing

现在让我们创建一个名为“venv”的新虚拟环境并激活它:

virtualenv venvsource venv/bin/activate

现在让我们继续安装感兴趣的库。对于本教程,我们当然需要 zappa 来进行部署,flask 来构建应用程序,scikit-learn 来管理我们的模型,joblib 来保存和加载我们的模型:

pip install zappa scikit-learn flask joblib

安装完我们的库后,让我们再次激活虚拟环境:

source venv/bin/activate

让我们继续创建一个名为 train 的新目录和另一个名为 models 的目录,在 train 目录中,我们将创建一个名为 train.py 的文件:

mkdir train
mkdir models
cd train
vim train.py

在 train.py 文件中,我们将添加以下代码:

回想一下,我们在这里的目标是训练一个样本模型,并演示我们可以加载分类器本身,以及预处理工件。如果您检查 models 目录,您现在应该看到两个 joblib 文件。

回到主目录,我们现在创建一个名为 app.py 的新文件:

vim app.py

在这个文件中,我们将准备我们的 API 框架。我们将导入我们的库,加载模型,并准备两条路径:一条路径到主目录“/”,另一条路径到“/predict”:

到目前为止,我们应该有以下目录结构:

sklearn-zappa-ml-with-preprocessing
    |__ venv |__ models
        |__ rfc.joblib
        |__ scaler.joblib |__ train
        |__ train.py |__ app.y

我们可以通过运行 Flask 服务器来测试我们的模型:

python3 app.py

使用 Postman [2],您可以通过创建针对本地服务器的 POST 请求来测试 API:

图 5—显示 POST 请求的 Postman 应用程序的屏幕截图,带有示例输入数据(作者的屏幕截图)

4.使用 Zappa 部署

既然我们已经确认了我们的应用程序可以在本地工作,现在让我们开始配置 Zappa。我们可以从使用 Zappa 中的 init 函数开始:

zappa init

当您完成初始化过程时,会要求您提供一些项目:

  • 环境:您可以指定感兴趣的环境,比如 dev、test 或 prod。出于本教程的目的,请输入“dev”
  • 应用程序路径:这里你需要设置主应用程序的路径。我们可以使用默认值“app.app”
  • 桶名:您可以在这里指定感兴趣的 AWS S3 桶。我建议您保留默认值,让 Zappa 为您处理这个问题。
  • 全局:你可以使用这个特性来优化分配。出于本教程的目的,输入“n ”,这是跳过此功能的默认值。

完成此过程后,Zappa 将在您的当前目录中生成一个名为 zappa_settings.json 的文件。继续操作并打开该文件以检查设置。打开文件,继续添加两个新的键值对:“slim_handler”和“tags”。slim_handler 配置将用于优化部署过程,因为我们使用的是 scikit-learn——一个相对较大的库。此外,“标签”将用于确保我们创建的基础架构被适当标记,以用于组织和计费目的。

{
“dev”: {
    “app_function”: “app.app”,
    “profile_name”: “zappa”,
    “project_name”: “sklearn-zappa-m”,
    “runtime”: “python3.8”,
    “s3_bucket”: “zappa-123456789”,
    “slim_handler”: true,
    “tags”: {
        “Project”: “ZappaProject”,
        “Stage”: “dev”
        }
    }
}

确认设置正确后,现在可以使用以下命令部署 API 了:

zappa deploy dev

这将继续并准备您的基础设施,以服务于我们之前准备的 Flask 端点。最后,需要了解两个主要组件:管理 API 外部流量的 API Gateway,以及包含应用程序逻辑的脚本 AWS Lambda。

图 AWS 架构的表示(图片由作者提供)

完成部署过程后,Zappa 将向您返回一个 URL,其结构如下所示:

https://123456789.execute-api.us-east-2.amazonaws/dev

您可以使用 postman 再次测试应用程序的部署,并在上面的 URL 末尾添加“/predict”。您应该会收到一个状态为 200 的成功响应,与我们之前看到的类似。

5.用密钥保护 API

既然已经成功部署了 API,现在全世界都可以看到和使用它了。在许多情况下,我们的 API 端点可能是保密的,我们只想授予特定用户或应用程序访问权限。我们可以使用两种方法之一来实现这一点:API 密钥和 IAM 权限。让我们看一个使用 API 键实现这一点的例子。

继续操作,在您的 AWS 帐户上导航到 API Gateway。您应该能够看到刚刚部署的应用程序列在该页面中。如果没有,请确保选择了正确的区域。

点击 API,然后点击左侧的 Resources。单击名为{proxy+}的资源,您将看到类似下图的内容:

图 7 —来自 AWS API 网关的屏幕截图。(作者截图)

您可以看到 API 键当前被设置为“不需要”。继续点击下面的“任何”和“方法请求”。将“需要 API 密钥”更改为 True。注意,为了使用它,我们需要都生成一个密钥,并将其添加到一个使用计划中。

您可以通过单击屏幕左侧的 API 密钥来生成密钥。单击“操作”,然后单击“创建 API 密钥”。

图 8—显示 AWS 上 API 键下拉菜单的屏幕截图(作者截图)

接下来,继续创建新的使用计划。为计划命名和描述,然后根据需要设置限制和配额设置。单击 next,然后将 API 密钥添加到使用计划中。

这样,你现在应该都准备好了。您可以在 Postman 上测试密钥,方法是将密钥添加到您的请求的标头中。密钥应该是“x-api-key”,值应该是您生成的密钥。

图 9 —添加了 api 键的 postman 请求(作者截图)

这样,您现在就有了一个在 AWS 上部署和保护的无服务器机器学习模型!概括地说,这种模型部署方法的主要优点之一是,您将使用“随用随付”模型,确保您不会收到无意义的账单,即使在不活动时也是如此。

参考资料:

[1]https://www . prnewswire . com/news-releases/data dogs-2022-state-of-server less-report-finds-server less-reaching-mainstream-adoption-301560418 . html

[2]https://www.postman/

使用 SAM 开发 Lambdas 并在本地调试它们

原文:https://towardsdatascience/develop-lambdas-and-debug-them-locally-using-sam-8f367793cc1a

开发无服务器应用程序有其挑战性,SAM 为这些挑战提供了一个解决方案。了解如何使用 SAM 开发 lambdas 并在本地调试它们。

图片由珀西·博尔梅尔提供。Gopher 由拓也·上田提供,原始 Go Gopher 由勒内·弗伦奇提供(CC BY 3.0)

无服务器应用程序很棒,我们可以在生产中以超快的速度启动并运行一个功能,正常运行时间非常长,而且几乎没有成本。

Lambda 是一项 AWS 服务,它允许您部署可运行的小段代码。例如,我们可以部署一个小型的 Go 二进制程序来执行一个任务,并通过一个 API 来触发它,调度它,或者让它基于其他几个事件来执行。

然而,调试这些服务可能很难,因为它们运行在云上。我过去构建函数的方式可以很容易地在本地运行它们,并且简单地用 lambda 处理程序包装那个函数。这是可行的,但是有时我们想要调试整个流程以及我们使用的服务。

我经常鼓吹软件需要在本地运行,SAM 帮助我们在本地运行我们的云应用。

在本教程中,我希望你已经有了一些要求,否则就没有理由阅读如何本地调试 lambda 了。

  • 拥有足够 IAM 权限的 AWS 帐户
  • 安装和配置 AWS CLI

如果您没有 AWS 帐户或 AWS CLI,请按照官方文档安装。

如果你更喜欢视频格式,你可以在我的 Youtube 上找到这篇文章。

本文的视频版本

你可以在 GitHub 找到视频中使用的完整代码。

山姆是谁?

Sam(无服务器应用模型)是一个帮助我们构建云应用的 AWS 框架。Sam 有一个模板语言,我们可以用它来编写云架构的结构,我们可以利用该模板在本地部署和运行它。Sam 正在幕后使用 CloudFormation ,你现在不需要了解 CF。

在本文中,我们将创建几个简单的 lambda,并使用 SAM 对它们进行测试,我们还将尝试通过附加远程调试器来调试 lambda。SAM 允许我们使用 docker 在本地运行 lambdas 或 lambdas 的 API。

使用 SAM 与 IDE 无关,您可以使用任何 IDE 来利用 SAM。据我所知,大多数人确实倾向于使用 VS 代码,因为他们有很棒的插件,我们将在最后介绍。

我们从安装 SAM 开始,你可以找到关于如何在 AWS 上安装的官方文档。

我使用的是 Linux,所以下面是我安装 SAM 的方法。

用于安装 SAM 的安装脚本

您可以通过运行 version 命令进行验证

sam --version

创建 Lambda

让我们创建第一个简单的 lambda。我将在本教程中使用 Go 来演示,但是你应该能够使用任何你想要的支持 lambdas 的语言。您可以在 AWS 文档中找到关于您的语言的代码示例,每种支持的语言都有一个名为Working with $LANGUAGENAME的章节。

创建一个新文件夹并初始化一个 go 模块,创建一个名为main.go的文件和一个名为template.yml的文件。暂时忘记模板文件,让它保持空白,我们稍后会谈到它。

touch sam-lambda-demo
cd sam-lambda-demo
go mod init programmingpercy.tech/sam-demo
touch main.go
touch template.yml

让我们用整个宇宙中存在的最简单的λ来填充main.go,我们将接受一个包含名称的输入事件,我们将打印Hello $name

你猜对了,这是一个 Hello World Lambda!

main . go—gopher 历史上最简单的 lambda。

Event结构定义了我们的 lambda 输入应该是什么样子,我们将输出一个string,error。您可以返回您想要的任何结构,或者任何 AWS 定义的事件。稍后,当我们尝试在 lambda 前面使用 API 网关时,我们将介绍 AWS 事件。

使用 Sam 模板

在我们开始调试之前,我将介绍 SAM 的一些简单方面,以便我们理解正在发生的事情。

Sam 打包了一系列功能,它甚至可以将您的应用程序部署到 AWS 中。现在,让我们慢慢来,构建 lambda 并尝试调用它。

当我说应用程序时,我指的是整个云资源集,而不是您的单个 Go 二进制文件——资源集构成了我们的无服务器应用程序

为了构建我们的应用程序,我们首先需要定义应用程序拥有哪些云资源。这是在template.yml中使用特定的格式完成的。

我们将从我能想象到的最简单的模板开始,并经历一切是什么。

template.yml —单个 lambda 的简单 SAM 模板文件

在文件的开头,你会看到一些我从未见过改变的默认设置。我们定义要使用的模板版本。事实上,根据文档只有一个有效版本。

我们将重点关注Resources部分。在其中,我们可以定义整个 SAM 应用程序将拥有哪些资源。

语法非常简单,您以资源的名称开始 yml,我们创建一个名为HelloGopher的 lambda。这可以是你喜欢的任何东西,重要的是你可以用这个名字来引用其他资源,当你需要一个特定的 arn 时,这很重要。

所有资源都接受一个Type输入,类型可以是 cloudformation 允许的任何东西,通常是AWS::Serverless:RESOURCETYPE。如你所见,我们将类型设置为AWS::Serverless::Function,这告诉 cloudformation 为我们生成一个 lambda。

每种类型都有自己的一组可用属性,可以在文档中找到。要找到函数的可用属性,请查看它们的文档。

CodeUri非常重要,这是包含我们代码的 ZIP 文件的本地路径或 S3 路径。在这个例子中,我使用了同一个文件夹,在一个真实的项目中,你可能有 lambdas,你可以创建一个类似于lambdas/hello-gopher/的文件夹结构,并将 codeuri 更改为一个更具可伸缩性的解决方案。

Handler用于设置一旦执行 lambda 就会调用的某个二进制文件,让我们试着用 SAM 来解释这个。

如果您现在尝试通过运行sam local invoke来运行 Lambda,您应该会看到一个崩溃报告,说没有这样的文件。

由于没有这样的文件,Sam 崩溃

这只是因为我们将Handler设置为指向尚不存在的hello-gopher二进制文件。让我们开始利用山姆来帮助我们。

Sam 构建和调用

我们可以使用 SAM 来打包我们的应用程序,build 命令带有许多参数标志。例如,您可以构建并将其发送到 S3。

使用 SAM build 很好,因为它将利用您的模板文件,并通过使用runtime属性来使用 go 的正确版本。

它非常容易使用,在与您的template.yml相同的文件夹中运行以下命令

sam build

您应该会看到一个.aws文件夹出现,打开该文件夹会显示 lambda 和名为hello-gopher的二进制文件。

通过本地调用 lambda 重试运行项目的时间。

sam local invoke

你应该看到它打印,你好,但没有给出名称。这是因为我们需要添加输入事件。这是通过使用-e--event选项来完成的,它们可以指向一个文件或一个 JSON 字符串。我更喜欢使用文件,因为这也可以作为 lambda 的示例文档。

在名为event.json的文件夹中创建一个文件,并粘贴到与 lambda 中的事件结构相匹配的 JSON 中。

event . JSON——我们期望 lambda 中的有效负载。

现在,再次调用 lambda,但是这次我们添加了指向event-json文件的-e标志。

Sam 使用有效负载调用

令人惊讶的是,它现在打印了我们在有效载荷中使用的名称。AWS SDK 中有大量的自定义 lambda 事件可以使用,但是我们将在特定于 lambda 的教程中介绍这些事件。

有一个-d标志允许我们传入一个远程调试端口,记住这一点非常重要。这是允许我们将调试器附加到 lambda 的特性。

请注意,我们只有一个 lambda,但是如果您有多个 lambda,您可以通过在命令中添加 lambda 的名称来指定要运行的 lambda。

sam local invoke hello-gopher # Runs a specific lambda

如果你想运行一个 lambda 并将其作为一个服务公开,就像它在真实的云上运行一样,你可以使用start-lambda命令来模拟。

让我们尝试运行以下命令

sam local start-lambda

这应该会打印出 lambda 公开的 URL,我们可以将它添加到 AWS cli 来调用 lambda。默认的网址是 http://127.0.0.1:3001 。

您可以使用 URL 作为 AWS CLI 的端点,通过以下命令调用它。

aws lambda invoke --function-name HelloGopher --endpoint "[http://127.0.0.1:3001](http://127.0.0.1:3001)" --payload '{ "name": "percy"}' response.json

这个命令将调用 lambda,插入有效负载并将响应输出到response.json

Sam API 网关

很多时候,您希望在运行 Lambda 时,前面有一个 API 网关。API 网关将把 Lambda 作为 HTTP API 公开。

与 SAM 一起管理和设置非常简单。我们需要创建 lambda 资源监听的Events,这不一定是 HTTP,它可以是 SQS 或许多其他 AWS 服务事件。使用类型API会让 Sam 知道这是一个 API 网关。

我们将修改template.yml来添加 API 端点作为 POST。

template.yml —添加 API 事件

我们还需要修改 lambda 来接受 API 网关事件,这些事件的结构有点不同。它们用一些元数据(如请求标识符)包装原始请求。

main . go——修改了我们的 lambda,使其作为 API 端点运行

要打开 API 并在本地公开端点,这在您开发具有许多端点的 API 并希望在本地尝试您的系统时非常方便,我们可以再次使用 SAM。

让我们构建新的 Lambda 并用sam local start-api运行 API。

sam build
sam local start-api

您应该看到一个输出,它指定了 API 在哪个端口上运行,对我来说,输出如下。

Mounting HelloGopher at [http://127.0.0.1:3000/api/hellogopher](http://127.0.0.1:3000/api/hellogopher) [POST]

我们可以用 CURL 来尝试,并发送预期的数据负载。

curl -X POST localhost:3000/api/hellogopher -d '{"name": "percy"}'

Sam 环境变量

大多数时候,你的 lambda 需要配置。很多时候这是通过使用环境变量来完成的。

我建议在template.yml中指定期望的变量,这提供了使用 CLI 修改变量的能力,我们将很快介绍这一点。

为了添加环境,我们修改了模板并添加了一个简单的Environment属性。

下面是我的template.yml和一个名为my-cool-variable的环境变量的片段。

template.yml —将环境变量添加到我们的 lambda 中

接下来,我们需要开始使用 lambda 中的环境变量,我将只把它的值添加到输出中,修改main.go中的第 31 行如下。

main.go:31 —添加了环境变量

这看起来似乎微不足道,但是您现在可以在 SAM CLI 中非常灵活地利用它来设置新的变量。我们可以使用-n参数修改调用之间的变量。记住,在 API 中可以有多个 lambda 端点,每个 lambda 可以需要自己的一组环境变量。

您可以创建一个特殊的环境 JSON 文件来控制每个 lambdas 环境。您必须使用来自template.yml的资源名称,并且只有在template.yml中指定的环境是可修改的。如果你试图设置一个没有在模板中声明的变量,它将不会被添加。

创建一个名为environments.json的新文件,我们将用它来修改每个 lambda resources 环境变量。

environments.json —我们要修改的变量

尝试使用-n标志重新构建并执行 API 来指出环境文件,您现在应该会看到打印出的新值。

sam local start-api -n environments.json

还有一些参数,它们与环境变量不同,但它们与云的形成有更大的关系,我们在这里不讨论细节。

Sam 生成事件

并不是所有的 lambda 都被公开为 API,例如,一些 lambda 监听 SQS 事件或 S3 事件来触发它们。

一种非常常见的方法是用 lambda 监听 SQS 事件,遗憾的是这很难测试。没有办法将 Sam 连接到 SQS 队列来测试它,相反,测试它的方法是生成一个 SQS 有效负载并使用该有效负载调用 lambda。这将模拟一个被发射到 lambda 中的现场事件。

现在你可能想知道,SQS 事件看起来如何?我不知道,我们也不需要知道,因为 Sam 可以帮助我们为通常与 lambdas 相关的已知 AWS 服务生成虚假的有效载荷。

让我们从更新template.yml并添加一个新的 lambda 开始,这个 lambda 将在一个名为my-awesome-queue的队列上监听 SQS 事件。现在,正如我所说的,我们不能让萨姆在本地监听my-awesome-queue,但是我们可以伪造有效载荷。以下要点显示了如何告诉山姆关于 SQS 的事情,template.yml中唯一的新部分是新的 lambda,它会触发 SQS 事件。

yml——我们添加了一个 lambda 函数,它在 SQS 队列上触发

CodeUri中,我们指定了./sqslambda的位置,所以我们可以从创建那个文件夹开始,并用我们的 lambda 在其中添加一个main.go

mkdir ./sqslambda
touch main.go

我们新的 lambda 将非常简单,只将输入事件打印到日志中。我们将使用来自 AWS SDK 的相同的events包,并指定该事件是一个SQSEvent。我们可以进入 SDK,尝试使用 JSON 标签复制 SQSEvent 结构,但这将是一项繁重的工作。

。/sqslambda/main.go —接受 SQS 负载的简单 lambda

现在,在我们触发这个 lambda 之前,我们需要一个 SQSEvent。我们可以使用 Generate-Event 命令为我们创建一个event.json文件,我们可以将它作为有效载荷传入。

语法非常简单,使用generate-event后跟服务名和receive-message子命令。目前实际上只有一个子命令,即 receive-message。谁知道也许他们已经计划好了send-message

我们将在--body中传递一个参数,用于修改 SQS 有效载荷的主体,主体是用户特定的有效载荷。

sam local generate-event sqs receive-message --body 'My Own Event Payload'

运行它,您将看到一个生成的 JSON 有效负载,它模拟了一个 SQS 事件。您可以将这个有效负载写入一个名为event.json的文件,并像以前一样使用-e标志将该有效负载传递给调用。

对于-e标志有一个很好的技巧,但是,如果你传递一个-作为输入,它将从标准输入中读取值。这意味着我们可以将生成事件命令与调用链接在一起。

sam local generate-event sqs receive-message --body 'My Own Event Payload' | sam local invoke -e - SQSLambda

运行该命令应该会打印出整个事件并调用 lambda。

太好了,我们现在可以测试任何 lambda,不管是什么服务触发了它。

附加远程调试器

在开发服务时,调试是一个非常重要的方面,附加一个调试器来查看运行时发生了什么是解决问题的最有用的方法之一。

为此,我们可以在 Sam 命令中添加-d标志来打开远程调试器端口,您可以将端口指定为-d 的参数。这适用于所有调用,start-lambdastart-api也接受调试器标志。

Sam 需要安装 Linux Delve 调试器,如果您没有运行 Linux,您仍然可以使用“GOOS = Linux go arch = amd64 go install github/go-delve/delve/cmd/dlv@latest"”来安装它们

记住调试器应该安装在您的主机上,我们可以使用--debugger-path=hostURL/to/debugger参数指定调试器的位置。我还需要使用 delveAPI 版本 2 来让调试器顺利运行。

让我们运行 SQS 事件来调试 lambda。我将添加它所需的调试标志,以便在调试模式下公开 lambda。请注意,当您使用-d调用时,它会在开始时暂停 lambda 并等待调试器连接。

sam local invoke SQSLambda -d 8099 --debugger-path=/home/percy/go/bin --debug-args="-delveAPI=2"

接下来,我们需要附加一个调试器,如何做取决于你是使用 VS 代码还是 Goland 等等。我正在使用 VS 代码,所以我将在我的.vscode/launch.json中添加一个新的配置。如果你用的是 Goland,请看这里如何附加调试器。

。vscode/launch.json —这是我们的调试附件

基本上我们所做的是创建一个新的附加请求到一个远程调试器,在 localhost:8099 上。确保您使用的端口与您给-d命令的端口相同。

保存文件并在第 13 行的sqslambda/main.go中放置一个调试器。然后运行调试配置。您应该看到它在您放置的断点处中断。

我们在调试时附加了一个断点

现在,让它运行需要一点工作,有一些技巧可以自动运行调试器命令,比如在 launch.json 中使用预启动效果。但是,如果您使用 VS 代码,我将很快介绍如何使用 AWS 插件,这将使调试更加容易。他们不再需要使用任何 CLI 命令,这非常方便。

在 SAM 中使用 VS 代码

如果你正在使用 VS 代码,我建议你下载 AWS 工具包,如果你还没有的话。

进入扩展,搜索AWS toolkit并安装它。

使用 AWS 云资源的 VS 代码扩展

下载后打开扩展并登录您想要的配置文件,只需按下Connect to AWS按钮。

用插件连接到 AWS

这个过程应该很简单,它会要求您进行一些配置,如默认区域、要使用的配置文件等。选择您想要的选项。之后,您应该会看到一堆云服务出现。

在本教程中,除了本地部署,我们不会部署任何 SAM 应用程序,但是您可以这样做(即使没有插件)。

该插件现在将添加许多 SAM 内置功能,以取代需要运行命令行。最好的特性是现在每个 lambda 上面都会有一个文本,询问你是否想要创建一个调试配置。

AWS 插件可以为我们生成调试处理程序。

点击Add Debug Configuration,你的launch.json应该会更新。

launch.json — AWS 插件为我们生成了一个全新的调试器。

现在,这看起来和我们之前创建的有很大不同。这是这个插件很酷的一点,它创建了一个独特的调试类型,叫做aws-sam,允许我们调用 lambdas。还有一种 API 调用的请求类型,可以通过访问 API lambda 并为其生成一个调试调用来生成。

如您所见,您可以指定调用目标、环境变量和有效负载。这些都非常方便,所以我们可以跳过使用 API,而只使用一个简单的 launch.json。

您应该熟悉所有您可以更改的内容,因为这正是我们在本文中讨论的内容。

那么,为什么我们不从一开始就使用插件呢?因为那样会有太多的魔法,我们也不明白插件在为我们做什么。我相信,从长远来看,学习工具的基础是最好的,而且你不一定要使用 VS 代码,而是任何你想要的 IDE,因为我们知道如何附加调试器,以及为什么我们需要这样做。

设置本地堆栈和 SAM 网络

如果您的 lambdas 使用其他 AWS 资源,您可以模拟那些使用 Localstack 的资源。在本教程中,我不会讨论 localstack,但是我们将看看如何强制 SAM 资源与 localstack 实例在同一个网络上运行。

如果您使用 localstack 并通过 docker 运行它,请确保您还指定了 docker 网络。如果您在名为mock-aws-network的 docker 网络上运行 localstack,您可以通过在大多数命令上使用输入标志docker-network mock-aws-network来让 Sam 使用相同的网络。

sam local invoke --docker-network mock-aws-network
sam local start-api --docker-network mock-aws-network

这很方便,因为 lambdas 倾向于使用其他需要通信的 AWS 服务,这样我们也可以调试它。

如果你使用的是 VS 代码插件,你可以把这一行添加到launch.json

launch.json —指定用于 Sam 的 docker 网络

结论

在本教程中,我们学习了如何使用 SAM 开发 lambdas,以及如何在本地调试它们。我认为 SAM 在开发 lambdas 时提供了帮助,消除了我在开始开发无服务器应用程序时遇到的许多挫折。调试之类的事情很难,但现在不再是了。

SAM 中还有更多我没有在这里介绍的特性,比如创建其他 AWS 资源(SQS 队列等)以及在 lambda 中直接引用它们的 ARN。

您应该开始试用 SAM,并找出它提供的所有令人惊奇的工具。

感谢您的阅读,一如既往,我喜欢反馈和讨论。

使用 Python 开发您自己的日历来跟踪重要日期

原文:https://towardsdatascience/develop-your-own-calendar-to-track-important-dates-with-python-c1af9e98ffc3

开发一个日历 GUI 界面来管理您 2022 年及以后的计划

在 Unsplash 上由Towfiqu barb huya拍摄的照片

时间是至关重要的。时间不等人。关于时间的重要性,还可以引用几百句话。因此,如果你计划掌握数据科学或编程,你将需要一个简明的计划来获得这一整年的最佳知识。

随着新的一年已经开始,跟踪你的效率和生产力变得很重要。有什么比借助你自己的日历更好的方法来有效地跟踪这一进程呢?这将有助于你为今年剩下的时间创造一个清晰的、有指导意义的视角和方向。

在本文中,我们将着重于构建一个日历,通过它我们可以查看必要的数据并相应地分析我们的计划。我们还将关注您可以对该项目进行的一些关键更新和改进,这样您就可以不断地提醒自己这一年中还有很多重要的事情要做。

在我们开始用 Python 构建我们的日历 GUI 界面之前,如果您刚刚开始学习数据科学,并希望在今年内掌握它,我有一篇文章非常详细地介绍了这一点。查看我以前的一篇博客,通过下面提供的链接中的 12 个关键步骤,你可以在 12 个月内掌握数据科学。

</12-steps-for-beginner-to-pro-in-data-science-in-12-months-c6f6ba01f96e>

开发您的日历:

作者截图

从上图中我们可以注意到,这个项目需要我们使用图形用户界面(GUI)来构建一个视觉上吸引人的日历。我们将利用 python 中可用的 Tkinter 库来构建这样一个用户界面。要了解更多关于这些 GUI 工具的知识,我建议查看我以前的一篇文章,这篇文章解释了其中的七个工具,并附有入门代码,可以帮助您快速入门。

</7-best-ui-graphics-tools-for-python-developers-with-starter-codes-2e46c248b47c>

除了 Tkinter GUI 模块之外,我们还需要安装一个额外的 tkcalendar,它为 Tkinter 界面提供了日历和日期输入小部件。它允许用户对不同的窗口小部件进行定制控制,从而按照用户的要求相应地操纵日期和时间。下面的命令应该允许您轻松安装下面的模块。

pip install tkcalendar

一旦我们成功安装了必要的库,我们现在就可以相应地导入它们了。进行导入时的星号(’ * ')表示我们正在导入 Tkinter 模块的所有类,因为我们将需要其中的一些类来成功计算这个项目。从 Tkinter 日历库中,我们将只需要日历模块,通过它我们可以显示交互式日历及其相应的小部件。

# Importing The Essential Libraries
from tkinter import *
from tkcalendar import Calendar

一旦我们完成了所需库的导入,我们将继续创建 GUI 对象作为显示界面的根。然后,我们可以根据用户的选择相应地选择我们的几何设置。我将界面尺寸设置为 700 x 700,因为我喜欢在大多数任务中使用更大的可交互屏幕。然后,我们将添加我们最近安装的日历模块,作为 Tkinter GUI 的附加小部件。

使用这个日历模块,我们可以根据需要设置根路径、特定的日、月和年。在打包这个变量时,我将在 y 轴上应用填充,这样,从交互式屏幕的顶部到我们创建按钮、标签或任何其他类型的交互式小部件的地方,距离为 20 个像素。我们将填充两边并将变量扩展到屏幕的末端,这样我们就可以有一个更丰富的日历视图。这个过程的代码如下面的代码片段所示。

# Create The Gui Object
tk = Tk()

# Set the geometry of the GUI Interface
tk.geometry("700x700")

# Add the Calendar module
cal = Calendar(tk, selectmode = 'day',
               year = 2022, month = 1,
               day = 11)

cal.pack(pady = 20, fill="both", expand=True)

在下一个代码片段中,我们将创建一个函数,通过它我们可以获取用户需要的特定日期。grad date 函数包含的文本将在我们单击其中一个按钮部件时显示。如果您想在下面的函数中添加更多的命令,那么您可以随意地进一步探索它。

# Function to grab the selected date
def grad_date():
    date.config(text = "Selected Date is: " + cal.get_date())

最后,我们将为我们的项目创建一些需求来选择合适的日期和时间。首先,我们将创建一个按钮,通过我们的函数来获取我们用鼠标光标选择的特定日期。然后,我们将添加一个标签,当单击按钮时,该标签将在屏幕上显示带有特定日期的文本。应用 20 像素的填充操作来保持标签和按钮的相等距离。然后,我们将为日历项目执行 Tkinter 循环。

# Adding the Button and Label
Button(tk, text = "Get Date",
       command = grad_date).pack(pady = 20)

date = Label(tk, text = "")
date.pack(pady = 20)

# Execute Tkinter
tk.mainloop()

一旦您完美地执行了以下代码片段,您就可以继续运行 Python 程序来接收类似于上面显示的图像的结果。让我们转到下一节,探索完整的代码,并讨论一些我们可以添加的改进,使这个项目变得更好。

更新和改进:

下面提供了用 Python 构建日历 GUI 界面项目的完整代码。通过添加更多的函数和其他创新来开发这个日历项目的各种独特的应用程序,您可以随意试验代码。

我建议添加到日历中的一个主要改进是将所选日期保存在文本文件中的能力,以便您可以在不同的 Python 项目中使用这些保存的日期来构建待办事项提醒列表,该列表将提醒您某人的生日、特定事件、重要日期等等。我建议检查一个以前的提醒应用程序项目,为这些日期创建一个提醒提醒。

另一个绝妙的主意是将你的日历与特定的日期联系起来,使你的电子邮件自动化,或者将信息转发给你想接收信息的人。我们将讨论如何实现这些目标的未来项目。在此之前,请继续探索您刚刚创建的日历的众多隐藏可能性!

结论:

由este 扬森斯在 Unsplash 上拍摄

“时间是免费的,但它是无价的。你不能拥有它,但你可以使用它。你不能留着它,但你可以花它。一旦你失去了它,就再也找不回来了。”
—哈维·麦凯

日历是生活中必不可少的一部分,因为它帮助我们管理一年中的日程、计划和其他任务。它们帮助我们很好地记录时间,但显示在墙上的项目或手机上的日历应用程序有时会很无聊。你不能添加额外的功能到它们里面,这些功能完全是你自己构建的。因此,构建自己的日历 GUI 是一个好主意!

在本文中,我们讨论了时间的重要性,并使用 Tkinter GUI 界面构建了一个日历项目。我们能够从图形界面中选择日期,并单击界面上的一个按钮,向我们返回一个存储所选日期、日期和年份的标签。我们还研究了通过额外的更新和集成可以对此项目进行的一些改进。

如果你想在我的文章发表后第一时间得到通知,请点击下面的链接订阅邮件推荐。如果你希望支持其他作者和我,请订阅下面的链接。

https://bharath-k1297.medium/membership

如果你对这篇文章中提到的各点有任何疑问,请在下面的评论中告诉我。我会尽快给你回复。

看看我的一些与本文主题相关的文章,你可能也会喜欢阅读!

谢谢你们坚持到最后。我希望你们都喜欢这篇文章。祝大家有美好的一天!

用 Python 开发自己的牛顿-拉夫森算法

原文:https://towardsdatascience/develop-your-own-newton-raphson-algorithm-in-python-a20a5b68c7dd

求解最优解、平衡点等。使用 NR 方法

戴维·克洛德在 Unsplash 上的照片

牛顿-拉夫森方法是一种迭代方法,用于逼近函数的根或零点。由于许多原因,确定根可能是重要的;它们可以用来优化金融问题,解决物理学中的平衡点,模拟计算流体动力学等。正如你所看到的,它的用途远远超出了任何一个主题。一般来说,在复杂的方程中,根是不能明确求解的,所以它们必须是近似的;这就是牛顿-拉夫森方法发挥作用的地方。

牛顿-拉夫森方法(或算法)是计算根的最流行的方法之一,因为它简单而快速。结合计算机,该算法可以在不到一秒的时间内求解根。该方法要求函数符合以下形式。在大多数情况下,这可以通过简单的加法或减法来实现。

以下面的例子为例。简单的减法就是将方程转换成上面的形式所需要的。等式的左边将是函数, f(x) 。我们稍后会用到这个等式,所以请记住它。

该方法的第一步采用初始猜测,并使用函数和函数导数来计算下一个猜测。然后,以类似的方式使用该猜测来计算下一个猜测,依此类推,直到满足容差或迭代限制。如下面的动画所示,导数f’(x)(红线)被用作斜率,以帮助计算 x 的下一个猜测值。

牛顿-拉夫森方法可视化【由拉尔夫·普费菲创造】

让我们把方程中发生的事情写出来,这样更有意义一点。第一次迭代如下所示:

第二次迭代:

后续迭代,直到达到 f(xᵢ) 值的某个容差(或迭代极限):

如果你(或者一个代码)可以计算出 f(x) 的导数,那么你就可以用这个算法迭代计算一个方程的根。你最初的猜测可能非常重要。根据问题的不同,如果你从一个糟糕的猜测开始,它会让你的收敛需要一段时间或者根本不收敛。然而,如果猜测正确,牛顿-拉夫森算法将在几次迭代内相对快速地收敛到一个解。如果你有一个多重根的方程,你最初的猜测也很重要。根据你的第一个猜测,你可以收敛到任何一个根。这些问题可以通过使用有根据的初步猜测来缓解。

牛顿-拉夫森算法可以使用 Python 或任何编码语言相对容易地实现。正如你在例子中看到的,当最初的猜测是合理的时候,计算机可以很快得出想要的答案。我们还会看到当你最初的猜测很糟糕时会发生什么。让我们开始编码:

导入包

我通常通过从 Matplotlib 导入 N umPypyplot 来开始我所有的 Python 代码。 NumPy (为便于调用,定义为 np )用于数组操作和基本数学函数,如余弦、正弦、指数和对数函数。 Pyplot (为便于调用,定义为 plt )用于创建图形和可视化数据。这两个软件包都很棒,比我在这里展示的功能多得多。

# Importing Packages
import numpy as np
import matplotlib.pyplot as plt

定义函数

在这部分代码中,我们将定义一个方程,我们试图找到它的根和它的导数。这两个方程将被定义为 Python 函数,所以我们可以为它们提供一个输入值, x ,它们将返回方程的值及其在该值处的导数。作为参考,我们将使用本文前面的等式。

# Defining Equation and Derivative
def f(x):
    res = np.cos(x)-2*x**3
    return res

def dfdx(x):
    res = -np.sin(x)-6*x**2
    return res

牛顿-拉夫逊回路

本节提供了确定目标方程的根所需的迭代循环。在迭代 while 循环之前,最好包含一个最大迭代次数变量 max_iter 。这很重要,因为如果算法不能收敛到一个解,它将防止 while 循环无限期运行。公差 tol ,用于确保我们得到我们想要的精度。在开始我们的迭代之前,我们还包括最初的猜测,【x₀】。

现在,在 while 循环中,我们使用牛顿-拉夫森通用方程来获得我们的下一个猜测,【Xi】,根据上一个猜测,【Xi _ 1*(x₀用于第一次迭代)。然后将 xi 值输入到原始方程中,以对照所选公差进行检查。这里,我们正在确定我们的新猜测是否使原始方程接近于零。当等式的绝对值小于我们的容差或者我们已经达到最大迭代次数时,将会中断 while 循环。如果它没有被破坏,循环继续更新对根的值的猜测。*

*# Newton-Raphson Algorithm
max_iter = 20  # Max iterations
tol = 1E-15  # Tolerance
i = 0  # Iteration counter
x0 = 1  # Initial guess
xi_1 = x0
print(‘Iteration ‘ + str(i) + ‘: x = ‘ + str(x0) + ‘, f(x) = ‘ + 
      str(f(x0)))# Iterating until either the tolerance or max iterations is met
while abs(f(xi_1)) > tol or i > max_iter:
    i = i + 1
    xi = xi_1-f(xi_1)/dfdx(xi_1)  # Newton-Raphson equation
    print(‘Iteration ‘ + str(i) + ‘: x = ‘ + str(xi) + ‘, f(x) = ‘ +    
          str(f(xi)))
    xi_1 = xi*

你可能已经注意到,我们在每次迭代中打印了**【Xi】**f(xi) 的值,以及它们发生在什么迭代中。这有助于我们跟踪算法的执行情况。该代码将输出以下内容:

*Iteration 0: x = 1, f(x) = -1.4596976941318602
Iteration 1: x = 0.7866397888154096, f(x) = -0.2673205221391448
Iteration 2: x = 0.7261709381607133, f(x) = -0.018132645287873284
Iteration 3: x = 0.7214340390454733, f(x) = -0.0001059518195203335
Iteration 4: x = 0.7214060336500903, f(x) = -3.6893424981698786e-09
Iteration 5: x = 0.721406032674848, f(x) = -1.1102230246251565e-16*

在查看我们的输出后,看起来牛顿-拉夫森算法在 5 次迭代内收敛。相当快。它也接近我们非常小的公差的解决方案。这意味着我们成功实现了融合!

绘制方程和结果

您可以通过绘制包含最终根结果的范围的方程来检查您的结果。您也可以绘制您的根值,以查看您的结果如何与直线匹配。

*# Creating Data for the Line
x_plot = np.linspace(-2, 2, 1000)
y_plot = f(x_plot)

# Plotting Function
fig = plt.figure()
plt.plot(x_plot, y_plot, c=’blue’)
plt.plot(xi, f(xi), c=’red’, marker=’o’, fillstyle=’none’)
plt.xlim([-2, 2])
plt.ylim([-2, 2])
plt.xlabel(‘x’)
plt.ylabel(‘y’)
plt.grid()
plt.show()*

这将创建下面的情节。正如你所看到的,牛顿-拉夫森算法的结果与 x 轴交叉处非常吻合。这意味着我们计算了这个例子方程的根的一个很好的近似值。

牛顿-拉夫森示例[由作者创建]

让我们尝试一个不好的猜测,看看牛顿-拉夫森方法有多好。如果我们不知道零可能在哪里,我们可能会猜测根在 100 左右。这将导致算法花费 17 次迭代来达到最终结果,但是它仍然以期望的容差达到最终结果。这就是算法的力量。以下是这次试验的结果,以供参考:

*Iteration 0: x = 100, f(x) = -1999999.1376811278
Iteration 1: x = 66.66639972214995, f(x) = -592586.2434629743
Iteration 2: x = 44.44370527065607, f(x) = -175573.33453879558
Iteration 3: x = 29.629768898508654, f(x) = -52025.53704873974
Iteration 4: x = 19.751306671606308, f(x) = -15409.906816284196
Iteration 5: x = 13.170008297565373, f(x) = -4567.829385058682
Iteration 6: x = 8.783189380524185, f(x) = -1355.9491714365759
Iteration 7: x = 5.857511541738072, f(x) = -401.03685300814516
Iteration 8: x = 3.9055163566277287, f(x) = -119.86426242296075
Iteration 9: x = 2.585811794335439, f(x) = -35.42914973938403
Iteration 10: x = 1.7141632818943917, f(x) = -10.216519425753903
Iteration 11: x = 1.1654743473093252, f(x) = -2.7718839271038136
Iteration 12: x = 0.859829105239771, f(x) = -0.6187868181406497
Iteration 13: x = 0.7406842579217826, f(x) = -0.07469127827436395
Iteration 14: x = 0.7218536001388265, f(x) = -0.0016940906277266299
Iteration 15: x = 0.7214062815658834, f(x) = -9.415553438030244e-07
Iteration 16: x = 0.721406032674925, f(x) = -2.9121149935917856e-13
Iteration 17: x = 0.721406032674848, f(x) = -1.1102230246251565e-16*

正如你所看到的,这是一个非常强大的方法来获得一个方程的零点的非常接近的近似值。根的求解可以不用基于图的猜测,也不用代数求解(如果可能的话)。这可以应用于许多不同的领域,所以你自己试试吧!

感谢您阅读文章!如果您对代码有任何问题或者想了解更多关于这种方法的信息,请告诉我。如果你有兴趣,可以看看我关于 Python、轨道力学和物理学的其他文章!

用 Python 开发不到 10 行的天气应用程序

原文:https://towardsdatascience/develop-your-weather-application-with-python-in-less-than-10-lines-6d092c6dcbc9

使用 Python 构建我们的天气电视广播应用程序,以接收所需位置的更新

美国国家海洋和大气管理局在 Unsplash 拍摄的照片

天气是我们生活中最重要的方面之一。它规定了我们想要在一天、一周或一个月中计划的不同种类的活动。解读天气模式的一种古老方法是观察天空,预测天气是晴朗、下雨还是潮湿。

如果你不像我一样精通气候,并且总是以预测错误告终,这种方法可能不是最有效的。另一种方法包括等待和观看新闻频道的每日报道来分析天气。然而,这些方式对于我们今天生活的现代来说似乎有点过时了。

有不同的设备和工具可以让你从卫星报告和众多的科学研究中解读当前的天气状况。在本文中,我们将利用 Python 中的 API 技术,用不到十行代码创建您自己的天气预报应用程序。所以,事不宜迟,让我们开始完成这个项目。

发展我们的天气电视广播:

照片由唐纳德·詹纳蒂在 Unsplash 上拍摄

对于这个项目,我们将利用 Python 和一个天气报告服务,该服务为我们提供一个 API 密钥来解释任何特定地方的每日天气情况。这个项目需要的少数几个库需求之一是 Python 中可用的请求模块。如果您还没有它,可以用一个简单的 pip install 命令安装下面的模块,并导入如下所示的库。这个工具将允许我们直接访问所需天气 API 应用程序的 HTTP 链接。

import requests

现在,我们将需要一个网站的 API 键,该网站存储有关天气的信息,并预测它们的准确结果。 Open Weather Map 网站提供了一种科学而简单的方法,在我们的 Python 代码中利用他们的技术来快速生成天气预报的预期结果。要生成您自己的 API 密钥,只需登录以下网站并创建一个完全免费的帐户。您可以使用他们建议的 API 密钥之一,也可以自己生成一个。将这个生成的 API 键粘贴到您选择的变量中,如下所示。

API_Key = ""

我们的下一步是允许用户输入他们想要分析或查看天气状况的位置。我们可以使用输入命令执行以下操作,允许用户在所需的位置键入内容。请注意,只允许您键入实际存在的位置。如果您键入了错误的位置名称或不存在的位置名称,将会显示一条错误消息。

我们现在将创建一个变量来存储天气访问网站的默认 URL 位置。对于最终的 URL,我们将把打开的天气地图网站的默认路径与我们之前生成并存储在 API_Key 变量中的 API 键结合起来。最后,在天气数据变量中,我们将使用请求库来获取天气数据并相应地存储信息。

location = input("Enter Your Desired Location: ")weather_url = f"http://api.openweathermap/data/2.5/weather?q={location}&appid="
final_url = weather_url + API_Keyweather_data = requests.get(final_url).json()

现在,我们已经成功地在各自的变量中收集了天气信息,我们可以继续向用户显示所需的数据。下面的操作可以用 print 语句来完成,如下面的代码片段所示。

print(weather_data)

您可能会注意到,print 语句中显示的信息并不像您预期的那样漂亮,因为收集和显示的数据是原始格式的。因此,我们可以利用 Data pretty 打印机模块,以一种对用户来说更可展示、更可读的方式打印有用的信息。

from pprint import pprintpprint(weather_data)

在本文的下一部分,我们将查看构建天气应用程序的完整代码,并分析我们可以对该项目进行的大量改进和提高。

最终代码和进一步改进:

通过对上一节中所有基本代码片段的讨论,我们可以将它们组合在一起,为这个项目构建最终的代码块。请随意使用下面提供的代码来试验不同的位置。下面是一个结果,显示了这个项目的有效运作。

import requests
from pprint import pprintAPI_Key = ""location = input("Enter Your Desired Location: ")weather_url = f"[http://api.openweathermap/data/2.5/weather?q={location}&appid=](http://api.openweathermap/data/2.5/weather?q={location}&appid=)"
final_url = weather_url + API_Keyweather_data = requests.get(final_url).json()pprint(weather_data)

作者截图

Enter Your Desired Location: Bangalore
{'base': 'stations',
 'clouds': {'all': 15},
 'cod': 200,
 'coord': {'lat': 12.9762, 'lon': 77.6033},
 'dt': 1641477819,
 'id': 1277333,
 'main': {'feels_like': 294.17,
          'grnd_level': 912,
          'humidity': 45,
          'pressure': 1013,
          'sea_level': 1013,
          'temp': 294.78,
          'temp_max': 296.05,
          'temp_min': 294.78},
 'name': 'Bengaluru',
 'sys': {'country': 'IN',
         'id': 2040609,
         'sunrise': 1641431598,
         'sunset': 1641472610,
         'type': 2},
 'timezone': 19800,
 'visibility': 10000,
 'weather': [{'description': 'few clouds',
              'icon': '02n',
              'id': 801,
              'main': 'Clouds'}],
 'wind': {'deg': 118, 'gust': 8.31, 'speed': 4.81}}

用户可以试用这个项目的一个独特的变化是,每当你启动这个程序时,显示你所在位置的天气报告。并且每隔几个小时继续显示一次,以便快速检查气候变化,从而相应地计划您的日程。您可以按照代码中的要求设置您想要的位置,并以类似于我在以前的一篇文章中提到的提醒应用程序的方式构造项目。请随意从下面提供的链接中查看。

用户可以做出的另一个额外改进是构建一个 GUI 应用程序来相应地显示天气状况。如果你不太熟悉 Python 的图形工具,你可以看看我以前的一篇文章,了解更多关于 7 个最好的 GUI 的入门代码。

</7-best-ui-graphics-tools-for-python-developers-with-starter-codes-2e46c248b47c>

结论:

NOAA 在 Unsplash 上拍摄的照片

"无论你去哪里,无论天气如何,都要带上自己的阳光."安东尼·j·德安杰洛

如前所述,天气在我们的日常生活中起着至关重要的作用。因此,开发一个天气应用程序来帮助我们成功地跟踪自然的这一不可或缺的元素是非常有益的,这样我们就可以相应地计划我们的时间表,并选择我们日常生活中的最佳行动路线。

在本文中,我们学习了如何用大约十行 Python 代码构建一个天气预报应用程序。我们研究了简单的 API 密钥生成,并使用请求模块来访问显示特定位置的准确天气报告所需的信息。我们还分析了一些额外的改进,我们可以习惯于这个项目,使它更有吸引力和有用。

如果你想在我的文章发表后第一时间得到通知,请点击下面的链接订阅邮件推荐。如果你希望支持其他作者和我,请订阅下面的链接。

https://bharath-k1297.medium/membership

如果你对这篇文章中提到的各点有任何疑问,请在下面的评论中告诉我。我会尽快给你回复。

看看我的一些与本文主题相关的文章,你可能也会喜欢阅读!

谢谢你们坚持到最后。我希望你们都喜欢这篇文章。祝大家有美好的一天!

为浓缩咖啡建立一个体面的形象

原文:https://towardsdatascience/developing-a-decent-profile-for-espresso-c2750bed053f

咖啡数据科学

试图模仿金快车

我等着买一台像样的浓缩咖啡机,因为我仍在寻找我的 Kim Express 机器的改进之处,但我最终买了这台由数据和控制回路驱动的机器。到达后,我立即着手制定一个与我的 Kim Express 相关的基线,然后从那里开始改进。

所有图片由作者提供

金特快列车

金快递是一个弹簧杠杆机器,在我看来,是最好的家用杠杆机器,特别是对于不受控制的水锅炉。这台机器提供了许多有趣的能力,但它们都不是金特快独有的。许多功能与其他杠杆机器相同,这些功能指导我充分利用 DE:

预浸:由于活塞允许水进入咖啡球,所有的杠杆机器都提供自然的预浸,并且这种预浸是可变的。使用控制杆,您可以缩短或延长预输注时间,甚至改变预输注压力。

水温:灯头在锅炉内部,所以灯头处的水温非常接近锅炉,这使得水温保持在锅炉的温度附近。因为加热器是不受控制的,所以仍然有一些温度冲浪,但它比其他机器更容易管理。

体面的个人资料

开发这些配置文件教会了我很多关于机器如何运行的知识,当我开始向前倾斜时,我的配置文件能够变得非常好。在这两者之间,我有许多个人资料,但我想强调最有趣的变化以及我是如何做到这一点的。

压力脉冲 1

这第一个轮廓是建立在开花轮廓上的。我用的是同样的预灌注,开花期间没有压力。我对脉冲进行了明确的转换,但这些脉冲有一个大约 3 秒的大间隔。我在金特快上的典型间隔是 0.5 秒。在 profile maker 中,我还被限制了最多 20 步。

我开始的时候水温是 97C,但是经过思考后我开始改变它。

压力脉动 2

我首先减少了预灌注时间,然后是温度,我在开花期增加了一个缓慢的斜坡。

压力脉动 3

预输注对我来说不太合适,所以我从一个较慢的斜坡开始,但它仍然由流量控制。我也开始最大限度地提高温度,因为我发现金快车的温度要高得多。事实上,我发现 116℃到 123℃之间的罐温范围对 Kim 来说是理想的,因为它提供了大约 2.2 巴的罐压,这对于预浸泡来说是理想的。

另外,我把开花期的流速调得比零高。金快车没有零压开花阶段,我认为这有助于排出一些释放的二氧化碳。

压力脉动 9

我延长了花期,并开始计算何时结束基于水进入冰球的预灌注。这可以在咖啡和重量中拨入。我的目标是过滤器在进入开花期之前被咖啡覆盖。人们建议使用秤和最初的几滴,但当时,我的 Acaia Pyxis 不被支持。这种情况正在改变,但最好的办法是用相机来提供这种反馈。

压力脉动 14

我把开花期调整到压力控制,就像 2.2 巴左右的 Kim Express。我还设置了 10 毫升的退出标准,因为我通常会等待大约那么多的液体出来。

然后这是偶然发生的:

冰球在开花阶段产生阻力,导致 PID 控制器中的质量波动,因为流量和压力控制器努力达到它们的目标。

我意识到,通常人们会把压力和流量作为你实际可以达到的目标,但也许这可以成为我的优势。

压力脉冲 16:改变脉冲

我进行了一项测试,将压力目标设置为高于适当的流量目标。我意识到这是一种不用 18 步就能产生更快脉冲的方法。

压力脉动 20

我将预输注变得更简单,并且我在压力脉动部分做了改变。开花期的流量目标是有问题的。

压力脉冲 27

我再次将开花期转换为压力目标,并在预输注中添加了第二期。第一阶段是让所有人自由达到我的压力目标,然后我开始寻找一个退出点。

压力脉冲 28

在压力脉动期间,我开始增加压力目标,并改变了流量和压力从 2 巴/步过渡到 6 巴/步的速度。改变步进限制器有助于增加脉冲频率。

压力脉动 30

然后,我修改了预输注,使其在流速低于 3 ml/s 时结束。这更接近我的全自动化目标。

压力脉动 33

我再次增加压力脉冲,我开始接近 1 秒的脉冲间隔。然而,压力徘徊在 3 到 4 巴之间。多次发射的平均压力在 3 到 4 之间。这远远低于人们认为你应该使用的 6 到 9 格浓缩咖啡,但我的提取率很高。

压力脉动 36

我再次增加脉冲的压力,但是我也发现了一个问题。如果我的拨片拨得不对或者剂量太高,压力脉冲就不会正常工作。相反,如果剂量太低或研磨太粗。所以我开始建立一个适应性档案。

压力脉冲 38 自适应

我定义了压力截止点,因此如果压力由于高阻力而变高,它可以下降到较低的压力并继续。我又做了一个改变,插入阶段,让压力下降一点,然后再尝试脉冲。每个阶段都有一套不同的压力和流量目标,以允许持续的压力脉动。

压力脉冲 40 手动

对于所有这些变化,我仍然没有在盖上过滤器的时候停止预输注。花开也不是在最好的时候结束的。所以我做了一个 profile 延长预灌注和开花来强迫我手动进入下一阶段。这一改变稍微影响了提取并减少了消耗。

更改日志

我做了很多小改动,还原了很多改动。我追踪它们是为了好玩,在这里未经编辑就把它们呈现出来。

绩效指标

我使用一些指标来评估技术之间的差异:最终得分和咖啡萃取。

最终得分 是记分卡 7 个指标(尖锐、浓郁、糖浆、甜味、酸味、苦味和回味)的平均值。当然,这些分数是主观的,但它们符合我的口味,帮助我提高了我的拍摄水平。分数有一些变化。我的目标是保持每个指标的一致性,但有时粒度很难确定。

用折射仪测量总溶解固体量(TDS),这个数字结合咖啡的输出重量和输入重量用于确定提取到杯中的咖啡的百分比,称为提取率(EY)** 。**

强度半径(IR) 定义为 TDS vs EY 控制图上原点的半径,所以 IR = sqrt( TDS + EY)。这一指标有助于标准化产量或酿造比的击球性能。

我还采用了每个配置文件的最大 TDS、EY、IR 和最终得分(味道)指标,以查看数据显示了什么,并警告有多次烘烤:

随着时间的推移,TDS、EY 和 IR 都开始出现大幅增长,但有些是倒退。也有一些断奏镜头混合在一起,在所有指标中得分更高。

我的 Pyxis 秤现在得到了支持,所以我做了一些基于输出重量的结束步骤的工作,特别是开花。然而,我仍然发现在过滤器被覆盖的基础上结束预浸的第二阶段已经提供了最好的提取产量。

如果你愿意,可以在推特、 YouTube 和 Instagram 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。也可以关注我在中和订阅。

我的进一步阅读:

我未来的书

我的链接

浓缩咖啡系列文章

工作和学校故事集

与 GPT-3 一起为一个非政府组织开发战略机器人

原文:https://towardsdatascience/developing-a-strategy-bot-for-an-ngo-39cddf912eba

如何创建自己的自定义版本的 GPT-3,甚至更好的结果

JESHOOTS.COM在 Unsplash 上拍照

这是怎么回事?

当 OpenAI 在 2020 年发布 GPT-3 时,自然语言处理(NLP)社区变得疯狂(类似于过去几个月由文本到图像模型创造的炒作,如 DALL-E 2 和稳定扩散)。几周之内,人们意识到并收获了用 GPT-3 创造惊人演示和应用的潜力,并取得了惊人的成果。2021 年 12 月,OpenAI 引入了微调 GPT-3 的能力,这意味着客户可以根据他们的特定应用创建他们自己的定制版本的模型。

在这篇博文中,我们将学习如何创建一个定制版的 GPT 3,我们还将看到一个非政府组织如何使用这项技术为年轻的社会企业家创建一个战略机器人。

为什么这很重要?

自从引入像 BERT ,微调这样的流行的最先进的 NLP 模型以来,这些 NLP 模型已经成为适应特定任务的主要机制。这种技术利用了 迁移学习 的概念:使用预先训练的模型,并使其适应新的(专门的)领域,这显著提高了模型性能并降低了训练成本。

来源:https://www . CSE . ust . hk/~ qyang/Docs/2009/tkde _ transfer _ learning . pdf

GPT-3 最初没有提供微调的选项。相反,它已经接受了各种任务和专业领域的训练,无需进一步训练就能表现出色。然而,随着时间的推移,组织开始意识到开箱即用的模型令人印象深刻,但往往不够好,不足以用于生产。

在定制数据集上微调 GPT-3 并创建其定制版本的选项将使模型性能超过组织可以轻松将其用于生产工作负载的阈值。

问题陈述

阿育王成立于 1980 年,是世界上最大的社会企业家网络。这些社会企业家开发系统改变解决方案,通常以战略文件开始,详细说明他们想要解决的问题,他们的方法,以及他们的解决方案如何扩大间接和系统的影响。制定这些策略可能是一项艰巨的任务,Ashoka 希望用一个策略机器人来支持社会企业家,即一个可以帮助编写这些策略的文本生成模型。

他们尝试了 GPT-3 的普通版本,发现结果很有希望,但对于他们的特定目的来说还不够好。他们知道微调 GPT-3 的选项,并需要有人可以在他们的数据集上训练模型,这就是我参与的地方🙂那么,让我们来看看我们该如何着手此事!

解决方案演练

阿育王有 4000 多份以前的战略文件样本,加上一点功能工程,是 GPT-3 的一个很好的训练数据集。在开始微调之旅之前,我们还想了解一下它的成本。最后,在开始培训之前,我们必须以特定的方式准备数据集。让我们一步一步来。

数据准备

Ashoka 提供的数据集由几列感兴趣的文本组成,我们的目标是将它们浓缩成两列:一列是提示文本,另一列是我们希望 GPT-3(理想情况下)从提示中生成的文本。这是根据 OpenAI 的指导方针,数据需要如何准备进行微调:

来源:https://beta.openai/docs/guides/fine-tuning

对于提示文本,我们可以使用数据集中名为简介的列。不过,有些还是太长了,所以我们决定只把那篇文章的前两句话作为提示。此外,我们发现,如果我们在提示符后附加一条简短的指令,GPT-3 的性能甚至会更好:

该练习的结果将如下所示:

作者图片

类似地,我们将把来自不同列的文本编译成完成特性,让 GPT-3 知道我们希望它生成什么。要了解这些策略需要什么,你可以查看 https://www.ashoka/en-us/story/strategy-plan-action 的。

需要注意的是,完成文本应该有一个独特的短语来表示文本生成的结束(关于这个的更多信息在 OpenAI 的网站)。因此,我们以这段代码结束了创建完成:

估价

既然我们已经准备好了数据,我们可以提交它来创建培训作业。不过,在我们这么做之前,我们想快速计算一下培训的成本——没有什么比培训一个模型之后才意识到成本远远超出预期更糟糕的了。(事实上,如果 OpenAI 能够提供一个预先估计微调工作价格的功能,那就太好了,但据我所知,在我撰写本文时,这个功能还不存在)

幸运的是 OpenAI 的定价网站给了我们一些如何计算价格的线索:培训最有能力的模型(达芬奇)的费用是每 1000 个代币 3 美分。该网站还声明,一个代币是文字块,1 个代币大约相当于 4 个字符:

来源:https://openai/api/pricing/

最后,OpenAI 还提供了一些关于我们应该在多少个例子上训练模型的指导:

来源:https://beta . open ai . com/docs/guides/fine-tuning/preparing-your-dataset

我们决定用 500 个例子,因此我们的价格估计是,培训将花费我们大约 10 美元,相当实惠🤗

微调

我们已经准备好了数据,我们很清楚微调的成本,所以现在是扣动扳机的时候了。 OpenAI 的 API 参考非常清晰且易于理解——要微调模型,我们只需上传训练文件并调用 FineTune.create API:

作者图片

提交培训工作后,大约需要两个小时才能完成,但这显然取决于您的培训数据,您的里程可能会有所不同。培训工作完成后,新模型将出现在操场应用程序中:

作者图片

现在我们终于可以测试我们自己的 GPT-3 模型了😃

测试

在测试这些模型时,我们没有太多可以自动化的东西——不幸的是,仍然没有好的基准来评估生成的文本是否“好”。所以我们做了自己的手工测试,我们对模型的表现感到非常惊讶。

该模型从一个简单的想法中创建的策略包括间接和系统的影响,它还包括围绕开源和培训其他组织的各种聪明的策略。这正是我们所需要的🎉

结论

在这篇博文中,我们看到了创建我们自己的 GPT-3 模型是多么容易(而且相当实惠)。我们已经看到,微调模型的结果超出了我们的预期,足以用于生产工作负载。Ashoka 目前正在内部测试和实施这一模式,并将向社会企业家推广,以帮助他们创造新的战略,让世界变得更好🌍

如果你有兴趣联系,请联系 LinkedIn https://www . aiml . consulting/

用 aiSTROM 框架开发成功的人工智能策略

原文:https://towardsdatascience/developing-a-successful-ai-strategy-with-the-aistrom-framework-a1d8f979b2a9

由 Dall-E2 生成。

如何实现人工智能技术的战略

大量人工智能项目失败。Rackspace Technology 的调查估计这个数字高达 34% [2]。这种失败很大程度上是由于管理层不理解人工智能技术的风险和复杂性,反之亦然,开发人员不知道如何扩展技术或业务需求。许多管理人员似乎认为人工智能项目就像典型的软件项目一样,然而,也有一些特殊的挑战。这些挑战可能涉及团队所需的技能、要求模型透明的法律问题、大数据治理、采用的文化挑战等等。

在我最近关于aiSTROM——在 IEEE Access [1]中开发成功人工智能策略的路线图的论文中,我提出了如何应对这些挑战的详细路线图。缩写 aiSTROM 代表以人工智能为中心的战略路线图。如需深入讨论,请参考全文 [1]。在接下来的内容中,我们将简要介绍 aiSTROM 路线图的各个步骤。

aiStrom 概述,图片基于[1]。

1.发现机会

人工智能技术提供的机会可能是巨大的。aiSTROM 建议与领域级专家和技术专家一起举办头脑风暴研讨会,以提出一个 top- n 项目列表,例如前 5 个项目。在确定这些问题时要问的一些问题可能包括:我们的竞争对手在做什么?我们能自动化流程吗?我们能利用人工智能以新的方式做事并提供创新服务吗?

关于选择项目时需要注意的事项的完整列表和广泛讨论,请参考[1]。在下文中,将根据框架中的下一步,首先是"数据",审查每个项目的考虑因素。

2.数据

“大数据”的可用性是当前深度学习时代的催化剂之一,此外还有 CNN 等新技术以及 GPU 硬件的广泛可用性。我们可以将大数据的首次提及追溯到 1997 年的 Cox 和 ells worth[3]:

“……给计算机系统带来了一个有趣的挑战:数据集通常非常大,占用了主内存、本地磁盘甚至远程磁盘的容量。我们称之为大数据的问题。当数据集不适合主内存(在内核中)时,或者当它们甚至不适合本地磁盘时,最常见的解决方案是获取更多资源……”

大数据通常有三个特征:量(大量数据)、多样性(杂乱数据)和速度(快速增长)。这些最初的 V 有时会随着价值(商业价值)和准确性(偏见)而扩展。在机器学习中,需要大数据来训练我们的模型。这意味着我们需要建立必要的数据库或仓库基础设施来处理项目所需的容量。下面讨论一些需要记住的特殊注意事项。

**数据来源。**组织中是否已经有可用的数据?如果没有,可能需要收集,或者你会考虑购买数据吗?如果你考虑自己收集数据,请记住这需要很多时间,通常需要伦理委员会的批准,以及预处理和质量检查。然而,开始收集越早越好,即使你还不确定你是否需要这些数据。看看亚马逊 MTurk 等众包方法可能会提供一种比自我收集更快的替代方法,但在质量方面往往更差。找到正确、高质量的数据源是一项重要的决策。更多的数据通常是好的,但请记住贝尔曼[5]的“维数灾难”,以及维护大型数据池的成本高昂这一事实。

**法律问题。**存储/收集数据时,需要牢记大量隐私和安全注意事项。您是否遵守当地的隐私法,组织中谁有权访问数据等。是需要考虑的重要问题。有必要在允许人工智能员工大规模访问你公司的所有数据(快速开发想法)与隐私和安全之间找到一个良好的平衡。

**存储数据。**公司是组织内部存储(这涉及大量成本和管理人力),还是使用外部数据中心?在决定时,考虑数据应该存储在靠近客户所在地的地方,因为传输速度较慢。此外,这些数据是以原始形式存储,例如存储在一个数据湖中,还是经过预处理成为结构化形式?这些选择应考虑数据管理原则,如 CAP 定理和 PACELC 定理[4]。

3.人工智能团队

开发人工智能模型不仅仅是一项具有技术挑战性的任务,它涉及前沿模型和创造力,以及研究水平的思维能力和问题解决能力以及领域知识。Herremans 在[1] 中提供了一个更全面的技能列表。公司经常雇佣博士级别的开发人员,和/或与学术机构合作。另一种快速雇佣大量人才库的方法是通过收购:当一家公司收购另一家公司,但只是为了重用这些人员。这方面的一个例子是 2005 年谷歌雇佣 Android,当时还没有开发出任何产品。

4.艾在公司

人工智能的发展将会如何发生?

**团队定位。**AI 团队将如何在组织中定位?一些组织选择分散的方法,每个部门负责自己的人工智能项目。在一个更集中的方法中,可以雇佣一个可以跨部门工作的 CAI。这种方法可以形成一个卓越的中心或研究实验室。最后,一些组织可能更喜欢混合方法。最佳设置将取决于组织的需求和准备情况。

投资组合方法。 AI 项目和金融资产有一些共同点:两者都会有风险等级。一家公司可以实施一系列人工智能项目,这将降低风险,并在其中一些项目出错时提供缓冲。

AIaas —人工智能即服务。一些服务已经存在,为什么不直接使用 API 呢?这可能有效,但如果服务对核心业务至关重要,则不建议这样做。

是否在内部开发?外包可能是快速进行开发的一个好选择。这个决定可能取决于公司的人工智能准备程度。除了内部开发,另一个选择是收购一家已经开发出该技术的公司。

**敏捷。**像任何 IT 项目一样,敏捷开发方法通常被推荐。另一个最佳实践是 MLOps,这是 DevOps 与机器学习的融合。

5.技术

我们在这里的目的不是概述人工智能技术。但是,有意思的是,要强调与技术选择相关的几点:

准确性与黑盒。 AI 系统是随机系统。经理可以命令开发商预测客户的行为,但不能保证模型的准确性。事实上,这往往取决于它是否是一个黑箱模型(更准确,但无法解释)。在某些领域,如信用评分,法律要求公司对做出决定的原因做出解释。在这种情况下,需要使用简单、不太准确的系统,如基于规则的系统,而(通常)更准确的深度学习模型本质上是黑盒模型。

**人类在回路中。**一些策略使用预先标记的数据集,例如,有人浏览了数据并标记了照片中的所有汽车。然而,在强化学习策略中,系统将不断地接受来自用户的反馈和纠正。

取代或增加人类。人工智能系统通常被视为对人类工作的威胁。实际上,它们为用户提供了机会,使他们能够更好、更有创造性、更容易、更好地控制自己的工作。

**云与内部托管。**这一决定将基于内部托管服务器的成本(人力资本+设备)与订阅费,后者通常比租用服务器更容易扩展。

6.KPI

像任何项目一样,从一开始就有清晰的基于价值的成功指标是至关重要的。这些应该与组织的战略目标相联系。请注意上面的“基于价值”一词,这表明我们应该不仅仅关注财务目标,还应该关注人工智能技术如何为客户或员工创造价值。另外,考虑到 AI 模型是随机的,准确性也不能保证,这也是要评估的事情!

7.设定风险等级

AI 系统在开发过程中需要监控的 风险 包括:

  • 它们的随机性。模型可能无法准确工作!
  • 偏见和道德。在开发的任何模型中,必须避免种族/性别/…习得性偏见
  • 安全。该模型应该能够抵抗对抗性攻击以及欺骗攻击。
  • 其他战略决策。风险可能源自之前的任何决策:内部开发、招聘、托管失败、数据不安全等。

在考虑风险的时候,我们还要权衡 利益 。理想情况下,这些由上述基于价值的 KPI 来捕获。

一个 SWOT 分析 可以把这两者放在一起,提供一个很好的管理决策概览。

8.促成文化转变

直接参与项目的人员,无论是 it 经理还是开发人员,都必须了解人工智能技术。甚至其他员工,尽管他们看起来与项目相去甚远,也为组织的整体文化做出了贡献。接受人工智能教育的员工可能会基于他们对公司的特定知识贡献想法和见解。

通过建立一个卓越中心,该公司可以提高意识并教育员工,这将导致整个组织拥抱人工智能技术。任何对被人工智能技术取代的恐惧通常都会通过提高人工智能素养来缓解,因此这将极大地有助于培养人工智能采用的文化。

结论

我希望已经提供了一些伴随着实施长期人工智能战略而来的战略管理决策的良好概述。aiSTROM 提供了一个路线图,指导经理在实施人工智能战略时通过不同的领域和需要战略决策的领域。

如果你有兴趣阅读更多的细节,请查看原文 aiSTROM 论文,或者联系讨论我可以如何帮助你!需要生成 aiSTROM 报表的界面或模板,或者有其他需求,请告诉我!

关于作者

dorien herre mans(IEEE 资深会员)在安特卫普大学获得应用经济学博士学位。她获得了玛丽-居里奖学金,在伦敦玛丽皇后大学数字音乐中心工作。在此之前,她于 2005 年毕业于安特卫普大学管理信息系统专业,成为一名商业工程师。之后,她在世界领先的瑞士布鲁切莱斯罗切斯酒店管理学院担任 Drupal 顾问和 IT 讲师。她目前是新加坡科技与设计大学的助理教授。在 SUTD,她还是 SUTD 游戏实验室的主任,并领导音频、音乐和人工智能(AMAAI)实验室以及人工智能金融(AIFi)小组。她的激情包括战略思维以及人工智能技术的新颖应用。她在许多委员会和董事会任职,并应邀在世界各地发表演讲。她入选了新加坡 2021 年 100 名科技女性榜单,该榜单旨在表彰和庆祝新加坡为科技行业做出重大贡献的鼓舞人心的女性。

参考

[1] D. Herremans,“aiSTROM——开发一个成功的人工智能策略的路线图”,在 IEEE Access,第 9 卷,第 155826-155838 页,2021,doi:10.11109/Access . 2002003005

[2] *全球报告:组织在人工智能和机器学习方面取得成功了吗?*2021 年【在线】可用:【https://www.rackspace/solve/succeeding-ai-ml/ty.】T2

[3] M. Cox 和 D. Ellsworth,“用于核外可视化的应用程序控制的按需分页”, Proc .第八次会议。Vis。【VIS】《T5》,第 235 页,1997 年。

[4] M. Chen,S. Mao 和 Y. Liu,“大数据:一项调查”,移动网络。申请,第 19 卷,第 2 期,第 171–209 页,2014 年。

[5] R. Bellman,自适应控制过程:导游,普林斯顿,新泽西州,美国:普林斯顿大学出版社,第 3 卷,第 2 页,1961 年。

开发软件:使用 Linux,即使是在 Windows 中

原文:https://towardsdatascience/developing-software-use-linux-even-in-windows-62dfaff0c3e3

使用相同的操作系统进行开发,测试和部署

在开发、测试和生产中使用相同的环境,因此对于开发,测试和部署。由托尔加·乌尔坎在 Unsplash 拍摄的照片

下面的六个词构成了今天的故事:

在 Linux 中部署?在 Linux 中开发。

这比乍看起来更重要——对任何软件来说,数据科学产品也不例外。

有些人可能认为开发环境并不重要,特别是当项目中使用的编程语言可以在任何操作系统下工作时。但事实远不止如此。

即使你的编程语言可以在任何操作系统中工作,也不意味着它在所有操作系统中的工作方式都是一样的。有时候差异可能不会太大;有时候是这样的。这就像说所有的汽车都以非常相似的方式工作。基本上是这样,但这是否意味着你会使用沙漠环境来开发一辆在斯堪的纳维亚国家使用的汽车?当然不是。在这两种情况下,都需要四轮驱动,但在沙漠中工作良好的汽车可能在严冬条件下工作不太好。也许会,但你不能确定,是吗?

对于软件,事情以类似的方式工作。如果你想开发一个好的产品部署在一个特定的环境中,你应该在尽可能相似的环境中开发它。在 IT 部门,通常不可能重新创建一个生产环境,尤其是当该环境已经运行了相当长一段时间,并且为其客户提供了许多不同的软件产品时。尽管如此,通常还是有可能创建一个类似的环境,而且越类似于生产环境越好。

虽然这个主题很笼统,但本文将集中讨论这个故事的一个方面——但也是最重要的一个方面:操作系统。更准确地说,我将关注开发人员的工作方式,并考虑以下问题:当产品将被部署在 Linux 环境中时,我是否应该,或者我是否能够在 Windows 中进行开发?

为了简单起见,我将集中讨论这两个操作系统,原因有二。第一,在行业中,这两者在软件项目中频繁混用。第二,我对这两个操作系统有经验,但对其他操作系统经验不多。根据我开发数据科学软件的经验,在 Windows 机器上开发并部署到 Linux 是很常见的。这就是我几年来的工作方式。而这是没什么好怕的,只要你知道怎么做。

当提到三种类型的环境之一时,我将使用以下缩写:

  • DEV for 开发环境,
  • 测试测试环境,以及
  • 生产环境产品。

为什么?

我想你会同意我的观点,在 IT 领域,开发和生产环境中最重要的一个方面是操作系统。通常情况下,它将是环境中最重要的方面*,在开发、测试和部署时会产生很大的影响。*

不成文的规定如下:

在尽可能接近生产环境的环境中开发和测试代码。

注意,规则并不严格。它没有说同样的环境,而是一个尽可能接近生产环境的环境。由于这个细节,这个规则给了你相当大的调整余地。您可以根据具体情况,尤其是项目所拥有的资源来使用这种余量。但是如果你不想冒险让这个项目给你带来超出你所能接受的麻烦,尽量不要过度使用这个余量。如果你真的过度使用保证金,那你就活该头疼,除非你这么做是因为别人让你这么做的。我曾经遇到过这种情况,我非常头疼,因为我得到的开发资源有限,没有任何测试资源。

我想说,这条规则不仅仅与编程或 IT 相关。这是一个相当普遍的规则,类似于我们在科学中发现的许多类似的规则——就此而言,在我们的生活中也是如此。

为了说明这一点,让我给你看一个完全不同的例子。想象你正在开发一种新的植物除草剂。你应该在它将被应用的环境中开发它。让它成为一种用于谷类植物的除草剂。如果是这种情况,那么你不应该想在果园里进行实验(这是开发过程的一部分),而是用谷物——以及不同的谷物品种,就此而言,不只是一种。此外,你永远不应该把除草剂当作肥料、食品配料或飞机燃料来测试。不,你应该在尽可能接近最终产品的环境中开发和测试产品。

在我们软件开发的舒适区的背景下,应该如何理解这一点?正如你将在下一句中看到的,我们应该以非常相似的方式来理解它。当开发一个软件产品时——不管这个产品是什么——你应该在一个类似于生产环境的环境中开发和测试它。

为什么不能直接用生产环境本身来开发和测试产品呢?当我们已经在使用这种环境时,这难道不是最简单的方法吗(这在行业中是常有的事),也是最好的方法*?您几乎永远无法重新创建生产环境,除非是一个全新的环境。那么,为什么不使用它而不是重新创建它呢?*

事实上,这个看起来是目前为止最好的解决方案:产品将在它将被部署的相同环境中被开发。这样,在开发过程中就已经知道产品将如何在这个环境中工作,可能会发生什么样的问题(如果有的话),等等。没有其他环境能给我们提供这样的信心,使我们相信产品在生产中会很好地发挥作用。**

即使这种方法可能很诱人…它不仅不是最好的,而且可能非常危险。在我看来,只有在极少数情况下,当你完全没有其他选择的时候,你才应该选择这个解决方案。在开发软件的时候,我们总是可以对开发环境做一些改变,甚至打破它。有时,要恢复环境,您需要从头重新安装。这就是为什么我们不应该在生产环境中开发的原因:虽然破坏开发或测试环境是每个人都接受的风险,但是破坏生产环境会带来不可接受的风险,尤其是当生产环境已经被其他软件产品使用时。

这就是为什么软件通常在开发环境中开发,在测试环境中检查,然后在生产环境中部署。这给了我们自然的顺序DEV → TEST → PROD,尽管大多数项目包括混合了三个步骤中的两个,通常是DEV ↔ TESTTEST ↔ PROD

不幸的是,现实常常强加限制,迫使软件开发者适应有限的资源。我们经常被迫在两种环境中工作:开发和生产。如果你不幸发现自己在这样的项目中,你必须选择其中的哪一个应该成为测试环境。不幸的是,这两种解决方案都不好——说实话,最终,这类项目的测试阶段并不是真正的测试。虽然涉及到一些测试,但这不是真正的产品测试,除非你能在生产环境中执行。我说过,这是,也应该是,业内非常罕见的情况。

这三个环境(包括测试)的可用性对于有重要时间限制的项目特别有用。在我过去的一个项目中,我必须检查一个附加包的重新安装。不幸的是,当我这样做时,新版本的包破坏了测试环境。要再次使用它,我必须完全重新安装,但由于时间限制,这是不可能的。因此,在这里我使用开发环境进行开发和测试。但是,如果这发生在只有两个环境(DEV 和 PROD)的项目中会怎么样呢?我将不得不重新安装开发,没有时间了;除了夜以继日地工作,我还有什么选择呢?幸运的是,我是一个幸运的开发人员,有三个环境可以使用。因此,我能够在开发环境中完成产品,尽管我没有真正的可能性来测试产品。我直接从开发转到生产,由于产品的复杂性,这让我很不舒服。此外,在开发期间,开发环境经历了产品环境中没有的小的修改;直到我在 PROD 上完成安装并尝试运行该应用程序的那一刻,我才意识到这一点。最终,在额外的工作之后,一切都结束得很好,我完成了这个项目,并获得了一些重要的经验,从那以后我一直在使用这些经验。拥有三个环境总是一件好事:开发、测试和生产;在 DEV 上开发,然后在 test 上测试,只有在一切就绪后,才在 PROD 中部署。

让我们总结一下为什么?这里的部分解释了为什么我们应该在尽可能接近生产的环境中开发。为此,让我们使用上面使用的更具体的场景,即 Windows 对 Linux 开发。

当你正在开发的软件产品要部署在 Linux 机器上、云中或任何地方时,你应该用 Linux 开发代码。我猜在业界,Linux 是几乎总是的生产操作系统。在我们创建软件解决方案的 20 多个数据科学项目中,我记得只有一个项目我们必须将解决方案部署到 Windows 服务器上。这不是一开始就计划好的,而是一系列事件的意外结果。

总而言之,作为一名软件开发人员,你应该尽最大努力在尽可能接近计划生产环境的环境中开发和测试软件产品——而不是要部署产品的实际生产环境。

这基本上意味着,无论何时您在一个项目中工作,其中的解决方案将在 Linux 中部署,您也应该在 Linux 中开发和测试代码。

怎么会?

我想前一部分现在对你来说非常有意义。是吗?

应该的。这是它应该如何工作。但是很多时候,不管是在小公司还是大公司,甚至是最大的公司,情况都不是这样。

假设我们的小公司雇佣了 2-3 名开发人员和大约 10 名其他人员。不是 It 公司,是用的多的公司;比方说,它应用数据科学来支持它的研究,然后将它的结果呈现给外人。它的软件产品是数据科学产品,因此它们使用户能够为他们的数据运行一些模型。

像往常一样,该公司的员工使用装有 Windows 操作系统的笔记本电脑。然而,由于规模太小,该公司没有足够的资源来维护自己的服务器,以部署和维护他们的产品。因此,他们转而租用服务器和各种云服务。

我想你已经明白我的意思了。开发人员在 Windows 笔记本电脑上工作,但是在 Linux 环境中部署他们的产品。这不是他们的选择;这是他们仅有的资源。他们很少能使用他们的私人资源,即使他们想用(我不会),所以他们被迫使用他们所拥有的。对于开发,该资源是一台 Windows 笔记本电脑——这台笔记本电脑就是我们应该考虑的开发环境。

他们应该如何进行?

我们可以列出很多方法,但我将强调其中的两种。人们使用一种时下流行的工具,集装箱化。然而,这不是你通常认为的标准集装箱化。当我设想容器时,我通常看到它们在 PROD 环境中实现。在这里,我们将讨论用于开发的容器,它们不同于 PROD 中使用的容器。当我们讨论开发容器时,请记住这一点。

第二种方法提供了第一种方法所没有的工作便利性。当在 Windows 机器上使用 Linux 时,这是可行的——但不使用虚拟机,因为这种方法,至少在我看来,很不方便。相反,这种方法使用 Linux 的 Windows 子系统(WSL)。我一直在使用它,在我几乎所有的项目中——我非常重视它。

在这两者之间,容器化使您能够使用类似的环境来生产。由于 WSL 使用安装在您机器上的 Linux 子系统,模拟 PROD 操作系统是非常困难的,通常是不可能的,特别是对于几个项目。WSL 的主要好处是它可以在大多数项目中使用,但是这个优点很容易变成一个缺点。一旦我们完成了开发容器,我们将回到这个方法。

开发容器

如前所述,它们与生产容器不同:前者用于在 DEV 环境中开发产品,而后者用于在 PROD 环境中安装产品(及其环境)。

开发容器提供了一个专用的开发环境。在这里,您可能有单元测试,这在生产容器中是不需要的。同样,您可能需要一些在生产中不需要的附加包。通常,开发容器的组织方式不同于生产容器。简单地说,组织它们就像在本地机器上开发代码一样,没有容器。

考虑下面的例子。您开发您的代码,以便一旦代码准备好就可以打包。因此,您的开发容器将包含一个文件夹,您将在其中保存要打包的代码。另一方面,您的生产容器将而不是包含这些原始代码。相反,这个包将从包注册中心安装到生产容器中。这导致两种类型的容器具有非常不同的组织结构。

通常,您的开发容器将提供与生产容器环境相似的环境。但是,它可以包含 PROD 中不需要的其他工具。因此,在开发环境中运行良好的代码不一定要在生产环境中以同样的方式运行——您需要检查这一点。然后你可以测试生产容器,为此,有一个测试环境是很好的。

在我看来,开发容器非常有意义,而且非常有帮助。然而,它们有一个明显的缺点:使用它们很困难。一方面,容器应该在不同的机器上以相同的方式运行。另一方面,它们会造成一些困难,尤其是在几台 Windows 机器上使用时;机器越多,发生意外的风险就越大。有时它可能是非常小的事情,但找到解决方案可能比看起来要困难得多。

用于 Linux 的 Windows 子系统(WSL)

WSL 提供了一个在 Windows 操作系统中模拟 Linux 的好方法。用了好几年了,很欣赏。

当您选择安装了 WSL 的 Windows 机器时,您可以同时使用 Windows 和 Linux。在许多项目中,您可能需要能够使用 Windows。当你别无选择,必须使用 Windows 机器时(这可能是由于公司资源的原因),WSL 是开发人员的绝佳选择,因为正如我之前提到的,大多数软件产品都部署在 Linux 中。

许多用户没有选择,但是我有:我可以选择 Linux 机器。而是选择了 Windows 机,我这么做是有原因的。我这样做是因为有时出于各种原因,我不得不使用 Windows。在这种情况下,Linux 机器没有任何帮助。所以,我有了 Windows——感谢 WSL,我也有了 Linux。如果我没有使用 WSL 的可能性,我会更喜欢使用 Linux 机器。但是自从我可以使用 WSL 以来,我完全可以使用 Windows 笔记本电脑。

我知道,这很重要。WSL 不是 Linux。它没有真正的 Linux 快。可能存在差异,有些差异不如其他差异显著。但是,作为一个开发代码的人,所有这些对我来说并没有什么大问题。例如,WSL 没有 Linux 快?我开发代码,而不是运行它;所以,这对我来说根本不是问题。其他问题?是的,我遇到过一些小问题(例如,行尾),但是它们太容易解决了,我甚至都不记得了。坦白地说,我确实遇到了一个关于行尾的大问题,但是是在…一个开发容器中!

在 Windows 机器上使用 WSL 还有一个好处。当你开发一个可以在两个操作系统中使用的产品时,你应该在两个操作系统中检查你的产品。虽然 WSL 当然不是真正的 Linux(尽管 WSL 2 确实有一个 Linux 内核),但是当某些东西在 WSL 中工作时,它很可能也在 Linux 中工作。例如,我已经编写或合作编写了四个开源包( easycheck 、 makepackage 、 perftester 和rounder);我在 WSL 中处理了每一个问题,然后在 Windows 中检查了每一个问题。

总而言之,当你在 WSL 中开发时,你可以在一个将要开发产品的操作系统中开发(除非这个 OS 没有 WSL 版本)。一旦完成了 WSL 的安装,一切都变得简单了。最重要的 ide 与 WSL 合作。我使用 Visual Studio 代码,由于专用的 WSL 扩展,它工作得非常好。当我在 WSL 中开发时,我有在 Linux 中开发的相同感觉。

老实说,现在我已经好几年没有在 Windows 上开发任何有意义的东西了,我感觉自己像个 Linux 迷。每当我转移到生产环境时,几乎总是在 Linux 中,一切都感觉很自然。如果你曾经试图在 Windows 中开发一个可以在 Linux 中部署的产品,你应该明白我的意思。我去过那里,那种感觉并不好。就好像产品内部的某些东西似乎是错误的,可能会导致大问题。WSL 是一种很好的止痛药,它让我作为开发人员的生活变得更好;实际上,是为了更好。

开发容器还是 WSL?

我和他们都合作过。虽然很难说哪个更好,但我知道我更喜欢哪个。这也是为什么我会把重点放在我的喜好上,并解释它们。然后你可以自己决定什么对你的项目更好。

老实说,如果没有我信任的 DevOps,我不会选择开发容器。我甚至不知道如何开始!有了一个好的 DevOps,开发容器可能是最好的解决方案——但是有时会减慢你的编码工作。在这种情况下,除非你知道如何解决这样的问题,否则你可能会感到非常沮丧,因为简单的事情似乎无法用简单的解决方案来解决,而你几乎肯定这些解决方案会奏效*。*

我记得在一个项目中,我们的 DevOps 在一个两人数据科学团队中编排开发容器,加上他自己作为第三个成员。虽然他对此没有问题(向他致敬!),我们确实遇到了一些问题,他不得不时不时地帮助我们。有一两次,我不得不重新构建整个容器,因为事情停止工作,没有特别的原因,只有重新安装似乎有所帮助。对我来说,这是一项艰难的工作。我们所有人都必须使用 Visual Studio 代码(这对我来说不成问题,因为我以前就用过),以及一些与容器相关的扩展。

我确实记得我在那个项目中遇到的一个重大而不寻常的问题。DevOps 最终找到了问题的根源,那就是 Git。我使用安装在 WSL 中的 Git,这是我一贯的做法。很明显,这个 Git 工具没有很好地与我们的开发容器配合。相反,我应该使用 Git bash 。在我开始使用那个之后,所有这些问题都消失了。我不喜欢这种奇怪的问题。对我来说,这个例子表明开发容器可能很精致——对我的开发人员来说太精致了。

总而言之,我认为开发容器提供了一个很好的解决方案,但是对于没有丰富 DevOps 知识的人来说太难了。没有它,任何安装和更改看起来都很困难。如果你遇到一个更大的问题,你可能会觉得自己很无助,就像我在上面描述的项目中几次遇到的那样。

另一方面,WSL 提供了一个简单得多的解决方案。要在您的机器上安装它,您不必是 DevOps。在过去的几年里,我在 WSL 中没有遇到任何我自己不能解决的问题。这表明基于 WSL 的解决方案比开发容器更容易使用。

然而,WSL 并不是没有代价的。它提供给你一个 Linux 替代品,仅此而已。在那里安装了许多包,在 WSL 和生产容器中有完全相同的环境的可能性很小。因此,使用 WSL 意味着在 Linux 中工作,而不是在相同的——甚至是非常相似的——环境中工作。

因此,WSL 是否适合您取决于各种因素,其中最重要的两个因素是您的技能和项目本身。在许多情况下,当次要的细节不那么重要时,它可以是你的解决方案。但是如果他们这样做了,开发容器可以给你提供一个更大的机会,让你的产品运行良好。

我们讨论了在DEV → TEST → PROD链中开发软件产品的两种方法,但是还有其他方法。我描述了两个我知道并使用过的。如果你知道并使用其他方法在 Windows 下的开发环境中开发软件产品,但该产品将部署在 Linux* 下的生产环境*中,那么请在评论中描述它。**

你也可能对使用开发容器和 WSL 有不同的看法。请也在评论里分享一下吧。这篇文章旨在收集知识和观点,并将其传达给其他人,但这个话题很容易带有主观性——对我有效的不一定对你有效。

感谢阅读这篇文章。我意识到它比平常少了很多技术性,但这并没有降低它的重要性。事实上,我们已经触及了非常重要的话题。你看,DEV → TEST → PROD软件开发链构成了任何软件项目的本质。在一些项目中,它被改变了;例如,没有测试或者有一个额外的预生产(我们可以称之为PRE-PROD)环境。

您如何组织环境会产生影响,有时这种影响比您在编码过程中需要决定的一些特定的技术细节要大得多。因此,千万不要忽视DEV → TEST → PROD基础设施的重要性!

资源

*https://learn.microsoft/en-us/windows/wsl/about https://code.visualstudio/docs/devcontainers/containers *

使用 Streamlit 快速开发基于 Web 的实时视频/音频处理应用

原文:https://towardsdatascience/developing-web-based-real-time-video-audio-processing-apps-quickly-with-streamlit-7c7bcd0bc5a8

在本文中,我们将了解如何使用 Streamlit 创建浏览器就绪的实时视频/音频处理应用。

作者图片

Streamlit 是一个 Python 框架,开发人员可以使用它快速构建 web 应用程序,而无需前端编码。在此基础上,开发人员可以开发实时视频/音频处理应用程序,从用户的媒体设备接收视频/音频流,在最简单的例子中,只需大约 10 行代码。

由于这类应用程序是基于网络的,它们可以被部署到云上,与用户轻松共享,并拥有现代化和用户友好的用户界面。

这个技术堆栈对于创建视频/音频应用程序的演示和原型设计非常有用,例如人体或物体检测、风格转换、图像过滤器、语音识别、视频聊天应用程序等。

一个简单的基于网络的物体检测应用程序。用户可以在执行过程中交互更改阈值。 在线试玩🎈

一个基于 web 的风格转移应用程序示例。用户可以在执行过程中交互更改模型类型和模型参数。 在线演示🎈

您可以在下面的示例部分看到更多示例。

:这些样本应用托管在公共云上( Streamlit Cloud ),视频和音频流传输到云服务器上进行处理。虽然这些数据只在内存中处理,不会保存到任何存储中,但是,如果您担心,请不要使用它们。至于本文中的以下内容,我们可以在本地全部执行。此外,您可以按照下面的示例部分的说明,在本地尝试上述示例。

**注:**我在europhon 2022上做了一个关于这个主题的演讲,题目是“使用 Streamlit 的实时浏览器计算机视觉应用”演讲视频如下:

**更新:**本文已于 2022/09/02 更新,使用的是从 v0.40.0 开始可用的streamlit-webrtc新引入的 API。

基于网络的应用程序的优势

我们通常使用 OpenCV 来构建图像或视频处理的实时演示应用。你们中的一些人(尤其是这类领域的开发人员或研究人员)可能已经多次看到下面的代码或类似的代码。

import cv2

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()

    img = cv2.Canny(frame, 100, 200)  # Some image processing

    cv2.imshow('frame', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

与上面使用运行在本地环境的cv2.VideoCapturecv2.imshow的 GUI 应用程序相比,基于网络的应用程序有如下优势。

易于共享和运行:

  • 如果我们在云上部署应用程序,我们可以通过发送 URL 与用户分享应用程序。
  • 用户只有通过网络浏览器才能使用这些应用程序。它不需要任何设置或外部依赖。

可在智能手机上使用:

  • 因为用户只需要网络浏览器,所以他们可以在智能手机上使用这些应用。如果我们能在这样的便携设备上展示演示,那就太方便了。

用户友好的用户界面:

  • 开发人员可以使用文本输入、滑块或其他基于 web 的组件来接受用户输入或显示数据。近来,这种基于网络的用户界面比桌面图形用户界面对用户更友好。

辅导的

我们将创建一个简单的基于 web 的实时视频处理应用程序,其 LoC 约为 10 或 20。请在有网络摄像头和麦克风的环境中尝试本教程。

你可以在这个资源库里查看这个教程的最终结果。此处是部署的在线演示🎈

在本教程中,我们将在app.py中编写代码。请先创建一个空的app.py

$ touch app.py

安装必要的软件包

接下来,我们必须安装本教程所需的软件包。

$ pip install -U streamlit streamlit-webrtc opencv-python-headless
  • streamlit:Streamlit 主包。
  • streamlit-webrtc:Streamlit 的定制组件,处理实时视频和音频流。
  • opencv-python-headless : OpenCV。我们在这里选择 headless 版本,因为我们将使用 Streamlit 构建 UI。

第一次接触 Streamlit

注意:如果您有使用 Streamlit 的经验,请跳过这一部分。

首先,用下面的命令启动 Streamlit。请运行与app.py相同目录下的命令。

$ streamlit run app.py

过一会儿,Streamlit 服务器进程将启动。然后访问 http://localhost:8501 看到如下图的页面(或者默认会在浏览器中自动打开)。这里的截图是在黑暗模式下,如果你使用的是光明模式,看起来会有所不同。

这时,网页上没有内容,因为app.py是空的。我们将在 Streamlit 应用程序的app.py中添加代码行。

用你的编辑器打开app.py,写下下面的代码。

import streamlit as st

st.title("My first Streamlit app")
st.write("Hello, world")

当您保存文件时,Streamlit 将检测文件更改,并在屏幕右上角显示“重新运行”和“总是重新运行”按钮。

单击“重新运行”按钮。然后网页被重新加载,页面内容如下所示。网页内容基于app.py代码生成。

如果你点击了“总是重新运行”按钮,每次文件改变时,页面会自动重新加载。

请注意,在更新app.py时,您必须按照下面的说明重新加载页面。

现在,我们已经了解了 Streamlit 应用的基本开发流程。你用像st.title()st.write()这样的 Streamlit 组件编写 Python 代码并传递给streamlit run命令,然后 Streamlit 在网页上生成相应的前端内容。

在下一节中,我们将看到如何在 Streamlit 之上开发一个实时视频处理应用程序。除此之外,Streamlit 本身涵盖了更多的用例,如机器学习、数据科学或更通用的用途。此类用例请参见官方 Streamlit 教程举例。

引入实时视频/音频流组件

如下更新app.py

import streamlit as st
from streamlit_webrtc import webrtc_streamer

st.title("My first Streamlit app")
st.write("Hello, world")

webrtc_streamer(key="example")

我们用webrtc_streamer()添加了一行。web 应用程序将类似于下面的屏幕截图。

在第一次试用时,可能需要一些时间来编译软件包,以便在单击“重新运行”按钮后,页面在一段时间内保持显示“正在运行”的消息。在这种情况下,请等待该过程完成。

单击“开始”按钮开始视频和音频流。第一次试用时,可能会要求您允许使用网络摄像头和麦克风。在这种情况下,请给予许可。

上面的webrtc_streamer(key="example")是一个 Streamlit 组件,它通过 web 浏览器处理视频和音频实时 I/O。key参数是脚本中标识组件实例的唯一 ID。我们在这里将其设置为"example",但是您可以使用任何字符串。该示例中的组件仅接收来自客户端网络摄像头和麦克风的视频和音频,并输出原始流。这是组件的最基本版本。我们将通过在以下部分添加其他选项来增强它的功能。

实时视频处理应用程序的开发

如下更新app.py

import streamlit as st
from streamlit_webrtc import webrtc_streamer
import av
import cv2

st.title("My first Streamlit app")
st.write("Hello, world")

def callback(frame):
    img = frame.to_ndarray(format="bgr24")

    img = cv2.cvtColor(cv2.Canny(img, 100, 200), cv2.COLOR_GRAY2BGR)

    return av.VideoFrame.from_ndarray(img, format="bgr24")

webrtc_streamer(key="example", video_frame_callback=callback)

像上一节一样,通过单击“开始”按钮来尝试一下。在这个新示例中,您可以发现图像过滤器被应用于视频流。

我们已经定义了一个接收输入帧并返回输出帧的回调。我们还将图像处理(本例中是边缘检测)代码放在回调函数中。于是,我们通过回调把图像处理代码注入到实时视频 app 中。

关于代码的详细解释如下。

  • webrtc_streamer()可以通过video_frame_callback自变量取一个函数对象作为回调。
  • 回调接收并返回输入和输出图像帧。这些是来自[PyAV](https://github/PyAV-Org/PyAV)[VideoFrame](https://pyav/docs/develop/api/video.html#av.video.frame.VideoFrame)类的实例。PyAV库是ffmpeg的 Python 绑定,提供视频和音频功能。它作为streamlit-webrtc的依赖项安装。
  • 回调的参数是来自网络摄像头的输入视频流中的图像帧。可以用frame.to_ndarray()转换成 NumPy 数组。
  • 回调的返回值显示在屏幕上。在上面的示例中,要返回的新的VideoFrame对象是从一个 NumPy 数组中生成的,带有av.VideoFrame.from_ndarray(img, format="bgr24")
  • 任何代码都可以放在回调函数中。在上面的例子中,我们使用了边缘检测滤波器cv2.Canny(img, 100, 200)(和灰度转换器cv2.cvtColor(img, cv2.COLOR_GRAY2BGR))作为例子。

现在,我们已经创建了一个浏览器就绪的实时视频处理应用程序!在这个例子中,我们使用了一个简单的 Canny 边缘检测器,您可以在您的原始应用程序中用任何图像处理代码替换它。

如果我们对该部分使用对象检测或样式转换,该应用程序将类似于本文开头的截图。

接收用户输入

如下更新app.py

import streamlit as st
from streamlit_webrtc import webrtc_streamer
import av
import cv2

st.title("My first Streamlit app")
st.write("Hello, world")

threshold1 = st.slider("Threshold1", min_value=0, max_value=1000, step=1, value=100)
threshold2 = st.slider("Threshold2", min_value=0, max_value=1000, step=1, value=200)

def callback(frame):
    img = frame.to_ndarray(format="bgr24")

    img = cv2.cvtColor(cv2.Canny(img, threshold1, threshold2), cv2.COLOR_GRAY2BGR)

    return av.VideoFrame.from_ndarray(img, format="bgr24")

webrtc_streamer(key="example", video_frame_callback=callback)

然后点击“开始”按钮。你会发现在这个例子中有 2 个滑块。您可以通过滑块修改cv2.Canny()的参数,即使是在实时执行期间。

有了这次更新,

  • 我们添加了threshold1threshold2变量。
  • 我们添加了两个带有st.slider()的滑块组件,并将它们的值赋给这些变量。st.slider()是 Streamlit 的内置组件。它的官方 API 参考是https://docs . streamlit . io/library/API-reference/widgets/ST . slider。
  • 然后我们将这些变量作为参数传递给回调函数中的cv2.Canny()

现在我们有交互式输入来控制实时视频过滤器!

回调的执行模式和重要注意事项

与 OpenCV 不同,streamlit-webrtc需要回调来处理图像和音频帧。这种基于回调的设计是 OpenCV GUI 和streamlit-webrtc之间的一个主要区别,关于它有一些事情你必须知道。

请注意,回调是在一个分叉线程中执行的,该线程不同于运行 Streamlit 应用程序代码的主线程。它做了如下一些限制。

  • global关键字在回调中没有像预期的那样工作。
  • 诸如st.write()之类的 Streamlit 方法不能在回调中使用。
  • 回调内部和外部之间的通信必须是线程安全的。

将应用部署到云

我们将把 web 应用程序部署到云中,让每个人都可以使用它。

配置 WebRTC

要将应用程序部署到云中,我们必须将rtc_configuration参数添加到webrtc_streamer()中。

webrtc_streamer(
    key="example",
    video_frame_callback=callback,
    rtc_configuration={  # Add this line
        "iceServers": [{"urls": ["stun:stun.l.google:19302"]}]
    }
)

当服务器在远程主机上时,此配置是建立媒体流连接所必需的。

streamlit_webrtc使用 WebRTC 进行视频和音频流传输。它必须访问全局网络中的“STUN 服务器”,以便远程对等点(确切地说,是 NAT 上的对等点)建立 WebRTC 连接。虽然我们在本文中没有看到关于 STUN 服务器的细节,但是如果感兴趣的话,请使用关键字如 STUN、TURN 或 NAT traversal 来搜索它。

在上面的例子中,我们将代码配置为使用 Google 提供的免费 STUN 服务器。您也可以使用任何其他可用的 STUN 服务器。

参数rtc_configuration的值将被传递给前端的[RTCPeerConnection](https://developer.mozilla/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection)构造函数。

HTTPS

我们必须通过 HTTPS 在远程主机上提供网络应用程序,以使用网络摄像头或麦克风。

不仅我们在这里使用的webrtc_streamer()组件,而且任何访问客户端网络摄像头或麦克风的前端应用程序都使用[MediaDevices.getUserMedia()](https://developer.mozilla/ja/docs/Web/API/MediaDevices/getUserMedia) API。这个 API 不能在“不安全的上下文”中工作

文件说

简而言之,安全上下文是使用 HTTPS 或 *file:///* URL 方案加载的页面,或者从 *localhost* 加载的页面。

media devices . getuser media()-隐私和安全

因此,我们需要 HTTPS 在访问客户端网络摄像头或麦克风的远程主机上提供网络应用。

流线云

我推荐使用 Streamlit Cloud 托管 Streamlit 应用。只需点击几下鼠标,你就可以从 GitHub 库部署应用程序,它会通过 HTTPS 自动提供应用程序。而且 Streamlit Cloud 似乎提供了比 Heroku free-tier 更好的运行时,而 Streamlit Cloud 免费提供了大部署容量。

其用法请参考公文。

我在 Streamlit Cloud 上实际部署了我们在本文中看到的 app:https://share . Streamlit . io/whit phx/Streamlit-webrtc-article-tutorial-sample/main/app . py。

它的 GitHub 资源库是https://GitHub . com/whit phx/streamlit-webrtc-article-tutorial-sample。

注意添加了requirements.txt来在 Streamlit 云环境中安装必要的依赖项(streamlit-webrtcopencv-python-headless):https://github . com/whit phx/Streamlit-webrtc-article-tutorial-sample/blob/main/requirements . txt

通知;注意

如上所述,源自客户端设备的视频和音频流被传输到服务器并在服务器处被处理。

因此,这个库是不可扩展的,并且依赖于网络连接。您可能认为它主要用于原型制作或演示目的。

如果担心将媒体传输到远程云服务器,你还必须考虑将应用托管在本地网络中。

例子

本部分是在https://github/whitphx/streamlit-webrtc的样品清单的副本。

展示包括以下例子和更多

⚡️Repository ,🎈在线演示

  • 对象检测(这是本文开头的样例应用程序的截图)
  • OpenCV 过滤器
  • 单向视频流
  • 音频处理

您可以在您的本地 env 上使用以下命令来试用这个示例应用程序。

$ pip install streamlit-webrtc opencv-python-headless matplotlib pydub
$ streamlit run https://raw.githubusercontent/whitphx/streamlit-webrtc-example/main/app.py

实时语音转文本

⚡️Repository ,🎈在线演示

它能实时将你的声音转换成文本。这个 app 是自带的;它不依赖于任何外部 API。

实时视频风格传输

⚡️Repository ,🎈在线演示

它将各种各样的风格转换过滤器应用于实时视频流。

视频聊天

⚡️Repository (不提供在线演示)

你可以用大约 100 行 Python 代码创建视频聊天应用。

东京 2020 象形图

⚡️Repository : 🎈在线演示

MediaPipe 用于姿态估计。

音频呢?

您可以像处理视频一样处理音频流。如果您定义了一个回调函数并将其传递给audio_frame_callback参数,那么回调将会在音频帧中执行。在音频的情况下,回调的输入参数和返回值是[AudioFrame](https://pyav/docs/develop/api/audio.html#module-av.audio.frame)类的实例。

请参见上面示例中的更改音频增益的示例应用程序或语音转文本应用程序的源代码。

原载于https://www . whit phx . info

计算机视觉的发展

原文:https://towardsdatascience/developments-occurring-within-computer-vision-9d485a072d46

概述计算机视觉领域以及技术基础设施的进步如何支持其发展和可扩展性

Nubelson Fernandes 在 Unsplash 上的照片

从事计算机视觉(CV)工作的人工智能(AI)从业者和开发者在计算机和计算机系统内实施和集成涉及视觉的问题的解决方案。图像分类、人脸检测、姿态估计和光流是 CV 任务的典型例子。

深度学习算法非常适合解决计算机视觉问题。卷积神经网络的结构特征使得能够检测和提取图像数据中存在的空间模式和特征。换句话说,机器可以识别和分类物体,甚至对它们做出反应。

因此,计算机视觉工程师称自己为深度学习工程师或只是普通的旧机器学习工程师。

计算机视觉是一个快速发展的领域,包括研究、商业和商业应用。对计算机视觉的高级研究现在可以更直接地应用于商业领域。

计算机视觉领域正在快速向前发展,这使得 CV 专家必须跟上最新的发现和进步。

关键要点

  • 帮助扩展深度学习解决方案的云计算服务
  • 自动机器学习(AutoML)解决方案减少了标准机器学习流程中所需的重复工作量
  • 研究人员努力使用变压器架构来优化计算机视觉任务

云计算

云计算通过互联网向个人或企业提供计算资源,如数据存储、应用服务器、网络和计算基础设施。与使用本地资源执行计算相比,云计算解决方案为计算资源可用性和扩展提供了快速且经济高效的解决方案。

机器学习解决方案的实施需要存储和处理能力。在机器学习项目的早期阶段(数据聚合、清理和争论)对数据的关注涉及用于数据存储和应用/数据解决方案接口访问的云计算资源(BigQuery、Hadoop、BigTable)。

泰勒·维克在 Unsplash 上的照片

最近,具有计算机视觉能力的设备和系统显著增加,例如用于步态分析的姿态估计、用于移动电话的面部识别、自动车辆中的车道检测等。

对云存储的需求正在增加,据预计2021 年该行业的价值将达到 3903.3 亿美元,是当前市场价值的五倍。

预计市场规模和应用程序的计算机视觉将大幅增长,从而导致使用入站数据来训练机器学习模型的数量增加。开发和训练 ML 模型所需的数据样本的增加与更大的数据存储容量需求和广泛强大的计算资源直接相关。

GPU 可用性的提高加速了计算机视觉解决方案的发展。然而,当服务于数千甚至数百万消费者时,仅靠 GPU 并不总能提供这些应用所需的可扩展性和正常运行时间。这个问题的显而易见的答案是云计算。

云计算平台,包括亚马逊网络服务(AWS) 、谷歌云平台(GCP) 和微软 Azure ,为机器学习和数据科学项目管道的核心组件提供解决方案,包括数据聚合、模型实现、部署和监控。

提高对与计算机视觉和通用机器学习相关的云计算服务的认识,会使任何 CV 工程师在企业中占据优势。通过进行深入的成本效益分析,可以确定云计算服务的好处。

一个很好的经验法则是,确保作为一名 CV 工程师,您了解或以某种形式接触到至少一个主要的云服务提供商及其解决方案,包括它们的优势和劣势。

大规模计算机视觉需要云服务集成

以下是支持典型计算机视觉操作的 NVIDIA 服务的示例,以强调哪种类型的云计算服务适合 CV 工程师。

利用英伟达广泛的预训练深度学习模型的英伟达图形处理单元云(NGC)目录抽象出深度学习模型实施和训练的复杂性。深度学习脚本为 CV 工程师提供现成的管道,可定制以满足独特的需求。健壮的模型部署解决方案自动向最终用户交付模型。

此外, NVIDIA Triton 推理服务器支持在任何基于 GPU 或 CPU 的基础设施上部署来自 TensorFlow 和 PyTorch 等框架的模型。NVIDIA Triton 推理服务器提供了跨各种平台的模型可扩展性,包括云、边缘和嵌入式设备。

此外,NVIDIA 与云服务提供商如 AWS 的合作伙伴关系支持部署基于 CV 的资产的能力。无论是 NGC 还是 AWS,通过利用由英伟达专家整合的打包解决方案,对基础设施和计算资源的考虑都很少。这意味着 CV 工程师可以更专注于模型性能和优化。

鼓励企业在可行的情况下降低成本和优化策略。云计算和云服务提供商通过提供基于使用和基于服务需求扩展的计费解决方案来满足这一需求。

AutoML

机器学习算法和模型开发是涉及许多任务的过程,这些任务可以通过创建自动化操作管道从自动化和减少手动过程中受益。

以特征工程和模型选择为例。特征工程是一个涉及从数据中检测和选择相关信息和属性的过程,该过程非常适合于描述数据集或提高基于机器学习的解决方案的性能。

模型选择涉及评估一组机器学习分类器、算法或给定问题的解决方案的性能。这些活动需要 ML 工程师和数据科学家花费相当多的时间来完成,并且经常需要从业者重新访问程序操作以提高模型性能或准确性。

人工智能(AI)领域致力于自动化机器学习过程中的大量手动和重复操作,称为自动化机器学习或 AutoML。

斯蒂芬·道森在 Unsplash 上拍摄的照片

有几个正在进行的大型项目来简化机器学习项目管道的复杂性。AutoML 是一项超越抽象的努力,它专注于 ML 工作流和过程的自动化和增强,以使 ML 对于非 ML 专家来说容易和可访问。

花一点时间来考察汽车行业的市场价值,预测预计到 2030 年汽车市场将达到 140 亿美元。这意味着其规模将比目前的价值增加近 42 倍。

计算机视觉项目有一系列重复的任务来实现预期的目标。参与模型实现的 CV 工程师太了解了。寻找合适的超参数的重复工作的数量使得模型的训练能够收敛到最佳损失并实现期望的精度,该过程被称为超参数优化/调整。

模型选择和特征工程是耗时且重复的过程。AutoML 是机器学习管道中自动化重复过程的努力。

机器学习和自动化的这种特殊应用正在获得牵引力。CV 工程师需要了解 AutoML 的优势和局限性。

实践中的自动化

AutoML 仍然是一项专注于自动化标准机器学习程序的新技术。然而,从长远来看,所获得的优势是显著的。

AutoML 对 CV 和 ML 工程师的一个明显好处是节省时间。数据聚合、数据准备和超参数优化是耗时的过程,可以说不使用 ML 工程师的核心技能和能力。

超参数调优涉及一个带有有根据猜测的试错过程。虽然数据准备和汇总是必要的过程,但它们涉及重复的任务,并取决于找到适当的数据源。事实证明,AutoML 功能在自动化这些流程方面非常成功,使 CV 工程师能够将更多的时间和精力投入到要求更高、更有成就感的任务中。

AutoML 及其应用程序,尤其是数据源,仍然有助于数据质量,主要是模型性能。特定于问题领域的高质量数据的获取对于自动化来说还不成熟,需要专业的人工观察和监督。

对于那些对探索 GPU 驱动的 AutoML 感兴趣的人来说,广泛使用的基于树的流水线优化工具(TPOT) 是一个自动化的机器学习库,旨在通过遗传编程优化机器学习过程和流水线。 RAPIDS cuML 提供通过 GPU 计算资源加速的 TPOT 功能。这篇文章提供了更多关于 TPOT 和急流城的信息。

机器学习库和框架

机器学习库和框架在任何 CV 工程师的工具包中都是必不可少的。ML 库和框架的发展和进步是渐进和持续的。主要的深度学习库如 TensorFlow 、 PyTorch 、 Keras 、和 MXNet 在 2021 年得到了不断的更新和修复,没有理由认为这不会持续到 2022 年。

最近,在以移动为重点的深度学习库和软件包方面取得了令人兴奋的进展,这些库和软件包优化了常用的 DL 库。

MediaPipe 在 2021 年扩展了其姿态估计功能,通过 BlazePose 模型提供 3D 姿态估计,该解决方案可在浏览器和移动环境中使用。在 2022 年,预计会看到更多涉及动态运动的使用案例中的姿态估计应用,并需要稳健的解决方案,如舞蹈中的运动分析和虚拟角色运动模拟。

PyTorch Lighting 由于其简单性、对复杂神经网络实现细节的抽象以及对硬件考虑的增强,在研究人员和专业机器学习实践者中越来越受欢迎。

最先进的深度学习

深度学习方法长期以来一直被用来应对计算机视觉挑战。用于进行面部检测、车道检测和姿态估计的神经网络架构都使用卷积神经网络的深度连续层。

CV 工程师非常了解 CNN,并且需要更加适应该领域的研究发展,特别是使用 Transformer 来解决计算机视觉任务。Transformer,2017 年《注意力是你需要的全部》论文中介绍的深度学习架构。

该文章提出了一种新的方法,通过利用注意力机制来导出输入数据的一部分相对于其他输入数据段的重要性,从而创建数据的计算表示。变压器神经网络架构没有利用卷积神经网络的惯例,但是研究已经展示了变压器在视觉相关任务中的应用。

通过 NGC 目录探索变压器模型,其中包括 PyTorch 中实际变压器模型的架构和利用的详细信息。

变压器在 NLP 领域产生了相当大的影响,只需参考 GPT(生成式预训练变压器)和伯特(来自变压器的双向编码器表示)的成就。

这篇发表于 2021 年最后一个季度的论文,提供了 Transformer 网络架构在计算机视觉中的应用的高级概述。

CV 工程师对应用 ML 感兴趣,不熟悉阅读研究论文,那么这篇帖就为大家呈现了一套系统的阅读和理解研究论文的方法。

移动设备

边缘设备变得越来越强大,设备上的推理能力是期望快速服务交付和人工智能功能的客户所使用的移动应用程序的必备功能。

照片由在 Unsplash 上主屏化

在移动设备中结合计算机视觉使能功能减少了获得模型推断结果的等待时间;将计算机视觉功能集成到移动设备中可带来诸多优势,例如:

  • 减少获得模式推断结果时的延迟。在设备上进行和提供的推理结果不依赖于云服务器,反而减少了对推理结果的等待时间。
  • 根据设计,设备上的推理功能限制了数据从设备到云服务器的传输。该功能增强了数据的保密性和安全性,因为几乎没有数据传输要求。
  • 消除对云 GPU/CPU 服务器的依赖以进行推理的成本降低提供了额外的财务优势。

许多企业正在探索其产品和服务的移动产品,这也包括探索如何在移动设备上复制现有人工智能功能的方法。CV 工程师应该知道几个平台、工具和框架来实现移动优先的 AI 解决方案。

  • TensorFlow Lite
  • CoreML
  • 苹果愿景框架
  • 张量流-反应
  • CreateML
  • 媒体管道
  • MLKit

摘要

随着人工智能越来越多地融入我们的日常生活,计算机视觉技术的使用将会增加。随着它在我们的社会中变得越来越普遍,对具有计算机视觉系统知识的专家的需求将会上升。

CV 工程师必须紧跟行业的最新发展和趋势,以保持领先地位并利用最新的进步。2022 年,你应该意识到 PyTorch 照明、以移动为重点的深度学习库以及变形金刚在计算机视觉应用中的使用越来越受欢迎。

此外,边缘设备正变得越来越强大,企业正在探索其产品和服务的移动产品。以移动为重点的深度学习库和包值得关注,因为它们很可能在未来一年中增加使用。

2022 年,预计 AutoML 功能将得到更广泛的应用,ML 库和框架将继续增长。增强和虚拟现实应用的不断发展将允许 CV 工程师将其技能扩展到新的领域,如开发将真实对象复制到 3D 空间的直观有效的方法。计算机视觉应用将继续改变和影响未来,在支持计算机视觉系统的技术基础设施方面将会有更多的发展。

这篇文章的一个版本最早出现在 Nvidia 开发者博客

摘要

完成步骤 1-4,了解我在媒体和其他平台上制作的最新内容。

  1. 成为推荐媒介会员,支持我的写作
  2. 订阅我的 YouTube 频道
  3. 订阅我的播客 苹果播客|Spotify|可听
  4. 订阅我的 邮件列表 获取我的简讯

利用卷积神经网络从 X 射线图像中诊断肺炎

原文:https://towardsdatascience/diagnosing-pneumonia-from-x-ray-images-using-convolutional-neural-network-fe9975cab808

图像分类技术在医学诊断中的应用

乌曼诺德在 Unsplash 上拍摄的照片

免责声明:本文中的信息无意提供或替代任何专业医疗建议、诊断或治疗。

介绍

深度学习,也称为神经网络,近年来获得了牵引力,现在被广泛应用于多个领域,其中一个受欢迎的应用是使用卷积神经网络(" CNN ")的图像分类。在医学诊断领域中,也正在探索图像分类的潜力。在本文中,我将讨论如何构建一个卷积神经网络,帮助我们从胸部 x 射线图像中诊断肺炎。

神经网络

首先,神经网络可以描述为一系列算法,其目标是识别数据中的关系或模式。简单的神经网络由不同类型的层组成,即输入层、输出层和隐藏层。每一层都包含许多神经元,每个神经元都由算法组成,这些算法将前一层的输出作为输入,生成进一步的输出并将它们传递到下一层。

下图显示了一个简单神经网络的示例架构。在本例中,输入层中有 4 个变量,用绿色圆圈表示。它们被输入到第一个隐藏层中由蓝色圆圈表示的 4 个神经元中的每一个。然后,这些神经元将产生进一步的输出,传递给第二个隐藏层中的神经元。最后,第二个隐藏层的输出将进入由橙色圆圈表示的输出层中的神经元,该神经元将生成最终输出。

作者图片

卷积神经网络(CNN)

卷积神经网络是一类通常应用于与图像相关的任务的神经网络。一般来说,它包括 3 个不同类型的层,即卷积层,池层和全连接层。

完全连接的层基本上与上面简单神经网络示例中的隐藏层相同。下面我将依次讨论卷积层和池层。

卷积层

顾名思义,卷积层对数据进行卷积运算。这是一种数学运算,将两个数字数组相乘,得到第三个数字数组。

例如,在下图中,3×3 过滤器(或内核)中的每个值都乘以 4×4 图像的 3×3 子部分,并且相乘的结果在每个子部分中相加。然后,滤波器在图像上移动到下一个子部分,并重复计算,直到填满整个输出阵列。

作者图片

示例中的滤波器可以被认为是从图像中识别边缘的边缘检测器。其他类型的特征可以用不同的过滤器来识别。在卷积层中,我们通常会有多个滤波器来检测不同类型的特征。

然而,我们可能不一定知道哪些过滤器最适合应用于我们的任务。因此,代替设置我们自己的过滤器,神经网络将确定最佳过滤器,该过滤器最好地检测我们的分类任务所需的特征。

图像通常表示为 RGB 值,由 0 到 255 的 3 个值组成,每个值对应红、绿、蓝三种颜色。因此,卷积滤波器通常是三维的(例如 3x3x3)。

汇集层

汇集层通过将图像的子部分简化为单个值来减少数据的维度。例如,在下图中,应用最大池会通过将图像每个子部分中的最大值作为输出来缩小图像。

作者图片

数据准备和扩充

在本文中,我使用的数据集来自这里的(数据集是 CC BY 4.0),其中包括 5856 张标记为“肺炎”或“正常”的胸部 x 光图像。这些胸部 x 光图像选自广州妇女儿童医疗中心 1 至 5 岁儿童患者的回顾性队列。这些 x 射线图像被分成训练集、验证集和测试集。训练集中有 5,216 幅图像,验证集中有 624 幅图像,测试集中有 16 幅图像。我保存文件夹的目录,并在下面的代码中相应地命名它们。

下面我从训练集中画出了 10 张 x 光图像,其中 5 张是“正常”,5 张是“肺炎”。在普通的胸部 x 射线图像检查中,放射科医生会在肺部寻找白色斑点,以确定患者是否患有肺炎。然而,作为非医学专业人员,我们可能不一定有专业知识或经验来区分“肺炎”图像和“正常”图像。

作者图片

让我们看看神经网络是否可以帮助我们这些非医学专业人士区分肺炎和非肺炎的胸部 x 光图像。首先,我在下面的代码中列出了数据准备和扩充的步骤。

我使用 Tensorflow 中的图像预处理库从文件夹中提取并生成批量图像。如上所述,图像用 RGB 值表示,范围从 0 到 255。在卷积神经网络中,每个图像应该只贡献等量的信息。然而,具有高像素值的图像可能比具有低像素值的图像具有更大的权重。因此,我对图像应用了 1/255 的重缩放因子,使它们的值在 0 和 1 之间。

我还应用样本集中和标准化来集中和标准化图像。图像的平均值为 0,标准偏差为 1,这是通过减去每个图像中的平均像素值并除以像素值的标准偏差得到的。

为了减少模型可能过度拟合训练集并且不能很好地概括它从未见过的图像的影响,我应用数据扩充来生成更多看起来与原始图像略有不同的图像,以包括在数据集中。额外的图像被随机缩放 0.2 倍,并且它们的高度和宽度与总量相比被随机移动 0.1 的分数。

我将数据增强应用于训练集和验证集,以评估模型在具有相似数据增强的相似图像分布中的表现。然而,我没有对测试集应用数据扩充,而只是对测试集进行了重新调整和标准化,以评估该模型在图像失真可能性较小的正常情况下更可能遇到的图像上的表现。

类别模式设置为二进制,因为类别为“肺炎”或“正常”。我将图像缩小到(160,160)的大小,以减少输入的数量。批量大小设置为 16,这意味着模型中的内部参数将在每运行 16 个样本时进行更新。可以认为,该模型每观察 16 个样本,就会向最优值迈一小步。

构建卷积神经网络

我在下面的代码中列出了我的卷积神经网络的结构。

有 4 个类似的层块,一个卷积层,然后是批量标准化和最大池层。对于跨越所有四个块的卷积层,过滤器的数量从 32 个增加到 128 个,内核大小为 3×3。

在每个块的卷积层之后,我应用批量归一化来归一化结果。然后它们被输入到激活函数中,我将其设置为 ReLU 函数。然后,我应用最大池层,池大小为 2x2。

在四个块卷积和池化层之后,我展平该层,并包括一个具有 512 个神经元的全连接层,以 ReLU 作为激活函数。最后,我包括一个具有 1 个神经元的输出层,其 sigmoid 函数作为我们的二元分类任务的激活函数。

我使用随机梯度下降作为优化方法,学习率从 0.01 开始指数衰减,二进制交叉熵作为损失函数。

然后,我用 20 个时期(或周期)训练该模型,每个时期的步数等于训练集中的图像数除以批量大小,这将允许在每个时期训练整个训练集。我在下面列出了模型摘要。

作者图片

我绘制了各种指标,包括准确度、丢失率、精确度和召回率。

作者图片

训练集中的准确率提高到 95%以上。我们可能会倾向于得出这样的结论:这个模型做得相当好。然而,当我们查看跨时期验证集中的准确率时,它徘徊在 75%到 90%左右,没有随着我们通过更多时期训练模型而增加的明显趋势。

作者图片

训练集中的损失呈下降趋势,而验证损失在最初几个时期后没有显示出明显的下降趋势。

作者图片

作者图片

相似的观察结果可以在精度和召回率中被识别,其中在训练和验证集之间没有明显的收敛。

我们还看到,总体精度低于验证集中的精度,这表明一定比例的预测是假阳性;而验证集中的召回率通常较高,这表明低百分比的预测是假阴性。

上述观察可能暗示我们的模型遭受过拟合的问题,该模型过拟合训练集,并且当它遇到从未见过的新图像时不能很好地概括。

混淆矩阵

下面我列出了模型在预测训练、验证和测试集时的混淆矩阵。

作者图片

在训练集中,该模型正确地预测了大多数“肺炎”图像,以及精确度稍低的“正常”图像。

作者图片

在验证集中,模型准确地预测了“肺炎”图像,但在“正常”图像中预测得不太好。

作者图片

在测试集中可以看到类似的模式,即模型不能有效地区分“正常”图像和“肺炎”图像。

从验证集和测试集中的结果,我们可以得出结论,该模型可以正确地预测大多数肺炎的胸部 x 射线图像,但不能预测正常的胸部 x 射线图像。

因此,该模型不是一种万无一失的方法,在该方法中,高百分比的“正常”图像被分类为“肺炎”图像。

后续步骤

上述结果可能是由于数据集中的不平衡,因为“肺炎”图像的比例较大,而“正常”图像相对较少。神经网络可能没有看到足够多的“正常”图像来正确识别它们。

此外,过度拟合似乎仍然是一个问题,尽管我们扩大了数据集的数据增加。因此,收集更多的胸部 x 射线图像添加到我们的数据集,特别是正常图像,可能会给我们一个更准确的模型。

我们也可以探索迁移学习的应用。迁移学习是采用预先训练的模型,该模型在非常大的图像集上进行训练,并针对更具体的任务重新训练顶层。这有可能超过我们当前的模型,因为预训练的模型已经从非常大的图像集中学习了基本特征,这将理想地帮助模型处理更复杂的任务。

结论

卷积神经网络作为神经网络的一个分支,常用于图像相关的任务,可以应用于医疗诊断等不同领域。然而,深度学习是数据饥渴的,为了训练一个性能良好的模型,需要大量的数据,这可能是医疗领域的一个障碍。

本文标签: 中文翻译博客TowardsDataScience一百三十六