TowardsDataScience 博客中文翻译 2020(七百八十四)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

谷歌 Play 商店应用点评

原文:https://towardsdatascience.com/sentiments-of-google-play-store-apps-reviews-13f9ee7246c6?source=collection_archive---------36-----------------------

基于评论者报告的情绪分析谷歌 Play 商店应用程序评论

关于这篇文章

他的文章在谷歌 Play 商店应用评估的背景下讨论了一个数据可视化项目的结果。T2 谷歌 Play 商店 T3 是世界上使用最多的数字分发服务之一,拥有大量的应用程序和用户。因此,有很多关于应用程序及其用户评价的数据可用。
该项目是作为巴西纳塔尔北里奥格朗德联邦大学 Metrópole Digital 学院的数据科学 I 课程的一部分征集的,用于练习课堂上所学的科目。

方法

在这个项目中,我们将在 Kaggle 中可用的谷歌 Play 商店应用数据集中搜索趋势。为此,我们将确定一些初始假设,并试图找到有助于巩固这些假设的信息。我们将使用 Google ColabPython 来完成这个项目。
这个项目使用的代码可以在这个 GitHub 库中找到。

设置和下载数据

该项目中使用的软件包有:

  • Google . Colab:Google Colab 中的文件操作;
  • Kaggle :从 Kaggle 网站导入数据集;
  • 熊猫:数据集操作;
  • NumPy :处理数学运算;
  • Pyplot :创建图形和表格。

代码 01:设置环境和下载数据。作者代码。

通过 Kaggle API,我们可以下载数据集。我们的主数据集包含谷歌 Play 商店可用应用程序的信息,还有一个包含应用程序评论信息的辅助数据集。

过滤评论

代码 02:过滤评论。作者代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表 01:过滤的评论数据集。图片作者。

reviews 数据集包含大量无效观察值。由于我们将使用数字数据,并且无法识别缺失数据的值,因此最好完全删除这些观察值。这个项目中不会用到“翻译评论”这一栏,所以我们也可以删除它。此外,可以优化列的名称。
每个应用程序都有多个评论,所以我们需要与它合作。

转换

正如我们在 unique 方法中看到的,情绪列假设了三个值:负面的、中性的和正面的。知道了这一点,我们可以应用李克特量表来评估这些信息的数值。
李克特量表是问卷中最常见的心理测量量表。它包括要求回答者在从负面到正面的范围内评价某事。
对于本项目,李克特量表为-1 表示负面,0 表示中性,1 表示正面。这样,当计算平均值时,我们得到一个介于-1 和 1 之间的数字,其中较高的值意味着更多的正面评价,较低的值意味着更多的负面评价,以及更接近零的中性。

代码 03:转换数据。作者代码。

组合和重新过滤

函数 merge 将完成几乎所有需要的工作。常见的一栏是 app 名称,是 reviews_mean 的索引。因为索引保留了“App”这个名称,所以该函数仍然可以访问它。默认的“内部”方法将只保留两个数据集中有值的观测值。
得到的数据集有 1229 个观测值,而 reviews_mean 有 865 个观测值。这意味着出于某种原因,我们的数据集中有多个外观的应用程序。删除重复将确保每个应用程序只有一个观察。

现在,我们将只选择所需的列,并将 Installs 列的值更改为 numeric。

代码 04:合并和重新过滤数据。作者代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表 02:过滤后的数据集。图片作者。

分析

首先,我们先建立一些初始假设。这些可能是在调查数据或初步猜测之前看起来合乎逻辑的事情。

  1. 情绪影响 app 的最终评分;
  2. 付费内容会有更好的评分;
  3. 热门类别有更积极的情绪。

人气和评分

代码 05:创建直方图。作者代码。

让我们检查一下我们现在的数据。为此,我们希望看到情绪和评级的直方图。如果我们的假设是真的,如果情绪有很多高值,那么评级也会有很多高值,这意味着在我们的数据集中这两个变量之间有很高的相关性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 01:情绪和评级直方图。图片作者。

查看直方图,我们可以看到两列都有积极的趋势。在情绪方面,大多数值都高于中性值(0),在-1 到 1 的范围内约为 0.5。但是对于评级栏来说,这种趋势看起来更加明显,在 0 到 5 的范围内,许多值都在 4 到 5 左右。

代码 06:计算中位数并绘制散点图。作者代码。

中间值有助于形象化。作为第二个资源,我们可以通过评级绘制一个情绪线图,并查看线条的行为。如果情绪影响了评级,我们可以预期接近直线上升。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 02:情绪 x 评级散点图。图片作者。

付费内容和评级

首先,我们需要分离内容类型(免费和付费)。然后,我们可以得到每个类别的平均值。

代码 07:计算免费和付费内容的平均值。作者代码。

正如我们所见,付费内容的平均值略高于免费内容的平均值。但是这种差异似乎不足以支持我们的假设。此外,只有 9 个付费应用程序,这可能会误导由于低数量的观察信息。

热门类别和人气

代码 08:绘制渐变线。作者代码。

在我们的数据集中,我们有 Installs 列,包含应用程序被安装的次数,通过分组和排序,我们获得了类别的流行度排名。

让我们来看看人气排名中的情绪反应。我们将使用渐变线来帮助我们看到图形中的变化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 03:人气排名 x 人气的渐变线。图片作者。

结果

我们所有的三个假设都在分析部分被观察到了。由于我们只是试图看到数据的宏观状态来猜测关于它的事情,而没有使用任何真实的信息测试或推断,我们无法做出任何假设。尽管如此,这个项目的工作可以帮助创造一个更好的假设。

  • 假设 1 :直方图指出了情绪和评级之间的某种联系,但这可能是由于相似的因果关系,而不是由于这两个变量之间的相关性。之后创建的散点图没有添加任何新的信息,保持我们从直方图的猜测。
  • 假设 2 :由于付费类别的观察数量较少,该数据集不适合回答我们的假设。分析手段,两者并无显著差异。
  • 假设 3 :观察创建的图形,没有明确的信息可以获得。随着受欢迎程度等级降低,更高情感值的出现更少,这可能有助于我们最初的假设。

下一个

在未来的工作中,有许多可行的方法来继续这个项目。首先,有可能假设其他假设,并尝试像我们所做的那样将其可视化。
另一种可能是通过统计检验和方法来验证这里提出的假设。

最后,人们可以用推理的方法接近数据集,试图找到关于它的新信息。例如,卡方检验可以应用于这里使用的李克特量表。

参考文献

python 中的 Sentinel-2 图像聚类

原文:https://towardsdatascience.com/sentinel-2-image-clustering-in-python-58f7f2c8a7f6?source=collection_archive---------23-----------------------

关于如何在 python 中使用 scikit-learn 和 rasterio 执行无监督分类的分步教程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

左图:苏丹杰济拉州 Elhasaheesa 地区的 Sentinel-2 图像。右图:Elhasaheesa 聚类图像(4 类)。

聚类或无监督分类是根据统计相似性将图像的像素值分组或聚集成一定数量的自然类(组)的过程。在本教程中,我们将在 jupyter 笔记本中使用 rasterio 进行 sentinel-2 图像操作,并使用 power fullscikit-learnpython 包进行聚类。

Scikit-learn 是一个针对 Python 编程语言的免费软件机器学习库,包含各种分类、回归和聚类算法。要安装此软件包:

conda install -c anaconda scikit-learn

Rasterio 是一个开源的 python 库,可以读写不同格式的栅格数据集,如卫星影像和地形模型,如 GEOTIFF 和 JP2。

conda install -c conda-forge rasterio

算法: Scikit-learn 有不同的聚类算法,这些算法可以直接从聚类子库中导入。 K-Means 算法简单,是聚类中使用最多的算法之一。它基本上将 n 个观察值(在我们的例子中是像素值)分成 k 个簇(由用户预先定义的类的数量),其中每个观察值属于具有最近平均值的簇。本教程将基于 K-means,但你可以很容易地切换到尝试其余的,代码将几乎保持不变,但你只需要改变算法。

本教程将分别使用苏丹杰济拉州 El-hasaheesa 和 Elmanagel 地区的 Sentinel-2 图像进行训练和预测。这个数据和本教程的完整代码可以在 github 上找到。

要开始这项工作,首先要导入所有需要的包:

import rasterio as rio
from rasterio.plot import show
from sklearn import cluster
import matplotlib.pyplot as plt
import numpy as np

然后将使用 rasterio 打开图像并读入其元数据

# Open the image 
elhas_raster = rio.open("Elhasaheesa.tif")print(elhas_raster.meta)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

元数据为我们提供了有关图像的信息,如数据类型、大小(宽度、高度)、计数(波段数)和坐标参考系统。为了更好地可视化这张图像,首先需要通过拉伸来调整它的对比度,你可以在这里 阅读更多关于图像增强的内容

# Read, enhance and show the image
elhas_arr = elhas_raster.read() # read the opened image
vmin, vmax = np.nanpercentile(elhas_arr, (5,95))  # 5-95% contrast stretch# show the enhanced image
plt.figure(figsize=[20,20])
show(elhas_raster, cmap='gray', vmin=vmin, vmax=vmax)
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果我们打印此图像的形状,我们会看到它的顺序为(带、高、宽),这需要首先更改为形状顺序(高、宽、带)。我们将通过以下方式改革这一模式:

  • 使用元数据中的图像大小、计数和数据类型创建一个空数组。
  • 使用一个 for 循环来分割每个波段,并在我们的空数组中重组它。

在这个循环的最后,我们将得到一个具有所需形状顺序的新数组,它具有相同的大小和带数。

# create an empty array with same dimension and data type
imgxyb = np.empty((elhas_raster.height, elhas_raster.width, elhas_raster.count), elhas_raster.meta['dtype'])# loop through the raster's bands to fill the empty array
for band in range(imgxyb.shape[2]):
    imgxyb[:,:,band] = elhas_raster.read(band+1)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,我们几乎准备好训练我们的分类器,但首先,我们需要将我们的 X(宽度)和 Y(高度)维度转换为 1 维,因此要有一个 2d 数组而不是 3d 数组,然后我们可以将它提供给 K-means 分类器。

# convert to 1d array
img1d=imgxyb[:,:,:3].reshape((imgxyb.shape[0]*imgxyb.shape[1],imgxyb.shape[2]))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**训练:**要设置的最重要的参数是 n_clusters ,它表示我们要将像素分组到的簇的数量,在我们的图像中,我们可以直观地看到它有三个主要类别(建筑区、裸地和耕地),但我们还有一个额外的类别,即感兴趣区域之外的黑色区域,其像素也可以分组到一个组中。K-means 有一些其他参数,如最大迭代次数和初始化次数,但在本教程中我们将把它们保留为默认值。

cl = cluster.KMeans(n_clusters=4) # create an object of the classifier
param = cl.fit(img1d) # train itimg_cl = cl.labels_ # get the labels of the classes
img_cl = img_cl.reshape(imgxyb[:,:,0].shape) # reshape labels to a 3d array (one band only)

为了显示结果图像,我想使用一个自定义的颜色图,我可以控制每个类的颜色。我们将保持外部区域为黑色,其余的类使用红色、绿色和黄色。

# Create a custom color map to represent our different 4 classes
cmap = mc.LinearSegmentedColormap.from_list("", ["black","red","green","yellow"])# Show the resulting array and save it as jpg image
plt.figure(figsize=[20,20])
plt.imshow(img_cl, cmap=cmap)
plt.axis('off')
plt.savefig("elhas_clustered.jpg", bbox_inches='tight')
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**预测:**一旦训练了分类器,就可以用它来预测任何看不见的图像中的相同的学习聚类。我们将使用 Elmanagel locality(与 Elhasaheesa 相邻)的图像来预测上面的 4 个类。

要使用 Elmanagel 的图像进行预测,我们需要对之前的图像进行所有的预处理(重新调整形状并重新形成 2d 数组),然后才能将其提供给分类器。此外,还需要前面相同的步骤来显示得到的预测聚类。

# open the raster image
elmanagel = rio.open(‘elmanagel.tif’)# create an empty array with same dimensions and data type 
elman_xyb = np.empty((elmanagel.height, elmanagel.width,elmanagel.count), elmanagel.meta['dtype'])# loop through the raster bands and fill the empty array in x-y-bands order
for band in range(elman_xyb.shape[2]):
    elman_xyb[:,:,band] = elmanagel.read(band+1)# convert to 1d array
elman_1d = elman_xyb[:,:,:3].reshape(elman_xyb.shape[0]*elman_xyb.shape[1], elman_xyb.shape[2])# predict the clusters in the image 
pred = cl.predict(elman_1d)# reshape the 1d array predictions to x-y-bands shape order (only one band)
elman_cul = pred
elman_cul = elman_cul.reshape(elman_xyb[:,:,0].shape)

现在让我们在子图中显示原始图像和结果预测图像,但首先,我们将通过对比度拉伸来增强原始图像,以便更好地查看。

elman_arr = elmanagel.read() # Read the image
vmin, vmax = np.nanpercentile(elman_arr, (5,95)) # 5–95% contrast stretch# show the original and predicted image
fig, (ax1,ax2) = plt.subplots(figsize=[15,15], nrows=1,ncols=2, sharey=False,)
show(elmanagel, cmap='gray', vmin=vmin, vmax=vmax, ax=ax1)
show(elman_cul, cmap=cmap, ax=ax2)
ax1.set_axis_off()
ax2.set_axis_off()
fig.savefig("pred.png", bbox_inches='tight')
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

左图:原图。右图:集群图像。

参考文献

[## 卫星图像聚类

应用科学与技术丛书(BRIEFSAPPLSCIENCES)遥感的一部分

link.springer.com](https://link.springer.com/chapter/10.1007/978-981-13-6424-2_3) [## sci kit-学习

“我们使用 scikit-learn 来支持前沿基础研究[…]" "我认为这是我设计过的最棒的 ML 套装…

scikit-learn.org](https://scikit-learn.org/stable/) [## Rasterio:访问地理空间栅格数据- rasterio 文档

编辑描述

rasterio.readthedocs.io](https://rasterio.readthedocs.io/en/latest/) [## 遥感概论

为什么我们要增强卫星图像?使用不同的图像增强方法来准备“原始数据”,以便…

seos-project.eu](https://seos-project.eu/remotesensing/remotesensing-c05-p02.html)

软件设计中关注点的分离

原文:https://towardsdatascience.com/separation-of-concerns-in-software-design-aaad847b3b44?source=collection_archive---------26-----------------------

应用计算机科学的基本原理来提高各级软件的质量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

艾伦·格林伍德在 Unsplash 上的照片

关注点分离 (SoC)是软件开发中最基本的原则之一。

SoC 是如此重要,以至于 5 个坚实的原则中有 2 个(单一责任和界面分离)是从这个概念直接衍生出来的。

原则很简单:不要把你的程序写成一个完整的块,相反,要把代码分解成小块,这些小块是系统中最终确定的小块,每个小块都能够完成一项简单而独特的工作。

在这篇文章中,我详细阐述了在抽象的所有层次应用这个深刻的原则:从每个功能内部的编程代码和模块的设计到整个应用程序的架构,所有这些都是为了实现我们所说的定性软件的特征。

用于编程功能的 SoC

如果我们拿最底层(实际的编程代码)来说,SoC 指导我们避免编写冗长复杂的函数。当函数开始变大时,这是一个危险信号,表明该方法可能一次处理太多的事情。

在这种情况下,SoC 推动我们重构它,变成一个更简洁、更具描述性的版本。在这个过程中,原始算法的一部分被导出并封装在具有私有访问级别的独立的较小函数中。我们获得了代码的清晰性,算法的大部分最终变得可以被其他部分重用,即使我们最初没有预料到这种情况会发生。

模块的 SoC

在更高的层次上,这一原则告诉我们将功能分组到独立的模块中,每个模块负责完成一组具有明确逻辑关系的任务。

这个过程非常类似于我们必须为功能所做的事情:分离不太相关的功能,并将服务于相同明确目的的功能组合在一起

内聚和耦合

关注点分离的应用包括两个过程:减少耦合和增加内聚

内聚性是通过职责集、细节层次和位置来衡量相似性。比如函数drawCircledrawTriangle足够内聚,属于同一个负责绘图的模块,感觉在代码中把这两个函数放在一起很自然(高相似~高内聚)。

耦合则是衡量该部分对系统其余部分的依赖程度(低依赖~松耦合)。

前述的drawCircledrawTriangle可以被另一个功能drawCybertruck使用。我们也可以将这个函数放在绘图模块中,但是drawCyberthuck可能依赖于物理引擎和外部状态。因此,这将使整个绘图模块的可重用性大大降低,并与其他一些组件紧密耦合。

你可以看出原始绘图函数和drawCyberthuck属于不同的抽象层次和逻辑复杂度,因此它们需要驻留在不同的模块中。

如果在某个时候我们决定在另一个项目中使用绘图模块——将不再依赖于物理引擎,所以我们将能够更容易地提取它。

一种快速记住应该增加或减少哪个属性的方法:

  • 解耦是好的——所以我们需要瞄准一个松耦合
  • 内聚的代码是好的——我们需要瞄准高内聚

高内聚(低分散)代码的一个很好的例子是使用闭包回调而不是委托方法。

这里我应该注意,代码示例是在 iOS 应用程序开发的环境中用 Swift 编写的,但并不太多,它们很好地展示了这个概念。

考虑发送网络请求的代码:

// configuring and sending the request
session.send(request: URLRequest) { response in
    // handling the response
}

想象一下,如果 URLSession 有一个基于委托的 API 来发出请求:所有的响应都将被交付给一个函数handle(response: URLResponse, for request: URLRequest)

这将使网络更加容易出错和乏味,因为处理所有响应的逻辑现在必须绑定到那个函数。

使用基于回调的 API,动作和动作的结果在一个地方处理,这使得跟踪执行流更加容易。

如果我们需要在函数或模块之间跳来跳去,因为我们遵循算法的逻辑,这意味着代码具有低内聚,这通常被称为意大利面条代码

松耦合和高内聚的好处

遵循关注点分离的原则有助于改进代码库的许多特性:

  1. 更清晰的代码。当每个模块都有一个简洁明了的 API 和一组有逻辑作用域的方法时,理解程序中发生的事情就容易多了。
  2. 更好的代码重用性(干原理)。重用代码的主要好处是降低了维护成本。每当您需要扩展功能或修复 bug 时——当您确定它只出现在一个地方时,这样做就不那么痛苦了。
  3. 更好的测试性。具有适当范围功能的独立模块以及与应用程序其余部分的隔离很容易测试。您不需要设置整个环境来查看您的模块如何工作——用虚拟模拟或假数据源替换相邻的真实模块就足够了。通过这种方式,您可以通过验证输出将模块测试为黑盒,或者通过查看在连接的模块上调用了哪些方法将模块测试为白盒( BDD )。
  4. 更快的项目进展。无论是新功能还是现有功能的更新,模块的隔离都有助于确定程序中可能受变化影响的区域,从而加快开发速度。
  5. 更容易组织多个工程师同时开发。他们只需要就他们在哪个模块上工作达成一致,以确保他们不会互相干扰。只有模块 API 的更新可以作为明确通知其他开发人员的标志,而大多数更改可以在其他贡献者没有立即注意的情况下添加。当与良好的测试覆盖相结合时,并行开发变得和每个单独工作的工程师的累积生产率一样有效(它通常更慢)。

如你所见,从程序员的角度来看,耦合和内聚是最终影响使用代码的便利性的特征。

用于系统设计的 SoC

对于一堆具有不同职责和明确目的的模块,我们仍然需要概述一个全局策略,以说明模块之间应该如何相互引用。

如果我们不引入这种策略,我们可能会以一个关系错综复杂、数据流难以跟踪的系统而告终。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

系统设计的主要目标是勾勒出模块相互感知的边界。

每个现有的架构模式都提供了这种策略。以我们为例,模型-视图-控制器,我们会看到视图不允许与模型直接交互,而应该使用控制器作为中介。

在我看来,这些策略往往来自于纵容不好的普遍观念。在我看来,这要么导致过度设计的解决方案,要么导致职责分离不足的系统。

我倾向于认为系统的设计需要一个更加正式的方法,有明确的标准和动机。

我们已经看到,当 SoC 应用于功能和模块时,总是会产生更多可重用、可测试和可维护的代码。那么,为什么不将内聚性和耦合性作为这些指标,并在应用程序级别应用 SoC 呢?

这就是我们如何将模块分成的方法。这不是一个具体的架构模式,而是我刚才谈到的策略的高级规范。

模块按层分组,就像我们从一组不同的功能中形成一个模块一样。

基于系统中相似的职责和相同的抽象级别,在一层中产生的模块集具有高度的内聚性,而层之间的通信和环境感知非常受限,以实现松散耦合。

我们不仅限制了通信——底层具有更高环境细节的层(存储库,如数据库包装器或网络服务)被禁止直接引用在更高层(业务逻辑或 UI)中定义的任何东西。

因此,如果我们只采用与后端对话的网络服务,它应该对系统的其余部分一无所知并且只提供发送请求的 API。

业务逻辑层将知道并使用该存储库,但是它不知道是否有任何 UI 附加到系统上。

UI 层知道业务逻辑模块,并使用它们的 API 来读取最新的数据和触发动作,但同时,它对存储库一无所知,因为业务逻辑对它隐藏了实际的底层基础结构。

这样我们可以保证整个系统内在的可测试性,其中每一层要么不知道另一层的存在,要么是高度解耦,很容易被测试中的模拟包围。

贮藏室ˌ仓库

尽管业务逻辑和 UI 的解耦是一个标准举措,但我发现令人惊讶的是,我们为 iOS 开发的大多数流行模式都没有强调业务逻辑与数据网关(如网络层)解耦的重要性。

我多次看到请求直接从视图控制器或其他业务逻辑模块发出。数据库查询、用户默认值和任何其他本地或远程数据存储也是如此。

正如您可能猜到的,我不喜欢这里的紧耦合。但这不仅仅是模块之间的耦合,这或多或少是可以容忍的。

我们讨论的是算法的输入和算法本身之间的紧密耦合。这样的代码几乎不可能测试或进化。

您不希望在业务逻辑中嵌入直接读写操作的原因有很多,因此无法轻松地用模拟的调用交换真实的调用:

  1. 在运行未完成的算法时,您可能会意外损坏有价值的数据
  2. 对真实数据的访问可能很慢(本地资源的文件很大,访问远程资源时网络/测试服务器很慢)
  3. 外部数据可能不可用(本地数据库为空,需要预先填充,服务器关闭或互联网连接中断)
  4. 后端可能会在你意想不到的时候突然改变响应格式

后一种情况是臭名昭著的。当然,在一个理想的世界里,这种情况永远不会发生,但它确实发生了,而且比你想象的还要频繁。就算是 CI 也救不了你。

应用程序将停止工作,而第一个被指责的人将是你,移动工程师。你的应用损坏。在失败被发现后的最初几分钟,你不得不找借口,看起来很可怜。

想象一下,你公司的首席执行官正在为投资者展示一个重要活动的应用程序,这种情况发生了。

理想的解决方法是:应用程序不会崩溃,而是优雅地显示一条用户友好的错误消息。我们交给老板另一个设备,它可以使用模拟的演示数据在离线模式下运行,演示继续进行,事故几乎没有被注意到。

离线演示模式?听起来工作量很大!但是如果您已经从数据网关中分离和抽象出来,就不是这样了。

当我们有一个从其他地方查询数据的业务逻辑模块时,我们需要将访问外部数据资源的问题提取到一个单独的模块中,并将不必要的查询细节隐藏在外观后面。

这就是知识库的形成过程。

让我们看一个例子。我们有一个 ViewController,它加载并显示一些项目的列表:

首先要做的是引入ListRepository协议并重构 ViewController 来使用它:

现在,我们可以自由地替换实际适用于后端的实现:

或者甚至在离线模式下提供演示数据的虚拟存储库:

通过这种设置,应用程序可以配置为使用真实的网络 API 或模拟数据,我们也可以将这些数据保存在捆绑资源中,而不是硬编码。

对于上面的例子,我还应该注意,当我们实现异步 API 调用的存根时,我们应该始终保持它的异步性(从内部DispatchQueue.main.async触发回调)。否则,我们将会释放萨尔戈。

您可以看到存储库在我为 SwiftUI 应用提议的 Clean 架构变体中扮演了一个固有的角色:

[## SwiftUI 的干净架构

VIPER、MVVM、Clean Swift (VIP)、RIBs 或 ELM 是否适合 SwiftUI 项目?

medium.com](https://medium.com/swlh/clean-architecture-for-swiftui-6d6c4eb1cf6a)

结论

关注点分离是一个巨人,他的肩膀上站着许多我们今天知道的时髦术语模式。仅仅这个原则就为软件质量在各个层面上的显著提高提供了必要的指导。

在编写代码或设计架构时,不要忽略它。松耦合和高内聚是你的朋友!

为了更好的可测试性,将算法从输入和输出中分离出来,即使没有坚实的基础,你的软件也会坚如磐石:)

推特上关注我,关注即将发布的帖子!顺便说一下,我所有的文章都可以在我的技术博客( RSS )中免费阅读:

[## 阿列克谢·瑙莫夫

iOS 开发最佳实践、软件架构设计、功能反应式编程、Swift、SwiftUI、Combine…

nalexn.github.io](https://nalexn.github.io/?utm_source=xm)

九月版:部署机器学习模型

原文:https://towardsdatascience.com/september-edition-deploying-machine-learning-models-309518cca140?source=collection_archive---------31-----------------------

月刊

从您的投资中获得最大收益

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由来自 PexelsPixabay 拍摄

通常,数据科学任务的最后一步是部署。假设你在一家大公司工作。您正在为公司的客户构建一个项目,并且您已经创建了一个运行良好的模型。不幸的是,您创建的模型只有在客户拥有您编写的代码、您创建的环境和您一直在使用的机器的情况下才能被客户使用。

然而,如果您将您的模型部署到生产中,客户唯一需要的就是…产品。换句话说,一个机器学习模型将提供真正的价值,当它对用户可用时,它是为创建的。在投入生产之前,您的模型只是一个概念验证(PoC ),然后它就成为可交付产品。

有许多方法可以部署机器学习模型。部署的基本理念包括允许最终用户利用您的模型。产品需要根据最终用户的需求进行定制,因为他们将会使用它。部署是至关重要的一步,因为它允许其他人使用构建的机器学习模型。

选择如何将您的模型部署到产品中可能很困难,您需要评估最终用户想要什么和需要什么。也许你的模型需要实时工作。也许需要用它来一次做很多预测。你可能需要一个特定的架构,等等。一个产品可能有很多很多的需求,更重要的是,它需要在所有用例上工作,这就是为什么调试你的模型是必不可少的。

《走向数据科学》的编辑迈克尔·阿玛尼奥斯。

为什么我们用 Go 而不是 Python 部署机器学习模型

凯勒·凯瑟 — 5 分钟阅读

生产机器学习不仅仅是 Python 脚本

用 Python 开发 NLP 模型&用 Flask 逐步部署

苏珊李 — 6 敏念

Flask API,文档分类,垃圾邮件过滤器

部署 ML 模型有两种截然不同的方式,以下是两种方式

由汤姆·格雷克——9 分钟读完

如果一个 ML 模型用 Jupyter 做了一个预测,周围有人听吗?

使用 Streamlit 快速构建和部署仪表板

通过马腾 Grootendorst — 7 分钟读取

将您的 Streamlit 应用程序部署到 Heroku,展示您的数据解决方案

构建并部署您的第一个机器学习 web 应用

Moez Ali — 11 分钟读取

使用 PyCaret 在 Python 中训练和部署机器学习管道的初学者指南

构建 Web 应用来部署机器学习模型

李宗德魏恩 — 19 分钟读完

所以我们已经建立了我们的 ML 模型——现在呢?如何使用 Flask 离开 Jupyter 笔记本并进入 Web 应用程序!

如何使用 Angular 部署 TensorFlow Web 应用

詹姆斯·布里格斯

在角度构建的 web 应用程序中使用 Python 构建的模型

让我们部署一个机器学习模型

达里奥·拉德契奇 — 5 分钟阅读

如何在生产中使用机器学习模型

新视频

新播客

我们也感谢最近加入我们的所有伟大的新作家朱迪·周卡米拉·哈马尔契科娃金蒙·金罗恩·西林斯基尼尔斯·弗拉舍尔马特伊万·戴维斯达尼·索利斯布恩·杨史蒂夫·利文博士 罗宾·怀特安德烈亚斯·坎兹格泽戈尔兹·梅勒帕万·库马尔·博伊纳帕里阿列克谢·赫鲁斯塔列夫普拉蒂克·罗伊杰森·詹森德鲁·西沃德何塞·赫拉索等众多。 我们邀请你看看他们的简介,看看他们的工作。

英语到法语翻译的 Seq2Seq 建模

原文:https://towardsdatascience.com/seq2seq-modelling-for-english-to-french-translations-f6e4aa7aa02c?source=collection_archive---------42-----------------------

使用 Tensorflow 和 Keras 从头构建 Seq2Seq 网络

在隔离期间,我试图学习如何说法语,让自己有事可做。这一尝试并不成功,因此我建立了一个神经网络来尝试为我学习它。

为了做到这一点,我使用了一个具有注意力层的 seq2seq 递归神经网络,在加拿大第 36 届议会的众议院和参议院辩论中进行了训练(见此处)。基于注意力的 seq2seq 模型通常用于各种各样的任务,事实上,如果你曾经使用过 Siri 或谷歌翻译,你就有可能从这种模型中受益。

但是在我开始讨论我们如何自己构建一个之前,我认为快速了解 seq2seq 模型如何工作背后的一些理论是一个好主意——重点关注使这些模型表现如此良好的几个关键元素。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Alex OvsUnsplash 上拍摄

什么是 seq2seq 模型?

seq2seq 模型关于 NLP 的目标实质上是在考虑输入单词序列时计算输出单词序列的概率。这对机器翻译很有用,因为我们可能有一堆潜在的翻译,我们想知道哪个序列是最好的——例如狗是大的>大的是狗。或者我们可能需要选择一个最适合给定序列的词——例如上班迟到>上班慢跑迟到。

对于机器翻译,我们需要将一个单词序列编码成一个易于被模型消化的向量,然后让模型将这个向量解码成我们的目标语言。我们可以使用一个模型来进行编码和解码,但当您考虑到输入长度可能与输出长度不匹配时,问题就出现了,例如,“我妈妈爱法国”翻译成“ma maman aime la france”,需要一个额外的单词。这些输出序列长度不一定事先知道。

这将我们引向 seq2seq 模型。这个想法是,你得到一个模型——编码器——把一个单词序列转换成一个编码器向量,这个向量代表你要翻译的句子中的所有信息。然后你得到一个解码器,它使用 softmax 函数获取这个向量并输出翻译后的单词。

首先,编码器接受一个输入序列,并返回它自己的隐藏状态。当计算编码器隐藏状态(ht)时,我们只需要考虑当前输入(xt)和先前步骤隐藏状态(ht-1 ),因此等式看起来像这样

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后,解码器获取编码器的最后一个隐藏向量(c=ht)、前一个隐藏状态(ht-1)和前一个预测输出字(yt-1)。考虑到我们也是从编码器的最后一个隐藏向量计算的,我们使用先前预测的输出字可能看起来很奇怪,但是使用它允许 softmax 对当前预测(yt)产生影响。此外,yt-1 实际上给出了关于前一个单词是什么的明确答案,而不是概率分布,这有助于防止模型重复单词。所以总的来说,我们的解码器隐藏状态的公式看起来像这样-

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在我们需要做的就是在最后应用一个 softmax 函数,因为本质上这仍然是一个多类分类问题,但是现在我们的类是下一个时间步目标语言中的每个单词。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LSTM 细胞

因此,上面我们已经为 seq2seq 模型设计了结构。但是你可能想知道编码层和解码层是由什么组成的。编码器/解码器层可以由基本的 RNN 单元组成,但是这些单元不能在长序列中寻找上下文。因此,如果它试图根据前面的单词预测下一个单词,它可能会很好地处理类似“坐在椅子上的人”的事情,因为坐和椅子之间没有很大的差距。然而,对于像“正在做牛排…然后我坐下来吃牛排“它可能不会表现得很好,因为我们想要预测的单词(牛排)和这个单词的上下文之间有更大的差距(关于为什么 RNN 细胞在长序列上表现不好的详细信息,Bengio 等人有很好的论文详细说明了困难

这就是 LSTM 细胞的用武之地。不仅仅是将前一时间步的隐藏状态与当前输入相结合,还有四个层在起作用。基本的想法是,这些细胞可以将对未来决策有用的信息保存在细胞内。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

加戈、詹妮弗·乔安娜&瓦斯科、瓦伦蒂娜&茹卡沃斯基、巴特克&帕塔奇尼、乌戈&蒂哈诺夫、瓦迪姆&维克托斯、胡安&巴拉格尔、卡洛斯。(2019).序列对序列自然语言到类人机器人手语。链接

在每个时间步,我们都要修改以下内容-

输入门-

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

遗忘之门-

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

输出-

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

前三个方程都非常相似。sigmoid 函数,因此它们的输出将位于 0 和 1 之间,这意味着它们的输出向量可以定义另一个向量可以通过第一个向量的量。xt 是当前输入,ht-1 是前一时间步隐藏层,W U 是权重。

然后我们有了新的存储单元,它与标准的 RNN 层相同,只是我们用输入向量的输出来控制它的输出。我们可以将这一层视为候选隐藏状态。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后我们将它们与最终的存储单元和隐藏状态结合在一起。

输入门决定了我们对当前单词向量的关心程度。换句话说,它决定了你想让当前输入的新计算状态通过多少。例如,如果我们试图预测电影评论的情绪,但当前向量正在谈论这个人晚餐吃了什么,那么权重可能接近于零,当前向量将不会通过这个门。

输出门将对当前预测重要的内容与对未来重要的内容分开,因此它不会对当前时间步长的单元输出产生影响,但会改变其隐藏状态。这很有用,因为有时当前步骤可能现在对输出没有用,但以后可能会有一些好处。

遗忘门使用当前步骤输入来决定我们应该从长期状态(h(t-1))中遗忘什么。所以回到前面的例子,如果我们试图预测一部电影评论的情绪,而前面的时间步骤只是关于情节,而当前的时间步骤是“我讨厌它”,你可能会想忘记前面的信息,只关注当前的时间步骤。值得注意的是,所有这些门都是向量,我们不应该认为它们是绝对的,而是会忘记一个长期隐藏的单元的某些元素。

所有上面的层都是单层神经网络,然后我们把它们放在最终的存储单元(ct)中,就像这样-

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个等式有直观的意义,因为我们的遗忘门(ft)决定了我们想要忘记多少以前的记忆,所以我们将其应用于以前的时间步。同时,我们希望将当前时间步长的输入门(it)和标准 RNN 单元(c̃t)结合在一起。

最后,我们使用这个存储单元和输出门来确定时间 t -时的隐藏状态 ht

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基本上就是这样了!要更详细地了解 LSTMs 是如何工作的,这里有一些很好的资源

[## 了解 LSTM 网络

2015 年 8 月 27 日发布人类不是每秒钟都从零开始思考。当你读这篇文章时,你…

colah.github.io](https://colah.github.io/posts/2015-08-Understanding-LSTMs/)

注意层

在我们进入代码之前,我将快速讨论一下注意力层,因为它在这个模型的性能中起着很大的作用。

尽管 LSTM 单元对于单词远离模型试图预测的单词的上下文很有帮助,但它并没有完全缓解这个问题。注意层允许解码器关注在该时间步获得正确输出所需的序列部分,从而缩短输入字到其翻译之间的路径,从而减轻 LSTMs 可能具有的一些存储器限制。它通过提供一种针对源序列上的所有标记对目标序列中的标记进行评分的方式来实现这一点,并使用这种方式来改变解码器序列的输入。分数然后被输入到 softmax 激活中,以进行注意力分配。

注意力如何融入模型架构的其他部分?我们不是只发送编码器的最终状态,而是将其所有输出发送给解码器。在每个时间步,解码器的注意力单元计算所有这些编码器输出的加权和,并使用 softmax 激活函数确定在每个步骤中它将关注哪些单词。关于注意力机制的更详细的解释,请看这里

[## 注意力和增强递归神经网络

递归神经网络是深度学习的主要内容之一,允许神经网络与序列一起工作…

蒸馏. pub](https://distill.pub/2016/augmented-rnns/)

数据清理和准备

现在,我们已经快速浏览了理论,我们可以进入实际的编码,我不会覆盖项目中的所有代码,但会在最后将 github repo 与所有内容联系起来。此外,如果你的计算机上没有 GPU 访问,我会推荐使用谷歌 Colab 这样的东西,这样你就可以使用他们的免费 GPU,因为它将大大加快训练时间。

第一步是清理数据,并将其转换成可用的格式。要做到这一点,我们需要删除所有奇怪的东西,如空格,标点符号和不可打印的符号。

接下来,我们需要限制每个句子的长度,以加快训练速度。此外,对于目标序列,我们需要在每个序列的开头和结尾添加一个开始字符()和一个结束字符()。我们这样做是为了当我们想要翻译看不见的数据时,我们可以输入开始字符来让模型运行,并在翻译完成时给模型一个停止的方法。最后,我们需要填充英文数据,这样每个序列都是相同的大小。

我们准备的下一步是为每种语言创建字典,字典中的每个单词都与一个数字相关,该数字可以很容易地为模型进行编码。重要的是,我们将在字典中添加一个符号,用于解释模型词汇表之外的单词。

最后,我们必须实际编码我们的训练和测试数据。在每一个时间步,我们都将输入数据和下一步的目标数据提供给模型。

手套嵌入

因此,我们可以从这里直接进入建模,但我们可以采取一个额外的步骤,可以大大提高模型的性能。我不会说太多细节,但基本上我们可以在模型中给单词预设权重,以反映单词的相似程度——例如,国王和王后比国王和胡萝卜更相似。关于这个概念的更详细的观点,这里是原文——https://nlp.stanford.edu/pubs/glove.pdf

创建和训练模型

好了,现在我们已经做好了所有的数据准备,我们可以开始创建模型了。编码器模型是一个两层 LSTM,解码器是一个单层 LSTM,还增加了一个关注层。这提供了很好的性能,仅在几个时期后验证精度就达到了 0.96,但在未来,我希望研究双向 LSTMs 来提高性能。

在训练初始模型后,我们将训练好的层转移到推理模型中,这样我们就可以实际使用它了。

运行推理模型

最后,在创建我们的推理模型后,我们可以用它来翻译任何我们想要的英语句子!为此,我们将英语句子输入推理编码器,然后将编码数据和起始标记输入解码器。接下来,我们使用 while 循环继续遍历整个句子,直到模型预测到结束标记()或者达到最大句子长度。

测试模型

那么模型做的怎么样呢?我用下面验证集中的几个句子进行了测试-

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接下来,我想尝试一个全新的句子

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总的来说,只有几个训练时期非常棒!

结束语

在本文中,我们展示了 seq2seq 模型在机器翻译中的强大功能。然而,还有更多事情要做!在未来,我想引入波束搜索和双向层,因为它们可以进一步提高性能。对于这个项目中使用的完整代码,你可以访问 github repo 这里

注意:具有注意机制的序列 2 序列模型

原文:https://towardsdatascience.com/sequence-2-sequence-model-with-attention-mechanism-9e9ca2a613a?source=collection_archive---------4-----------------------

Bahdanau 和 Luong 提出的序列 2 序列模型中注意机制的详细解释

在本文中,您将了解到:

  • 为什么我们需要序列 2 序列模型的注意机制?
  • Bahdanua 的注意力机制是如何工作的?
  • Luong 的注意力机制是如何工作的?
  • 什么是本地和全球关注?
  • Bahdanau 和 Luong 注意机制的主要区别

先决条件:

像 LSTM 和 GRU 这样的循环神经网络(RNN)

Seq2Seq-神经机器翻译

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

什么是注意,为什么我们需要序列 2 序列模型的注意机制?

让我们考虑两个场景,场景一,你正在阅读一篇与当前新闻相关的文章。第二种情况是你准备考试。两种情况下的注意力水平是相同还是不同?

与新闻文章相比,你在准备考试时会相当注意阅读。在准备考试的时候,你将会更加关注关键词来帮助你记住一个简单或复杂的概念。这同样适用于任何深度学习任务,我们希望专注于感兴趣的特定领域。

序列到序列(Seq2Seq)模型使用编码器-解码器架构。

seq2seq 的几个用例

  • 神经机器翻译(NMT)、
  • 图像字幕,
  • 聊天机器人
  • 抽象文本摘要等。

Seq2Seq 模型将源序列映射到目标序列。在神经机器翻译的情况下,源序列可以是英语,目标序列可以是印地语。

我们将英语中的源句子传递给编码器;编码器将源序列的完整信息编码成单个实值向量,也称为上下文向量。这个上下文向量然后被传递给解码器,以产生目标语言(如印地语)的输出序列。上下文向量负责将整个输入序列总结成一个向量。

如果输入的句子很长,来自编码器的单个向量能否容纳所有相关信息提供给解码器?

在预测目标词时,是否可以关注句子中的几个相关词,而不是保存整个句子信息的单个向量?

注意力机制有助于解决问题。

注意机制的基本思想是避免试图学习每个句子的单个向量表示,而是基于注意权重来注意输入序列的特定输入向量。

在每一个解码步骤,解码器将被告知需要对每个输入单词给予多少“关注”,使用一组**。这些注意力权重向解码器提供上下文信息以进行翻译

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

巴赫达瑙注意机制

Bahdanau 等人提出了一种学习联合对齐和翻译的注意机制。它也被称为附加注意,因为它执行编码器状态和解码器状态的线性组合

让我们来理解巴赫达瑙提出的注意机制

  • 编码器(前向和后向)和解码器的所有隐藏状态都用于生成上下文向量,不像 seq2seq 中只使用最后一个编码器隐藏状态而不加注意。
  • 注意机制利用由前馈网络参数化的比对分数来比对输入和输出序列。它有助于注意源序列中最相关的信息。
  • 该模型基于与源位置和先前生成的目标单词相关联的上下文向量来预测目标单词。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意机制

具有注意机制的 Seq2Seq 模型由编码器、解码器和注意层组成。

注意力层包括

  • 对准层
  • 注意力权重
  • 上下文向量

比对分数

比对分数映射了位置”****j”周围的输入和位置I”**处的输出匹配得如何。分数基于预测目标单词之前的前一解码器的隐藏状态 s₍ᵢ₋₁₎ 和输入句子的隐藏状态 hⱼ

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解码器决定需要关注源句子的哪一部分,而不是让编码器将源句子的所有信息编码成一个定长向量

与源序列具有相同长度的对齐向量,在解码器的每个时间步长进行计算

在我们的例子中,为了预测第二个目标词,,我们将为输入词 快速生成一个高分**

注意力权重

我们将 softmax 激活函数应用于比对分数,以获得注意力权重**。**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Softmax 激活函数将获得总和等于 1 的概率,这将有助于表示每个输入序列的影响权重。输入序列的注意力权重越高,其对预测目标单词的影响就越大。

在我们的例子中,我们看到输入单词***【तेज़ी】具有较高的注意力权重值*

上下文向量

上下文向量用于计算解码器的最终输出。上下文向量𝒸ᵢ是注意力权重和编码器隐藏状态(h₁、h₂、…,hₜₓ)的加权和,其映射到输入句子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

预测目标词

为了预测目标单词,解码器使用

  • 上下文 vector(𝒸ᵢ),
  • 前一时间步的解码器输出(y ᵢ₋₁ )和
  • 前一个解码器的隐藏状态( sᵢ₋₁)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解码器在时间步长 I 的隐藏状态

卢昂注意机制

Luong 的注意力也被称为倍增注意力**。通过简单的矩阵乘法将编码器状态和解码器状态转化为注意力分数。简单的矩阵乘法使它更快更节省空间。**

Luong 根据注意力在源序列中的位置提出了两种类型的注意机制

  1. ****全局关注关注所有源位置
  2. ****局部注意力其中注意力仅放在每个目标单词的源位置的一个小子集上

全局和局部注意力的共性

  • 在解码阶段的每个时间步长 t,全局和局部注意这两种方法首先将堆叠 LSTM 顶层的隐藏状态 hₜ作为输入。
  • 这两种方法的目标都是导出一个上下文向量 𝒸ₜ 来捕捉相关的源端信息,以帮助预测当前的目标单词 yₜ
  • 注意力向量作为输入被馈送到下一个时间步骤,以通知模型关于过去的对齐决策。

全局和局部注意力模型在如何导出上下文向量𝒸ₜ方面有所不同

在我们讨论全局和局部注意之前,让我们先了解 Luong 的注意机制在任何给定时间 t 所使用的惯例

  • 𝒸ₜ:语境向量
  • aₜ:对齐向量
  • hₜ:当前目标隐藏状态
  • hₛ:电流源隐藏状态
  • yₜ:预测当前目标词
  • ˜ₜ : 注意力向量

全球关注

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

全球注意力来源:基于注意力的神经机器翻译的有效方法

  • 当计算上下文向量𝒸ₜ.时,全局注意力模型考虑编码器的所有隐藏状态
  • 通过将当前目标隐藏状态h与源隐藏状态 hₛ 中的每一个进行比较,得到等于源序列中时间步长数量大小的可变长度对齐向量t1】aₜ****
  • 比对分数被称为基于内容的函数,我们考虑了三种不同的备选方案

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 全局上下文向量𝒸ₜ是根据对齐向量 aₜ 在所有源隐藏状态 hₛ 上计算的加权平均值

当源序列是大段或者大文档时会怎样?

当全局注意力模型考虑源序列的所有单词来预测目标单词时,它变得计算昂贵,并且翻译更长的句子可能具有挑战性****

我们可以通过使用局部注意来解决全局注意模型的这一缺陷

当地的关注

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

局部注意力来源:基于注意力的神经机器翻译的有效方法

  • 局部注意力只集中在每个目标单词的源位置的一个小的子集上,不像全局注意力那样集中在整个源序列上
  • 计算成本低于全局注意力
  • 局部注意力模型首先在时间 t 为每个目标单词生成对齐位置 Pₜ
  • 上下文向量 𝒸ₜ 是作为所选窗口内的源隐藏状态集合的加权平均值导出的
  • 可单调或预测地选择对齐位置

Bahdanau 和 Luong 注意机制的主要区别

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

双向编码器中前向和后向隐藏状态的 Bahdanau 级联。Luong attention 在编码器和解码器的顶层都使用隐藏状态

Bahdanau 和 Luong 注意机制中注意的计算

Bahdanau 等人在双向编码器中使用前向和后向隐藏状态的连接,在他们的非堆叠单向解码器中使用先前目标的隐藏状态

Loung 等人的注意力在编码器和解码器中的顶部 LSTM 层使用隐藏状态

Luong 注意机制使用当前解码器的隐藏状态来计算对齐向量,而 Bahdanau 使用前一时间步的输出

对齐功能

Bahdanau 仅使用 concat 评分比对模型,而 Luong 使用 dot、general 和 concat 评分比对模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有了注意力机制的知识,你现在可以构建强大的深度 NLP 算法。

参考资料:

通过联合学习对齐和翻译 Dzmitry Bahdanau 的神经机器翻译

基于注意力的神经机器翻译的有效方法:Minh-Thang Luong Hieu Pham Christopher d . Manning

** [## 神经网络中的注意机制

在机器翻译中,编码器-解码器架构是常见的。编码器读取一个单词序列,然后…

devopedia.org](https://devopedia.org/attention-mechanism-in-neural-networks)**

序列模型和递归神经网络

原文:https://towardsdatascience.com/sequence-models-and-recurrent-neural-networks-rnns-62cadeb4f1e1?source=collection_archive---------9-----------------------

理解深度递归神经网络(RNNs)

序列模型

序列模型是输入或输出数据序列的机器学习模型。序列数据包括文本流、音频片段、视频片段、时间序列数据等。递归神经网络(RNNs)是一种用于序列模型的流行算法。

序列模型的应用 1。语音识别 : 在语音识别中,给定一个音频片段作为输入,然后模型必须生成它的文本副本。这里输入和输出都是数据序列。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

语音识别(来源:作者)

2.情感分类**:情感分类中的**对一段文本中表达的观点进行分类。这里的输入是一个单词序列。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

情感分类(来源:作者)

3.视频活动识别 : 在视频活动识别中,模型需要识别视频片段中的活动。视频剪辑是视频帧序列,因此在视频活动识别的情况下,输入是数据序列。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

视频活动识别(来源:作者)

这些例子表明序列模型有不同的应用。有时输入和输出都是序列,有时输入或输出都是序列。递归神经网络(RNN)是一种流行的序列模型,它对序列数据表现出高效的性能。

递归神经网络

递归神经网络(RNN)是一种深度学习算法,是一种专门用于处理序列数据的人工神经网络架构。rnn 主要用于自然语言处理领域。RNN 维护内存,因此它们对于涉及顺序数据的机器学习问题非常有效。rnn 也用于时间序列预测。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

传统的 RNN 建筑(来源:Stanford.edu)

使用 RNNs 而不是标准神经网络的主要优点是标准神经网络中没有共享的特征。在 RNN,权重是跨时间共享的。RNNs 可以记住它以前的输入,但是标准的神经网络不能记住以前的输入。RNN 利用历史信息进行计算。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

损失函数

在 RNN,损失函数是根据每个时间步的损失定义的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

重量损失的导数

在 RNN,反向传播在每个时间点进行

RNN 建筑

基于输入和输出的数量,有几种 RNN 架构
1。一对多架构:图像字幕就是这种架构的一个很好的例子。在图像字幕中,它获取一幅图像,然后输出一系列单词。这里只有一个输入,但有许多输出。

2.多对一架构:情感分类是这种架构的一个很好的例子。在情感分类中,给定的句子被分类为肯定或否定。在这种情况下,输入是单词序列,输出是二进制分类。

3.多对多架构:在多对多架构中有两种情况,

  • 第一种是输入长度等于输出长度。命名实体识别是一个很好的例子,其中输入序列中的单词数等于输出序列中的单词数。
  • 多对多架构的第二种是当输入长度不等于输出长度时。机器翻译是这种架构的一个很好的场景。在机器翻译中,RNN 阅读一种语言的句子,然后将其转换成另一种语言。这里输入长度和输出长度是不同的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

RNN 建筑(来源:https://Calvin feng . git book . io)

长短期记忆(LSTM)

传统的 rnn 不擅长捕捉长程相关性。这主要是由于消失梯度问题。当训练非常深的网络时,梯度或导数随着其向下传播而指数下降。这就是所谓的消失梯度问题。这些梯度用于更新神经网络的权重。当梯度消失时,权重将不会更新。有时候会
完全停止神经网络的训练。这种消失梯度问题是非常深的神经网络中的常见问题。

为了克服 RNNs 中的梯度消失问题,Sepp Hochreiter 和 Juergen Schmidhuber 引入了长短期记忆。LSTM 是对 RNN 隐藏层的修改。LSTM 使 RNNs 能够长时间记住它的输入。在 LSTM 中,除了隐藏状态,单元状态被传递到下一个时间步。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基本 RNN 和 LSTM 单位的内部结构(资料来源:stanford.edu)

LSTM 可以捕捉远程依赖。它可以长时间记忆以前的输入。LSTM 的牢房里有三道门。LSTM 的记忆操作是通过这些门完成的。长短期记忆(LSTM)利用门来控制递归网络记忆中的梯度传播。

  • 遗忘门:遗忘门删除单元状态中不再有用的信息
  • 输入门:输入门增加了对单元状态有用的附加信息
  • 输出门:输出门增加了对单元状态有用的附加信息

LSTM 的这种门控机制允许网络学习何时忘记、忽略或保留记忆单元中的信息。

LSTM 是一种非常流行的序列模型深度学习算法。苹果的 Siri 和谷歌的语音搜索是一些使用 LSTM 算法的真实例子,它是这些应用程序成功的背后。最近的研究表明,LSTM 算法可以提高机器学习模型的性能。LSTM 也用于时间序列预测和文本分类任务。

参考文献

https://www . researchgate . net/publication/13853244 _ Long _ Short-Short _ Memory
https://Stanford . edu/~ shervine/teaching/cs-230/cheat sheet-recurrent-neural-networks

序列对序列模型:使用 Tensorflow 2 的注意力网络

原文:https://towardsdatascience.com/sequence-to-sequence-models-attention-network-using-tensorflow-2-d900cc127bbe?source=collection_archive---------46-----------------------

第 2 部分:序列到序列模型:从 RNN 到变压器

在本系列教程的第 1 部分中,我们讨论了带有简单编码器-解码器网络的序列间模型。简单网络更容易理解,但它也有其局限性。

简单编码器-解码器网络的局限性

如果您还记得第 1 部分,解码器仅基于编码器的最后隐藏输出进行解码。 这意味着,为了让普通的编码器-解码器网络正常工作,编码器需要确保在最后的隐藏状态输出中编码所有必要的信息。 这对于短序列很有效,但对于长序列效果不佳。

这就是为什么attention是序列到序列模型中的一个关键概念[1]。

注意力是如何工作的

注意机制的目标是向解码器提供上下文信息,以便解码器能够以更高的准确度解码。注意力网络表示上下文向量和整个输入序列之间的关系,而不是依赖编码器的最后隐藏状态中的单个上下文向量。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1:bahda nau 注意的编码器-解码器模型[1]

  • 我们计算一个上下文向量 c 作为输入序列的隐藏状态的总和,用alignment scores加权。
  • alignment scores给位置处的输入 x 和位置处的输出*分配一个 分数***

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2:注意力等式[4]

  • 不同的注意机制以不同的方式计算这个score
  • 解码器使用这些注意力分数来决定在每个解码时间步长对输入给予多大程度的关注

计算注意力得分主要有四种不同的方法——加法(Bahdanau 的注意力)和乘法(Luong 的注意力)、自我注意力和键值注意力。这里我们将重点关注 Bahdanua 的注意力。

巴丹瑙注意了

Bahdanau 等人[1]提出了原始的注意力机制,该机制使用一个隐藏层前馈网络来计算注意力对准分数[2]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3 —注意力得分计算

这里,vW是学习到的——注意网络的参数。 W₁W₂ 是分别学习当前隐藏状态的变换和编码器输出 s 的独立矩阵。**

如果你有点困惑,不要担心。我们会写一个方法让 Bahdanau 注意,让事情变得更清楚。

使用 Tensorflow 2.0 实现 Bahdanau 注意力

BahdanauAttention初始化器中,你会看到我们正在初始化三个Dense层— W1W2V。如图 3 所示,这些Dense层将用于计算正向传播中的分数,也称为call方法中的分数。

我们向W1W2层传递什么?W1W2分别将当前隐藏状态和编码器输出作为输入。在call方法内部——隐藏状态和编码器输出分别由queryvalue表示。一旦我们使用来自Decoder网络的BahdanauAttention,你会对分数计算有更清晰的了解。

接下来,当我们通过 softmax 层传递score时,我们计算attention_weights。由于 softmax 返回多类分类问题中目标类的概率分布[5],因此attention_weights本质上代表了解码器在解码过程中关注了哪个单词。

最后,我们计算context_vector,解码器将使用它来预测最可能的输出。

编码器和解码器:

Encoder等级与第一部分中描述的等级相同。除了添加了如下所示的注意机制之外,Decoder类也非常相似。

你会注意到在line #19我们正在初始化attention层。在call方法的前向传播过程中,我们用当前的隐藏状态和编码器输出实例化了attention层,该输出转化为BahdanauAttention类中的queryvalueattention层输出context_vectorattention_weights(第20行)。context_vector与解码器输入x连接(第#行26)。该连接的结果然后通过gru单元和一个完全连接的层(线# 35)。这里的Decoder类也输出attention_weights,稍后您可以使用它来可视化解码器关注的地方[3]

把所有的放在一起

端到端的工作流程与我们在第一部分中描述的相同——数据清理、定义EncoderDecoder类、训练模型、推理和评估。关于工作代码,请参考 TensorFlow 示例代码这里的

参考:

  1. 联合学习对齐和翻译的神经机器翻译https://arxiv.org/abs/1409.0473
  2. NLP 深度学习最佳实践https://ruder . io/Deep-Learning-NLP-Best-Practices/index . html #注意
  3. 有注意力的神经机器翻译https://www . tensor flow . org/tutorials/text/NMT _ with _ Attention
  4. https://lilian Weng . github . io/lil-log/2018/06/24/attention-attention . html
  5. Softmax 的直观解释https://www . machine curve . com/index . PHP/2020/01/08/how-the-soft max-activation-function-work/

序列到序列模型:使用 Tensorflow 2 的编码器-解码器

原文:https://towardsdatascience.com/sequence-to-sequence-models-from-rnn-to-transformers-e24097069639?source=collection_archive---------17-----------------------

第 1 部分:序列到序列模型:从 RNN 到变压器

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来自 Pixabay莫尼卡普的图片

序列到序列模型是对序列数据进行操作的基本深度学习技术。它将一个结构域的序列转换成另一个结构域的序列[1]。这些模型可以是基于 RNN 的简单编码器-解码器网络或高级的基于注意力的编码器-解码器 RNN 或最先进的变压器模型。序列到序列模型有许多应用,例如机器翻译、语音识别、文本摘要、问题回答、需求预测等等。

本文是关于序列到序列模型的三篇文章中的第 1 篇,在这篇文章中,我们将重点构建一个机器翻译系统。在这一部分中,我们将关注基于 RNN 的编码器-解码器网络的内部工作。为了举例说明,我们将构建一个西班牙语到英语的翻译模型。

本文的重点是模型架构、训练和使用 Tensorflow 2.0 的推理过程。因此,我们将省略关于数据准备的讨论。作为参考,数据准备部分可以按照 Tensorflow 教程[2]进行。如果您是 Tensorflow 2.0 的新手,您可能需要特别关注create a tf.data dataset部分[2]

如果你觉得这篇文章很有趣,请随时联系 LinkedIn。

编码器-解码器模型

直观上,编码器对输入进行编码,解码器将其解码到所需的域。在我们的例子中,编码器将对输入的西班牙语句子进行编码,解码器将它们解码成英语。在基于递归神经网络(RNN)的架构中,编码器和解码器都是 RNN 或其变体之一,如 LSTM 或 GRU。在本文中,我们将使用 GRU 单元。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1:机器翻译的编码器-解码器模型

编码器

  • 编码器的输入是英语单词。在每个时间步长,一个英语单词作为输入与前一个时间步长(称为隐藏状态)的 RNN 的输出一起传递给 RNN。一开始,这个隐藏状态被初始化为零。
  • 编码器通过这个 RNN 网络对输入数据进行编码

解码器

  • 在训练阶段,解码器的输入是移动一步的西班牙语单词。也就是说,给解码器一个它should have预测的输入字,而不管它实际预测的是什么。
  • 对于第一个时间步长,解码器被赋予start-of-sequence (SOS)。解码器应该以一个end-of-sequence (EOS)标记结束句子。

推理过程:

序列对序列模型中的一个关键概念是理解训练和推理模型的不同之处。它是关于解码器的。我们在推断时间和训练时间如何将输入提供给解码器是不同的。你大概可以直观的理解,在推理时间里,我们不知道目标翻译的单词。因此解码器将被馈送前一时间步的输出。当然,对于第一个时间步长,解码器被赋予start-of-sequence (SOS)

让我们深入研究一下实现。

编码器型号

我们将使用 Tensorflow 2 构建一个Encoder类。首先,确保您导入了必要的库

import tensorflow as tf

EncoderDecoder类都将继承自tf.keras.Model。至少,这些类将有两个方法——一个初始化器__init__方法和一个call方法。call方法在网络的正向传递过程中执行。如果您熟悉 Pytorch,那么您很可能熟悉这种定义模型的风格。

Encoder类中,我们还将定义一个初始化隐藏状态的方法。

__init__方法中,我们需要定义层——例如Embedding层、GRU层或完全连接的Dense层。我们还需要初始化定义这些层所需的变量。具体来说,我们需要定义

  • vocab_size:训练数据中的唯一单词数
  • embedding_dim:您希望嵌入的尺寸。一般来说,越高越好,但这也带来了计算和内存成本。
  • enc_units:GRU 单位的数量。例如,在figure-1中,我们有n个编码器单元
  • batch_size:你希望你的模型在每个时期训练的数据量。

call方法中,你想做你认为你的模型在网络的前向传播中应该做的操作。在编码器的情况下,我们需要得到嵌入的输入字,并通过 GRU 层传递它。

解码器模型

Decoder类与Encoder类非常相似。除此之外,您需要通过完全连接的Dense层传递 GRU 单元的输出,以便从网络中获得预测。

训练编码器-解码器网络

首先,我们将定义网络的优化器和损失函数。我们将使用 Adam 优化器。既然是分类问题,我们就用CrossEntropy损失作为损失函数。

在训练过程中—

  • 我们通过返回encoder outputencoder hidden state的编码器输入。
  • 然后将encoder outputencoder hidden statedecoder input传递给解码器。decoder input<SOS>(句首)标记开始。
  • 解码器输出predictiondecoder hidden state
  • prediction用于计算损失
  • 我们根据当前时间步的输入为下一个时间步创建decoder input。这个迫使解码器学习目标输出的过程称为teacher forcing
  • 当前时间步的decoder hidden state被送至下一个时间步。
  • 接下来,我们将计算梯度。随着 Tensorflow 进入急切执行模式[6],我们将使用tf.GradientTape来跟踪计算梯度的操作。梯度计算相对于模型的可训练参数发生。因此,在下面的行19中,你会发现我们正在总结编码器和解码器的可训练变量。
  • 当在tf.GradientTape的上下文中执行操作时,它们被记录。默认情况下会记录可训练参数[7]。如果你想记录张量,你必须通过在tf.GradientTape的上下文中调用watch方法来手动完成。
  • 最后,我们将对优化器应用梯度,优化器将更新模型参数——aka。反向传播。

推理

您可能已经注意到,在培训时,我们保存了模型检查点。保存检查点是保存模型的一种方式。或者,如果您有一个keras.Model对象,那么您可以使用saved_model.save来保存模型[8]。要运行推理,您需要重新加载检查点[9]。

如前所述,推理过程与训练过程非常相似,只是我们如何馈送给解码器。这里,解码器的输入是解码器在前一时间步的输出——无论它预测了什么,而不是目标。如果你理解训练过程,代码是简单的。

如果你已经理解到这一点,可以写一个基于 RNN 的编码器-解码器,可以做训练和编码推理方法-祝贺你!

即将推出!第 2 部分—关注基于 RNN 的编码器-解码器网络

参考:

  1. 十分钟序列对序列学习介绍https://blog . keras . io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras . html
  2. 关于数据处理/清理的一切https://www . tensor flow . org/tutorials/text/NMT _ with _ attention
  3. 原序对序纸https://arxiv.org/pdf/1409.3215.pdf
  4. https://machine learning mastery . com/define-encoder-decoder-sequence-sequence-model-neural-machine-translation-keras/
  5. 理查德·索契的机器翻译讲座
  6. 张量流急切执行https://www.tensorflow.org/guide/eager
  7. 张量流梯度带https://www.tensorflow.org/api_docs/python/tf/GradientTape
  8. https://www.tensorflow.org/guide/saved_model
  9. 张量流检查点https://www.tensorflow.org/guide/checkpoint

Python 中的序列解包

原文:https://towardsdatascience.com/sequence-unpacking-in-python-14d995f9a619?source=collection_archive---------33-----------------------

了解 Python 序列解包

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源

python 中的序列解包允许您获取集合中的对象,并将它们存储在变量中以备后用。这在函数或方法返回一系列对象时特别有用。在这篇文章中,我们将讨论 python 中的序列解包。

我们开始吧!

python 的一个关键特性是任何序列都可以通过赋值被解包到变量中。考虑与 Nike run 应用程序上特定跑步的属性相对应的值列表。该列表将包含跑步的日期、配速(分钟)、时间(分钟)、距离(英里)和海拔(英尺):

new_run = ['09/01/2020', '10:00', 60, 6, 100]

我们可以通过赋值用适当命名的变量解开这个列表:

date, pace, time, distance, elevation = new_run

然后,我们可以打印这些变量的值,以验证赋值是否正确:

print("Date: ", date)
print("Pace: ", pace, 'min')
print("Time: ", time, 'min')
print("Distance: ", distance, 'miles')
print("Elevation: ", elevation, 'feet')

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们正在解包的序列中的元素也可以是序列。例如,除了整体跑步的平均配速,我们还可以有一组英里分割:

new_run_with_splits = ['09/01/2020', '10:00', 60, 6, 100, ('12:00', '12:00', '10:00', '11;00', '8:00', '7:00')]

现在让我们打开新序列的包装:

date, pace, time, distance, elevation, splits = new_run_with_splits

我们可以打印英里分割:

print("Mile splits: ", splits)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们甚至可以进一步解开前面代码中的拆分列表。让我们用表示英里数的变量来解开分割列表:

date, pace, time, distance, elevation, (mile_2, mile_2, mile3_, mile_4, mile_5, mile_6) = new_run_with_splits

让我们打印英里变量:

print("Mile Two: ", mile_2)
print("Mile Three: ", mile_3)
print("Mile Four: ", mile_4)
print("Mile Five: ", mile_5)
print("Mile Six: ", mile_6)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们还可以使用’ _ '字符来删除不需要的值。例如,如果我们想省略日期和高度,我们会这样做:

_, pace, time, distance, _, (mile_2, mile_2, mile_3, mile_4, mile_5, mile_6) = new_run_with_splits

我们还可以使用 python 的“星形表达式”(*)来解包任意数量的元素。例如,如果我们想存储第一个和最后一个变量,并将中间值存储在一个列表中,我们可以执行以下操作:

date, pace, time, distance, elevation, (first, *middle, last) = new_run_with_splits

让我们打印第一个、中间和最后一个变量:

print("First: ", first)
print("Middlle: ", middle)
print("Last: ", last

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我想强调的是,我们序列中的对象可以是任何类型。例如,对于英里分割,我们可以使用字典而不是元组:

new_run_with_splits_dict = ['09/01/2020', '10:00', 60, 6, 100, {'mile_1': '12:00', 'mile_2':'12:00', 'mile3':'10:00', 'mile_4':'11;00', 'mile_5':'8:00', 'mile_6':'7:00'}]

让我们打开新清单:

date, pace, time, distance, elevation, splits_dict = new_run_with_splits_dict

现在,我们可以通过键访问英里分割值:

print("Mile One: ", splits_dict['mile_1'])
print("Mile Two: ", splits_dict['mile_2'])
print("Mile Three: ", splits_dict['mile_3'])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我就讲到这里,但是我鼓励你自己去研究代码。

结论

在这篇文章中,我们讨论了如何在 python 中解包序列。首先,我们展示了如何解包与发布到 Nike Run 应用程序的跑步相关的值列表。我们还展示了序列中的值也可以是序列,其中序列或其元素可以存储在单独的变量中供以后使用。然后,我们展示了如何使用下划线字符删除值。接下来,我们讨论了如何使用 python“星形表达式”解包任意数量的对象。最后,我们演示了如何从对象列表中解包一个字典对象,并通过键访问字典值。我希望你觉得这篇文章有趣/有用。这篇文章中的代码可以在 GitHub 上找到。感谢您的阅读!

建议中的顺序决策

原文:https://towardsdatascience.com/sequential-decision-making-in-recommendations-6ebddb8f46dd?source=collection_archive---------59-----------------------

活动讲座

Jaya Kawale | TMLS2019

在多伦多机器学习峰会上的演讲

关于演讲者

Jaya Kawale 是网飞大学的高级研究科学家,致力于解决与网飞主页上的建议相关的问题。在加入网飞之前,她曾在 Adobe 研究实验室和雅虎工作。研究。她在明尼苏达大学获得了博士学位,她的论文赢得了在超级计算 11 上颁发的“通过计算探索科学”奖。她在包括 NeurIPS、KDD、CIKM、SDM 和 IJCAI 在内的顶级会议上发表了多篇论文。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

建议中的顺序决策

使用 GANs 的顺序图像生成

原文:https://towardsdatascience.com/sequential-image-generation-with-gans-acee31a6ca55?source=collection_archive---------36-----------------------

生成敌对网络(GANs)在生成非常清晰和真实的图像方面非常成功。这篇文章简要地解释了我们的基于 GANs 的图像生成框架,它顺序地组成一个图像场景,将潜在的问题分解成更小的问题。有关深入的描述,请参见我们的出版物:用 GANs 进行场景生成的基于层的顺序框架。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1:建议的图像生成过程。给定一个语义布局图,我们的模型一步一步地组成场景。第一行显示了输入语义图和由最新基线生成的图像。

什么是生成性对抗网络?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2:氮化镓框架。

生成对抗网络(GAN) [1]是一类机器学习框架。两个神经网络:(I)生成器,和(ii)鉴别器在一个博弈论场景中相互竞争。生成器将随机噪声作为输入,并生成假样本。鉴别器试图区分从训练数据集中提取的样本(真实样本,例如手写数字图像)和由生成模型产生的样本(假样本)。这个游戏驱动鉴别器学习正确地将样本分类为真或假。同时,生成器试图欺骗分类器,让它相信它的样本是真实的。在收敛时,生成器样本与训练数据无法区分。更多详情请看原文本帖。GANs 可用于图像生成;他们能够学习生成清晰逼真的图像数据。

单镜头图像生成限制了用户对所生成元素的控制

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3:前景对象的不同缩放。

在 GAN 文献[2,3,4]中已经广泛研究了自动图像生成问题。它主要被认为是学习从单源,例如噪声或语义图,到目标,例如斑马的图像的映射。这个公式对单独控制场景元素的能力设置了主要的限制。因此,举例来说,很难改变一个斑马的外观或形状,同时保持图像场景的其余部分不变。让我们看看图 3。如果我们改变对象大小,即使每行的输入噪声相同,背景也会改变。

我们的方法:基于层的顺序图像生成

我们的主要想法类似于风景画家如何首先勾画出整体结构,然后用其他元素逐渐修饰场景,以填充场景。例如,绘画可以从山脉或河流作为背景开始,而树木和动物作为前景实例依次添加。

主要目标被分解成两个更简单的子任务。首先,我们用背景生成器 Gbg 根据噪声生成背景画布 x0 。其次,我们用前景生成器 Gfg 依次添加前景对象,以达到最终的图像 xT ,其中包含画布上预期的 T 个前景对象(T 不固定)。我们的模型允许用户控制要生成的对象,以及它们的类别、位置、形状和外观。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 4:提议的框架概述。Gbg、Gfg 分别是背景和前景生成器。

表现如何?

我们用 MS-COCO 数据集的子集运行了几个实验。图 5 比较了数据集中六个对象类的场景生成任务的不同基线的视觉结果。标准的 CNN 产生模糊的结果,尽管 L1 损失,以补救这一特殊问题。Pix2Pix [2]生成更清晰的图像。然而,标准的 CNN 和 Pix2Pix 都试图复制地面真相,这表明它只记住了数据集。它们在生成过程中缺乏随机性,这抑制了生成图像的多样性。应该避免这种行为,因为目标是生成逼真的场景,而不是模仿数据集中的场景。当添加最新的 GANs 训练技术时,多样性和图像质量得到改善,如 Pix2Pix++和我们提出的模型所示。然而,当存在多个对象(第 1、2、4 和 5 行)时,Pix2Pix++似乎很难处理。它不能产生一个可信的场景。我们的模型明确地将前景和背景生成过程分开,克服了这些问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 5:使用来自训练集的对象遮罩与现有技术模型的比较。从上到下:羊、牛、熊、大象、长颈鹿和斑马。地面真实对应于原始图像。

前景对象遮罩变换

在这个实验中,将几个仿射变换应用于输入对象遮罩。图 6 示出了当平移、旋转和缩放操作变换前景对象时,Pix2pix++和所提出的顺序模型如何保存场景。考虑 Pix2Pix++模型(图 6 的左栏)。应用平移时,前景和背景都会改变。旋转对象时,前景对象开始与背景融合。Pix2Pix++似乎学习了地面和斑马腿之间的颜色相关性,这使得无法绘制旋转较大的对象。当对象放大时,前景对象的颜色开始在背景中渗色。相比之下,我们提出的顺序模型(图 6 的右栏)保留背景直到仿射变换,并且不会遭受对象混合或渗色。然而,它确实稍微改变了前景物体的外观。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 6:物体遮罩仿射变换。Pix2Pix++无法保留场景。它要么改变背景,混合前景和背景,要么遭受颜色混合。我们的模型不会受到这些伪像的影响。

前景物体遮挡

在这个实验中,两个前景对象在水平轴上平移,直到它们彼此遮挡。图 7 比较了 Pix2Pix++和所提出的顺序模型在它们各自的对象遮罩变得更接近时如何生成前景对象。首先,Pix2Pix++不能正确地描绘这两个对象。考虑 zebra 示例和 Pix2pix++模型。当蒙版彼此轻微接触时(第 2 行),它会在错误的位置分割斑马。当它们被完全遮挡时(第 4 行),它只绘制一条斑马。第二,Pix2Pix++倾向于为两个对象产生相似的模式。现在考虑长颈鹿的例子和 Pix2pix++模型。当遮罩变得更近时(第 2 行),它会为长颈鹿输出相似的颜色。当它们彼此轻微接触时(第 3 行),它会合并长颈鹿,并绘制一个连续的图案。当它们被完全遮挡时(第 4 行),它会画一个有两个头的长颈鹿。这两种类型的伪影不会出现在我们提出的顺序模型中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 7:水平平移两个物体,直到它们相互遮挡。Pix2pix++描绘了前景对象上的伪像,这在我们提出的模型中是不存在的。

前景对象控件

在这个实验中,我们展示了物体的外观可以通过改变相关的噪声来改变。在图 8 中,我们添加了来自不同噪声矢量但在相同背景上具有相同遮罩的前景对象。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 8:通过改变相关的输入噪声 z1 来控制前景物体的外观。

超出生成的背景

我们的前景模型也可以用于图像编辑的目的,通过添加一个对象到现有的图像。在图 9 中,我们将对象添加到相同的场景,但是具有不同的照明或季节条件。前景模型知道背景场景的内容及其环境条件,例如全局照明。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 9:向现有图像添加新对象。全局照明影响对象外观。

超越对象遮罩

在当前的问题公式中,前景生成器以对象遮罩为条件。这限制了用户对所提出的顺序模型的控制,因为用户将不得不画出物体的形状来获得场景。在这个实验中,我们展示了如何通过引入一个单独的掩码生成器模型来轻松扩展当前的框架。这个想法是基于边界框生成物体形状。它们可以进一步用作当前框架的输入。遮罩生成器是一个条件 GANs 模型,它将边界框和对象类作为输入,并在感兴趣的区域中输出对象遮罩。图 10 呈现了从边界框生成的掩模样本及其最终生成的图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 10:从边界框而不是对象遮罩开始生成图像。请注意,掩码是在本实验中生成的。盒子的位置控制水平线,而形状控制视点。

要了解更多关于我们方法的细节或看到更多结果包括定量结果,您可以看看我们的出版物:

用 GANs 生成场景的基于层的顺序框架。在 AAAI。2019.

如果您想在您的项目中使用我们的方法,可以在这里获得代码**。**

参考

[1] I. Goodfellow、J. Pouget-Abadie、M. Mirza、B. Xu、D. Warde-Farley、S. Ozair、a .库维尔和 Y. Bengio,“生成性对抗网络”,载于《神经信息处理系统进展》,第 2672-2680 页,2014 年。

[2] P. Isola,J.-Y. Zhu,T. Zhou,A. A. Efros,“有条件对抗网络的图像到图像翻译”,2017 年 IEEE 计算机视觉与模式识别大会(CVPR),第 5967–5976 页,2017。

[3]宫户,t;t .片冈;Koyama,m;还有吉田,Y. 2018。生成对抗网络的谱归一化。在 ICLR。

[4]王;刘,男,女;朱;陶;考茨,j;和卡坦扎罗,B. 2018。用条件 gans 进行高分辨率图像合成和语义处理。在 CVPR。

二元序列中的序列相关性

原文:https://towardsdatascience.com/serial-dependence-in-binary-sequences-409c5e8f54d0?source=collection_archive---------50-----------------------

用 Meixner 正交多项式检验序列相关性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2018 Julian Wergieluk

在这篇博文中,我将研究随机二进制序列中的序列(即时间)依赖现象。

随机二进制序列是由随机过程产生的 0 和 1 的序列。大多数随机数生成器生成的主要输出是二进制的。二进制序列通常对随机事件的发生进行编码:

  • 金融市场的极端回报。
  • 机器、服务器等的故障
  • 金融市场风险模型中的风险价值超额指标。

在许多这样的情况下,有必要确保被跟踪的事件彼此独立地发生。例如,生产系统中事件的发生不应该使系统更容易发生事件。为此,我们需要仔细研究一下所考虑的二进制序列的依赖结构。

概述

在这篇博文中,我将开发并测试一种评分方法,用于量化随机二进制序列中的依赖强度。Meixner 依赖分数易于实现,并且基于与几何分布相关联的正交多项式。

读完这篇博文,你会知道:

  1. 如何用统计术语来表述序列相关性度量的问题。
  2. 如何从几何分布中导出迈克尔逊多项式?
  3. 如何计算等待时间序列的 Meixner 依赖分数,以量化依赖强度。
  4. 如何使用简单的 Monte-Carlo 实验测试依赖性评分方法,该实验涉及具有已知依赖性结构的马尔可夫链。

问题的统计公式

给定一个随机变量序列 X = (X[0],X[1],…,X[n]) 取集合 {0,1} 中的值和一个概率 p∈(0,1) ,我想考察 X 的元素之间的序列依赖关系。这个调查应该基于从 X 中抽取的一个样本 x ,即一个有限的 0 和 1 序列 (x[0],x[1),…,x[n]) 。这是一个非常困难和深刻的问题,在这篇博文中,我将重点收集证据来支持或拒绝以下两个基本假设:

  1. 随机变量*X【I】*具有分布 Ber( p )(成功概率为 p 的伯努利分布)。
  2. 随机变量*X【I】*是独立的。

如果我们假设 x 的元素是来自一个固定伯努利随机变量 X[0] 的独立样本,那么我们可以通过计算 x[0],x[1],…,x[n] 的平均值来估计概率 p 。这是因为 X[0] 的期望是 𝔼 X[0] = p

为了给串行相关性检测问题设置一个合适的上下文,让我注意到随机二进制序列 x 通常与具有两个状态的系统的谨慎观察相关联。如果 x[0] = 1 ,我们说“一个事件”发生在时间 i

我们如何检查我们的事件是否彼此独立地发生,并收集事件时间之间没有序列相关性的证据?

我们经常倾向于在不存在序列相关性的情况下看到序列相关性。典型的例子是赌场里的赌徒所经历的“好运连连”。

为了根据观察结果 x 严格研究序列 X 中的序列相关性问题,我们可以看看事件之间等待时间的分布。例如序列

[0, 1, 1, 0, 0, 1, 0, 0]

产生以下等待时间序列

[1, 3].

请注意,等待时间计算会丢弃事件序列 x 中的初始零和尾随零。

为了基于 x 正式定义等待时间序列y =(y【1】,…,y【m】),考虑索引I =(I【1】,I【2】,…) 的序列,使得对于每个 i∈ I 我们有 x 我们出发了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于同分布的伯努利随机变量序列,等待时间序列由几何分布的同分布随机变量组成。让我们仔细看看它的属性。

几何分布

参数为 p 的几何分布的概率质量函数(PMF)由下式给出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

参数为 p=0.1 的几何分布的 PMF 如下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

参数为 p=0.1 的几何分布的概率质量函数

测试等待时间序列是否遵循几何分布的一种方法是查看由该分布生成的正交多项式

一族正交多项式与 上的每个概率分布 μ 密切相关。对于任何这样的分布,我们可以将(平方可积)实值函数 fg 之间的标量积定义为

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中 Y 是分布为 μ 的随机变量。对于几何分布,上述标量积采用以下形式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们说函数 fg 正交(相对于 μ )当且仅当 ⟨f,g⟩ = 0。

最后,一个多项式序列 (q[i])i≥ 0 称为正交,当且仅当,对于所有的 k ≠ i ,q[i]⟩ = 0 ,每个*q[I】*都有度 i 。因此,对于 i > 0 ,我们得到 𝔼 qi = 0 。这是我将要用来检查给定的 Y 是否遵循几何分布的工具。

对应于几何分布的正交多项式族 M = (Mi) 是由负二项分布(几何分布的推广)导出的 Meixner 族的特例。Meixner 家族的成员满足以下方便的递归关系:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

M1 = 1M-1 = 0 。该关系用于计算序列 M 。另外,请注意 M[k] 取决于参数 p 的值。

在配套的 python 源代码中,函数meixner_poly_eval用于在给定的点集上计算 Meixner 多项式到给定的次数。我用这个函数画出了这些多项式的 55 次曲线。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

p=0.1 到 55 度的 Meixner 正交多项式的图

如上所述,对于每个多项式*M【k】(y)*在 M 中的等式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当且仅当 Y∈ Geom( p )和 k > 0 成立。

这个关系可以用来检验给定的等待时间样本是否属于参数为 p 的几何分布。我们将估计期望值 𝔼 Mk 并将估计值用作分数:接近零的值可以解释为参数为 p 的几何分布的证据。如果值远离零,这是一个信号,表明我们需要重新考虑我们的假设,并可能放弃关于原始事件序列的 i.i.d .假设。注意,如果事件是独立的,也可能出现与零的显著偏差,但是真实概率*p’*与假定的 p 显著不同。如前所述,这很容易测试。

Meixner 依赖分数

为了获得在上述意义上量化串行相关性程度的单个数字(分数),我们将定义 Meixner 相关性分数(MDS) 作为在等待时间 y=(y[1】的样本上评估的第一个 k Meixner 多项式的期望估计的平均值,…,y[m]) :

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用正交多项式来测试二进制序列中依赖结构假设的思想源于矩推断方法,并在金融文献中被发展用于回溯测试风险值模型。在这篇博客文章中,我采用了 Candelon 等人提出的方法,请参见下面的参考资料部分。

蒙特卡罗研究

为了找出上面设计的过程是否有机会在实践中起作用,我将使用综合生成的数据来测试它。这种类型的测试程序通常称为蒙特卡罗(MC)研究。它不会用真实世界的数据替换测试,但可以帮助在受控环境中评估统计方法。

我们要执行的实验包括以下步骤:

  1. 使用具有已知序列相关性结构的模型生成二进制序列。
  2. 估计对 k=1,…,10 的期望 𝔼 Mk
  3. 在大量独立试验中重复第 1 步和第 2 步,并将汇总结果可视化。

让我们从一个简单的例子开始,用成功概率 p[0] 来模拟伯努利随机变量的 i.i.d 序列。这可以用作健全性检查,并测试我们的过程实现是否正确。

对于下面的实验,我们设置 p[0] = 0.05 并模拟来自 X = (X[1])的 5000 个样本,…,X[1000])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于一个具有简单形式的序列相关性的模型,我们选择概率0<p[1]<p[0]<p[2]<1,并设置序列中随机变量的分布 X = (X[0],X[1],X[2],…) 如下。让 X[0] 为伯努利,成功概率 p[0]X[i] 对于 i > 0 的分布以 X[i-1] 为条件:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了将该模型与具有成功概率
的 I . I . Bernoulli 模型 p[0] 进行比较,我们需要设置 p[1]p[2] ,使得 X[i] 的无条件
分布为 Ber (p[0])

换句话说,对于给定的0<P[1]<P[0]<1,我们寻找的是P[2]∑(0,1) ,使得上述定义的随机二进制序列满足 P(X[i] = 1) = p[0]
这个二元序列可以用状态空间{0,1}表示为简单的马尔可夫链,转移概率矩阵 P 由下式给出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

而初始分布 λ = (1-p[0],p[0])X[i] 的边际分布由下式给出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个基本结果可以在任何一本关于马氏链的书中找到(参见下面的参考资料部分)。找到一个 p[2] 使得 P(X[i] = 1) 尽可能接近 p[0] 的任务,可以用现成的优化算法,例如 BFGS 很容易地解决。

例如,对于 p[1] = 0.02p[0] = 0.05 ,上述过程很快得出 p[2] = 0.62

蒙特卡罗研究结果

让我们测试下面的值 p[1]p[2] 的依赖评分算法。Meixner 多项式的 MC 评估产生以下 Meixner 相关性分数:

+------+------+-------+
|  p1  |  p2  |  MDS  |
+------+------+-------+
| 0.5, |  0.5 | 0.083 |
|  0.4 | 0.24 | 0.194 |
|  0.3 | 0.43 | 0.382 |
|  0.2 | 0.62 | 0.583 |
+------+------+-------+

同样,对长度为 1000 的样本的 5000 次模拟产生了下面的期望估计直方图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正如我们所见,直方图略微向左偏移。

这篇博文中展示的所有结果和图表都是使用以下 Python 脚本生成的: meixner.py

结束语

在这篇博文中,我们了解了二进制序列中的序列相关性的概念。我们基于 Meixner 正交多项式实现了一种串行依赖性检测方法,Meixner 依赖性得分,并使用简单的马尔可夫链模型测试了它的性能。

依赖性测试的一个重要财务用例是分析由市场风险模型生成的风险价值超出事件序列。市场风险模型广泛用于银行业的监管资本要求计算,以及资产管理行业的投资组合构建和风险管理。

风险价值 (Var)是固定时间范围内金融资产价格损失分布的分位数。例如,持有黄金多头头寸的投资者可能对美元黄金价格在一天时间范围内的 95% VaR 感兴趣。对于校准良好的风险值模型,在一个投资期内观察到的 5%营业日的极端损失将超过 95%的风险值分数。VaR 超过事件不仅必须以预期的频率发生,还必须相互独立。对市场风险模型进行适当校准,将超出事件的相关性降低到较低水平,通常比超出频率的简单校准要困难得多。但这在金融危机时期尤为重要,因为低估风险不可避免地会导致投机倒把,甚至可能导致更严重的损失。

非常感谢 Sarah Khatry 阅读了这篇博文的草稿,并提供了无数的改进意见和更正。

参考

成为数据科学家的一系列免费课程

原文:https://towardsdatascience.com/series-of-free-courses-to-become-a-data-scientist-3cb9fd591739?source=collection_archive---------4-----------------------

链接到知名大学的高质量课程,可以免费学习。循序渐进地学习这些课程,成为一名数据科学家。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:蒂姆·莫斯霍尔德

现在有很多资源声称它们会让你成为一名数据科学家。刚开始在网上上课的时候,我花了一段时间才明白哪些课程好。我开始了一门课程,几天或几周后,我意识到它没有帮助。再次转移到别的东西上。我希望我能找到一个可靠的向导,告诉我到底该学什么,从哪里开始,以及如何进行学习之旅。虽然我找到了一些材料,但我仍然不得不挣扎了很多。这就是为什么我决定分享一个完整的学习和课程计划,最终给你足够的知识来找到一份数据科学家的工作。最棒的是,它是免费的!

我将展示一条成为 Python 数据科学家的途径。因为我是 python 用户,我喜欢。还有,我相信如果你是初学者,学好一门语言是很好的。然后继续学习更多。以下是循序渐进的免费学习计划:

1.学习 Python

如果你不知道 Python,这个免费课程是一个好的开始。Udacity 有一门免费的课程“计算机科学入门”,教授 python 编程语言,有很多例子和练习题,对初学者来说非常好。不幸的是,如果你去 Udacity 的主页搜索它,它现在会把你重定向到另一个课程。但是幸运的是,在下面的链接中,你仍然可以找到所有的资料。

[## Udacity CS101 资源

这个页面为我的 Udacity cs101:计算机科学入门(构建搜索引擎)收集了一些资源…

www.cs.virginia.edu](http://www.cs.virginia.edu/~evans/cs101/)

这门 Python 课程应该给你足够的知识,让你开始学习数据科学工具。

2.了解 Python 的数据科学库

Coursera 有很多课程,你可以免费学习。是学习者的福气。他们有密歇根大学的专业“应用数据科学与 Python ”。它包含以下五门课程:

a.Python 中的数据科学简介

b.应用 Python 进行绘图、制图&数据展示

c.在 Python 中应用机器学习

d.在 Python 中应用文本挖掘

e.应用 Python 进行社会网络分析

我只想警告你一件事。如果你选择学习这些课程,你必须保持耐心。因为作业很难,尤其是如果你是初学者。你只需要不断努力,做到最好。但是因为作业很难,如果你能完成作业,你真的会学得很好。你只需要花足够的时间在上面。如果你不想要证书,只想学习,你不需要支付任何费用。你可以免费旁听所有课程。

下面是查找审计选项的说明。**不要在专业化页面注册。**只免费 7 天。转到个别课程的页面。然后,您会在页面顶部看到一个注册选项。甚至不要从那里注册。继续向下滚动单个课程的页面。在每周的课程讨论和教员信息之后,你会发现另一个注册选项。单击注册选项。一个窗口将会打开,在它的底部,你会看到一个非常小的“审计”选项。单击审核选项并从那里注册。即使你不能按时完成,你也可以再次审计。您可以根据需要多次审核课程。如果你不能遵循上面的指示,我有一个视频可以带你完成这个过程:

3.学习 SQL

SQL 是数据分析师或数据科学家的必备之一。如果你已经完成了上述专业之一的课程,学习 SQL 应该很容易。有一些共同的想法。这里有一个专业,可以教你足够多的 SQL,让你开始成为一名数据科学家:

[## 了解数据科学的 SQL 基础知识

由加州大学戴维斯分校提供。这个专业是为以前没有编码的学习者设计的…

www.coursera.org](https://www.coursera.org/specializations/learn-sql-basics-data-science)

该专业有四门课程:

a.用于数据科学的 SQL

b.使用 SQL 进行数据争论、分析和 AB 测试

c.使用 Spark SQL 的分布式计算

d.SQL for Data Science 顶点项目

我之前已经解释过如何审核这些课程。

4.了解更多信息

学完以上课程后,你就可以申请工作了。你会发现很多适合你的机会。但是,如果你想在数据科学方面取得进步,还有很多东西要学。例如,在处理数据时,了解一些统计学概念是很好的。上面步骤 2 中的应用机器学习课程教你,如何使用一个非常好的机器学习库 scikit-lean。它给出了许多机器学习算法的基本概念,你可以通过从 scikit-learn 库中调用它们来使用它们。它适用于很多问题。但是从头开始学习编写算法会给你更多的能力。以下是一个统计专业化课程和一个机器学习课程的链接:

用 Python 统计

机器学习

对于初学者来说,这可能看起来太多了。但是请记住,你不必在一天之内学会所有的东西。无论何时你要改变职业或者开始新的事情,都需要时间。如果你能做到步骤 2 中提到的数据科学专业化,那么学习 SQL 将会非常容易和快速。所以,这并不像看起来那么难。再给你一个提示。当你有一个好的学习伙伴时,保持动力和耐心会容易得多。大概你已经知道了,只是提醒一下。

推荐阅读:

[## 12 周能成为数据科学家吗?

12 周的合理学习目标是什么

towardsdatascience.com](/can-you-become-a-data-scientist-in-12-weeks-58ed9e3064a6) [## 学习编程、软件工程、机器学习等的最佳免费资源

找到所有高质量的计算机科学课程,从麻省理工学院,哈佛大学,和其他大的大学成为专家…

towardsdatascience.com](/best-free-resources-to-learn-programming-software-engineering-machine-learning-and-more-89ee724b90c3) [## 使用 Pandas Cut 或 Qcut 方法对数据进行分类和分段

当你在寻找一个范围而不是一个确切的数值,一个等级而不是一个分数

towardsdatascience.com](/sort-and-segment-your-data-into-bins-to-get-sorted-ranges-pandas-cut-and-qcut-7785931bbfde) [## 如何在 Python 中呈现多个变量之间的关系

了解如何使用 Python 中的多元图表和绘图来呈现要素之间的关系

towardsdatascience.com](/how-to-present-the-relationships-amongst-multiple-variables-in-python-fa1bdd4f368c) [## Pandas 的 Groupby 功能详细,可进行高效的数据汇总和分析

学习对数据进行分组和汇总,以使用聚合函数、数据转换、过滤、映射、应用函数…

towardsdatascience.com](/master-pandas-groupby-for-efficient-data-summarizing-and-analysis-c6808e37c1cb) [## Python 中从头开始的多项式回归

学习用一些简单的 python 代码从头开始实现多项式回归

towardsdatascience.com](/polynomial-regression-from-scratch-in-python-a8d64845495f) [## 置信区间、计算和特征

什么是置信区间,如何计算它及其重要特征

towardsdatascience.com](/confidence-interval-calculation-and-characteristics-1a60fd724e1d)

从 API 提供预测

原文:https://towardsdatascience.com/serve-predictions-from-an-api-1d84b4ac9a7c?source=collection_archive---------53-----------------------

使用 Python 和 Flask 建立与 ML 模型交互的 API

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

弗洛里安·克拉姆在 Unsplash 上拍摄的照片

关于

在本文中,我将尝试演示如何建立一个快速的 Flask API 来为 ML 模型预测服务。

一旦你创建并训练了你的模型,你就会想要与它互动。虽然可以在 jupyter 笔记本中手动完成这项工作,但您很可能希望自动完成预测。

我已经使用 React.js 创建了一个仪表板,它使用户能够配置游戏的功能,然后我们可以将其发送到 API 以接收预测。

安装

继续启动你选择的编辑器。我用的是 VS 代码,是免费的,可以在这里下载。它非常直观,当您第一次启动它并开始处理 python 文件时,它会提示您安装一些模块,帮助您轻松创建 python 文件。

这里有一篇关于为 python 开发设置 VS 代码的很棒的文章:

[## Visual Studio 代码中的 Python

使用 Microsoft Python 扩展,在 Visual Studio 代码中使用 Python 是简单、有趣且高效的。的…

code.visualstudio.com](https://code.visualstudio.com/docs/languages/python)

创建 Flask 服务器

现在我们准备写一些代码。

继续创建一个新文件夹,为 Flask 服务器创建一个新文件,为“PredictGame”路径创建一个新文件:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们继续为我们的 Flask 服务器添加基本功能。

首先,我们加载设置 REST 服务器所需的 flask API。

然后导入将要实现的 provider 类,它将负责处理预测请求。

最后,我们告诉编译器启动服务器。

路由处理器

现在,我们有了一种与将要接收的请求进行交互的方法,以及一种发送回正确信息的方法。

让我们继续创建一个路由处理器,它将包含我们接收游戏信息的所有逻辑,并发送回正确的预测。

首先,我们导入所需的库。我们从 Flask 导入“reqparse”和资源。

我们将使用’ reqparse '使处理请求参数像使用字典一样简单。

“Resource”将允许我们继承一个超类,该超类将允许我们实现不同的 HTTP 方法,如“get”、“delete”、“put”、“post”。

这对我们来说很容易,因为我们需要做的就是在“get”方法中实现功能。

接下来,我们导入“xgboost ”,因为我们必须创建一个新的模型,将预训练的权重加载到该模型中。

我们导入 numpy,因为模型期望数据是某种形状,并且是 numpy 数组类型。

最后,我们导入 json,这样我们可以将游戏参数从 json 对象转换成 python 列表。

在我们的构造函数中,我们设置了参数解析器,并用保存的权重初始化模型。

然后,我们创建我们的“get”方法,该方法只是从请求中解析游戏对象,然后我们将游戏对象格式化为模型期望的格式,最后,我们进行预测并在字典中返回它们。

这是一个超级基本的实现,没有任何错误处理或类型检查。

最后,在底部我们有一个私有的 helper 方法,用于将数据转换成正确的格式。

启动服务器

首先,在 server.py 文件所在的目录中打开一个终端,并使用以下命令运行该文件:

$ python server.py

这将启动 Flask 服务器,您应该会看到一些文本,宣布服务器正在运行,并且您可以在以下地址找到它:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在我们的服务器正在运行,我们可以与 API 进行交互。

使用 API

现在我们已经有了一个运行的服务器,我们需要测试我们的工作。

虽然测试 API 端点最流行的工具肯定是 Postman,但是有几种方法可以发出 HTTP 请求。

Postman 是一个免费的应用程序,用于使用 HTTP 创建和运行测试,当您发出请求时,它可以让您准确地看到正在发送的内容和正在接收的内容。

继续并下载 Postman ,我们可以用它来发出 http 请求并查看原始响应。

[## 下载邮差 App

下载邮差!加入依赖 Postman 作为唯一完整 API 的 1100 万开发者和 50 万家公司…

www.postman.com](https://www.postman.com/downloads/)

下载完成后,继续打开它,您应该会看到类似如下的屏幕:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

令人欣慰的是,邮差用户界面非常直观,很容易适应所有东西的位置。

输入我们要测试的 URL,在本例中为:

http://127.0.0.1:5000/game

请注意,您的地址可能会因端口而异。此外,“127.0.0.1”有时也被称为“localhost”,因此向以下地址发送请求基本上是一样的。

http://localhost:5000/game

注意地址末尾的/game,这是我们在 server.py 文件中设置的路由。

回到 Postman,在 Query Params 下,您应该看到一个“key”“value”字段的列表。

在这些字段中键入我们的参数,将会自动用正确的值和特殊字符(如空格)的 URI 编码填充我们的 URI。

继续用下面的值创建一个“游戏”键(我知道它很长,每个游戏预测都是基于 84 个不同的特性):

[5.39279682138009,6.683608045460701,0.15919970376939438,3.55590999603135,1.1554737031359337,0.7067666437650326,1.1426873175695553,1.2569168628035827,-0.7803980111346107,-0.2962583460820777,-0.24055440492626987,-1.7136287338568992,-0.1651305355827784,-0.2036357303066871,-0.4540528313626752,-0.48914117436953486,-0.22271712167442767,-0.5282740359736868,-0.031858861469518406,-0.24937339127109132,-0.32994634379035076,-0.512297869820368,-0.7031963621472596,-0.07105583014744833,-0.29576266052192457,0.1870374024689484,-0.14092851934520698,-0.33523660382633563,-0.14365069955967955,-0.12421426326285712,-0.06650450595001171,-0.10261069449730548,-0.1123532348785659,3.27774725901111,-0.45335715532058596,-0.16592152231605703,1.5775085110873435,1.5048682557955273,1.9597419248177352,-0.48621831608959837,1.642609246782289,0.5213592693458309,-0.48290073165693087,-0.3244873199973241,-0.301429739232314,2.4736135100111123,-0.22133313058352583,3.8765749060205286,-0.23604923873792524,-0.2401213205987764,-0.27373953556863745,-0.35059866422759306,4.098403285704536,4.559516332813075,-0.28035794137016523,-0.2973715918552079,-0.30799315147252165,3.713847136118922,3.139731271607883,-0.2625780433542825,2.3218106291644776,-0.30943922402842255,2.6890016668398484,-0.2316238571204376,3.884818704555654,-0.35758626244129893,-0.31778939411173085,-0.24428267916420615,-0.43130531370481745,-0.2341397130078093,-0.22087023503836106,-0.3216777806746954,-0.21651103657152967,-0.28636063937475126,-0.21776380127418174,-0.2768681688204387,-0.7287651618291123,-0.355929439908863,-0.24655521427098337,-0.22667679255666365,-0.2785523148360368,-0.2524454873949673]

继续按“发送”,您应该会得到类似如下的回复:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

完美!我们的服务器接受一个表示单个游戏特性的浮点字符串列表,并返回一个数字,该数字是 Steam 商店中外观的预测排名。

结论

在本文中,我们经历了创建一个 HTTP 服务器的整个过程,该服务器可以接受一个包含游戏特性列表的请求,然后用一个表示 Steam store 页面上预测排名的数字进行响应。

我们将服务器做得非常简单,没有处理任何错误处理或参数验证。关于如何做到这一点,有大量的参考资料,并且可能是将来的一篇文章。

感谢您的阅读,如果您有任何想法或问题,请让我知道,我很乐意有机会谈论任何与技术相关的话题。

使用简单的 Python 服务器为您的机器学习模型提供服务

原文:https://towardsdatascience.com/serve-your-machine-learning-models-with-a-simple-python-server-5a72d005e0ae?source=collection_archive---------28-----------------------

如何轻松服务于机器学习模型

许多数据科学项目中最大的挑战之一是模型部署。在某些情况下,您可以批量离线进行预测,但在其他情况下,您必须实时调用您的模型。

此外,我们看到越来越多的模型服务器像[TensorFlow Serving](https://www.tensorflow.org/tfx/guide/serving)[Torch Serve](https://pytorch.org/serve/)被发布。尽管有很多很好的理由在生产中使用这些解决方案,因为它们快速高效,但是它们不能封装模型技术和实现细节。

这就是为什么我创造了[mlserving](https://pypi.org/project/mlserving/)。一个 python 包,帮助数据科学家将更多的火力集中在机器学习逻辑上,而不是服务器技术上。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

mlserving尝试一般化预测流,而不是您自己实现预测,或者为此使用另一个服务应用程序。

通过实现一个简单的接口,您可以轻松地为您的模型设置一个端点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

这个接口表示一个通用的预测流。

让我们看一个例子(假设我们已经有了一个训练好的模型)

首先,我们将训练好的模型加载到构造函数中,并实现接口。

稍后,我们创建一个ServingApp,并添加我们刚刚实现的推理处理器。

在这个例子中,我们没有对输入进行任何处理,但是正如您所看到的,为您的模型设置一个端点是非常容易的。

通过发送 POST 请求来调用我们的模型。

curl -X POST [http://localhost:1234/api/v1/predict](http://localhost:1234/api/v1/predict) \
-H 'Content-Type: application/json' \
  -d '{
    "features": [...]
}'

使用 TensorFlow 服务也不例外,用我们的定制处理来包装 TensorFlow 服务非常容易,但首先,我们需要设置我们的 TensorFlow 服务。在本例中,我们将使用 docker:

docker run -p 8501:8501 \
  --mount type=bind,source=/path/to/my_model/,target=/models/model \
  -e MODEL_NAME=model -t tensorflow/serving

在这里阅读更多:https://www.tensorflow.org/tfx/serving/docker

现在我们已经成功运行了 TensorFlow 服务,让我们围绕它创建一个 python 处理层:

这一次,我们没有在构造函数中加载我们的模型,因为 TensorFlow Serving 已经加载了它。

def predict方法由TFServingPrediction 实现,基本上,它发送从def pre_process 返回的有效载荷,并处理 TensorFlow 服务的推理。所以我们剩下要做的就是实现预处理和后处理。

就是这样!我们已经设法用一个易于使用的 API 来包装我们的模型。

我很乐意听到任何反馈或建议,随时联系!

感谢阅读!

附加资源

无服务器:无痛的 AWS 样板文件

原文:https://towardsdatascience.com/serverless-a-painless-aws-boilerplate-e5ec3b4fb609?source=collection_archive---------16-----------------------

为 AWS lambda 部署提供支持离线测试的样板文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AWS Lambda

无服务器开发由于易于部署而受到关注。此外,鉴于 AWS lambda 能够将其他服务与 AWS SDK 集成,它已经成为一种流行的选择。然而,如果你不具备可伸缩性,当你扩展你的 API 时,从小处着手可能会给你留下巨大的重构空间。因此,在这里,我将总结我在一家初创公司的经验,并分享一个很好的样板文件,通过以一个简单的 REST API 作为起点,它将使您的开发变得快速和可伸缩。我假设您对 AWS 部署如何工作和云形成有所了解。

要记住的要点

  1. Cloudformation 模板将只允许每个部署 200 个资源。(文档)。因此,服务部署应该以更细粒度的方式完成。
  2. 每个部署的服务将拥有多个资源,并独立访问其他服务。
  3. 如果我们有单独的服务,我们可以单独捆绑,使捆绑包的大小更小。

在本文中,让我们关注第一个限制。针对这一限制的唯一可行的解决方法是使用只关注一个任务的隔离服务(这确实是使用微服务的动机。).让我们使用无服务器框架来制作样板文件(入门指南:此处为)。还有,你需要无服务器离线插件(获取:这里)。

构建无服务器配置

简而言之,我们将为每个服务建立单独的文件夹,并为每个文件夹建立一个service.yml。在无服务器框架中,当我们部署或运行离线插件时,我们可以使用--option VALUE提供任何选项。我们将利用这个工具来选择单独的服务进行部署或离线运行。我们将在命令行中使用--service选项加载每个服务,并使用--stage选项进行分段。

在这个样板文件中,我将如下组织我的文件夹结构。

- serverless.yml (main serverless config file)
- prod.env.yml (configs for the prod environment)
- dev.env.yml (configs for the dev environment)
- offline-serverless.js (offline runner for testing)
- package.json (node modules neede, for nodejs)// Folders containing the application logic- first-service
-- service.yml
-- main.js- second-service
-- service.yml
-- main.js// Utils for routing
- utils
-- lambda-router.js
-- errors.js (Error message, not essential)
-- db-util.js (Managing the database connection)

serverless.yml 的内容

这是我们服务结构的核心。在 YML 中,我们可以构造符号,以便在运行时填充部分文件。在我们的例子中,从每个服务的service.yml文件中选择与服务相关的内容。

我们的serverless.yml如下所示。

无服务器. yml

这里,package将携带要包含的文件夹,而functions将携带每个服务内部的功能。这些将从每个服务的文件夹的service.yml文件中加载。

部署脚本命令示例:

serverless deploy --stage dev --service service1

用于测试的离线配置

离线运行命令的示例如下所示:

serverless offline start --stage dev --service service1 --port 3000

然而,为了测试,我们必须在不同的端口上运行每个服务。下面是一个脚本,使我们的任务变得简单。

无服务器-offline.js

这里PATH1PATH2是基本路径(例如;users/为用户服务,posts/为帖子服务)。这在服务内部是不相关的,因此,请注意,我已经删除了基本路径;在第 24 行。每个服务都专注于一件事,所以拥有一个单独的基本路径是多余的(然而我们将在最终的 API 部署中拥有它)。

我们可以简单地离线运行我们所有的服务进行测试;

node offline-serverless.js

每个服务内部的内容

每个服务应包含所需的资源。在这个例子中,我们将放置 REST API 端点。这段代码将如下所示。

service.yml

注意,这里我们包括了node_modules utils和携带逻辑的文件。

部署

部署就像普通的无服务器框架部署一样。然而,在 API 网关中有一些值得注意的事情。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

具有多个服务的示例部署视图

如前所述,尽管我们的应用程序有端点,如users/profile-detail,但我们的用户服务将只接受profile-details,因为它的唯一目的是处理用户。然而,我们需要 API 知道users/请求必须提供给用户服务 lambda。我们就是这么做的。

转到—API,然后转到自定义域名。您将看到以下视图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

自定义域名

在这里,您可以单击编辑并添加自定义映射。例如,在上面的设置中,我将它们添加如下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基本路径、服务和阶段的映射

对于这个 API,生产环境只有一个映射。如果你有几个在线测试的环境,你必须这样设置。在这里,我已经购买了一个域,并为我的 API 链接了子域。然而,您可以使用无域 API,但是这样您将不得不依赖 AWS 为每个服务随机生成的 URL(不整洁!).

清盘

  • 路径是相对于serverless.yml记录的,所以加载外部文件时要小心。总是使用__dirname + ‘/file.extension’来加载文件。
  • 我为这个样板文件做了一个 repo ,包括我的 lambda 路由器和 DB 处理器。看一看,星,叉,提高,发个 PR 给我。
    https://github . com/anuradhawick/AWS-lambda-server less-boilerplate
  • 看看 lambda 路由器吧,它非常简单,支持LAMBDA_PROXY集成(请看这里的)。你可以在这里看到我是如何使用它的
  • 如果您计划向serverless-offline.js添加更多服务,请选择不同的端口及其基本路径。更新第 4 行中的services数组。

相信这篇文章会对日以继夜辛勤工作的开发者有所帮助。
感谢阅读!干杯!

带 HuggingFace 和 AWS Lambda 的无服务器 BERT

原文:https://towardsdatascience.com/serverless-bert-with-huggingface-and-aws-lambda-625193c6cc04?source=collection_archive---------12-----------------------

用 BERT、HuggingFace、无服务器框架和 AWS Lambda 构建一个无服务器问答 API。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Samule 孙Unsplash 上的照片

原载于 2020 年 6 月 30 日https://www . philschmid . de

介绍

“无服务器”和“BERT”是强烈影响计算世界的两个主题。无服务器架构允许我们动态扩展和缩小软件,无需管理和配置计算能力。它允许我们,开发者,专注于我们的应用

伯特可能是最有名的自然语言处理模型。你可以说它改变了我们处理文本数据的方式以及我们可以从中学习到什么。“BERT 将帮助[Google]搜索[实现]更好地理解[ing]10 个搜索中的一个” 。伯特及其伙伴罗伯塔、GPT-2、艾伯特和 T5 将在未来几年推动商业和商业理念,并将像互联网曾经做过的那样改变/颠覆商业领域。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

搜索语言理解伯特

想象一下,将这两者结合在一起,您将获得怎样的商业价值。但是 BERT 并不是最容易在无服务器架构中部署的机器学习模型。BERT 很大,需要相当大的计算能力。您在网上找到的大多数教程都演示了如何在“简单”的环境中部署 BERT,比如一个具有 16GB 内存和 4 个 CPU 的 VM。

我将向您展示如何利用无服务器架构的优势,并在无服务器环境中部署 BERT 问答 API。我们将使用 HuggingFace 的变形金刚库、无服务器框架和 AWS Lambda。

通过 Huggingface 创建变压器库

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

变形金刚 logo by huggingface

变形金刚库为自然语言理解(NLU)和自然语言生成(NLG)提供最先进的机器学习架构,如 BERT、GPT-2、罗伯塔、XLM、DistilBert、XLNet、T5。它还提供了 100 多种不同语言的数千个预训练模型,并在 PyTorch & TensorFlow 2.0 之间具有深度互操作性。它使开发人员能够针对不同的 NLP 任务(如文本分类、情感分析、问答或文本生成)微调机器学习模型。

自动气象站λ

AWS Lambda 是一种无服务器计算服务,让你无需管理服务器就能运行代码。它只在需要的时候执行你的代码,并且自动伸缩,从每天几个请求到每秒几千个请求。您只需为您消耗的计算时间付费,当您的代码不运行时,则不收费。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AWS Lambda 标志

无服务器框架

无服务器框架帮助我们开发和部署 AWS Lambda 功能。它是一个 CLI,开箱即可提供结构、自动化和最佳实践。它还允许我们专注于构建复杂的、事件驱动的、无服务器的架构,由函数和事件组成。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

无服务器框架标志

如果你不熟悉或者还没有设置无服务器框架,看看这个无服务器框架快速入门

辅导的

在我们开始之前,确保您已经配置并设置了无服务器框架。你还需要一个工作的 Docker 环境。Docker 环境用于构建我们自己的 python 运行时,我们将其部署到 AWS Lambda。此外,您需要访问 AWS 帐户来创建 S3 桶和 AWS Lambda 函数。

在教程中,我们将使用预先训练好的BERT模型构建一个问答 API。这个想法是我们发送一个上下文(小段落)和一个问题给 lambda 函数,它会用问题的答案来响应。

由于本指南不是关于构建模型,我们将使用一个预构建的版本,这是我用distilbert创建的。你可以在这里查看 colab 笔记本

在我们开始之前,我想说我们这次不会深入细节。如果你想更多地了解如何在 AWS Lambda 中使用深度学习,我建议你看看我的其他文章:

我们正在构建的架构将会是这样的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们要做什么:

  • 使用无服务器框架创建 Python Lambda 函数
  • 创建一个 S3 桶并上传我们的模型
  • 配置serverless.yaml,添加transformers作为依赖项,并设置一个 API 网关用于推理
  • colab 笔记本中的BERT型号添加到我们的功能中
  • 部署和测试功能

你可以在这个 GitHub 库colab 笔记本中找到我们正在做的一切。

创建 Python Lambda 函数

首先,我们通过使用带有aws-python3模板的无服务器 CLI 创建 AWS Lambda 函数。

该 CLI 命令将创建一个包含handler.py.gitignoreserverless.yaml文件的新目录。handler.py包含一些基本的样板代码。

添加transformers作为依赖项

除了requirements.txt,无服务器框架几乎创建了我们需要的任何东西。我们手动创建requirements.txt并添加以下依赖项。

创建一个 S3 存储桶并上传模型

AWS S3 和 Pytorch 提供了一种独特的方法来处理大于 250MB 的机器学习模型。为什么是 250 MB?Lambda 函数解压缩后的大小限制为 250MB。

但是 S3 允许文件直接从 S3 加载到内存中。在我们的函数中,我们将把来自 S3 的模型squad-distilbert加载到内存中,并作为 Pytorch 中的缓冲区从内存中读取它。

如果您运行 colab 笔记本,它将创建一个名为squad-distilbert.tar.gz的文件,其中包含我们的模型。

要创建 S3 存储桶,您可以使用管理控制台或以下命令来创建。

在我们创建桶之后,我们可以上传我们的模型。您可以手动或使用提供的 python 脚本来完成。

配置serverless.yaml

这次我为我们提供了完整的serverless.yaml。如果你想知道每一节是做什么用的,建议你去看看从零到英雄的缩放机学习。在本文中,我介绍了每种配置,并解释了它们的用法。

colab 笔记本中的BERT模型添加到我们的功能中

典型的transformers型号由pytorch_model.binconfig.jsonspecial_tokens_map.jsontokenizer_config.jsonvocab.txt组成。pytorch_model.bin已经被提取并上传到 S3。

我们将把config.jsonspecial_tokens_map.jsontokenizer_config.jsonvocab.txt直接添加到我们的 Lambda 函数中,因为它们的大小只有几 KB。因此,我们在 lambda 函数中创建了一个model目录。

如果这听起来很复杂,可以查看一下 GitHub 资源库

下一步是在保存我们的模型类ServerlessModelmodel/目录中创建一个model.py

handler.py中,我们创建了一个ServerlessModel的实例,并可以使用predict函数得到我们的答案。

部署和测试功能

为了部署该功能,您只需运行serverless deploy

这个过程完成后,我们应该看到类似这样的东西。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

测试和结果

为了测试我们的 Lambda 函数,我们可以使用失眠症、邮差或任何其他 REST 客户端。只需在请求体中添加一个带有contextquestion的 JSON。让我们用 colab 笔记本中的例子来尝试一下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的ServerlessModel83.1正确回答了我们的问题。此外,您可以看到完整的请求花费了 319 毫秒,而 lambda 执行时间大约为 530 毫秒。老实说,这是相当快的。

最棒的是,如果有几个传入请求,我们的 BERT 模型会自动扩展!它可以扩展到数千个并行请求,而不用担心任何问题。

如果您重新构建它,您必须小心第一个请求可能需要一段时间。首先,Lambda 正在解压和安装我们的依赖项,然后从 S3 下载模型。

感谢阅读。你可以在这里找到带有完整代码 GitHub 库,在这里找到 colab 笔记本

感谢阅读。如果你有任何问题,随时联系我或评论这篇文章。你也可以在推特(Twitter)或领英(LinkedIn)上与我联系。

无服务器:构建自己的路由器

原文:https://towardsdatascience.com/serverless-building-your-own-router-c2ca3071b2ec?source=collection_archive---------10-----------------------

如何为基于角色访问的 REST API 开发自己完整的 lambda 路由器

在我的上一篇文章中,我介绍了如何开发一个样板文件来支持 AWS lambda 部署。在本文中,我将展示如何为 REST API 开发一个合适的 lambda 路由器。这是开发可伸缩 AWS lambda 实例的重要一步。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AWS API 网关架构

为什么是路由器,而不是 NodeJS 服务器?

人们通常会在 lambda 中部署一个成熟的 NodeJS HTTP 服务器。然而,在理想的情况下,我们应该避免这样做,因为它会在 lambda 函数内部产生延迟。此外,我们肯定会错过 API 网关的唯一目的和特性,如身份验证和授权。

在这种情况下,我们将实现一个简单的路由器,它不启动单独的服务器,而是利用 lambda 代理实现头将请求导航到我们实现的功能逻辑。通过这种方法,当 lambdas 被调用时,我们将拥有请求的即时路由。

AWS Lambda 代理集成请求事件

使用无服务器框架的默认部署将通过 Lambda 代理集成来部署 lambdas。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Lambda 代理集成 API 示例

lambdas 由带有三个参数 事件上下文、回调 的函数组成。事件对象包含所有有用的信息,包括请求体、路径参数、查询参数、请求路径、源、cookie 信息、头和其他请求参数。在代理集成中,我们的 lambdas 的行为类似于 Nginx 路由器(其中我们有所有的重写规则、转发、静态文件呈现等)。我们将利用来自事件对象的信息来构建我们的路由器。首先,让我们看一下事件对象。

示例请求的事件对象

观察事件对象,我们可以清楚地注意到以下两个主要有用的属性。

- resource
- httpMethod

这基本上是我们纯路由所需要的。哪个method中的哪个path应该被转发给目标function。这简单地类似于开关情况。但是 switch case 应该有更多的功能,包括响应构建和处理不同类型的请求方法。

构建路由器

路由器的输入

路由器必须与 AWS 函数调用一致,即使用 事件上下文回调 作为参数。

创建路由器类或函数

在经典的 javascript 中,类是用函数来模拟的。因此,在这个例子中,我将使用一个考虑到朴素场景的函数(这通常是 Lambdas 中的首选均值)。

我们将实现一个名为Router的函数,它将接受eventcontextcallback作为参数(类似于构造函数属性)。在其中,我们可以有一个函数来调用分配给方法和路径的相关处理程序。让我们看看我们的代码会是什么样子。

路由器实施

你也可以看到我还有另一个功能builResponse。它负责构建响应、字符串化主体和分配状态代码。这将使事情变得简单得多,在下一个关于如何使用路由器的代码片段中,您将会看到这一点。

使用路由器

现在我们已经实现了路由器,让我们看看如何使用它。在下面的代码中,我将展示如何让路由器处理路径datadata/{taskId}上的 GET 请求。如您所见,第二个路径是一个路径模板。路由必须相对于由服务的 service.yml 文件确定的服务来完成。我在之前的文章中已经讨论过这个问题(此处阅读)。如果整个程序只有一个server less . yml文件,可以使用完整路径忽略我前面那句话。

路由器使用

您可以看到,我们可以使用路由器并传递一个处理函数,该函数具有与我们从 lambda 调用中获得的参数相同的参数。我们必须用errorresponse值调用callback函数。但是,我们以 HTTP 状态代码的形式返回错误。因此,error参数将始终为null

授权和认证

如果没有适当的访问控制,应用程序基本上是无用的。认证是授权访问具有用户身份的 API 端点。授权是确保任务由有适当权限的人来完成。最好使用 Cognito 用户池进行身份验证,其中每个用户的头都根据用户池进行验证(从此处了解更多信息)。这将允许带有有效令牌的请求到达 lambda 调用。

角色认知组

当您拥有角色并且角色有权执行特定操作时,需要更细粒度的控制。换句话说,必须对报头进行验证,以检查令牌持有者的权限。这可以通过使用认知用户组来完成。这些可以通过 Cognito 控制台轻松创建。下面是来自真实世界应用程序的几个组。您可以看到一个管理组。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为管理员创建的管理员组

可以创建这些组来向用户分配特定的角色。一个用户可以被分配到多个组。注意,这些组可以使用 AWS SDK 动态创建,不需要访问这个 UI。

验证 Lambda 事件对象的角色

我们分配的这些角色必须在我们的路由器中进行验证,在路由器中我们实际实现了基于角色的访问。我们可以在 AWS 中使用 IAM 角色来执行此操作。但是,这种方法更复杂,更适合限制对 AWS 资源的访问;即 S3 桶、用户池等。因此,我们将在 lambda 内部的路由器级别实现基于角色的访问,以便操纵对数据库和其他资源的访问。

事件对象将在路径event.requestContext.authorizer.claims中具有授权属性。这个对象将有一个名为cognito:groups的属性。这可以是一个数组,也可以是一个值,匹配组或者这个人所属的组。这个值可以用来实现我们的授权。

带角色验证的路由器

这可以简单地作为我们路由器的route功能的扩展。让我们看一下修改情况。

增强型路由器实施

你可以看到我已经检查了cognito:groups是否是一个数组。由于无服务器离线仿真和实际 lambda 行为的不匹配,我不得不这样做。无论如何,它使函数对可能的错误更强。我们的 route 函数调用只需要一个额外的参数,roles 数组。仅此而已!。比如说;

router.route(
    "GET", 
    "/path", 
    (event, context, callback) => { /* Logic + callback */      }, 
    ["Admin", "Some other group", ...]
);

现在你有了一个完整的 lambda 路由器,你可以导入并使用它。lambdas 或重代码处理路由中没有服务器实例。这是一个遵循 【责任链】 设计模式的大开关案例。在每个函数调用中,如果函数调用负责给定的方法路径,处理它们,或者忽略。

这个路由器设计是我们创业时努力的结果,我一直在改进最初设计的一些细节,以适应新的需求。完整的样板文件可以在 GitHub 中找到。

感谢阅读!干杯!

使用 Python 和 AWS Lambda 的无服务器新冠肺炎数据刮刀

原文:https://towardsdatascience.com/serverless-covid-19-data-scraper-with-python-and-aws-lambda-d6789a551b78?source=collection_archive---------8-----------------------

一个重要的 PYTHON 技巧

分步教程:使用 AWS Lambda 调度 Python 脚本

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

插图作者:金彩云

在数据科学中,获得完整的数据源是最重要的事情之一。在几个项目中,数据源是动态变化的,更新速度很快。对新冠肺炎·疫情来说,病例数一直在变化。大多数可用的开放新冠肺炎源仅在每天的时间间隔内可用;然而,较高分辨率的数据似乎对发现与其他参数如空气质量、环境条件等的关系很重要。通过从实时更新源抓取数据来收集数据是获得您想要的数据的解决方案之一。一些文章已经展示了如何用 Python 轻松做到这一点的例子。然而,安排这样一个 Python 项目需要一台一直运行的服务器。对于一个小项目来说,自己为此目的租用/托管服务器可能不值得。

你好,AWS Lambda!λ

出于这个原因,我想介绍亚马逊的一项计算服务,你可以运行或调度任何 Python 脚本(或其他编程语言,如 Java、Go、Node.js、Ruby、c# …),而无需自己维护服务器。有了 AWS Lambda,我们还可以轻松地与 AWS S3 存储桶中的文件同步。

定价呢?💵

最棒的是, AWS Lambda 处于永远免费层服务中!(截至 2020 年 5 月)它允许我们每月提出多达 100 万个请求!例如,如果我们每 1 分钟从互联网上抓取一次数据集,那么每月只有 43200 个请求*(60[请求/小时]* 24[小时/天]* 30[天/月])* 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AWS Lambda 免费领带津贴(作者从 AWS 获取)

本文展示了使用 AWS Lambda 和 AWS S3 桶存储来调度用于抓取新冠肺炎数据的 Python 脚本的分步说明。

我们开始吧

步骤 1:获取新冠肺炎案例的 Python 脚本

首先,我们将准备一个 Python 脚本( covid19scraper.py ),使用RequestsBeautiful Soup库从 Worldometer 中抓取实时全球新冠肺炎数据。总体而言,用于抓取新冠肺炎数据的 Python 脚本如下例所示:

covid19scraper.py (作者举例)

这项技术已经展示过几次了。所以我将只给这个脚本一个简短的介绍。requests用于向 URL 发出 GET 请求,然后BeautifulSoup用于查询 HTML 主体的特定类。在我们的例子中,新冠肺炎案例数据在名为“maincounter-number”的类中,因此调用bsObj.find_all(…)来查找我们感兴趣的所有值。通过调用scrapeGlobalCase(),我们将得到以下结果:

**testResult = scrapeGlobalCase()**testResult: -**{
        ActiveCases: 2302944,
        ConfirmedCases: 3908271,
        Deaths: 270216,
        RecoveredCases: 1335111,
        date: "2020-05-08 00:33:05.775806"
    }**

步骤 2:准备 Python 包

为了在 AWS Lambda 服务上托管我们的 Python 脚本,我们需要用 zip 文件中的脚本准备 Python 模块。首先,我们必须用pip-t ./标签在本地安装所有模块,以指定保存在本地目录中。在我们的示例中,我们需要datetime beautifulsoup4request模块,您可以运行以下命令来本地安装它们:

**$ pip3 install datetime beautifulsoup4 requests -t ./**

然后,使用 zip 命令创建这个 python 文件夹的 zip 文件,或者使用您喜欢的 zip 软件(Winzip,7zip,…).

**$ zip -r python_package.zip ***

步骤 3:准备 S3 桶

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 AWS 上创建 S3 桶(作者从 AWS 控制台捕捉)

因为我们将把我们的结果保存到 AWS S3 存储桶,所以让我们通过 web 浏览器访问您的 AWS 控制台来创建一个存储桶。单击 create a bucket,并为此项目指定一个有意义的名称。您可以根据自己的喜好选择任何地区。我将它命名为“hourlycovid19 ”,用于每小时保存新冠肺炎案例数据。

步骤 4:准备 AWS Lambda 执行角色

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 AWS 身份和访问管理上创建 Lambda 执行角色 (IAM) — 1(由作者从 AWS 控制台捕获)

我们需要为 AWS Lambda 生成一个角色,以便能够访问我们刚刚在上一步中创建的 S3 存储桶。请访问 AWS IAM 控制台。(此处)在菜单中选择“角色”,点击“创建角色”,然后选择“Lambda”用例。找到一个名为“AWSLambdaExecute”的策略,它将允许 Lambda 访问 S3 存储桶。确认后,您可以将此角色命名为“lambda-s3-role”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 AWS 身份和访问管理(IAM)上创建 Lambda 执行角色 — 2(由作者从 AWS 控制台捕获)

步骤 5:上传我们的 Python 脚本到 AWS Lambda 层

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将我们的 Python 脚本上传到 AWS Lambda 层(作者从 AWS 控制台捕获)

现在,一切都差不多了,是时候将我们的 zip Python 包上传到 Lambda 层,以使我们的 Python 脚本在 Lambda 上可执行。我们可以通过浏览 AWS Lambda 页面,点击“层”菜单,然后点击“创建层”,给出一个名称,选择我们的 zip 文件,然后选择 Python 运行时。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建 AWS Lambda 层(作者从 AWS 控制台捕捉)

步骤 6:创建 Lambda 函数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建 AWS Lambda 函数— 1 (作者从 AWS 控制台获取)

现在,让我们创建一个 Lambda 函数来执行我们准备的脚本。浏览到 AWS Lambda 页面,点击“功能”菜单,点击“创建功能”,如上图所示。然后,用“Python 3.x”运行时选择“从头创作”。重要的是选择您在步骤 4 中创建的现有角色“lambda-s3-role ”,以允许此功能访问 s3 时段。您可以遵循下图中的示例设置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建 AWS Lambda 函数— 2 (作者从 AWS 控制台获取)

在创建了“covid19scrape”函数之后,然后将我们在步骤 5 中创建的“covidScraper”层附加到这个函数上。该操作将使我们的函数能够读取和调用我们在步骤 1 中创建的 Python 脚本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将 covidScraper 层(来自步骤 5) 附加到 AWS Lambda 函数(作者从 AWS 控制台捕获)

现在,请转到 lambda 函数中的函数代码部分。在这里,我们将编写一个 Python 脚本,它定义了 Lambda 处理程序,该处理程序从“covid scrape”层的“covid 19 scrape”Python 脚本(如您在步骤 1 中所命名的)中导入“scrapeGlobalCase”函数。我们还导入了“boto3”库来访问 S3 服务。总的来说,用于抓取新冠肺炎数据并保存到 S3 桶的函数代码中的 Python 脚本将如下图所示,或者您可以在此要点查看该脚本。(* 请更改 BUCKET_NAME 以匹配您在步骤 3 中创建的 S3 存储桶)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AWS Lambda 中用于抓取实时新冠肺炎数据并保存到 S3 桶的功能代码。(作者从 AWS 控制台捕捉)

你可以点击“测试”按钮进行测试。有时,可能会出现超时错误,解决这一问题的技巧是调整基本设置以获得更高的 ram/更长的超时时间。对于我来说,我将 ram 设置为 3000 MB,超时时间为 5 秒。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AWS Lambda 功能基本设置。(作者从 AWS 控制台捕捉)

恭喜你!!🎉如果你一直进行到这一步,现在这个 Lambda 函数已经准备好抓取新冠肺炎数据了。

最后一步:调度 Lambda 函数

由于我们的函数已经准备好了,现在让我们使用 CloudWatch 安排我们创建的函数每小时运行一次(或者根据您的喜好)。请转到 AWS CloudWatch 页面并转到事件/规则。在那里,我们可以使用固定的时间比率或使用 Cron 表达式创建一个调度规则,在一天中的特定时间调度作业。如果你是 Cron expression 的新手,请阅读关于如何创建一个 Cron expression 的文档这里。在我们 1 小时计划的例子中,您可以使用这个表达式:0 * * * ? *

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 AWS CloudWatch 安排 Lambda 函数每小时运行一次(作者从 AWS 控制台获取)

检查结果:

所有结果都作为单独的 JSON 文件保存在“hourlycovid 19”S3 桶中。您可以通过访问 S3 铲斗概述来检查它们。您可以通过 AWS CLI 从 S3 bucket 下载所有 JSON 文件到您的本地机器。如果你想用 easy GUI 从 S3 下载多个文件,我推荐 Cyberduck 🦆工作得很好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

S3 桶中的前三个 JSON 结果(作者从 AWS 控制台获取)

为了展示如何使用该数据集的示例,您可以使用下面的示例脚本来读取输出文件夹中的所有 JSON 文件,并将它们添加到 dataframe 中。

将多个 JSON 文件加载到 Pandas dataframe 的示例 Python 脚本。(作者提供的示例脚本)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每小时一次的新冠肺炎全球病例结果数据帧。(作者截图自 Spyder IDE)

至此,我相信您可以很容易地找到几个教程来继续使用 Python Pandas Dataframe 进行一些非常棒的数据分析或数据可视化。尽情享受吧!!✌

结论

所以,就这样吧!如果你是云计算服务的新手,一开始你可能会觉得这很复杂,但是我相信一旦你让它运行起来,你会爱上它的。我希望你喜欢这篇文章,并且能够在将来应用这个无服务器 Lambda 服务来运行你的工作流。

如果您有任何问题或意见,请随时给我留言。

安全健康健康**!💪**

感谢您的阅读。📚

无服务器数据集成——绝地大师尤达的十颗智慧珍珠(2020)

原文:https://towardsdatascience.com/serverless-data-integration-jedi-master-yodas-ten-pearls-of-wisdom-2020-fa536cf3724a?source=collection_archive---------65-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:flickr.com:atomtetsuwan2002

在无服务器数据集成项目中获得的重要经验

序文

问候爱、和平、健康与和谐!那是 1980 年,我还是个十几岁的少年,正在看我的第一部星球大战电影——《T2》《帝国反击战《T4》【第五集】。它让我难以置信地着迷,留下了不可磨灭的印象。差不多四十年过去了,我还是一个粉丝。绝地大师尤达是《星球大战》三部曲中我最喜欢的角色。

为了更好地阅读这篇文章,我使用了尤达大师的反序演讲格式,这使得分享智慧的珍珠更加有趣。当你大声朗读 10 颗珍珠时,想象它是用大师的声音呈现的:)

这些珍珠是我在第一个无服务器数据集成项目中学到的经验。这相当于绝地第一次用她的光剑做有意义的事。这段经历过去是(现在仍然是)无价的,我希望你能从中获得价值。说到无服务器数据集成,我想起了尤达大师的一句名言— 做…还是不做。没有尝试!我们开始吧。

智慧的结晶

数据集成在企业中创建了“数据真相”的单一版本。它为企业提供高质量的标准化数据,从而实现分析、机器学习和人工智能。无服务器数据集成使组织能够交付大量数据,同时优化运营成本。以下是我学到的经验:

#1 —将您必须的无服务器功能从状态中分离出来!

无服务器微服务本质上是短暂的。它由一个事件触发,并执行一个特定的动作作为响应,然后就完成了。微服务的微容器的内存内容不应该试图在当前调用之外直接共享。强制无服务器应用程序或函数调用直接共享其范围之外的状态,将导致次优设计。这会影响可伸缩性,并引入大量不必要的副作用。当需要时,微服务应该将暂时的状态信息写入数据库( Memcached 或 Redis )。在写入永久日志的情况下,应该使用其他可靠和持久的数据持久性机制。即使对于数据集成中心(Hub)也是如此。

#2 —测量您应该测量的系统安静时间!

并非所有工作负载都真正适合无服务器计算。集线器是无服务器实现的典型代表,它的特点是先有突发的活动,然后是一段安静的时间。它本质上是不可预测的。除了正常操作之外,中心还需要支持不同的每日数据量,在没有预设时间(没有计划的作业)的情况下接收和处理数据,并根据需要执行专门的一次性转换。通常,中心日常处理的这种不可预测性需要动态和即时的计算扩展来实现最佳性能。一旦操作完成,集线器进入安静状态。了解枢纽的安静时间特征,使我们能够准确量化运营成本节约。最后,空闲时间不会对我们造成任何损失,这意味着——无服务器计算的运营成本优化是安静时间的一个功能。

#3 —优化您的函数运行时间,不要因为函数资源分配而分心!

在系统性能优化领域,以下公式被视为圣杯:

响应时间(经过时间)=服务时间+等待时间

响应时间需要成为集线器所有组件的优化目标。每个微服务都需要优化到尽可能短的运行时间。这个概念可能适用于所有计算应用程序,而不仅仅是集线器。

AWS Lambda 中,分配给 Lambda 函数的内存量与其预计成本之间存在直接关联。成本(每秒)与分配的内存量成比例增加。众所周知,内存分配越大,vCPU 内核分配比例越大。 AWS Lambda 根据内存量(最多约 1.75–1.8 GB)分配单个 vCPU 内核。超过此内存阈值,将分配 2 个 vCPU 内核并按比例扩展。

借助双线程微服务设计,可以利用额外调配的资源(CPU 和内存)来提高性能。这直接导致运行时间的减少和成本的降低。请记住,您需要为程序的运行时间付费,运行时间优化应该是您唯一的关注点。不用说,收益递减规律会在资源分配(内存)上发挥作用。目标是在“拐点”之前分配足够的内存。因此,集线器中的大容量数据操作非常适合双线程微服务,这种服务利用 3GB 内存和 2 个 vCPUs。

#4 —不一定是约束,这些函数运行时限制!

一个 AWS Lambda 函数的当前运行时间限制是 900 秒 。这个限制很容易克服(如果需要的话),在一个 AWS 步骤函数中有简单的编排逻辑。使用一个简单的计时器和一个数据处理跟踪器(跟踪处理进度的指针),程序的运行时执行被监控。功能在适当的时间重新启动(比如定时器到期前 10 秒),确保程序持续运行时间超过 Lambda 的 900 秒限制。

说了上面的话,我想提醒我们所有人一个微服务意味着一个轻量级架构和一个短的运行时间(非常谦虚地说——我们没有理解微服务的哪一部分:)).我相信,当一个微服务被优化设计时,它不应该要求运行时间超过 15 分钟。在需要处理大量数据的情况下,可以使用步进功能协调同一个微服务,以启动多个并行执行,所有执行都在 15 分钟内单独完成。

#5 —这些功能延迟和冷启动辩论无关紧要!

函数延迟是用来量化启动一个 AWS Lambda 函数所用时间的术语。它表示重用一个已经配置好的微容器所花费的时间。当在短时间内发生多个独立的执行时,这是一个相关的讨论点。当功能执行频率大于 30 分钟时,微型容器需要重新配置。这被称为冷启动。解决这个问题的方法之一是利用 Lambda 函数配置中的“供应并发”。但是有一个与之相关的固定成本,它否定了安静时间和成本节约的概念。本质上,集线器对功能延迟甚至冷启动不敏感。它不是一个永不停机的应用程序,每小时每分钟每秒都要处理数百个 API 调用。因此,功能延迟和冷启动的问题与集线器无关。

#6 —您必须区分幂等处理和重复处理!

幂等元是计算机科学的一个基本构造,它定义了程序执行的最终状态。幂等执行要求在输入值相同的情况下,无论程序运行多少次,程序的最终状态都保持完全相同。例如,一个将客户地址修改为’ 123 Main Street '的程序是幂等的,无论我们运行它多少次。客户地址的最终状态是“123 Main Street”。多次运行这个程序没有负面影响。因此,一个程序是否是幂等的,取决于程序的需求、上下文、设计和操作的数据。

关于为什么 AWS Lambda 不能保证幂等的执行,存在疑问和争论。由于 Lambda 函数如何实现的动态和异步特性(包括在冷启动期间启动微容器),在一些边缘情况下,可以针对单个执行请求同时启动多个容器。作为云计算的实践者,我们需要用一个重要的原则来设计—‘一切可以打破的,都将打破’。因此,需要主动解决上面讨论的AWSλ的环境副作用。这是防止重复数据处理的一个简单例子。

作为数据从业者,我们都赞同保护系统免受同一数据集的任何意外重复处理的设计。这些安全措施建立在程序逻辑的范围内。这是绝对正确的,也是一个枢纽所需要的。重复数据处理的场景类似于消息队列的消费管理。为确保加工的完整性,设计结构如总是一次加工应优先于至少一次加工。当消费结构至少有一次是时,不能责怪队列产生重复数据。因此,λ函数不是幂等的是没有意义的。不管一个程序是否幂等,在一个中枢中为重复数据处理设计安全措施是不可协商的,并且必须合并。

#7 —避免将功能硬连线到您的 VPC 上!

AWS Lambda 的计算资源全部在 Lambda 的服务 VPCs 内运行。 Lambda 调用可以通过 AWS Lambda API发生。没有对函数运行的执行环境的“网络访问”的规定,因此不能仅仅侵入λ调用及其执行微容器。 AWS Lambda (当没有硬连接到你的 VPC 时)的默认行为是,它可以访问公共域中的任何东西,甚至是在 AWS 之外。仅仅因为一个短暂的函数可以访问公共资源,并不自动意味着它会。人们可以不厌其烦地讨论安全角度*,但是对于短暂的无服务器计算环境(不访问你的 VPC 资源)VPC——硬连线是不必要的。*

当一个λ函数硬连线到你的 VPC 时,它会在你的 VPC 内创建一个弹性网络接口(ENI)* ,允许访问私有资源。这将计入您所在地区的帐户限额(IP 地址、API 费率、网络费率)。当您试图增加和扩展函数调用时,您将面临这些帐户限制的挑战,因为每次调用一个 VPC 连接的函数都需要一个 ENI 。在集线器的情况下,λ功能需要访问 VPC 资源(数据),因此出于安全和隔离的目的,建议通过专用子网进行访问。功能互联网接入通常与集线器无关,但在需要和适用时,应通过 VPC NAT 网关进行控制。*

2019 年 9 月,AWS 推出了一种更高效的方法,让函数使用 AWS 超平面 ENIs 与您的 VPCs 进行通信。这个新的和改进的 VPC 网络,消除了之前在你的 VPC 中创建的众多运行时 ENIs 。使用新方法, Lambda 函数连接到超平面 ENIs* ,超平面 ENIs 反过来管理到您的 VPC ENIs 的连接(每个安全组一个:子网)。这样做,它消除了直接的 ENI 连接,使 VPC 网络更具可伸缩性,并减少了 VPC 有线函数调用的延迟时间。*

# 8——观察无服务器功能的工作方式!

无服务器环境明显缺乏功能可观察性*。这是由于计算环境的瞬时性。相反,在基于服务器的环境中,人们总是能够通过各种跟踪方法来观察程序的执行。因此,功能可观察性是观察执行行为和相关细节的行为。*

虽然在 AWS 的 CloudWatch 日志中记录了一组默认的标准指标,但是每天有大量函数调用的应用程序会在从 CloudWatch 中挖掘特定于函数的细节时产生问题。这类似于大海捞针。当然还有 AWS X 光进行功能调试和追溯。然而,我认为我们需要更好地控制我们观察到的东西。

在 Hub 中,每个微服务都应该配备一个日志记录功能,写入我们选择的日志表*。我们现在控制我们想要在函数执行中观察什么。在日志表的设计上做一点投资就可以走很长的路。以下是日志记录的一些基本属性— 函数名、运行日期、运行时间、总运行时间、对象名、行数和调用参数。这些属性给了我们一个良好的开端,我们可以根据我们不断发展的需求来扩充它。这为您的无服务器中心增加了重要的生产监控价值。以下是亮点:*

1)为功能执行日志的持久化量身定制结构,即没有一刀切的标准

2)基于执行标准和日志记录级别的灵活日志记录粒度,即调试/故障排除期间的较高粒度与正常操作期间的较低粒度**

3)易于将日志转换为可操作信息(AWS elastic cache),即清晰了解中心的健康状况

4)定制日志历史记录的保留,由您对性能基线的要求控制,并具有您定义的时间段

因此,功能可观察性,一个中心运营管理的关键方面,是我们需要拥有的东西,而不仅仅依赖于 CloudWatch

#9 —您必须抽象,以避免被云供应商锁定!

给无服务器讨论足够的时间,它将变成云服务提供商(CSP)锁定辩论。诚然,不需要必要的前期设计工作,CSP 锁定也是可能发生的。如果您的无服务器函数中有硬编码的专有 SDK API 调用,您可能会被锁定。即使对于基于服务器的应用程序也是如此——硬编码是一种糟糕的做法!

问题——一个 AWS Lambda 函数,用 Python 3 编程。至少有一个 AWS Python SDK 调用的 x(boto 3 或 botocore )不能被提升并“按原样”转移到另一个 CSP。这是因为没有任何 CSP 间 SDK。然而,有一种方法可以通过一些“计算抽象”来获得 CSP 独立性。考虑一个简单的微服务,它采用两个参数(storage _ bucket _ name&object _ name)从 CSP 的存储桶中检索和下载一个对象。这个任务的主要 Python SDK API 调用(跨 3 个示例 CSP)如图 1 所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1 — Python SDK API 调用 AWS、GCP & Azure 从存储桶下载对象

从图 1 中可以清楚地看到,由于 CSP 拥有专有的 SDK,因此每个 CSP 的微服务都是不同的。您将需要为 3 个不同的 CSP 提供 3 个不同的程序,从而维护 3 个不同的代码库。这对大型代码库来说是痛苦的。

解决方案 —如果微服务和基础程序设计保持简单,那么跨 CSP 的微服务执行和编排将成为现实。这是通过一点 JSON 杂耍和一个简单的代码部署配置完成的。目标是只维护基础程序的一个副本。CSP 特定调用的封装是用 JSON 文档完成的。图 2 提供了一个使用 JSON 的抽象方法,在代码部署时用一个基础程序设计一个特定于 CSP 的微服务:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2——使用 JSON 对 GCP AWS 的微服务进行简单的 Python 程序抽象& Azure

如图 2 所示,将每个 CSP 的 SDK API 调用分离到自己的列表中,可以促进基础程序的单一版本,同时保持代码的可移植性。以下是方法:

1.通过 SDK API 调用抽象所有 CSP 的微服务

2.创建一个名为 get_obj_from_bkt 的 JSON 文档,将每个特定于 CSP 的定义封装在一个列表中(如图 2 所示)

3.将 JSON 文档的内容— get_obj_from_bkt 存储在一个 NoSQL 文档集合中— 让我们称这个表/集合为 CodeAbstract

4.创建一个 Python 函数— CodePreProc ,它显式地为所有微服务生成代码。在我们的例子中,我们将为 get_object_from_bkt 微服务生成代码。

5.在代码部署期间(CI/CD 管道),使用运行时参数( aws/azr/gcp )调用 CodePreProc 。比如—CodePreProc(‘AWS’);**

6.基于这个运行时参数, CodePreProcCodeAbstract 表中查询和检索 get_obj_from_bkt JSON 文档。

7.AWS 代码数组( aws_get_obj_from_bkt )选自 JSON 对象{},假定’ aws’ 传递给了 CodePreProc

8. CodePreProc 然后在给定 CSP 代码数组的元素之间“连接”换行符(“\n”)(使用 join() 函数)并创建适当的 Python 程序—AWS _ get _ obj _ from _ bucket . py 文件

9.特定于 AWS 的 get-obj_from_bkt 微服务现在已经准备好在 CI/CD 管道的下一阶段进行测试和部署。

因此,通过将特定于 CSP 的 SDK API 调用封装在 JSON 文档的列表中,并使用简单的预处理脚本动态生成特定于 CSP 的函数,就有可能解决供应商锁定问题。同样,这种方法不是解决所有代码可移植性问题的灵丹妙药,但它确实为硬编码 CSP SDK API 调用提供了一种可行的替代方案。只有在预先完成了必要的抽象和设计工作,从而提供了跨云代码可移植性的自由时,这才是正确的。上述方法有两个优点:

a)利用单个基础/包装程序的能力,该程序没有特定于 CSP 的函数调用。这允许通过独立的 CSP 专用 SDK API 微服务(功能)支持具有相同代码库的多个 CSP。

b)对 SDK(参数/名称等)的更改。)对于给定的 CSP,只影响 JSON 文档中一个特定 CSP 的代码数组。对其他 CSP 和 orchestrator 计划没有任何影响。如果需要进一步分离,可以修改 JSON 文档的结构,将每个 CSP 的代码分离到一个独立的 JSON 文档中。

总之,特定于 CSP 的 SDK API 调用抽象需要预先设计,并且可能不适用于所有现有项目。然而,对于新的项目,它确实提供了一种将微服务从特定于 CSP 的 SDK API 调用中分离出来的方法。这有助于维护通用基础程序,并使我们摆脱供应商的束缚!

#10 —测试您应该…在本地测试云的这些功能!

好的集成开发环境(IDE)是程序员的工作台。设计良好的 ide 支持高效的程序开发和测试。“本地”测试云功能的需求是您在项目中很快会遇到的一个需求。没有云感知的 IDE,测试变得非常耗时,因为我们将花费更多的时间通过 CSP 的代码管理管道推送代码,而不是实际的测试。因此,本地测试大大提高了生产率。幸运的是,有一些云友好的 ide 可以拯救程序员。这种 IDE 的一个很好的例子就是 Stackery

结论

无服务器数据集成中心以尽可能低的运营成本提供企业数据真相的单一版本。持续学习、适应和成长的重要性需要在我们生活的各个方面成为一种长期的习惯。无服务器数据集成也不例外。我将带着尤达大师著名的智慧之珠离开你,它让我保持谦逊和脚踏实地——你还有很多要学的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值