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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何在 Python 中处理缺失数据

原文:https://towardsdatascience.com/how-to-deal-with-missing-data-in-python-1f74a9112d93?source=collection_archive---------1-----------------------

使用 Pandas 和 NumPy 处理数据集中的缺失值

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

弗兰基·查马基在 Unsplash 上拍摄的照片

L 去年,我在做一个处理 Twitter 数据 的项目。我们的数据库中有大约 10 亿条推文。我需要清理我们的数据,这样我们就可以在上面运行一些机器学习模型。

以下是数据集的快照:

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

来源:作者

奇怪的 Unicode 字符(表情符号),标识符变化的随机缺失值等。我仍然会做那个项目的噩梦。

但是,现实世界的数据集就是这样。您会得到缺失值、随机字符、错误的数据类型等。根据一些统计, 数据科学家最终要花费 80%的时间来组织和清理数据

数据集中常见的情况是 缺失值 。这可能是由多种原因造成的,如未记录的观察结果或数据损坏。

在本教程中,我们将通过使用 熊猫库 来了解在 Python 中处理缺失值的许多不同方式。

熊猫库为标记这些腐败的价值观提供了多种功能。我们将研究如何去除或估算这些值。

来源: Giphy

设置

本教程中的所有例子都在运行 Python 3.7 的 Jupyter 笔记本上测试过。我们将在本教程中使用 NumPy熊猫

这里有一个附带的 Jupyter 笔记本。

我强烈推荐建立一个虚拟环境,里面有测试所需的所有库。这是你可以做到的。

$ virtualenv missing_data
$ source ./missing_data/bin/activate
$ pip3 install pandas numpy

员工数据集

在本教程中,我们将使用小型员工数据集

从我的 Github repo 中下载 CSV 格式的数据集,并存储在您当前的工作目录:employees . CSV

让我们将这个数据集导入 Python 并查看一下。

输出:

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

来源:作者

我们将 CSV 文件读入一个 熊猫数据帧[.head()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.head.html)方法返回数据帧的前五行。

该数据集有 1000 个观察值,其中六个变量如下所示:

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

数据集中的所有变量。来源:作者

如何将无效/损坏的值标记为缺失

每个数据集中有两种类型的缺失值:

  1. 可见错误:空白单元格、特殊符号如 NA (不可用)、 NaN (不是数字)等。
  2. 模糊错误:未损坏但无效值。例如,负薪金或姓名的数字。

注意:对于埃隆的儿子 X?A-12,命名规则可能需要一些修改。

雇员数据集有多个缺失值。让我们仔细看看:

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

数据集的前 10 行。来源:作者

你会注意到像 NANaN这样的值?空白单元格。这些代表我们数据集中缺失的值。

让我们打印’**薪金’**列的前 10 行。

print(df['Salary'].head(10))

我们在下面的图片中描绘了数据集的快照和上述语句的输出。

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

左:数据集中的薪金列。右图:熊猫进口时的工资栏。来源:作者

Pandas 会自动将空白值或带 NA 的值标记为 NaN(缺失值)。

Pandas 还为每一行分配一个索引值。包含 NaN 的值在 mean、sum 等运算中被忽略。

虽然这适用于 na 和空白行,但熊猫无法识别其他符号,如 NA?,不适用,不适用。这可以在’**性别’**栏中看到:

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

左:数据集中的性别列。右图:熊猫进口时的性别栏。来源:作者

如前所述,Pandas 处理空白值并将其转换为 NaN。但对于第 6 行中的不适用,它无法这样做。

当多个用户手动将数据输入数据库时,这是一个常见的问题。我们可以将 **.read_csv()** 方法 中的所有这些符号作为一个列表来传递,以允许熊猫识别它们为腐败值。看一看:

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

现在,n.a .也转为 NaN。来源:作者

处理无效数据类型

到目前为止,我们丢失的值都有唯一的标识符,这使得它们很容易被发现。但是当我们得到一个无效的数据类型时会发生什么呢?

例如,如果我们期望一个数值,但是,用户输入一个字符串,如’ No’ 表示薪水。从技术上讲,这也是一个缺失值。

我设计了一个函数,允许我检查列中的无效数据类型。假设我希望确保’ Salary’ 列中的所有值都是类型int。我将使用以下内容:

此后,在出现无效条目的地方,薪金列中的值将是带有 NaN 的类型 int

使用 isnull 和 notnull 标记缺失值

在 Pandas 中,我们有两个用于标记缺失值的函数:

  • [isnull()](https://www.geeksforgeeks.org/python-pandas-series-isnull/):将数据集中的所有 NaN 值标记为真
  • [notnull()](https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.notnull.html):将数据集中的所有 NaN 值标记为 False。

看看下面的代码:

# NaN values are marked True
print(df[‘Gender’].isnull().head(10))# NaN values are marked False 
print(df[‘Gender’].notnull().head(10))

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

左:原始性别栏,中:isnull()函数输出,右:notnull()函数输出

我们可以使用isnullnotnull功能的输出进行过滤。

让我们打印所有没有性别遗漏的行。

# notnull will return False for all NaN values
null_filter = df['Gender'].notnull()# prints only those rows where null_filter is True
print(df[null_filter])

缺失值统计

isnullnotnull也可以用来汇总缺失值。

检查我们的数据帧中是否有任何缺失值:

print(df.isnull().values.any())# Output
True

每列缺失值的总数:

print(df.isnull().sum())# Output
First Name            70
Gender               149
Salary                 5
Bonus %                4
Senior Management     71
Team                  48

如何删除缺少值的行

既然我们已经将数据集中所有缺失的值标记为 NaN,我们需要决定如何处理它们。

最基本的策略是删除所有包含缺失值的行,或者在极端情况下,删除包含缺失值的整列。

Pandas 库提供了[dropna()](https://pandas.pydata.org/pandas-docs/version/0.21.1/generated/pandas.DataFrame.dropna.html)函数,可以用来删除丢失数据的列或行。

在下面的例子中,我们使用dropna()删除所有丢失数据的行:

# drop all rows with NaN values
df.dropna(axis=0,inplace=True)

[inplace=True](https://pandas.pydata.org/pandas-docs/version/0.21.1/generated/pandas.DataFrame.dropna.html)使所有更改发生在同一个数据框中,而不是返回一个新的数据框。

要删除列,我们需要设置 axis = 1。

我们也可以使用[how](https://pandas.pydata.org/pandas-docs/version/0.21.1/generated/pandas.DataFrame.dropna.html)参数。

  • **how = 'any’**:至少有一个值必须为空。
  • how = 'all’:所有值必须为空。

使用how参数的一些代码示例:

输入数据集中缺失的值

当缺少值的情况很少时,删除行是一个很好的选择。但是这并不总是可行的。我们需要用聪明的猜测来代替这些 NaNs。

替换缺失值时,有许多选项可供选择:

  • 单个预先确定的常数值,如 0。
  • 从另一个随机选择的样本中取值。
  • 列的平均值、中值或众数。
  • 使用预测模型插值。

为了填补数据集中缺失的值,Pandas 库为我们提供了[fillna()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html)[replace()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.replace.html)[interpolate()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.interpolate.html)函数。

让我们用例子一个一个地看这些函数。

用单个常数值替换 NaNs

我们将使用fillna()将**“薪金”**列中缺失的值替换为 0。

df['Salary'].fillna(0, inplace=True)# To check changes call
# print(df['Salary'].head(10))

我们也可以对像’**性别’**这样的分类变量做同样的事情。

df['Gender'].fillna('No Gender', inplace=True)

用前一行或下一行的值替换 NaNs

这是填充图像数据中缺失值的常用方法。我们使用method = 'pad’前一行中取值。

df['Salary'].fillna(method='pad', inplace=True)

我们使用method = 'bfill’从下一行的中取值。

df['Salary'].fillna(method='bfill', inplace=True)

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

来源:作者

使用列的中间值/平均值替换 NaNs

常见的合理方法。

# using median
df['Salary'].fillna(df['Salary'].median(), inplace=True)#using mean
df['Salary'].fillna(int(df['Salary'].mean()), inplace=True)

注意:关于fillna的其他选项的信息可在处获得。

使用替换方法

[replace](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.replace.html)方法是fillna方法的一种更通用的形式。这里,我们指定了要替换的值和替换值。

# will replace NaN value in Salary with value 0  
df['Salary'].replace(to_replace = np.nan, value = 0,inplace=True)

使用内插法

interpolate()函数用于使用各种插值技术填充 NaN 值。点击阅读更多关于插值方法的信息。

让我们使用 线性插值法 对缺失值进行插值。

df['Salary'].interpolate(method='linear', direction = 'forward', inplace=True) 
print(df['Salary'].head(10))

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

使用线性插值后的输出。来源:作者

结束语

不管我们喜欢与否,现实世界的数据都是杂乱无章的。 数据清洗 是每个数据科学项目的主要部分。

在本教程中,我们回顾了检测、标记和替换缺失值的技术。

数据经常由于随机原因丢失,如数据损坏、信号错误等。但有些时候,这种数据缺失还有更深层次的原因。

虽然我们讨论了使用平均值、中值、插值等进行替换,但缺失值通常与我们的数据有一种更复杂的统计关系。我建议浏览本指南的了解更多详情。

希望看完这篇教程,你少花点时间清理数据,多花点时间探索建模。很高兴在下面的评论中回答你的所有问题。

相关材料

Chaitanya Baweja 渴望用工程解决方案解决现实世界的问题。在 TwitterLinkedin 上关注他的旅程。

作为有抱负的数据科学家如何应对拒绝

原文:https://towardsdatascience.com/how-to-deal-with-rejection-as-aspiring-data-scientist-2b781d2b800a?source=collection_archive---------11-----------------------

在工作过程中跌倒后重新站起来的 12 条建议。

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

别担心,总有一天你会到达那里的。

你一直在申请数据科学的职位。但几个月来,你收到的唯一回复是这样开始的:“我很抱歉地通知你……”当你收到另一封来自一家公司的信时,你畏缩了,泪流满面,这家公司不会给你机会展示你所拥有的所有技能。

或者你过得更好。你获得了这家公司的第四次也是最后一次面试机会,而这家公司正是你真正想为之工作的。你对公司做了功课,为技术面试做了准备,并向正确的神祈祷。

但是当你认为你已经掌握了面试的机会时,你失败了。在决定命运的那一天,你太紧张了,以至于你不能发挥出 100%的水平。或者也许你 100%的努力还不够。

你被一家公司拒绝了。又来了。

对于那些处于这种情况的人,作为一名有抱负的数据科学家,这里有 12 条关于如何在精神和情感层面上处理拒绝的个人建议。我希望这些提示可以指导和重新激励你不懈的努力,在数据科学领域获得梦想的工作。

1.我们都经历过。

每一位在工业界工作的数据科学家都经历过和你现在一样艰难的工作流程。我们都以同样令人沮丧的方式失败了,但也以同样胜利的方式成功了。接下来的几个建议将深入探讨你如何处理你最低落的时刻。

第一个建议是假设你不是那种智商 167、资质完美、第一次尝试就拿到所有 FAANG offer 的人。像这样的地方很少。假设你不是那样的人,你是那 99%不懈努力实现梦想的人的一部分。

2.这是一个数字游戏。

如果你有一个数据科学伙伴可以把你的简历传给招聘经理,那就太好了。但是你们中的许多人正在转行,没有这种奢侈。这很好,因为冷申请无论如何都管用(我就是这样找到第一份工作的)。

从统计学的角度思考申请过程(作为未来的数据科学家)。假设你可以每隔 1~1.5 分钟发 1 个冷应用。所以每小时你会收到大约 40~60 份申请。如果每天花 3 个小时,那就是 120~180 个左右的应用。假设响应率的下限是 1%。那仍然是每 3 小时至少有一个响应。

相比之下,追求温暖的应用路线。你首先在 LinkedIn 上搜索一位前同事的朋友,他是一名数据科学家。你花每月的 LinkedIn premium 积分向熟人发送这样的直接消息,希望有人会回应你的咖啡聊天。一位数据科学家慷慨地同意了,然后你去了要求的位置。你尴尬地和那个人谈了大约一个小时,最后(紧张地)请求推荐。你得到了肯定的回答。万岁!。

整个过程需要多长时间?假设最初的搜索加上发送精心制作的消息花了 1 个小时。你花了一整天等待回应。也许一个感同身受的灵魂会在两天后当这个人有空的时候回应一次会面。直接会见数据科学家需要 30 分钟~ 1 小时,另外 1 小时用于咨询请求的对话。

两者都是有效的策略,但投资回报不同。如果统计结果正确,冰冷的电子邮件会导致招聘人员更多的回复。热情的方式让你离与招聘经理通话更近了一步。因此,了解这两种策略的优点和缺点。

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

我的战术侧重于掌握冷应用策略。通过试验和失败,我最终达到了每个公司每个应用程序 1~1.5 分钟的效率水平。当我现在的公司在我提交申请 3 天后联系我时,我已经完全忘记了他们实际上做了什么,因为那时我已经申请了 300 多个其他地点。

3。完善你的简历和求职信。

如果你的简历和求职信不合格,最大的申请效率并不重要。招聘人员在每份简历上花大约 7 秒钟寻找关键词。有时候公司会用 AI 根据这些词筛选出简历。换句话说,请专业人士审核你的简历。

大多数申请都有附信选项。当我没有附上求职信时,我还没有收到公司的回复。确保你写的求职信足够通用,适用于大多数公司,但也足够具体,这样即使你要改变公司名称和职位要求,求职信仍然有意义。

4.永远不要把所有的鸡蛋放在一个篮子里。

即使你即将得到那份工作,也不要停止申请。相信我;有一次,一家小公司的首席技术官直接找到了我,他在阅读了我的一篇关于数据科学的热门帖子后找到了我。我为这个事实感到非常自豪,以至于我不再申请其他角色。

这种专注于一家公司以实现单一回报最大化的策略在当时是有道理的。这似乎也很有效,我进入了面试阶段,直到与首席执行官面对面。他认为我很适合。但是当我最后一次技术面试时,我没能解析嵌套字典,他们不得不拒绝我的提议。

我崩溃了,更糟糕的是,我没有面试机会了,因为我的申请渠道已经枯竭了。感觉我不得不从头开始,这是一个令人心碎的时刻,如果我有其他的面试机会,这一时刻是可以弥补的。永远不要让这种情况发生在你身上。一直坚持申请。

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

5.这应该是(非常)艰难的

有成百上千的人申请同一个职位,他们的资历即使不比你好,也和你一样好。会很难,非常难。如果这个过程很简单,那实际上应该被视为公司的一个危险信号。这是一个违反直觉的说法,但听起来往往是正确的。

大多数拥有合法且经验丰富的数据科学团队的公司都会严格制定面试程序,以仔细衡量候选人的分析和解决问题的能力。这些技能可以代表候选人在被聘用后作为数据科学家的潜在表现。这就是为什么面试时间很长,并夹杂着棘手的脑筋急转弯问题。精心设计艰难面试过程的另一个原因是为了在众多初级求职者中找到最好的申请人。

从相反的角度思考这个问题;如果整个数据科学面试过程只有 1 个小时,没有任何技术问题,您对一家公司有多少信心?作为一名申请人,你也在评估自己是否适合这家公司,你希望置身于这样一个环境中,通过受到队友和经理的挑战而积极成长。

6.面试不同于数据科学技能。

扩展以上观点,技术面试本质上是智力测试。在我的另一篇文章中,我分解了智力测试的组成部分:

[## 抱歉,项目不会给你带来工作

我们如何高估了数据科学项目在工作过程中的作用——以及实际上…

towardsdatascience.com](/sorry-projects-dont-get-you-jobs-3e5d8e74bfdc)

作为 TLDR,切记数据科学技能 != 面试技巧。两者是不同的野兽。这就像标准化能力倾向测试(或你所在国家的大学入学可比能力倾向测试)。SAT 代表你的“智力”和对基础知识的掌握程度。他们有自己的规则和程序,如果你想进入一所好的大学,你需要玩这个游戏。从同样的角度考虑技术面试。

7.学位不是阻止你的东西。

相信我,当我说你不需要一个编程或统计硕士/学士学位就能成为一名数据科学家。我的学士学位是英国文学。如果你认为你很糟糕,想想我自己经历了什么。

学位和背景只对接到招聘人员的第一个电话有影响。之后其实就是我上面说的智力测试了。学位之所以重要,首先是因为竞争。我说几百个有着相同资历的人都在申请同一个职位。

他们中的许多人——至少是加利福尼亚湾区的人——拥有与数据领域相关的硕士学位。与学士学位相比,进入美国名牌大学攻读硕士学位相对容易(我知道这一点,因为我自己也是从常春藤盟校获得硕士学位的)。

加上 OPT / H1B 签证的情况,每年有 1000 多名拥有令人印象深刻的美国学位的毕业生试图获得那些利润丰厚的入门级数据分析师和科学家职位。如果你没有硕士学位,你看起来已经不如那些有硕士学位的人有竞争力了。

如果这是你担心的,我会罩着你的。在TDS 独家采访中,我采访了 DoorDash 的 Jeffrey Li,他分享了他在没有软件或统计学位的情况下获得多个数据科学职位的 3 个重要策略。这些策略贯穿整个面试过程,从接到招聘人员的电话到赢得招聘经理的芳心。

8.你可以做好每一件事,但仍然会被拒绝。

也许你有合适的学位和证书。对于你现在面试的这家公司来说,你在技术挑战上一点也没有失误。事实上,公司里你见过的每个人都给你一种强烈的感觉;他们似乎很有兴趣和你一起工作。为了进一步巩固你的地位,你可以利用 Jeffrey Li 在 TDS 采访中谈到的公文包场景。

但是,只是但是,几天后你发现他们拒绝了你的工作邀请。你感到震惊,困惑,崩溃。你不停地问自己,“我做错了什么?”。

我是来告诉你也许做错事的不是你。也许有些力量超出了你的控制范围,就像另一位决赛者的简历上有一件比你更令人印象深刻的事情。类似于数据科学,不确定性是工作流程中的固有变量。你可以尽力而为,但运气并不总是对你有利。把这种情况理解为公司不适合你。也许这反而是他们的损失。

9.失败可能是(巨大的)塞翁失马焉知非福。

也许你注定要失败。通过失败和从失败中成长,你已经成为一个更有能力和竞争力的候选人。这种成长我见过很多次了。申请人在最初几次面试中失败,在面试中变得更好,再失败一些,到第 30 次失败时,他们已经非常擅长面试,现在他们可以接受顶级公司最严格的面试。

10.这可能需要很多很多个月,但没关系。

我花了大约 4 个月的时间才得到最终的工作机会。对其他人来说,需要 8 个月,有些超过一年。想到你可能会失业一年,真是令人心碎。我知道。这是一个难以接受的现实。但是请记住,每个人最终都会到达他们想要到达的目的地。从那以后只会变得更加容易。

11.你恢复得越快,你就能越快成功。

恢复时间是需要这么长时间才能得到梦想中的数据科学工作的部分原因。忍受和克服痛苦的节奏因人而异,因为有些人沉浸在悲伤中的时间比其他人长。

我不是告诉你停止悲伤;我告诉你,当生活击倒你时,要增强你的精神毅力,重新站起来。在我第一轮与首席技术官的面试失败后,我经历了整整 3 天的痛苦和消极。但是通过体育、音乐和朋友,我立即投入了战斗。

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

12.其他角色也存在。

最后一点,你也可以随意申请其他职位。你不必只申请数据科学家的职位。数据分析师、数据工程师、业务分析师、产品分析师也是在某种程度上使用数据的重要角色。如果真的到了那一步,向其他机会敞开心扉。

[## Haebichan Jung - Medium

阅读容格在媒介上的作品。“走向数据科学|芯片领域的数据科学家”项目负责人…

medium.com](https://medium.com/@haebichan)

如何调试 ML 模型:NLP 中的分步案例研究

原文:https://towardsdatascience.com/how-to-debug-an-ml-model-a-step-by-step-case-study-in-nlp-d79d384f7427?source=collection_archive---------45-----------------------

虽然有这么多文章介绍如何开始学习 NLP 或向您提供指导,但最难学习的课程之一是如何调试模型或任务实现。

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

模型/任务实施前的精神状态,通过 Pixabay (CC0)的 StockSnap

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

模型/任务实施后的精神状态,Free-Photovia pix abay(CC0)

不要担心!本文将介绍一系列相当微妙(和不那么微妙)的错误的调试过程,以及我们如何修复它们,并通过一个案例研究来引导您完成这些课程。如果你想看提示列表,向下滚动到最后!

为了做到这一点,让我带你回到几个月前,那时我们(我的研究合作者 Phu 和我)第一次将屏蔽语言建模实现到 jiant 中,这是一个开源的 NLP 框架,目标是在 RoBERTa 模型上进行多任务训练。如果这听起来像是一种陌生的语言,我建议你先看看这篇关于迁移学习和多任务学习的文章,和这篇关于罗伯塔模型的文章。

设置场景

屏蔽语言建模是 BERT、RoBERTa 和许多 BERT 风格变体的预训练目标之一。它由一个输入噪声目标组成,其中给定一个文本,该模型必须预测给定上下文的 15%的标记。更困难的是,这些预测的标记有 80%的时间被替换为“[MASK]”,10%被另一个随机标记替换,10%是正确的、未被替换的标记。

例如,该模型如下所示

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

为 MLM 培训更改的文本示例。这里,模型将学习预测当前被“[MASK]”占据的令牌的“tail”

设计初始实施

我们首先查看了其他人以前是否实现过 MLM,发现了 Google 的最初实现和 AllenNLP 的 Pytorch 实现。我们几乎使用了所有的 Huggingface 实现 n(它已经被移动了,因为它看起来像是以前在那里的文件已经不存在了)来实现转发功能。根据 RoBERTa 的论文,我们在每个时间步动态地屏蔽了批次。此外,Huggingface 在这里暴露了预训练的 MLM 头,我们使用如下。

因此,我们代码中的 MLM 流变成了下面这样:

加载 MLM 数据->预处理和索引数据->加载模型->在模型训练的每个步骤中,我们:

1.动态屏蔽批处理

2.计算每个屏蔽令牌的 NLL 损耗

jiant 框架主要使用 AllenNLP 进行词汇创建和索引,以及实例和数据集管理。

我们首先用一个包含 100 个数据集示例的玩具数据集进行测试,以确保 AllenNLP 的加载是正确的。在我们经历了一些非常明显的错误之后,比如一些标签类型与 AllenNLP 不匹配,我们遇到了一个更大的错误。

麻烦的最初迹象

在确保我们的预处理代码与 AllenNLP 一起工作后,我们发现了一个奇怪的 bug。

TypeError: ~ (operator.invert) is only implemented on byte tensors. Traceback (most recent call last):

这是因为我们从 Huggingface 复制粘贴的代码是用旧版本的 Python 编写的,并且是在您需要使用的 Pytorch 中。byte()而不是 bool()。

因此,我们简单地修改了一行,从

indices_replaced = torch.bernoulli(torch.full(labels.shape, 0.8)).bool() & masked_indices

bernoulli_mask = torch.bernoulli(torch.full(labels.shape, 0.8)).to( device=inputs.device, dtype=torch.uint8 )

麻烦来了

现在,我们终于能够运行一个正向函数而不出错了!庆祝了几分钟后,我们开始验证更微妙的错误。我们首先通过调用 model.eval()并通过 MLM 转发函数运行模型来测试我们实现的正确性。因为这个模型,在这个例子中是 RoBERTa-large,已经在 MLM 进行了预训练,我们希望它在 MLM 会有很好的表现。事实并非如此,我们损失惨重。

原因很明显:预测总是与黄金标签相差 2%。例如,如果标记“tail”被分配了索引 25,那么“狗看到零食时摆动它的[面具]”和“[面具]”的标签将是 25,但是预测将是 27。

我们是打了这个错误才发现的。

`/pytorch/aten/src/THCUNN/ClassNLLCriterion.cu:105: void cunn_ClassNLLCriterion_updateOutput_kernel(Dtype *, Dtype *, Dtype *, long *, Dtype *, int, int, int, int, long) [with Dtype = float, Acctype = float]: block: [0,0,0], thread: [19,0,0] Assertion `t >= 0 && t < n_classes` failed.`

这个错误意味着预测空间大于类的数量。

经过大量的 pdb 跟踪,我们意识到我们没有使用 AllenNLP 标记/标签名称空间。在 AllenNLP 中,您可以使用名称空间(如标签名称空间和输入名称空间)跟踪 AllenNLP 词汇对象中需要的所有词汇。我们发现 AllenNLP 词汇对象 a 自动插入 @@PADDING@@和@ @ UNKOWN @ @标记来索引除标签名称空间(所有以“_tag”或“_labels”结尾的名称空间)之外的所有名称空间的 0 和 1 因为我们没有使用标签名称空间,所以我们的索引向前移动了两个,预测空间(由标签词汇大小定义)大了两个!发现这一点后,我们重新命名了标签索引,这种特殊的威胁得到了遏制。

最后一个隐藏的 Bug 和一个支点

到目前为止,我们认为我们已经捕获了所有或者大部分的错误,并且 MLM 工作正常。然而,当模型现在变得越来越不困惑时,一周后,当与第三个人一起查看代码时,我们发现了另一个隐藏的 bug。

if self._unk_id is not None: 
     ids = (ids — 2) * valid_mask + self._pad_id * pad_mask + self._unk_id * unk_mask 
else: 
     ids = (ids — 2) * valid_mask + self._pad_id * pad_mask

在我们几个月前编写的代码的某个单独部分,我们将任何基于 Transformer 的模型的输入向后移动了 2,因为 AllenNLP 将其向前移动了 2。因此,从本质上来说,模型看到的是胡言乱语,因为它看到的是距离正确输入索引两个索引的词汇标记。

我们是如何解决这个问题的?

我们结束了对以前的 bug 的修复,并且没有使用 label 名称空间作为输入,因为所有的东西都向后移动了 2。并且简单地确保动态生成的 mask_idx 在被馈送到模型中之前向前移位 2。为了修复之前预测和标签空间大小不匹配的错误,我们将标签的数量设为预训练模型的标记器的大小,因为这包括该模型预训练的所有词汇。

经过无数个小时的调试和初步实验,我们终于摆脱了 bug。唷!

因此,作为对我们所做的事情的回顾,以确保代码没有错误,也是为了回顾我们所看到的错误类型,这里有一个漂亮的列表。

调试模型的关键要点

  1. 从玩具数据集开始测试。对于本案例研究,预处理整个数据集需要大约 4 个小时。
  2. 如果可能,使用已经创建的基础设施。
  3. 请注意,如果您正在使用其他人的代码,请确保您确切地知道它如何适合您的代码,以及在将外部代码集成到您自己的代码中时可能出现的任何不兼容性,无论是微妙的还是不明显的。
  4. 如果您正在使用预训练的模型,并且如果有意义,请尝试加载一个训练过的模型,并确保它在任务中表现良好。
  5. 注意代码之间 Pytorch 版本(以及其他依赖版本)的差异。
  6. 索引时要非常小心。有时勾画出索引的流程是非常混乱的,会导致很多令人头疼的问题,为什么你的模型执行得不好。
  7. 让其他人也看看你的代码。
  8. 为了理解 bug 的来源,您可能需要更深入地了解这些杂草,并查看用于预处理的包的源代码(如 AllenNLP)。
  9. 创建单元测试来跟踪细微的错误,并确保您不会因为代码更改而依赖这些错误。

现在你有了它,一个调试案例研究和一些教训。我们都在一起进行更好的调试,我知道我远不是模型调试的专家,但是希望这篇文章对你有帮助!特别感谢 Phu Mon Htut 编辑这篇文章。

如果你想看最终的实现,点击这里查看!

如何调试机器学习模型以尽早发现问题

原文:https://towardsdatascience.com/how-to-debug-machine-learning-models-to-catch-issues-early-and-often-5663f2b4383b?source=collection_archive---------12-----------------------

通过更好的数据捕获、实时监控和及时干预,节省机器学习培训的时间和成本

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

Eek!我的神经网络有个 bug!

如果你从事软件开发,你会知道程序错误是生活中的事实。当你开始你的项目时,他们会在那里,当你把你的产品交付给客户时,他们也会在那里。在过去的几十年里,软件开发社区已经开发了大量的工具、ide、库和技术来帮助尽早地、经常地捕捉 bug,因此很少会出现在产品代码中。

不幸的是,机器学习开发人员和数据科学家并不享受传统软件可用的同样健壮的调试工具集。这就是为什么我们很多人在培训脚本中使用打印语句。在集群上运行分布式训练或大规模实验时,问题会变得更糟。您可以保存来自多个工作人员的日志,但是发现问题就像大海捞针一样困难。

在这篇博文中,我将讨论是什么让调试机器学习代码不同于传统软件,以及为什么它要困难得多。然后,我将展示如何使用更好的机制来捕获调试信息、实时监控培训期间的常见问题以及及时干预以防止不良工作浪费资源,从而应对这些挑战。

为了实现这些技术,我将使用 Amazon SageMaker 调试器——一个托管服务和一个用于调试机器学习模型的开源库。通过示例,我将展示如何使用 Amazon SageMaker 调试器和带有 TensorFlow、Keras 和 PyTorch 的 smdebug 开源库(也支持 MXNet 和 XGBoost)来收集训练期间的调试数据,设置规则来监控条件并实时或离线分析数据。

是什么让机器学习调试与众不同?

如果机器学习只是软件,那么只使用传统软件开发可用的相同调试工具不是很有意义吗?毕竟,今天你有很多工具。您可以:

  1. 使用您最喜欢的集成开发环境(IDE ),它允许您放置条件断点并检查中间变量,
  2. 利用特定于语言的编程结构进行异常处理和类型检查
  3. 使用静态代码分析工具来尽早发现错误,并检查是否符合标准
  4. 使用调试器库,如 gdb
  5. 使用记录器和精心选择的打印语句执行记录和跟踪

即使有了所有这些工具,仍然很难找到机器学习的错误,这有几个原因,我在下面描述。

(1)机器学习不仅仅是代码

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

传统软件代码与机器学习代码

让我们考虑一下典型的(简化的)数据科学问题——你有一个数据集和一个问题陈述,你必须建立一个模型来根据数据预测一些事情。然后你衡量它的准确性,如果满意就使用这个模型——例如,部署它,集成到一个更大的软件项目中,出售它等等。

与传统软件相比,机器学习代码有更多的活动部分。存在数据集、模型架构、在训练期间微调的模型权重、优化算法及其参数、在训练期间改变的梯度等等。

在某种意义上,机器学习代码在训练阶段是“动态的”。我的意思是,你的“源代码”本质上是随着你的模型训练而变化或发展的。在训练过程中,模型中的数百万个参数或权重在每一步都在变化。一旦训练完成,它就停止变化,此时您在训练中没有发现的错误现在是模型的一部分。与传统软件形成对比——代码中的逻辑和规则不会在每次运行时改变。可能会有条件分支,但代码仍然是“静态的”,因为不像机器学习训练那样有无限的结果。

调试这种动态的、不断发展的代码需要不同的工具。你需要的是一种方法,通过分析数百万个不断发展的变量来检查训练进度,并在满足某些条件时采取行动。您希望能够监控模型参数、优化参数和指标,以捕捉消失梯度、激活饱和度等问题。

在这个领域缺乏适当的工具是我们许多人使用打印报表和记录器来分析培训的原因。

(2)在机器学习训练期间的监控和干预是困难的

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

调试运行在集群上的代码比调试运行在笔记本电脑或 Amazon EC2 实例上的代码更难

大量的机器学习训练代码运行在集群上,或者至少运行在云中远离你的计算机上。这是因为在进行大规模培训时,短期租用大量具有 GPU 的强大机器更加高效和经济。

那么,如何在集群中运行的代码上设置条件断点呢?

当您的编程范式改变时,您的调试工具和方法也应该改变。当您在集群上运行一个分布式培训任务时,监控进度的主要方法是检测您的代码以生成日志,并将它们保存在一个中心位置以供分析。相反,您需要一种简单的方法来实时监控进度,并在满足特定条件时向您发出警报或采取一些措施。如果你不必修改你的训练脚本,那就更好了。这让我们面临下一个挑战。

(3)调试机器学习代码可能需要大量的重写或转换框架

在其核心,机器学习代码依赖于一系列用 C、C++和 CUDA 等语言编写的高度优化和微调的线性代数子程序。诸如 TensorFlow、PyTorch、MXNet 等更高级别的框架抽象出底层的复杂性,并为您提供一种简单方便的方法来设计和训练您的模型。当你隐藏了复杂性,你就为了易用性而牺牲了控制,调试就变得困难了。

机器学习框架遵循两种不同的哲学——(1)声明性方法,其中您将模型架构定义为图形,该图形被编译、优化,然后被执行(例如 TensorFlow) (2)命令性方法,其中您将模型架构定义为图形,并且它按照定义被执行(例如 PyTorch、TensorFlow eager mode)。在声明式方法中,您无法访问优化的图,因此调试会更加困难。在命令式方法中,调试更容易,但是需要努力在较低的级别检测代码以捕获调试数据,并且在某些情况下需要牺牲性能。

为了更好地调试,您必须编写额外的代码来检测您的训练脚本,或者重写您的代码来支持命令式风格或切换框架。或者更糟,在多个框架上维护相同的副本。所有这些选择都是更多错误的机会。

(4)错误会让您付出代价—基础架构成本,更重要的是,您的时间

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

机器学习会浪费计算和存储资源

大多数机器学习问题可以在训练过程的早期发现。一些常见的问题,比如初始化不好,渐变消失,激活函数饱和,可以而且应该尽早发现,以防止时间和资源的浪费。随着时间的推移,其他问题也会显现出来,比如过度适应或过度训练。早期和晚期发生的问题都会让你付出代价。

早期发生的问题是不可挽救的,并且由于训练运行产生垃圾,导致基础设施资源浪费。如果实践了良好的检查点,后期出现的问题是可以补救的。通过在问题发生时回退到检查点,您仍然可以获得一个好的模型。然而,在问题发生后用于培训的所有资源再次被浪费。

这种浪费会累积起来,耗费你的金钱和时间,尤其是当你有多个团队并行运行多个项目的时候。

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

尽早发现过度合身等问题,并采取措施减少浪费

在随附的图表中,您可以看到一个示例,当模型在 20k 步左右开始过度拟合时,应该停止训练。相反,培训一直持续到大约 40k,花费了您两倍的基础设施成本。诸如此类的问题很常见,因为我们指定了固定数量的时期来运行培训作业,然后出去吃午饭。

在机器学习调试器中寻找什么?

如果传统的软件开发调试工具对机器学习不起作用,你如何着手调试机器学习代码?

以下是一个好的机器学习调试器应该具备的显著特征:

  1. 捕获:调试器必须能够在训练期间捕获模型和优化器的特定信息。用户必须能够指定粒度(频率)和后处理(在张量上应用缩减)来管理调试数据。
  2. 反应:调试器必须能够监控捕获数据的变化并做出反应。用户必须能够指定满足条件时触发的断言规则,例如分解渐变或过度拟合。
  3. 分析:调试器必须允许你在训练期间实时分析捕获的数据。用户还必须能够对捕获的数据进行离线分析。

现在让我们看看如何使用 Amazon SageMaker 调试器来执行这些调试步骤。

使用 Amazon SageMaker 调试器进行调试

Amazon SageMaker Debugger 是 Amazon SageMaker 服务套件的一项新功能,使用它,您可以通过监控、记录和分析捕获训练作业状态的张量数据来全面了解模型训练。有两种方法可以使用它:

  1. **Amazon SageMaker 托管训练:**使用 Amazon SageMaker 训练模型时会自动启用调试器,您不需要对您的训练脚本进行任何更改。只需指定要监控的问题,它就会自动运行监控作业,可以捕捉许多条件,如消失的梯度,爆炸张量,过度拟合和训练期间的其他情况。它还会在训练期间捕捉张量,并将其保存在亚马逊 S3 中,以供实时或离线分析。
  2. **smdebug** **开源库:**对于 DIY 体验,你可以使用开源库对你用 TensorFlow、Keras、PyTorch、MXNet 或 XGBoost 编写的训练脚本进行插装,保存调试信息。然后,您可以在本地设置和运行监控。您可以使用它来调试 Amazon SageMaker 上的定制培训容器,或者在 Amazon SageMaker 上运行缩放之前,在您的笔记本电脑、台式机或 Amazon EC2 实例上本地调试框架。

让我们来看看亚马逊 SageMaker 调试器如何让您能够 (1) 捕获调试数据, (2)对特定调试条件做出反应,并为您提供工具来 (3)分析调试数据。

(1)使用调试器钩子捕获调试数据

机器学习训练期间的大部分繁重工作都发生在优化例程中。非常明确地说,我指的是数值优化例程,如随机梯度下降(SGD),而不是编译器优化。

这些例程负责将您的模型预测与实际值进行比较,计算梯度并更新权重以缩小预测损失的差距。这一步发生在机器学习框架的深处,并负责使用计算的梯度更新数百万个模型参数或权重和偏差。

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

钩子允许你捕获和保存模型和优化变量,如权重,偏差,梯度等。

为了在培训期间捕获这些信息,Amazon SageMaker 调试器可以自动将钩子插入到您的 TensorFlow、Keras、PyTorch、MXNet 或 XGBoost 代码中。当指定一个 SageMaker 调试器钩子时,你可以告诉它在训练期间需要保存什么信息。Amazon SageMaker 调试器支持一个预定义的张量列表,您可以要求它保存这些张量,其中包括权重、偏差、梯度、损失、度量、优化器变量等。如果想要在模型的特定层中捕获特定张量,也可以指定正则表达式字符串。

让我们来看看在使用(1) Amazon SageMaker 和(2) smdebug开源库进行本地调试或在定制容器中使用时,如何指定一个钩子

在 Amazon SageMaker 上使用钩子

如果您使用 Amazon SageMaker 运行培训作业,Amazon SageMaker 调试器会在 TensorFlow、PyTorch、MXNet 和 XGBoost 培训作业容器中自动配置,您不必更改您的培训脚本。

当指定您的培训工作时,您需要做的就是指定一个挂钩配置,如下所示。

在这个例子中,钩子被指定为每save_interval = 100 步节省(1)损失,(2)重量,(3)梯度和(4)偏差。如果您不想保存整个培训期间的信息,也可以提供开始和停止步骤。

当调用 SageMaker TensorFlow 估算器时,使用 Amazon SageMaker Python SDK 只需将钩子传递给debugger_hook_config参数。

如果你是亚马逊 SageMaker 的新手,请观看这个介绍性的网络研讨会,了解如何在亚马逊 SageMaker 上开展培训工作。TL;DR-Amazon sage maker 为您的培训工作提供全面管理的体验。只需提供如上所示的培训脚本,它就会自动提供所需的资源并运行培训。亚马逊 SageMaker 网页上也有大量资源,包括培训、模型调整和部署。

您看到了在 Amazon SageMaker 上运行培训作业时如何使用调试器挂钩。接下来,我们将看到如何使用开源的smdebug库,在你的笔记本电脑、台式机或亚马逊 EC2 机器上本地使用亚马逊 SageMaker 调试器。

通过开源 smdebug 库使用钩子

如果你想在你的训练脚本中加入钩子,你可以使用smdebug库:

  1. 在您的笔记本电脑或台式机上运行您的培训脚本,亚马逊 SageMaker 无法自动为您提供帮助
  2. 运行在 Amazon SageMaker 上,但是您使用了一个定制的容器映像,Amazon SageMaker 不能自动为您放置钩子

如果你是这两种情况中的一种,你可以使用smdebug库来放置钩子,只需要最小的代码修改。我在下面提供了 Keras 和 PyTorch 脚本的例子。

在 Keras 中放置挂钩

使用smdebug库,首先创建一个KerasHook,并指定钩子参数。在这个例子中,我要求KerasHookout_dir保存张量值,在tensorboard_dir保存张量板日志。我想保存的张量是梯度和偏差。我可以扩展这个列表来保存其他值,比如权重、optimizer_variables 等等。在后台KerasHook将配置必要的回调函数来捕获数据。

将吊钩放入 PyTorch

使用smdebug库,创建一个类似于上面 Keras 方法的钩子,然后在 net 变量中用神经网络注册这个钩子。您还可以使用损失函数注册挂钩,以在训练期间捕获损失值。

在你的训练循环中,使用钩子记录特定的张量值,使用hook.record_tensor_value

(2)使用调试器规则对调试数据中的变化做出反应

如果您不能在训练期间实时地对它们采取行动,那么使用钩子保存的调试数据就没有多大用处。这就是调试器规则的用武之地。规则是一段 Python 代码,用于在训练过程中检测特定条件。当规则状态改变时,会触发一个 Amazon CloudWatch 事件,您可以对该事件采取行动,例如停止训练,或者向您发送电子邮件或短信。

Amazon SageMaker 调试器为常见问题提供了几个内置规则,所以你不必为它们编写逻辑。这些包括:死 relu,爆炸张量,差权重初始化,饱和激活,消失梯度,全零,类不平衡,损失不减,过度拟合,过度训练和许多其他问题。如果您正在寻找的规则不在这里,那么您可以使用smdebug库编写一个自定义规则,我们将在下面看到。

对于主动监控培训作业和捕捉问题的规则,它需要作为服务与您的培训作业同时运行。如果你正在使用 Amazon SageMaker 运行培训作业,一个规则容器会自动运行来监控你的培训作业,不需要你做任何操作。

或者,您也可以使用smdebug库在您的笔记本电脑或台式机上本地运行规则。让我们来看看如何做到这两点。

对 Amazon SageMaker 培训工作使用规则

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

如果您使用 Amazon SageMaker 运行培训作业,一个规则作业将自动安排与培训作业一起运行。在训练期间,规则作业获取 Hook 保存的张量(来自 S3 ),并调用规则逻辑。

您可以拥有任意多的规则,系统会自动为您安排一个单独的规则作业。在附图中,我展示了两条规则:损失不减少和消失梯度。每个都将在 Amazon SageMaker 管理的独立容器中运行。

指定培训工作时,请指定挂钩配置,如下所示。

此示例显示了 3 个规则— 2 个内置规则(overtrainingoverfitting)和 1 个自定义规则(CustomGradientRule)

对于CustomGradientRule,您应该指定您希望 SageMaker 使用什么资源来运行规则。在这个例子中,我指定了一个t2.medium实例,它应该足以运行一个实现定制规则的简单 Python 脚本。

在您的 SageMaker 框架估计器函数(例如下面的 TensorFlow 估计器)中,您提供您的规则配置作为规则的参数。这将指示 Amazon SageMaker 不仅启动一个培训作业,还将规则作业,数量相当于您指定的规则数量。在本例中,有 3 条规则。

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

具有规则规范的培训作业将启动一个培训作业和监视该培训作业的规则作业

使用 smdebug 库的规则在本地运行它们

要在培训期间在你的笔记本电脑、台式机或 Amazon EC2 实例上本地运行规则,你需要使用smdebug库指定一个规则。

在下面的例子中,我定义了一个名为CustomGradientRule的规则。您可以通过从 Rule 类派生来定义自定义规则。核心逻辑在invoke_at_step函数中。在这里,我检查梯度的绝对平均值是否大于某个阈值——如果没有指定阈值,则阈值为 10。

为了调用规则,创建一个自定义规则类的对象并调用invoke_rule

输出:

INFO rule_invoker.py:15] Started execution of rule CustomGradientRule at step 0

(3)在训练期间离线或实时分析和可视化调试数据

使用钩子,你可以导出数据,如体重,梯度和其他在训练中,规则让你检查条件,以便你可以采取行动。在某些情况下,您只想分析原始数据并绘制图表,以找到您还不了解的问题。当你这样做的时候,你可以把它转换成一个规则,这样你就可以在下一次训练中抓住它。

有两种可视化结果的方法:

  1. 在 Amazon SageMaker Studio 上使用内置的可视化工具
  2. 在本地笔记本电脑、台式机或 Amazon EC2 实例上进行定制分析和可视化

使用亚马逊 SageMaker Studio 可视化

Amazon SageMaker Studio 建立在熟悉的 Jupyter 笔记本体验的基础上,集成了跟踪实验、可视化训练期间的性能曲线以及比较实验中不同试验的结果的功能。您还可以通过选择由调试器挂钩保存的值来调出自定义图表。

关于如何使用 Amazon SageMaker Studio 图表和可视化以及 Amazon SageMaker 调试器的演示演练,请观看我的 NVIDIA GTC 2020 会议演讲视频:
GTC 2020:使用 Amazon SageMaker 调试器提高 ML 培训性能

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

GTC 2020:利用亚马逊 SageMaker 调试器提高人工智能训练性能

使用 smdebug 库进行本地分析和可视化

为了在本地分析您的数据,您需要使用smdebug库创建一个试验。试用对象可用于查询张量名称、张量值等。

例如,如果您已经使用以下钩子训练了 PyTorch 模型来保存梯度和偏差:

hook = smd.Hook(out_dir=f'./smd_outputs/{job_name}',
               save_config=smd.SaveConfig(save_interval=10),
               include_collections=['gradients', 'biases'])

您可以在训练仍在运行时创建一个试验以进行实时分析:

import smdebug.pytorch as smd
trial = smd.create_trial(path=PATH_TO_S3_OR_LOCAL_DIR')

要查询保存了哪些张量,请运行:

trial.tensor_names()

因为我们要求保存梯度和偏差,所以当你调用 tensor_names 时,你会看到两者。

输出:

[2020-03-30 06:02:17.108 ip-172-31-28-67:31414 INFO local_trial.py:35] Loading trial pytorch-exp03-30-05-53-52 at path ./smd_outputs/pytorch-exp03-30-05-53-52
[8]:
['CrossEntropyLoss_output_0',
 'Net_conv1.bias',
 'Net_conv2.bias',
 'Net_fc1.bias',
 'Net_fc2.bias',
 'Net_fc3.bias',
 'gradient/Net_conv1.bias',
 'gradient/Net_conv1.weight',
 'gradient/Net_conv2.bias',
 'gradient/Net_conv2.weight',
 'gradient/Net_fc1.bias',
 'gradient/Net_fc1.weight',
 'gradient/Net_fc2.bias',
 'gradient/Net_fc2.weight',
 'gradient/Net_fc3.bias',
 'gradient/Net_fc3.weight',
 'loss_output_0']

检索和分析gradient/Net_conv1.bias运行:

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

你会注意到渐变是每 10 步保存一次,这是我们在钩子中指定的。通过循环运行上述命令来查询最近的值,可以在训练期间检索张量。这样,您可以绘制性能曲线,或者随着训练的进行,可视化过滤器权重的变化。看看这个演示如何使用smdebug在训练期间[实时监控课程激活](https://github.com/awslabs/amazon-sagemaker-examples/tree/master/sagemaker debugger/model_specific_realtime_analysis/cnn_class_activation_maps)

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

https://github . com/aw slabs/Amazon-sage maker-examples/tree/master/sage maker debugger/model _ specific _ real time _ analysis/CNN _ class _ activation _ maps

这一切是如何协同工作的

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

端到端 Amazon SageMaker 调试器工作流

让我们快速回顾一下 Amazon SageMaker 调试器如何与 Amazon SageMaker 的培训一起工作:

  1. 您使用 SageMaker Python SDK 和框架(TensorFlow、PyTorch 等)开始了一项 Amazon SageMaker 培训工作。)估计量。
  2. Amazon SageMaker 在指定数量的 CPU 或 GPU 实例上启动了一项培训工作。SageMaker 还将启动规则工作来监控培训工作。
  3. 使用调试钩子配置,Amazon SageMaker 将把权重、偏差和其他张量保存到指定的 S3 位置。
  4. 当挂钩数据可用时,嵌线作业开始运行指定的嵌线逻辑(过度拟合、渐层消失等)。)在他们身上。
  5. 当规则状态发生变化时,会生成一个 CloudWatch 事件,您可以指定一个 CouldWatch 规则来采取诸如停止训练或向您发送文本消息之类的操作。这里是一个当规则被触发时使用 AWS Lambda 停止训练的例子。
  6. 要对调试数据执行实时或离线分析,您可以使用smdebug库通过提供调试数据位置来创建一个试验对象。trail 对象可用于查询张量,您可以绘制它们来分析结果

摘要

调试很难,调试机器学习更难。在这篇文章中,我讨论了如何使用 Amazon SageMaker 调试器来减轻一些机器学习调试的痛苦。这里有 3 种方法可以将 Amazon SageMaker 调试器用于您的机器学习工作流:

  • 在 Amazon SageMaker 上运行培训作业时,您可以将它作为一个完全托管的服务来使用,无需对您的培训脚本进行任何更改。调试规则作业是自动计划和运行的,以检查问题。
  • 你可以使用开源的smdebug库在你的笔记本电脑、台式机或 Amazon EC2 实例上进行本地调试,通过检测你的代码来添加钩子和运行规则。
  • 通过使用 Amazon SageMaker 进行训练,并在本地使用smdebug来运行规则和分析调试张量,您可以在混合设置中使用这两者

因为它非常灵活,还允许您使用自定义规则扩展其功能,并使用正则表达式查询自定义张量。这篇博文中讨论的所有例子,以及一些额外的例子都可以在这里找到:

https://github . com/shashankprasanna/sagemaker-debugger-examples

对于亚马逊 SageMaker 调试器以及亚马逊 SageMaker 工作室演示的视频演练,请查看我在 NVIDIA GTC 2020 上的演讲:

GTC 2020:用亚马逊 SageMaker 调试器提高 ML 训练性能

如果你对这篇文章有疑问,对如何改进它有建议或者对新帖子有想法,请在 twitter ( @shshnkp ), LinkedIn 联系我或者在下面留下评论。尽情享受吧!

如何决定学习速度

原文:https://towardsdatascience.com/how-to-decide-on-learning-rate-6b6996510c98?source=collection_archive---------9-----------------------

使用 PyTorch Lightning 为您的神经网络找到好的 LR

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

用 PyTorch Lightning 为你的神经网络寻找 LR(图片由作者提供)

在机器学习算法中使用的所有超参数中,学习率可能是你最先了解的一个参数。很有可能这也是你开始玩的第一个。通过一点超参数优化,有机会找到最佳值,但这需要大量的实验。那么,为什么不让您的工具来做这件事(更快)?

了解学习速度

对什么是学习率的最简短的解释是,它控制着你的网络(或任何算法)学习的速度。如果你还记得监督学习是如何工作的,你应该熟悉神经网络的概念,它根据监督人的反应来适应问题,例如:

  • 错误类别——对于分类任务,
  • 输出值过低/过高 —用于回归问题。

由于这一点,它可以迭代地给出越来越准确的答案。每当它收到来自主管的反馈时,它就会知道正确的答案应该是什么。而学习率控制了响应于最近的错误(反馈)而改变模型感知的程度。

好的学习率,差的学习率

如果存在我们所寻求的“好的学习率”,“坏的学习”是否也存在?这意味着什么?让我坚持监督学习的概念,讨论一个微不足道的例子:

  • 我们在玩“猜数字”游戏,
  • 每猜错一次,你都会得到一个回应:【太低】或者【太高】

虽然这不是一个真正的神经网络的例子,让我们想象一下如何玩这个游戏,让我们假设这次不是纯粹的随机猜测。

每次你得到反馈时,你是愿意向正确答案迈出一小步还是一大步?虽然这个例子不是真正关于神经网络或机器学习,但这本质上是学习率如何工作的。

现在,想象一下,只迈出很小的一步,每一步都让你更接近正确的数字。这能行吗?当然了。然而,这真的需要一些时间,直到你到达那里。这是小学习率的情况。在机器学习的背景下,LR 太小的模型学习速度会很慢,并且需要更多的迭代来解决问题。有时你可能已经决定在训练结束前停止训练(或者玩猜数字游戏)。

你也可以选择一个太大的值。然后呢?例如,它可能会导致神经网络过多地(并且过于频繁地)改变它的想法。每一个新的样本都会对你的网络信仰产生巨大的影响。这样的训练会高度不稳定。它不再是一个学习缓慢的人,但它可能更糟糕:你的模型可能最终没有学到任何有用的东西。

学习率范围测试

Leslie N. Smith 在 2015 年撰写的论文 《训练神经网络的循环学习率》 引入了一个循环学习率的概念——在训练过程中轮流增加和减少。然而,论文中提到了一件重要的事情,即所谓的“LR 范围测试”(第 3.3 节)。

整个事情相对简单:我们运行一个短的(几个时期)训练会话,其中在两个边界值 min_lrmax_lr之间学习率增加(线性)。在开始时,学习率小,网络将开始慢慢收敛,导致损失值越来越低。在某些时候,学习率会变得太大,导致网络发散。

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

图一。lr_find 方法建议的学习率(图片由作者提供)

如果您绘制损失值与测试学习率的关系图(图 1。),你通常会在最陡下降损失曲线中间的某个地方寻找学习的最佳初始值——这仍然可以让你使用学习速率调度器减少一点 LR。在图 1 中。当损耗在 LR 0.001 和 0.1 之间开始显著下降时,红点表示 PyTorch Lightning 框架选择的最佳值。

在 PyTorch 闪电中寻找 LR

最近 PyTorch Lightning 成为我短期机器学习项目的首选工具。几个月前我第一次使用它,从那以后我一直在使用它。除了所有很酷的东西,它还提供了学习率查找器类,帮助我们找到一个好的学习率。

使用 LR Finder 无非是训练器类中的 auto_lr_find 参数:

现在,当你调用trainer.fit方法时,它在下面执行学习率范围测试,找到一个好的初始学习率,然后直接训练(拟合)你的模型。因此,基本上这一切都是在fit通话中自动发生的,你完全不用担心。

文档中所述,有一种替代方法允许您手动使用 LR Finder 并检查其结果。这一次你必须创建一个默认值为auto_lr_find (False)的Trainer对象,并手动调用lr_find方法:

仅此而已。这种方法的主要优点是,您可以更仔细地查看显示选择了哪个值的图(参见图 1。).

例如:时尚 MNIST 的 LR 搜索器

我决定在时尚 MNIST 数据集上训练一个相当简单的网络架构。我运行了四个独立的实验,它们的不同之处仅在于初始学习率值。其中三个是亲手挑选的(1e-5、1e-4、1e-1),最后一个是 Learning Rate Finder 建议的。整个实现和其他参数我就不描述了(自己看这里)。让我给你看看我的发现。

大概用了 12 秒(!)来找到最佳的初始学习率,对于我的网络和正在解决的问题,结果是 0.0363。看着 loss versusLR 图(完全是图 1 中的图),我很惊讶,因为建议的点并不完全是*“最陡下坡的中途”*(如论文中所述)。然而,我不知道这是好是坏,所以开始训练模型。

为了记录和可视化,我使用 TensorBoard 来记录训练和验证步骤中的损失和准确性。下面您可以看到四个实验中每个实验的指标历史。

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

图二。培训和验证。对于 4 个实验(图片由作者提供)

闪电(浅蓝色)建议的学习率似乎在训练和验证阶段都优于其他值。最后,它在验证集上达到 88,85%的准确率,这是所有实验的最高分(图 2 )。不仅如此,损失函数值显然是“find_lr”实验的最佳值。在最后一个验证步骤中,损失达到 0.3091,这是与图 3 中的其他曲线相比的最低值。

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

图三。4 个实验的训练和验证损失(图片由作者提供)

结论

在这个短暂的实验中,学习率查找器的表现超过了我亲手挑选的学习率。当然,有可能我会选择 0.0363 作为我最初的猜测,但是LR Finder 的整个要点是最小化所有的猜测(除非你是一个幸运的人)。

我认为使用这个功能是有用的,正如莱斯利·n·史密斯所写的:

每当一个人开始一个新的架构或数据集,一个单一的 LR 范围测试提供了良好的 LR 值和良好的范围。那么应该比较具有固定 LR 的运行和具有该范围的 CLR。无论哪一次获胜,都可以放心地用于余下的实验。

如果你不想使用不同的值来执行超参数搜索,这可能需要很长时间,你有两个选择:随机选择初始值(这可能会让你的性能和收敛性非常差,但如果你是一个幸运的人,可能会工作得很好)或使用你选择的机器学习框架中包含的学习率查找器。

你会选哪一个?

如何决定学习什么数据技能

原文:https://towardsdatascience.com/how-to-decide-what-data-skills-to-learn-e456be194137?source=collection_archive---------4-----------------------

获得就业市场上最有价值的技能

如果你用谷歌搜索“如何学习”,你可能会找到至少一门在线课程、youtube 教程、书籍或文章很好地涵盖了它。许多资源甚至是免费的。当决定在哪里学习一项技能时,有许多观点。持有这些观点的人没有尝试过每一个教育产品(甚至可能试图向你推销某些东西),所以很难说什么是最好的资源。说到挑选资源,我没有什么建议,除了 不喜欢就不要坚持。几乎总是有更好的资源可供选择。这里真正的问题是。你打算在谷歌搜索中加入什么技能?

不要按照工作描述去做

好吧,这听起来违背直觉。如果你不知道求职申请上有什么,你将如何吸引雇主?我有两个理由认为求职申请不是一个好的晴雨表。首先,要求的顶级技能包括像 Excel 和 Tableau 这样的东西,对我来说,以这些为主要要求的工作不是真正的数据科学工作。当然,您可能偶尔会将他们用作数据科学家,但这更多是数据分析师、商业智能人员或商业分析师的工作。从本质上来说,各公司对数据科学家和数据分析师的定义并不相同,因此求职应用程序并不是一个有效的衡量标准。

我不使用职位描述的主要原因是,它们通常是由人力资源和/或招聘人员编写的,而不是由你的未来经理编写的。我见过要求 5 年 PyTorch 经验的工作,考虑到它只有 3 年左右的历史,这种经验很难找到。你真的应该排队向不从事数据科学工作的人学习什么吗?我不这么认为。知道什么是有价值的技能的人是其他数据科学家。此外,你很有可能会在某个时候接受一位资深数据科学家的面试。因为他们可能是最难通过的过滤器,你应该优化给数据科学家留下深刻印象,而不是招聘人员。

不要只是做其他数据科学家做的事情

但是我刚刚告诉你要这么做!我建议这些条件。你首先需要拥有每个人都拥有的核心技能。这实际上是指 Python,包括 matplotlib、pandas、sklearn 和 numpy。但是如果你正在读这篇文章,你可能已经知道了。从那以后,我会用下面的图来帮助决定接下来要学什么。该图的数据来自数据科学家的 KDnuggets 调查;询问他们拥有什么技能,想要什么。我在这里提出的观点是,你不能只是问数据科学家他们使用什么工具,然后也学习这些工具。你必须将自己与其他数据科学家区分开来。要做到这一点,你必须学习他们中很少人拥有的技能。更好的是从少数人拥有的技能中挑出最想要的技能。本质上,你需要在这张图的左上方获得技能。

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

KD 掘金投票

我将图的左上方分为 4 个部分,大致排列如下:

  1. 深度学习——学习理论,然后如何在 TensorFlow 或 PyTorch 中实现(选哪个不是超级重要)
  2. NLP——排名比下面两个高,因为工具时好时坏,但是无论你如何实现它,NLP 知识都是有用的
  3. 大数据工具—Hadoop 是利用大数据的一项很好的技能,但大数据绝不仅限于 Hadoop。
  4. 火花

同样,我不知道学习这些技能的最佳方法,我认为其他人也不知道(希望有人有一个令人兴奋的数据集,可以证明我是对的还是错的)。尽管我确实相信这是选择学什么的最佳框架。了解其他数据科学家不知道但希望他们知道的东西,在就业市场上是一个强大的优势。

如何在 Python 中定义自定义异常类

原文:https://towardsdatascience.com/how-to-define-custom-exception-classes-in-python-bfa346629bca?source=collection_archive---------4-----------------------

编写自己的错误类

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

图片由西格蒙德通过 Unsplash 提供

创建自定义错误类

在 Python 中,我们有能力创建自己的异常类。自定义异常类的构造可以丰富我们的类设计。自定义错误类可以记录错误,检查对象。异常类做什么由我们决定,尽管自定义类除了显示一条消息之外通常不会做更多的事情。

当然,类型的错误本身就很重要,我们经常创建自己的错误类型来指示 Python 通常不涵盖的特定情况。这样,遇到错误的类的用户将确切地知道发生了什么。

这篇教程由两部分组成。首先,将孤立地定义一个异常类。第二部分将展示我们如何将定制异常类集成到我们的 Python 程序中,并演示这如何增强我们设计的类的可用性。

自定义异常类 MyCustomError

引发异常时需要 init()和 str()方法

当我们引发一个异常时,我们实际上是在创建一个异常实例并同时打印它。让我们分析一下下面显示的定制异常类。

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

在上面的 MyCustomError 类中,有两个神奇的方法 initstr 会在异常处理过程中自动调用。Init 是创建实例时调用的方法,str 是打印实例时调用的神奇方法。因此,当出现异常时,它们通常会被连续调用。Python 中的 raise 语句将程序置于错误状态。

init 方法的参数列表中有*个参数。*args 是在函数和方法中使用的特殊模式匹配模式。它允许传递多个参数,并将传递的参数存储为一个元组,但也不允许传递任何参数。

在我们的例子中,我们说,如果有任何参数被传递给 MyCustomError 构造函数,我们将获取传递的第一个参数,并将其赋给对象 message 中的一个属性。如果没有传递任何参数,则不会将任何参数分配给消息属性。

在第一个示例中,在没有任何参数的情况下引发了 MyCustomError,因此不会将任何参数设置为对象中的 message 属性。str 方法将被调用,并将打印消息“MyCustomError 消息已引发”。

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

引发 MyCustomError 时,括号中没有任何参数。换句话说,它看起来不像一个标准的对象构造。这只是 Python 在您引发异常时添加的语法帮助

在第二个示例中,使用字符串参数“我们有问题”传递 MyCustomError。这被设置为对象中的消息属性,并在引发异常时打印在错误信息中。

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

MyCustomError 异常类的代码可以在这里找到。

CustomIntFloatDic 类

创建一个只能存储整数和浮点数作为其值的自定义字典

现在让我们继续,演示自定义错误类是如何轻松有效地集成到我们自己的程序中的。首先,我将创建一个略显做作的示例。在这个虚构的例子中,我将创建一个自定义字典,它只能接受整数或浮点数作为它的值。

如果用户试图将任何其他数据类型设置为该字典中的值,将会引发异常。引发的异常将有效地通知用户如何使用字典。在我们的例子中,一条消息明确通知用户在这个自定义字典中只有整数和浮点数可以被设置为值。

我们必须注意,当我们创建自定义字典时,有两个地方可以添加值。第一种是在 init 方法中构造对象时(对象可能已经被赋予了键和值),另一种是在字典中设置键和值时。在这两个地方,我们都需要编写代码来确保值只能是 int 或 float 类型。

首先,我定义了一个名为 CustomIntFloatDict 的类,它继承自内置的 Dict 类。dict 在类名 CustomIntFloatDict 后面括号中的参数列表中传递。

如果创建了 CustomIntFloatDict 的实例,并且没有参数传递给键和值参数,则它们将被设置为 None。if 表达式的计算结果是,如果键为 None 或值为 None,将对对象调用 get_dict()方法,该方法将返回对象的 empty_dict 属性,该属性指向一个空列表。请记住,类属性可用于该类的所有实例。

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

这个类的目的是让用户传递一个列表或元组,其中包含键和值。如果用户为键和值输入一个列表或元组,这两个 iterables 将使用 python zip 函数压缩在一起。指向 zip 对象的压缩变量可以被迭代,元组可以被解包。当我们遍历元组时,我检查 val 是 int 还是 float 类的实例。如果不是,我将引发一个自定义的 IntFloatValueError,并将 val 作为参数传递。

IntFloatValueError 异常类

当我们引发一个 IntFloatValueError 异常时,我们正在创建一个 IntFloatValueError 类的实例并同时打印它。这意味着 init 和 str 魔法方法将被调用。

导致引发异常的值在 IntFloatValueError 类中被设置为名为 value 的属性。当调用 str magic 方法时,会出现一条错误消息,通知用户传递给 CustomIntFloatDict 的 init 的值无效。用户现在将知道他们必须做什么来纠正这个错误。

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

IntFloatValueError 和 KeyValueConstructError 异常类

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

如果没有引发异常,也就是说,如果压缩对象中的每个 val 都是 int 或 float 类型,它们将在字典中使用 setitem()进行设置,dict 父类方法为我们完成这项工作,如下所示。

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

KeyValueConstructError 异常类

如果用户输入的类型不是带有键和值的列表或元组,会发生什么?

同样,这个例子有些做作,但是将展示如何使用定制的异常类。

如果用户没有将键和值指定为列表或元组,将引发 KeyValueConstructError 异常。该异常类的目的是通知用户,为了将键和值获取到 CustomIntFloatDict 对象中,必须为 CustomIntFloatDict 类中的 init 构造函数指定一个列表或元组。

在所示的示例中,一个集合作为第二个参数传递给了 init constrictor,这导致了自定义 KeyValueConstructError 异常的引发。有用的是,显示的错误消息通知用户键和值需要作为列表或元组传递。

当引发异常时,将再次创建 keyvalueconstructor 的实例,并将键和值作为参数传递给 keyvalueconstructor 构造函数。这些属性在 KeyValueConstructError 中被设置为键和值属性,并在 str 方法中用于在打印对象时产生有用的错误信息。

此外,我甚至包括了添加到 init 构造函数中的对象的数据类型,以增强清晰度。

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

在 CustomIntFloatDict 中设置键和值

CustomIntFloatDict 继承自 Dict。这意味着除了我们选择有选择地修改其行为的地方之外,它的行为将与字典完全一样。

setitem 是我们在字典中设置键和值时调用的神奇方法。在我们的 setitem 实现中,我们验证该值是 int 还是 float 类型,然后才能在字典中设置它。如果不是,我们可以再次使用 IntFloatValueError 异常类。在这里,我们可以看到,当我们试图将字符串’ bad_value '设置为字典 test_4 中的一个值时,会引发一个异常。

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

本教程的代码在下面的 Github gist 中显示,可以在这里获得

总结:

自定义异常增强了类的可用性。异常类应该有 init 和 str 魔法方法,在异常处理过程中会自动调用这些方法。我们希望我们的自定义错误类做什么完全取决于我们自己。显示的方法包括检查对象和打印有用的错误消息。在这两种情况下,异常类使得该类的用户在错误发生时更容易处理错误!

如何定义你在数据科学方面的学习路径

原文:https://towardsdatascience.com/how-to-define-your-learning-path-in-data-science-24e722895188?source=collection_archive---------25-----------------------

决定下一步学什么很难。

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

莎伦·麦卡琴在 Unsplash 上的照片

数据科学是一个蓬勃发展的领域,有越来越多的专业和角色需要填补。随着热潮的兴起,有更多的课程、书籍和文章旨在帮助数据科学家学习他们需要的技能,以便更好地工作(或找到工作)。要学的东西太多了。那么,决定你下一步该去哪里的最佳方式是什么呢?

基础

从基础开始写似乎是一件愚蠢的事情。不过,我刚刚开始进入数据科学的旅程。我知道深度学习看起来超级酷,超级性感。但这不是开始的地方。在你尝试学习任何疯狂的东西之前,确保你对基础数学、统计学和计算机编程有坚实的理解。

一旦你对构成我们称之为数据科学的基本概念有了坚实的理解,就有很多不同的选择来决定下一步要学什么。没有完美的方法,你可能选择的每条学习道路都有利弊。

选择 1:把你的学习集中在新的东西上

组织你的学习的一个方法是专注于跟上你所选择领域的最新发展。你可以通过阅读和学习如何实现新的研究论文来做到这一点。对许多人来说,这是最难学习的方法之一,因为它需要你在足够深的层次上阅读和理解研究,以便能够将其翻译成代码。

优点:

专注于最新研究的好处是,你总是知道许多难题的最佳解决方案。它让你有机会从事有趣的项目,并创造出其他人很少(如果有的话)在创造的东西。如果你感兴趣的话,它还会让你做自己的研究。

缺点:

首先,很难阅读研究论文。梳理一篇研究论文并理解研究人员所做的一切需要时间。也很难准确理解这项研究对你正在处理的这类问题有多大用处。我发现许多人不喜欢用这种方式学习,如果你不喜欢学习,你就不会花时间去学。

选择 2:专攻感兴趣的领域

如果你对数据科学的某个特定领域感兴趣,比如自然语言处理、计算机视觉、可解释的机器学习或计算高效的深度学习,那么你就可以一头扎进那个领域。成为你感兴趣的某个领域的专家是一种非常有效的学习方式,它让你很容易知道哪些东西值得学习。

优点:

这种学习方式的好处是你只学习你真正感兴趣的东西。如果你把你的研究集中在一个特定的领域,也更容易成为该领域的专家,让你成为一笔宝贵的财富。

缺点:

成为专家的好处就是成为专家的坏处。把你所有的学习都集中在一个领域会让你处于一个缺乏灵活性的位置。您可能会错过一些更通用的方法可以提供给您的其他有价值的技能。

选项 3:学习一些东西来完成一项工作或项目

专注于学习对你当前工作最有用的东西是决定学习什么的另一个好方法。如果你正在做一个时间序列建模很有价值的项目,你可以开始学习。一旦你完成了这个项目,你就会发现什么主题对你的下一个项目最有帮助。

优点:

这种学习方法帮助你对你所学的东西有一个目标。它给你的学习时间明确的方向和动力。最重要的是,你所学的大部分东西都有一个清晰、直接的回报。

缺点:

我发现在不同的主题之间跳跃往往会在知识上留下一些空白。例如,学习如何在运行中进行图像分类可能会导致您无法理解卷积是如何工作的。有时这些漏洞最终变得微不足道,但有时它们是重要的漏洞,你必须回头去填补。

选项 4:遵循课程

这可以是任何东西,从大学学位,到 MOOC,到一本书。任何一种安排学习内容并提供学习材料的结构化程序。

优点:

这样做的一个巨大好处是它的便利性。你被告知知道什么是重要的,并提供你需要的一切来精通这些技能。大多数情况下,我们会为您提供示例和练习,这样您也可以获得实践经验。

缺点:

不幸的是,并不是所有的课程都是平等的。如果你选择走这条路,你需要考虑你学习课程的地方是否有很好的声誉,是否会提供好的内容。这种方法的另一个缺点是它通常是最昂贵的选择。你可能还会发现,你学到的技能和技术并不总是像在课堂上那样容易应用于现实世界。

选项 5:增加你所提供的价值

这种决定学什么的方式实际上可能适合其他任何一种方式。从职业的角度来看,你正在学习那些能让你变得最有价值的东西。例如,如果你的公司(或你希望为之工作的公司)重视全栈数据科学家,统计学家可能会专注于开发运营方面的学习。

优点:

带着让自己变得更有价值的目的去学习,很可能会带来职业生涯中最大的飞跃。它也可以为新的事物打开许多不同的大门。

缺点:

这有时会导致你去研究你不感兴趣的话题。这使得学习和掌握新材料变得非常困难,并且不能激发继续学习。

结论

在您涵盖了基础知识之后,剩下的选项并不相互排斥。事实上,我认为最好的学习方法是将所有这些东西结合起来。归根结底,最好的学习方法是找到一种你喜欢的学习方法,并坚持下去。

如何在不到 5 分钟的时间内将机器学习模型部署到云中

原文:https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-to-the-cloud-in-less-than-5-minutes-1811fb6aef3e?source=collection_archive---------22-----------------------

使用 Azure 机器学习和 Python 为训练好的 ML 模型创建一个 web 服务

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

西蒙·艾布拉姆斯在 Unsplash 上拍摄的照片

想象以下情况:

你是一名数据科学家,被要求创建一个预测模型。您执行数据探索和清理,选择一个模型,调整它,训练它。经过几次迭代和修复后,您运行了一些性能指标,结果非常好。您认为您在这里的工作已经完成了,但是接下来您被要求将您的模型投入生产。该模型在您的笔记本电脑上运行良好,但他们希望您创建一个用户可以消费的模型,对吗?

数据科学家有时面临的一个问题是,他们的工作似乎与其他人的工作脱节。他们独自工作,修补他们的模型,并产生一些可能与手头问题相关的结果。如果结果确实有用,涉众将希望最好的模型投入生产。然而,在这一点上,模型通常不适合生产。通常,数据、ML 和/或软件工程师团队必须将它们转换成可用的模型,以便进行部署,并可能与一些现有的应用程序或管道集成。

幸运的是,生产一个机器学习模型正变得越来越容易,越来越快,越来越容易被所有人接受。主要的云提供商提供开发机器学习解决方案的专用服务,如微软的 Azure 机器学习,亚马逊的 AWS SageMaker ,或谷歌云 AI 平台。这些服务通过实施面向机器学习的 DevOps(也称为 MLOps)在自动化管道中构建、训练和部署模型,实现了端到端机器学习生命周期的管理。它们都支持流行的框架和编程语言(如 Python、R、scikit-learn、XGBoost、Tensorflow 或 PyTorch),无论人们习惯使用哪种工具,都可以平稳地从本地工作过渡到本地工作。

如果数据科学家不熟悉工程任务,前面提到的数据科学和工程任务之间的脱节可能会有问题。但是随着这些云服务的易用性,这种情况不会再发生了。即使具备云基础设施的一些基础知识和使用这些工具的初步经验,数据科学家也已经能够更好地理解工程师的工作和决策,促进双方的沟通和合作,从而快速跟踪机器学习解决方案的生产。

放弃

对于本教程,我们将使用微软 Azure 及其机器学习服务,以及用于 Python 的 Azure ML SDK。

注意,本文的目的是展示 Azure 机器学习服务的易用性和速度,特别是对于模型部署。因此,在 Azure 中快速部署可以被其他应用程序和用户使用的工作模型所需的代码和解释被减少到最低限度。

然而,要为现实世界的应用程序生产机器学习模型,在部署期间需要考虑几个额外的方面。主要是,部署任务预计将包含在 CI/CD 管道中,但在 Azure 机器学习服务本身中还有进一步的考虑要做。一些例子是在 REST 端点上执行身份验证,或者如果我们希望服务是可伸缩的,则在计算集群而不是单个容器中部署模型。

此外,在信息支持,我们提倡在整个开发生命周期中使用 Azure 机器学习和类似的 MLOps 框架,而不仅仅是在部署期间。在本文中,我决定将重点放在后者上,假设在模型的构建和训练过程中遵循了良好的 MLOps 实践——希望这些可以在以后的文章中涉及到。

我真的可以在不到 5 分钟的时间内部署我的模型吗?

是的,真的。虽然有些操作可能需要几分钟的等待时间(即创建 Azure 机器学习工作区和 web 服务部署),但需要完成的实际工作可以在几分钟内完成。

为了证明这一点,我制作了下面的视频,其中涵盖了执行所有步骤的最快方法(从上传已经训练好的模型到使用已部署的 web 服务):

如果您想更深入地研究这些步骤,或者如果您更喜欢学习如何使用纯代码方法来执行每个步骤,请继续阅读。

我如何部署我的模型?

出发点

正如我前面提到的,我们假设我们已经成功地完成了部署之前的所有步骤:我们已经获得、探索和清理了数据;选择一个模型,并训练它,达到足够好的性能,开始在生产中使用这个模型。

为了便于演示,我们将以一个非常简单的解决方案开始本教程,该解决方案基于 scikit-learn 中直接提供的玩具数据集: 威斯康星州乳腺癌诊断数据库 。我们将建立一个决策树来尝试预测乳腺肿瘤是良性还是恶性的几率。

该数据集包含从其细胞图像中提取的乳房肿块的几个特征的测量值。我们将利用前 4 个可用特征,它们大致对应于乳房肿块的半径、纹理、周长和面积的平均值。

请再次注意,该模型用于演示目的,因此我们不关注算法选择或实际性能。我们的目标是获得任何经过训练的模型,以便在 Azure 机器学习中部署和测试它。

保存模型

假设我们已经在测试分割上运行了一些评估指标,我们对模型的性能感到满意。我们准备让其他用户或外部应用程序可以访问它。但是为了将我们的模型加载到云中,我们首先需要存储它。

经过训练的模型可以通过序列化来存储——也就是 Python 中通常所说的“酸洗”。pickle 一个模型意味着将它转换成一个二进制文件,这个文件可以被存储、复制、移动、传输和最终加载,以便检索原始模型。

这可以通过使用一个名为 pickle 的库来完成。但是,对于用 Python 序列化机器学习模型,经常推荐一个替代库: joblib 。该库支持有效存储和加载可能包含大型数据结构的 Python 对象,这可以从一些机器学习模型中预期。

继续我们之前的脚本,我们可以像这样轻松地序列化和存储我们训练好的模型:

对于文件名,。joblib 或者。bin 是支持的扩展的例子。也可以使用其他扩展(例如。z)用于进一步压缩,如果需要的话。

强烈建议记下用于创建存储模型的 Python 版本和依赖项的版本,因为可能需要它们来反序列化和使用它,同时确保完全兼容。在这种特定情况下,我们确实需要 Python 版本来匹配 Azure 机器学习当前支持的任何 Python 版本,以及在注册我们的模型时指示 scikit-learn 的版本。

安装 Azure ML SDK

可以只使用 Azure 机器学习门户 GUI 在 Azure 机器学习中部署一个已经训练好的模型,而不需要一行额外的代码。然而,在单个容器中部署 web 端点(这是部署模型的最快方式)只能通过代码或命令行来实现。

这就是为什么,在本教程中,我们将使用 Python 的 Azure ML SDK。除了通过 GUI(如果适用)解释程序之外,还将提供用于执行部署的每个步骤的代码片段。

为了安装带有默认包的 Azure ML SDK,我们在本地终端中运行以下命令:

pip install --upgrade azureml-sdk

注意,Azure Machine Learning 在用 Azure ML SDK 开发时使用了交互式 UI 认证。我们第一次使用带有订阅 ID 的 SDK 时,Azure 会提示我们登录我们的订阅帐户。

在 Azure 中创建工作区

我们在仓库里有一个功能模型,太好了!现在我们实际上可以开始钻研 Azure 机器学习了。

假设我们在 Azure 中已经有了一个帐户和一个有效的订阅,我们导航到 Azure 门户并搜索服务>机器学习

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

Azure 门户中的机器学习服务搜索

我们为我们的新工作区命名,并选择我们想要使用的订阅。因为我们假设从头开始一个项目,所以我们将创建一个新的资源组。我们可以选择基础版工作空间版,因为它提供了我们教程所需的所有功能。

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

在 Azure 门户中创建机器学习工作区

也可以使用 Azure ML SDK 直接创建工作空间。使用来自 Workspace 类的 create() 方法,我们可以提供与通过 Azure 门户提供的参数相同的参数:

一旦创建了资源组和工作空间,我们就可以通过 Azure Machine Learning dashboard 在ml.azure.com访问后者。

现在,我们需要获得包含工作区和订阅细节的 JSON 文件。在 Azure ML 门户中,在右上角的导航栏上,我们单击更改订阅>下载配置文件,并将文件放在我们的项目目录中。这个配置文件也可以通过在 Azure 门户中导航到新创建的工作区并在概览页面中点击下载配置文件来下载。一旦这个文件位于我们的项目文件夹中,我们就可以直接从 Python IDE 中部署我们的模型。

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

可下载的 JSON 配置文件的位置

注册模型

要上传并注册我们已经训练好的模型,我们进入左侧菜单的模型部分,点击注册模型。我们命名我们的模型,指出我们用来训练它的框架(在这种情况下,scikit-learn),并可选地为附加元数据编写描述。我们浏览我们的机器,选择并上传我们的序列化模型文件,然后我们点击注册

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

Azure ML 门户中的模型注册

使用 Python 脚本和 Azure ML SDK 也可以快速完成整个过程。我们首先需要使用 from_config() 方法连接到工作区,这将在项目的根目录中搜索我们的配置文件。然后,我们能够通过使用模型类来注册我们训练好的模型。我们可以定义与之前在 GUI 中指示的参数相同的参数:

运行这个脚本后,我们可以返回到 Azure 机器学习门户,并验证我们的模型已经在 Models 部分下注册。

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

Azure ML 门户中注册模型的列表

部署模型

一旦我们的模型被注册,我们就可以按原样部署它了。这意味着我们部署的 web 服务将接受与我们训练的模型相同的输入数据(在这种情况下,四个浮点数的数组表示我们选择的四个特征),并将输出预测(在这里,1 表示良性,0 表示恶性)。

为此,我们在工作区中定位我们注册的模型,并利用来自 Model 类的 deploy() 方法,为我们的 web 服务提供一个名称和指向模型的指针:

通过这样做,我们的模型将被部署在 ACI (Azure 容器实例)中。Azure 机器学习中的 ACI 旨在用于开发和测试目的,因为它们只支持 CPU 上的低规模工作负载。然而,他们可以利用高达 16GB 的 RAM 和 4 个 CPU,这可能足以进行概念验证,甚至足以生产原型模型,这取决于应用程序。

就是这样!我们的 web 服务现在将出现在 Azure 机器学习门户的端点部分下。在那里,我们可以获得其 REST 端点的 URI,并向 API 发送一些测试 POST 请求,以验证部署是否成功。该 web 服务期望的 JSON 格式的输入如下:

{
    "data" : [ <feature-value1>, <feature-value2>, <feature-value3>, <feature-value4> ],
    "method": "predict"
}

注意“数据键的值也可以是包含几个样本的 2D 数组,然后 web 服务将返回所有相应的预测。

使用方法参数,如果我们希望 web 服务输出预测的标签(0 或 1 ),我们可以指定值 predict ,或者如果我们希望获得每个标签的精确概率输出,我们可以指定值 predict_proba

当发送来自分割评估数据集的两个样本时(例如,通过 Postman ,我们看到我们获得了预期的预测(第一个样本对应于良性肿瘤,第二个对应于恶性肿瘤):

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

示例请求通过邮递员发送到我们的模型,部署为 web 服务

因此,我们部署的模型可以被外部应用程序使用。作为如何使用 Python 来使用它的示例,我们发送一个以前的数据示例:

使用自定义条目脚本的替代部署

我们已经看到按原样部署我们的模型是多么容易。然而,根据我们的模型或我们想要构建的应用程序的种类,它可能会受到限制。

当我们使用上面的脚本部署我们的模型时,我们实际上是在一个计算实例中部署它,该实例具有预定义的配置(单个 CPU 内核和 0.5 GB RAM 的 10%使用限制)和具有默认包和框架的环境(确切地说包括 scikit-learn)。

但是如果这个计算目标设置不能为我们的模型提供足够的计算能力呢?或者,如果我们使用默认环境中不包含的某些库,该怎么办?此外,我们可能希望更灵活地定义 web 服务如何与外部用户交互:例如,我们可能需要在将输入数据提供给模型之前对其执行额外的操作,比如规范化输入特性或以某种特定的方式处理缺失值。

我们可以通过两个额外的步骤来完成所有这些:指定一个推理配置(通过为我们的 web 服务和定制环境提供一个入口脚本)和一个部署配置。

参赛脚本(也称为评分脚本)必须包含以下两个功能:

  • 【init():它在托管我们的 web 服务的 Docker 容器启动时运行一次,通常用于将我们注册的模型作为全局对象加载
  • run(input _ data):每次 web 服务收到请求时运行,负责接收输入数据,发送给模型,返回模型的响应

我们模型的简单评分脚本示例如下:

我们的推理配置需要的另一个参数是执行环境。我们可以创建一个环境对象,给它一个名称,并指出我们想要安装的 Conda 或 pip 依赖项。请注意, azureml-defaults 包始终是模型作为 web 服务托管所必需的。

我们现在可以创建部署模型所需的推理配置:

最后,我们定义部署配置。例如,我们可以创建一个具有一个 CPU 内核和 2GB RAM 的计算实例:

我们将两个配置对象都提供给在默认部署期间已经使用的 deploy() 方法:

我们现在可以运行它来部署新的 web 服务,只需提供输入数据就可以向其发送请求:

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

示例请求通过邮递员发送到我们的客户 web 服务

搞定了。接下来呢?

我们的模型已经成功部署在 Azure 中。正如本文开头提到的,我的目标是展示我们使用 Azure 机器学习服务部署模型有多快多容易。然而,如果我们想在现实世界的应用中生产我们的模型,还有很多工作要做。

为了继续深入研究 Azure Machine Learning 必须提供什么,查看来自微软的这个资源库,在那里他们提供了几个关于如何使用 Azure ML SDK 的 Python 笔记本,以及 Azure Machine Learning 的官方文档

此外,如果你对教程的某些步骤有任何疑问,或者如果你在执行代码时遇到任何问题,请随时在下面的评论中问我,或者通过 LinkedIn 问我

如何用 5 个步骤在 Heroku 上部署机器学习 UI

原文:https://towardsdatascience.com/how-to-deploy-a-machine-learning-ui-on-heroku-in-5-steps-b8cd3c9208e6?source=collection_archive---------27-----------------------

Gradio 让你为你的机器学习模型建立一个 UI。Heroku 让你主持。以下是如何一起使用它们。

在本教程中,我将一步一步地向您展示如何在 Heroku 上创建和部署您的机器学习模型和 UI。我将使用我为 Inception Net 模型创建的这个拖放图像界面作为一个例子:

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

您可以在:https://arcane-tundra-83748.herokuapp.com/试用 GUI(dyno 启动可能需要一分钟)

格拉迪欧的作品

我假设你已经对 Gradio 库(https://github.com/gradio-app/gradio)有所了解。如果没有,这个 MNIST 教程是一个开始的好地方。快速概述是:Gradio 是一个 Python 库,它允许您通过指定三件事情来围绕您的机器学习模型创建 ui:Python 函数、输入组件和输出组件。

第一步:创建你的 Gradio 应用

我们将从一个脚本开始,该脚本围绕先启模型创建一个拖放图像界面。创建一个全新的目录,并将下面的代码复制粘贴到一个 python 文件中,我们称之为app.py:

这个脚本中发生的事情是,我们正在使用 Tensorflow Keras 加载 Inception Net 图像分类器。由于这是一个图像分类模型,我们将使用Image输入接口。我们将使用Label输出接口输出一个标签字典和它们相应的置信度得分。(要部署您自己的模型,请用您自己的代码来替换它)。

第二步:编写你的 **requirements.txt** 文件

我们需要确保将所有需要的 Python 库指定为依赖项。所以在与**app.py**相同的目录下创建一个**requirements.txt** 文件。对我来说,那就是:

让包版本在 Heroku 上工作可能有点棘手,但是上面的包和版本对我来说是有效的。重要提示: Heroku 将您的构建大小限制为 500 MB,考虑到 Tensorflow 包的大小,这很容易填满。我建议用 Tensorflow 2.0.0 库,比其他一些版本的库要小一些。

如果您想在本地测试脚本(您应该这样做!),从终端运行:pip install -r requirements.txt安装依赖项,然后python app.py启动 UI。此时,您应该看到您的界面正在localhost:7860(或另一个端口)上运行,如果您在浏览器中导航到该端口,应该会显示您的 GUI!

此 URL 可在本地访问。我们如何与世界分享这些?Gradio 带有一个内置的share参数,可以创建公共 URL,但这些 URL 会在一定时间后过期。为了创建永久的公共链接,我们将使用 Heroku!

Heroku 的作品

要在 Heroku 上部署您的 web 应用程序,您需要有一个 Heroku 帐户,拥有 Heroku CLI 也非常方便。因此,如果你还没有做的话,请继续创建一个 Heroku 帐户下载 CLI

现在,开始部署!

第三步:创建一个 **setup.sh** 文件

为了在 Heroku 上正确部署我们的应用程序,我们需要确保它服务于正确的 URL 和端口。下面的命令可以做到这一点,所以把它们放在一个名为**setup.sh** 的文件中,这个文件和你的应用程序在同一个目录下。

这里发生的事情是,我们告诉 Gradio 在0.0.0.0上提供 UI,特别是使用 Heroku dyno 让世界可见的端口。

第四步:创建一个

现在,我们要创建一个名为**Procfile**的文件(就是它,这个文件没有扩展名!)它的工作是告诉 Heroku 运行什么命令来启动 Gradio 应用程序。只有两个命令:运行我们在上一步创建的 bash 脚本,然后启动我们的应用程序。所以我们的 Heroku **Procfile** 看起来是这样的:

web: source setup.sh && python app.py

如果你想知道为什么我们使用source而不是sh,那是因为我们需要在脚本执行完毕后保存环境变量。

第五步:部署!

此时,您的目录应该如下所示:

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

一个目录中只有 4 个文件——超级简单!

如果您还没有将这些文件添加到 git repo 中,请在您的终端中运行以下命令:

git init
git add -A
git commit -am "commit message here"

我们只需要把这个推到 Heroku dyno 上。首先,让我们通过运行以下命令为我们的应用程序分配一个 Heroku dyno:

heroku create

Heroku 会自动旋转并给你的应用程序分配一个随机的名字。现在,我们把我们的改变推给 Heroku:

git push heroku master

给它几分钟时间在你的 dyno 上安装所有的依赖项。这里可能会遇到依赖性问题,您可以通过阅读错误消息并安装每个库的正确版本来解决这个问题(参见我上面关于 Heroku 大小限制的注释)。如果您没有看到任何错误,那么您应该能够通过运行以下命令打开您的应用程序:

heroku ps:scale web=1
heroku open

最后一个命令将打开您的默认浏览器,并把您带到应用程序。您会注意到网址是自动生成的实例名加上 Heroku 域。

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

就是这样!您有一个可以与任何人分享的实时链接。是时候开始运行一些预测了:)

如何免费部署 Postgres 数据库

原文:https://towardsdatascience.com/how-to-deploy-a-postgres-database-for-free-95cf1d8387bf?source=collection_archive---------6-----------------------

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

凯文·Ku 在 Unsplash 上的图片

数据存储

使用流行的数据库管理系统获得实际经验

PostgreSQL 是世界上最流行的关系数据库管理系统之一,为一些最大的企业提供支持。如果你下载 Postgres,你可能会很恼火地发现你只能把它托管在你机器的 localhost 服务器上,除非你支付一笔经常性的费用把它托管在 AWS 或 Azure 这样的平台上。在本指南中,我将向您展示如何使用 Heroku 免费部署您的数据库,并使用 Python 向其写入数据。

先决条件:

安装最新版本的 Postgres安装 pgadmin4安装 python3 ,pip3 安装 sqlalchemypsycopg2

1:创建你的 Heroku 账户&创建你的第一个应用程序

部署我们免费 Postgres 数据库的第一步是在 Heroku 上创建一个免费账户。Heroku 是一个云平台,你可以在上面部署你的应用和数据库。创建您的帐户并登录后,您应该会看到类似以下内容的控制面板屏幕:

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

你的新帐户不会有我上面列出的任何应用程序。找到并点击“创建新应用”按钮,进入以下页面:

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

为尚未使用的应用程序选择一个名称并创建它。点击“创建应用程序”按钮后,您应该会看到以下页面:

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

你现在有了你的第一个 Heroku 应用程序,让我们添加一个数据库!

2:将 Postgres 数据库添加到您的应用程序中

从你的应用程序的 Heroku 页面点击“资源”标签,查看你的项目拥有的 Dynos 和附加组件的空列表。我们希望将 Heroku Postgres 附加组件附加到您的项目中,因此请单击下图右侧的紫色“查找更多附加组件”按钮:

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

进入 Heroku 附件页面后,在页面右上角的“搜索元素”栏中输入“Heroku Postgres ”:

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

你现在应该已经找到了 Heroku Postgres 的附件,如下图所示。从这里,点击右上角的紫色“安装 Heroku Postgres”按钮,这样我们就可以将其添加到您新创建的应用程序中。

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

在将 Heroku Postgres 附加组件附加到您的项目的最后一页,您可以选择要附加该附加组件的计划和项目。确保你选择了“业余爱好自由发展”计划,这样你就不用为任何事情付费了!之后,搜索您的项目名称,选择它,然后单击紫色的“Provision add-on”按钮。

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

让我们学习如何连接到您的新 Postgres 数据库!

3:在 pgadmin4 中连接到数据库

要连接到您的新数据库,请返回 Heroku 应用程序的“资源”页面。你应该看到附件“Heroku Postgres”。点击下图右下方的“Heroku Postgres”链接,进入数据库管理页面。

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

“数据库概览”页显示了有关数据库的高级信息。最初,您应该没有连接、行或表。数据大小从 7.9 兆字节开始,这说明了与您的数据库相关的程序文件,您永远不需要看到或担心。一旦您添加更多数据,该大小将会增加。在免费计划中,您的数据库中只允许有 20 个连接和 10,000 行数据——这对于个人项目和实验来说非常实用。

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

如果您转到“设置”选项卡,然后单击“查看凭据”按钮,您将能够看到用于连接到数据库的数据库凭据。不要分享这些信息!

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

注意:以上凭证均未激活

现在我们有了数据库凭证,可以连接到 pgadmin。打开您应该已经安装在计算机上的 pgadmin 应用程序,它应该在您的默认浏览器中打开一个窗口,如下所示:

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

在这里,您可以单击 pgadmin 仪表板上的“Add New Server”按钮,并在提示符下输入您的数据库凭据。您不需要角色或服务:

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

注意:以上凭证均不有效

一旦你正确地输入了所有的字段,你可以点击“保存”,应该会看到你的 Postgres 服务器如下所示。这是一个有许多数据库的共享服务器,您只能通过在列表中找到它来访问您的数据库:

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

您现在已经连接到 pgadmin 中的免费 Postgres 数据库了!

4:从数据库中写入和读取数据

在最后一步中,我们将编写 python 代码来创建一个表,并将数据添加到数据库中。我们将首先创建一个 config.py 文件来存储我们的数据库凭证。我们的数据库凭据应该存储在一个单独的文件中,这样我们就可以将该文件添加到我们的。gitignore 在 GitHub 上分享我们的代码,不用担心有人访问我们的数据库。

配置. py

**host** = ec2-34-200-42-57.compute-1.amazonaws.com
**port** = 5432
**database** = dfg5a7fake6perlms
**user** = fdpbgfakeggheshfbv
**password** = a7cb88511fakea656dd5bb175220caa9646defd4f79e62085486b

下面的脚本 create_table.pyconfig.py 位于同一个文件夹中。首先,我们导入所有的配置变量和 sqlalchemy。然后,我们创建一个引擎,它接受所有的配置变量,并使用“ engine.connect() ”将它们连接到数据库。一旦我们连接到数据库,我们就获取数据库的元数据,这样我们就可以在" metadata = MetaData() "行上修改模式。我们已经准备好创建我们的第一个表了!

创建第一个表格

from **sqlalchemy** import *
from **config** import **host**, **port**, **database**, **user**, **password****conn_str** = f"postgresql://{**user**}:{**password**}@{**host**}/{**database**}"
**engine** = create_engine(**conn_str**)
**connection** = **engine**.connect()
**metadata** = MetaData()**first_tb** = Table('first_table', metadata,
   Column('id', Integer, primary_key=True),
   Column('name', String(255), nullable=False),
   Column('isHappy', Boolean, nullable=False)
)**metadata**.create_all(**engine**)
**query** = insert(**first_tb**).values(id=1, name="Student", isHappy=True)
**ResultProxy** = connection.execute(**query**)

在以“ first_table ”开始的行上,我们通过传递表名、元数据和所有列来创建我们的表。对于每一列,我们可以设置名称、类型以及我们希望每一列具有的约束。最后,在“metadata . create _ all(engine)”行上,我们在数据库中创建新表。现在我们的表已经创建好了,我们可以使用 insert() sqlAlchemy 方法创建一个查询,并向它提供表和我们想要添加到该表中的值。最后,我们可以在最后一行执行查询。

回到 pgadmin,我们可以转到:" database _ name "-> " Schemas "-> " public "-> " Tables "。如果你右击“first_table”,你可以选择:“查看/编辑数据”->“所有行”。这将运行一个选择查询,并将我们添加的行返回给您——如下所示!

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

结论

感谢阅读!我很乐意听到你的反馈或回答你的任何问题,所以请在下面评论。如果任何图片或信息不再是最新的,请让我知道!

如何使用 OpenCV 和 Flask 部署预先训练好的 Keras 模型

原文:https://towardsdatascience.com/how-to-deploy-a-pre-trained-keras-model-with-opencv-and-flask-86c9dab76a9c?source=collection_archive---------11-----------------------

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

作者照片

在这篇文章中,我将分享如何使用 Flask、OpenCV 和 Keras 将预训练的模型部署到本地托管的计算机上。我最初使用 Flask、Keras 和 jquery 在 PythonAnywhere 上部署了这个模型。该应用程序是为要求学生或员工剃掉面部毛发的远程学校教室或工作场所设置而设计的。

该应用程序允许用户上传一张照片,然后点击一个按钮将带有编码图像数据的 post 请求发送到网站的后端。图像转换和分类在后端处理,结果在 html 响应中返回到前端。响应动态更新页面,如ShavedUnshaved

该应用程序的后端是在 Flask 中构建的,但我想允许一个实时视频流检测用户的面部,并在屏幕上标记分类。因为我已经有了一个模型和一个基本的 Flask 框架,所以我想在我的本地机器上使用 OpenCV 来完成剩下的工作。

如果你有一个模型,你可以遵循相同的格式,但如果你没有,我会推荐阅读我以前的博客文章(建立一个卷积神经网络来识别剃毛与未剃毛的脸 & 如何分割一个腌制的模型文件以绕过 PythonAnywhere 上的上传限制)。

OpenCV

OpenCV(开源计算机视觉库)是一个开源的计算机视觉和机器学习软件库。OpenCV 旨在为计算机视觉应用提供一个公共基础设施,并加速机器感知在商业产品中的应用。

https://opencv.org/about/

在阅读文档,观看 YouTube 视频和阅读博客帖子后,我发现了一篇非常有帮助的文章,新冠肺炎:使用 TensorFlow 和 OpenCV 的人脸面具检测,作者 Gurucharan M K 。虽然 Gurucharan 使用 OpenCV 来检测新冠肺炎的面具,但我想先使用类似的格式来检测 a 是否有脸,然后确定该脸是否被剃掉。

对我的难题最有帮助的部分是首先检测人脸,这是通过使用人脸检测程序 基于 Haar 特征的级联分类器 来检测人脸特征来完成的。

face_classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

Haar Cascade是一种 机器学习 对象检测算法,用于识别图像或视频中的对象,基于 Paul Viola 和 Michael Jones 在 2001 年发表的论文《使用简单特征的快速对象检测Cascade中提出的特征概念

http://www.willberger.org/cascade-haar-explained/

视频捕捉

video = cv2.VideoCapture(0)

停止视频

video.release()

显示视频

(rval, im) =video.read()

翻转视频

im = cv2.flip(im, 1, 1)

调整视频大小

mini = cv2.resize(im, (im.shape[1] // 4, im.shape[0] // 4))

检测人脸

faces = face_classifier.detectMultiScale(mini)

Flask 是一个用 Python 编写的微型 web 框架。它被归类为微框架,因为它不需要特殊的工具或库。它没有数据库抽象层、表单验证或任何其他组件,而现有的第三方库提供了通用功能。

安摩尔·贝尔有一篇写得很好的文章,题为“使用 Flask 和 OpenCV 的视频流”。根据这篇文章,我能够构建一个 html 网页模板,以及使用计算机内置摄像头将每帧预测的视频流传输到浏览器所需的路径。

html 页面类似于我之前构建的页面,没有 jquery。

下面是我用来显示主页的简单代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Shaved or Not_Shaved </title></head>
  </head>
  <body>
    <center><h1>Shaved or Not_Shaved Streaming App Demo</h1></center>
    <center><img id="bg" src="{{ url_for('video_feed') }}"></center>
    <video id="video" autoplay>Video Stream not available.</video>
  </body>
</html>

为了构建路线,我使用了以下代码来处理页面何时被加载,以及从我们的camera.py文件中提取的摄像机图像,该文件在网站被加载时被初始化。

以下是我在main.py文件中使用的烧瓶代码:

from flask import Flask, render_template, Response
from camera import VideoCameraimport os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
app = Flask(__name__)@app.route('/')
def index():
    # rendering webpage
    return render_template('index.html')def gen(camera):
    while True:
        #get camera frame
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
    # defining server ip address and port
    app.run(host='0.0.0.0',port='5000', debug=True)

克拉斯

Keras 是用 Python 编写的深度学习 API,运行在机器学习平台tensor flow之上。它的开发重点是支持快速实验。能够尽快从想法到结果是做好研究的关键。

【https://keras.io/about/】T5T6

由于 Keras 运行在 TensorFlow 之上,我们可以利用 TensorFlow 模块中的 Graph 和 Session 方法。虽然图和会话的细节超出了本文的范围,但是在部署您的模型以便在预定的会话期间可以访问时,您仍然可以使用下面的代码。

import pickle
from keras import backend as K
from tensorflow import Graph, Sessionglobal loaded_model
graph1 = Graph()
with graph1.as_default():
	session1 = Session(graph=graph1)
	with session1.as_default():
		loaded_model = pickle.load(open('Combined_Model.p', 'rb'))

把这一切结合在一起。

最后一块是我们的camera.py文件。在这个例子中,我们的文件将包含一个函数,将我们的分割模型合并到一个 pickle 文件中。当应用程序加载时,我们将使用一个类摄像机来初始化相机,并将人脸检测程序与我们预先训练的 Keras 模型相结合。

import cv2
import numpy as np
import pickle
from keras import backend as K
from tensorflow import Graph, Session# defining face detector
classifier=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')size = 4labels_dict={0:'shaved',1:'not_shaved'}color_dict={0:(0,255,0),1:(0,0,255)}global loaded_model
graph1 = Graph()
with graph1.as_default():
	session1 = Session(graph=graph1)
	with session1.as_default():
		loaded_model = pickle.load(open('Combined_Model.p', 'rb'))class VideoCamera(object):
    def __init__(self):
        # capturing video
        self.video = cv2.VideoCapture(0) def __del__(self):
        # releasing camera
        self.video.release() def get_frame(self):
        # extracting frames
        (rval, im) = self.video.read()
        im = cv2.flip(im, 1, 1)
        mini = cv2.resize(im, (im.shape[1] // size, im.shape[0] // size))
        faces = classifier.detectMultiScale(mini)
        for f in faces:
            (x, y, w, h) = [v * size for v in f] #Scale the shapesize backup
            #Save just the rectangle faces in SubRecFaces
            face_img = im[y:y+h, x:x+w]
            resized=cv2.resize(face_img,(300,300))
            normalized=resized/255.0
            reshaped=np.reshape(normalized,(1,300,300,3))
            reshaped = np.vstack([reshaped])
            K.set_session(session1)
            with graph1.as_default():
                results=loaded_model.predict(reshaped)
            if results >.5:
                result = np.array([[1]])
            else:
                result = np.array([[0]])
            label = np.argmax(result)
            cv2.rectangle(im,(x,y),(x+w,y+h),color_dict[result[label][0]],2)
            cv2.rectangle(im,(x,y-40),(x+w,y),color_dict[result[label][0]],-1)
            cv2.putText(im, labels_dict[result[label][0]], (x, y-10),cv2.FONT_HERSHEY_SIMPLEX,0.8,(255,255,255),2)
            # encode OpenCV raw frame to jpg and displaying it
        ret, jpeg = cv2.imencode('.jpg', im)
        return jpeg.tobytes()

请注意,此应用程序仅限于您的本地计算机。希望这篇文章有帮助。我很乐意使用Node.jsTensorflow.jsOpenCV.js公开部署这个模型,但是这超出了本文的范围。如果我得到 100 条评论,我会把它作为我的下一篇文章!

以下是我的 GitHub 回购的链接:

https://github.com/cousinskeeta/shavedVnotShaved_opencv

资源:

新冠肺炎:Gurucharan M K使用 TensorFlow 和 OpenCV 的人脸面具检测

Anmol Behl使用 Flask 和 OpenCV 进行视频流传输

如何提取评论分类器模型以重用于实时分类

原文:https://towardsdatascience.com/how-to-deploy-a-review-classifier-in-any-application-c1c0e5a0e8ff?source=collection_archive---------25-----------------------

使分类器可重用简介

有很多教程和例子都是关于用大部分可用数据集训练一个评论分类器,并用剩余部分测试它,看看它的表现如何。

很高兴看到如何建立一个分类器,以及它是如何执行的,但是我们如何导出这个分类器,并在任何应用程序中安装、运行,以便我们可以进行实时检查分类呢?

在本帖中,首先我们将利用欧洲 515,000 条酒店评论数据构建一个评论分类器,并对其进行一些领域调整,使其更加通用,而不是针对特定酒店,然后我们将导出带有特征索引的分类器,以应用于我们选择的任何应用程序。

如果你只对我们如何在其他应用程序中提取和应用分类器感兴趣,你可以去我们有一个分类器,现在做什么?部分。

点击这里下载数据集

酒店数据集调查

我们这里有一个庞大的酒店数据集,它有许多功能,酒店地址,评论日期,平均分数,正面评论,负面评论等等。数据集中的每个条目都来自一个特定酒店的用户。每个用户都被要求对他们住过的酒店提供正面和负面的评价。值得一提的是,在某些情况下,用户只能选择其中之一。当用户未分别提供正面和负面评价时,我们会看到以下特征值:

  • 没有阳性
  • 没有负面影响

在这篇文章中,我们将只关注正面评论和负面评论,而不管哪个用户写了哪个酒店。

预处理

我们需要对数据集做一些预处理。首先,我们将创建一个新的数据集,只获取 1%的原始数据集的正面和负面评论。(在本文中,我们将只使用 5K 个数据条目,但是您可以稍后尝试使用整个数据集进行构建)。然后,我们将清除遗漏的评论(无负面、正面、无等等)。

删除空洞和无价的评论

让我们为项目创建一个文件夹,在该文件夹中找到数据集,然后创建一个新的 python 文件进行预处理。我把它命名为 hotel_review_pre_processor。

首先,我们将导入 pandas 和 numpy,然后加载原始数据集的 1%。

import pandas as pd
import numpy as np# load data
reviews_df = pd.read_csv("Hotel_Reviews.csv")#only get 1 percent of data. because the data is huge
reviews_df = reviews_df.sample(frac = 0.01, replace = False, random_state=42)

然后,让我们创建一个新的空数据框架,其中包含点评和 is_positive 特征,稍后我们将使用酒店数据集中的点评填充这些特征。

df = pd.DataFrame(columns=('review', 'is_positive'))

现在,我们将用空字符串替换数据集中的非正值和非负值,然后用 NaN 替换它们,最后删除它们:

#replace missing review info with empty strings
reviews_df = reviews_df.replace(['No Negative', 'No Positive'], ['', ''])#replace empty strings with NaN value (null) and then drop them.
reviews_df = reviews_df.replace(r'^\s*$', np.nan, regex=True)
reviews_df = reviews_df.dropna()

然后,我们将执行以下操作:

  • 仅从数据集中获取负面评论和正面评论列。
  • 为它们中的每一个创建单独的数据框
  • 对于每个数据框中的每个条目,使用 review 和相应的 is_positive 值(0 表示负面评论,1 表示正面评论)向我们的新数据框(df)添加一个新条目。
  • 然后,我们会将新的数据框保存为 reviews.csv。
#only get reviews.
reviews_df = reviews_df[["Negative_Review", "Positive_Review"]]#separate them
negative_reviews_df = reviews_df[["Negative_Review"]]
positive_reviews_df = reviews_df[["Positive_Review"]]#add all negative and positive reviews with related label 'is_positive' 0 for negative, 1 for positive.
for index, row in negative_reviews_df.iterrows():
    if "nothing" in row["Negative_Review"]:
        pass
    elif "Nothing" in row["Negative_Review"]:
        pass
    else:
        df = df.append({'review': row["Negative_Review"], 'is_positive': 0}, ignore_index=True)for index, row in positive_reviews_df.iterrows():
    if "nothing" in row["Positive_Review"]:
        pass
    elif "Nothing" in row["Positive_Review"]:
        pass
    else:
        df = df.append({'review': row["Positive_Review"], 'is_positive': 1}, ignore_index=True)#save the cleaned data as reviews.csv
endResult = df.to_csv('reviews.csv',index=False)

现在我们完成了预处理。我们将酒店数据集中的评论放入一个名为 reviews.csv 的新数据集中,该数据集中有 review 和 is_positive 功能。现在我们应该有大约 6500 条评论可供我们分析。正如我前面提到的,通过在下面一行中更改 frac 参数,您可以增加或减少您使用的数据集部分:

reviews_df = reviews_df.sample(frac = 0.01, replace = False, random_state=42)

使评论更加通用

现在我们已经处理了这些评论,并将它们重构为一个新的数据集,其中包含了我们感兴趣的特性,但是我们仍然有一个问题。由于原始数据集来自酒店评论,它们很可能包含酒店行业特有的词,如:酒店、床、淋浴、早餐等。如果我们想让我们的分类器以后变得通用,我们需要去掉这样的词。

但是首先,我们将去掉停用词(没有任何上下文含义的词,如:for、the、a、or、what 和 etc ),然后对评论中现有的词进行词干处理以删除重复的词。作为一个例子,当词干分析应用于下面的任何一个单词时,它们都将导致运行

  • (跑步,跑步,跑步)->跑步

继续创建一个名为 review_cleaner.py 的文件。

我们将把它创建为一个单独的类,因为我们稍后将从多个文件中再次需要这个方法:

import nltk
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmerclass ReviewCleaner:
    [@staticmethod](http://twitter.com/staticmethod)
    def clean_review(review):
        review = review.lower()
        review = review.split() ps = PorterStemmer() review = [ps.stem(word) for word in review
                    if not word in set(stopwords.words('english'))] review = ' '.join(review) return review

该方法将如下工作:

  • 接受名为 review 的字符串参数
  • 降低所有字符并拆分单词
  • 对每个单词应用词干并删除任何停用词(如果存在)。
  • 用带词干的单词创建一个名为 review 的新字符串并返回它

如果您曾经得到以下错误:“资源停用词没有找到”,即使您有 nltk 库。打开终端并执行以下命令:

  • python3

-导入 nltk

  • nltk.download(‘停用字词’)

-这应该可以修复错误。

现在,让我们创建一个名为 review _ generifier.py 的文件,并添加以下代码块:

import pandas as pd
import numpy as np
from collections import Counter
from review_cleaner import ReviewCleaner as rcreviews_df = pd.read_csv("reviews.csv")for index, row in reviews_df.iterrows():
    cleared_review = rc.clean_review(row['review'])
    reviews_df.at[index, 'review'] = cleared_reviewmost_common_100_words = Counter(" ".join(reviews_df["review"]).split()).most_common(100)print(most_common_100_words)

请注意,根据您的机器,对数据集中的每个数据条目应用清除需要一段时间。

这里,我们将 ReviewCleaner 类中的 clean_review 方法应用于数据集中可用的每个评论。然后我们打印出出现次数最多的 100 个单词以及出现次数。(为简单起见,仅显示了 20 个):

[('room', 3067), ('staff', 1697), ('locat', 1596), ('hotel', 1499), ('breakfast', 1171), ('good', 1057), ('bed', 831), ('great', 771), ('help', 665), ('clean', 658), ('nice', 637), ('friendli', 636), ('comfort', 540), ('small', 513), ('stay', 478), ('excel', 469), ('bathroom', 393), ('love', 384), ('would', 382), ('could', 358)]

如你所见,有这样的词;房间、员工、酒店、早餐等(你可以在整个打印列表上看到更多)都是酒店行业特有的。如果我们想使它通用,我们不希望这样的词被输入到我们的分类器中。因此,我们现在要删除这些词。

现在,让我们创建一个要从评论中删除的单词列表:

unwanted_words = ['room', 'staff', 'locat', 'hotel', 'breakfast', 'bed', 'shower']

您还可以/应该尝试删除其他单词,看看它是否会影响您的分类器的准确性。

我们需要导入 re 来删除不需要的单词。使用其他导入在文件顶部导入 re,如下所示:

import re

现在,让我们从数据框中删除不需要的单词,如下所示:

reviews_df['review'] = reviews_df['review'].str.replace('|'.join(map(re.escape, unwanted_words)), '')

您可以获取常用单词并在更新数据框后再次打印它们,您应该会看到在 wanted_words 中声明的单词现在已经消失了。

现在,我们将把更新后的数据集保存为 cleared_reviews.csv ,并在末尾添加以下代码:

#save the cleaned data as cleared_reviews.csv
endResult = reviews_df.to_csv('cleared_reviews.csv')

从现在开始,我们将使用 cleared_reviews.csv 数据集:)

用随机森林分类器训练评论分类器

现在我们有了通用数据集,我们可以训练一个随机森林分类器(RFC)【1】模型作为我们的通用分类器。(请注意,审查分类器可以用许多不同的方法实现,我只想用 RFC)。

现在,让我们创建一个新文件 rf_classifier_training.py,并添加以下代码:

import pandas as pd
import numpy as np
import pickle
import jsondataset = pd.read_csv('cleared_reviews.csv')from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(max_features = 1500)
X = cv.fit_transform(dataset["review"].values.astype('U')).toarray()
y = dataset["is_positive"]from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25)from sklearn.ensemble import RandomForestClassifiermodel = RandomForestClassifier(n_estimators = 501,
                            criterion = 'entropy')model.fit(X_train, y_train)
y_pred = model.predict(X_test)print('Score: ', model.score(X_test, y_test))

这里我们训练一个分类器如下:

  • 初始化 CountVectorizer 以从我们的评论中获取 1500 个特征,这里每个特征对应一个词(它选择数据集中出现最多的 1500 个词)。
  • 将数据集拆分为 75%和 25%,分别用于定型和预测。
  • 创建一个 RFC 模型,包含 n 个估计量和标准参数(不同的参数值可以提高性能,如果你愿意可以试试)
  • 训练模型,然后根据测试数据进行预测
  • 最后打印出分类得分的分数。

打印分数应该在 0.90 左右,这意味着每 10 篇评论中,有 9 篇被成功归类为当前标签(正面或负面)。我认为这对 RFC 来说是相当好的,因为我们没有试图优化它的参数。

我们有了一个分类器,现在怎么办?

现在我们有了一个分类器,可以将评论分为正面或负面。但是我们如何提取它,以便在应用程序中对新数据进行分类呢?

为此,我们需要保存我们的模型。但这还不够。因为如果我们对特征(单词)一无所知,我们如何将新数据放入这个模型。更具体地说,我们不知道哪个词在特征空间中有什么索引。因此,我们还将为每个单词找到特征索引,并分别保存它们。

在 rf_classifier_training.py 中打印分数后,立即添加以下代码:

words = cv.vocabulary_
words_for_json = {}for k, v in words.items():
    words_for_json[k] = int(v)pickle.dump(model, open('reviewClassifier.pkl','wb'))
with open('word_feature_space.json', 'w') as fp:
    json.dump(words_for_json, fp)

[word: index]字典保存为 word_feature_space.json 下的 json 键值,分类器模型保存为 reviewClassifier.pkl。

现在再次运行 rf_classifier_training.py 来保存 json 和 pkl 文件。

这些文件不会包含在 github repo 中,因为模型的大小大约为 100 Mb。所以你必须运行 rf_classifier_training.py 来获取这些文件。

编写可以在任何应用程序中使用的分类器服务

现在我们有了模型和 json,我们可以编写一个服务来为任何给定的文本提供分类。

我们的服务如下:

  • 清理收到的审核
  • 用收到的评论创建一个向量
  • 将这个向量拟合到模型中并进行预测
  • 以二进制形式返回预测值(0 =负,1 =正)

让我们创建 review_classifier_service.py,如下所示:

ReviewClassifierService

值得从评论中给出关于向量创建的更多细节,我们检查评论中的每个词,如果它存在于我们的词空间(word_feature_space.json)中,我们将它添加到向量空间并增加字数,但是如果它不存在,我们就简单地丢弃它。

请求

现在,我们将向服务发出一个示例请求,以查看我们的分类器如何处理新数据,让我们创建 example_request.py:

from review_classifier_service import ReviewClassifierServiceservice = ReviewClassifierService()positive_sample = "It was great"
negative_sample = "It was horrible"
print(service.classify(positive_sample))
print(service.classify(negative_sample))

输出是:

{"outcome": 1}
{"outcome": 0}

如您所见,我们的分类器服务可以提供一个 json 响应,值 1 表示肯定,值 0 表示否定。为了简单起见,我在这里没有尝试不同的评论,但是它应该工作得很好,除非你提供一个棘手的评论(一个有许多正面和负面单词的评论=D)。请继续尝试不同的评论。

结论

在本文中,我们看到了如何处理数据以使其有用,如何使数据集更通用,如何构建评论分类器,更重要的是,如何提取该分类器模型并使其能够应用于我们想要的任何应用程序。您可以使用这些或类似的方法来获得您的分类器,然后将它们部署在您的后端,并为许多应用程序和客户端提供服务。

您可以在这里找到完整的存储库

保重:)

在 AWS 上使用 Streamlit 和 Docker 部署机器学习应用程序

原文:https://towardsdatascience.com/how-to-deploy-a-semantic-search-engine-with-streamlit-and-docker-on-aws-elastic-beanstalk-42ddce0422f3?source=collection_archive---------17-----------------------

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

图片由 Kostas Stathoulopoulos 提供

在之前的博客中,我们讨论了如何用句子转换器和 Faiss 构建一个语义搜索引擎。这里,我们将创建一个 Streamlit 应用程序,并在本地和 AWS Elastic Beanstalk 上部署搜索引擎。

如果您想直接进入代码,请查看 GitHub repo!

简化应用程序

Streamlit 是一个开源的 Python 库,可以轻松创建用于机器学习和数据科学的应用程序。使用 Streamlit,您不需要学习 Flask 或任何前端开发,您可以专注于您的应用程序。

我们的应用程序将帮助用户搜索学术文章。用户将在搜索框中键入文本查询,并检索最相关的出版物及其元数据。他们还可以选择返回结果的数量,并根据论文引用数量和出版年份进行筛选。

在幕后,我们将使用句子蒸馏模型对搜索查询进行矢量化,并将其传递到预先构建的 Faiss 索引中进行相似性匹配。Faiss 将测量查询向量和索引纸张向量之间的 L2 距离,并返回与查询最接近的纸张 id 列表。

让我们看看这个应用程序会是什么样子,然后深入研究代码。

建立简化应用的原型

让我们导入所需的 Python 包。

接下来,我们将编写几个函数来加载数据、transformer 模型和 Faiss 索引。我们将使用 Streamlit 的 [@st.cache](https://docs.streamlit.io/en/stable/caching.html) 装饰器来缓存它们,以加速我们的应用程序。

最后,我们将创建应用程序的主体。

让我们一行一行地检查代码:

  • 第 4–6 行:调用上面显示的函数,加载并缓存数据和模型。
  • 第 8 行:设置我们应用的标题。
  • 第 11 行:在页面主体上创建一个多行文本输入小部件。那是我们的搜索框!
  • 第 14–17 行:创建搜索引擎过滤器,并将它们放在侧边栏上。
  • 第 22 行:对给定的文本查询进行语义搜索,并返回最相关结果的论文 id。这些将基于它们与文本查询的相似性来排序。
  • 第 24–28 行:根据发表年份和论文引用次数过滤数据。
  • 第 30–34 行:对于第 22 行中检索到的每个纸张 ID,从过滤后的数据集中提取其元数据。
  • 第 36–43 行:打印论文的元数据,即标题、引文、出版年份和摘要。

将申请归档

我们将使用 Docker 将应用程序及其所有依赖项打包到一个容器中。我们将创建一个Dockerfile,它是一个包含命令(即指令)的文本文档,用来组合一个图像。如果你不熟悉 Docker,本指南提供了深入的介绍

FROM python:3.8-slim-buster
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 8501
ENTRYPOINT ["streamlit","run"]
CMD ["app.py"]

让我们一行一行地解释这个 docker 文件将做什么:

  • 第 1 行:取一个 Python 基图
  • 第二行:将这个 GitHub repo 的内容复制到一个名为/app的目录下
  • 第 3 行:将工作目录更改为/app
  • 第四行 : Pip 安装requirements.txt文件。
  • 第 5 行:让容器在运行时监听 8501 端口。
  • 第 6 行:启动集装箱时执行streamlit run命令。
  • 第 7 行:指定将提供给ENTRYPOINT的参数,在我们的例子中,是应用程序的文件名。

现在,假设 Docker 正在您的机器上运行,我们可以用下面的命令构建映像:

$ docker build -t <USERNAME>/<YOUR_IMAGE_NAME> .

构建命令将创建一个符合Dockerfile规范的图像。现在,我们准备好部署我们的应用程序了!

部署应用程序

本地部署

在本地部署我们的语义搜索引擎非常简单。构建完映像后,我们将使用 run 命令在容器中旋转我们的应用程序。我们还将添加-p参数,以在 8501 发布容器的端口。

$ docker run -p 8501:8501 <USERNAME>/<YOUR_IMAGE_NAME>

您可以通过以下地址访问该应用程序:

http://localhost:8501/

AWS 弹性豆茎展开

为了在 AWS 上部署我们的应用程序,我们需要将我们的图像发布到一个注册中心,云提供商可以访问这个注册中心。为了方便起见,我们还是用 Docker Hub 吧。如果您以前没有推送过图像,客户端可能会要求您登录。提供用于登录 Docker Hub 的相同凭据。请注意,这一步可能需要一段时间,因为我们的图像相当大!

$ docker push <USERNAME>/<YOUR_IMAGE_NAME> .

在公共注册表上发布您的映像并不是强制性的,但是,它通过跳过一些配置步骤简化了部署。

现在,我们几乎可以在 AWS Elastic Beanstalk (EB)上部署我们的映像了。让我们列出步骤:

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

图片由 Kostas Stathoulopoulos 提供

  • 点击创建应用按钮,并命名您的应用。

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

图片由 Kostas Stathoulopoulos 提供

  • 选择 Docker 作为平台。现在,我们需要从本地文件上传我们的代码。因为我们的应用程序是 dockerized 的,所以我们只需要提供容器的细节。我们将通过点击选择文件按钮并上传[Dockerrun.aws.json](https://github.com/kstathou/vector_engine/blob/master/Dockerrun.aws.json) 文件来完成此操作。这是一个特定于 AWS 的文件,它与 EB 共享我们的应用程序的详细信息和 docker 配置。在上传之前,请确保您已经将Dockerrun.aws.json中的图像名称从kstathou/vector_engine更改为您之前使用的<USERNAME>/<YOUR_IMAGE_NAME>。上传文件后,点击配置更多选项。

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

图片由 Kostas Stathoulopoulos 提供

  • 编辑实例产能。从实例开始,将根卷类型更改为通用(SSD) 并将大小更改为 8GB。滚动到页面底部,点击保存。接下来,选择 Capacity 并将实例类型从 t2.micro 更改为 t3.medium。注意,我们选择的 EC2 实例不在空闲层中,您将因使用它而付费。请确保在使用完应用程序后关闭它!

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

图片由 Kostas Stathoulopoulos 提供

  • 点击创建应用程序。EB 将需要几分钟来部署我们的应用程序。一旦完成,你将能够通过它的 URL 访问和分享语义搜索引擎!

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

图片由 Kostas Stathoulopoulos 提供

结论

在本教程中,我向您展示了如何使用 Streamlit 构建应用程序原型,以及如何使用 Docker 在本地和 AWS Elastic Beanstalk 上进行部署。如果你有任何问题,请在评论中告诉我。

代码可以在 GitHub 上找到!

如何免费使用 Heroku 部署电报机器人

原文:https://towardsdatascience.com/how-to-deploy-a-telegram-bot-using-heroku-for-free-9436f89575d2?source=collection_archive---------1-----------------------

使用 python-telegram-bot 库的完整指南

在本地运行你的电报机器人足以满足简单的应用。但是,如果您想要扩展您的 bot 并使其他人能够使用您的 bot,即使您没有在本地运行 bot,您将需要更进一步来部署 bot。

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

伊恩·巴塔格利亚Unsplash 上拍摄

在本教程中,我将介绍如何使用 Heroku 的 python-telegram-bot 库部署您创建的电报机器人。更棒的是,我们可以完全免费地做到这一点!忘掉你从其他主机选项中产生的所有费用,Heroku 将很可能满足你的需求,你不用支付一分钱,也不用输入你的信用卡信息。

为此,我将使用一个取自 python-telegram-bot Github 存储库中示例的简单启动脚本,在该存储库中,bot 只是简单地回应用户发送的任何内容。您可能有不同的脚本,但是我将向您展示要修改哪些部分,以便使用 Heroku 部署 bot。

如果你想直接找到需要的文件,就去这个 Github 库下载吧!

这是我们的起点:

修改 python-telegram-bot 脚本

从轮询更改为 Webhooks

首先,我们将修改机器人获取新数据的方式。python-telegram-bot 脚本使用轮询而不是 webhooks 来获取新数据。对于简单的测试来说,轮询就足够了,因为它很容易实现。然而,轮询的缺点是效率低,而且它获取的数据总是旧的,从来不是实时的。这是因为轮询以预定的频率发送请求以检测数据中的任何变化,这意味着它不断检查数据是否被修改,而不是在数据发生变化时得到“通知”。

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

图片摘自https://community . Stuart . engineering/t/web hooks-vs-polling/257

另一方面,webhooks 的作用类似于推送通知。当数据被修改时,webhooks 被触发,而不是获取信息。这允许实时信息,也使它更有效,因为不需要不断地发送请求来检查数据。

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

图片取自https://community . Stuart . engineering/t/web hooks-vs-polling/257

我们首先导入 os,然后设置端口号来监听 webhook。

import os
PORT = int(os.environ.get('PORT', 5000))

接下来,我们修改下面的代码行

updater.start_polling()

updater.start_webhook(listen="0.0.0.0",
                          port=int(PORT),
                          url_path=TOKEN)
updater.bot.setWebhook('[https://yourherokuappname.herokuapp.com/'](https://yourherokuappname.herokuapp.com/') + TOKEN)

这样做的目的是将轮询方法更改为 webhook,使用上面用 port 变量指定的端口监听 0.0.0.0。令牌指的是你的电报机器人的 API 令牌,应该在代码的顶部定义。下一行是设置带有 heroku 应用程序链接的 Webhook,我们将在下一步讨论。

在对 python 文件进行了所有更改之后,它应该类似于下面这样(使用您自己的 Telegram bot 令牌):

创建 Heroku Webapp —设置目录

我们已经完成了 python-telegram-bot 脚本的编辑,除了更改 heroku 应用程序的名称之外,我们将很快进行更改。为了让 heroku 将以下内容识别为 python 应用程序,您需要将以下文件放在同一个目录中:

bot.py
Procfile
requirements.txt

python 代码应该在 bot.py 文件中,我将完成创建 Procfile 和 requirements.txt 的过程。

首先,将终端/命令提示符的目录更改为包含 python 脚本的目录。然后,创建包含以下行的 requirements.txt 文件:

python-telegram-bot==12.7

这需要告诉 heroku 需要安装哪些库来执行代码。假设你用的是上面的样例代码,你唯一需要的库是 python-telegram-bot,我们用的版本是 12.7。如果要导入其他库来运行 python 代码,请确保在 requirements.txt 文件中也包含其他库。

接下来,您需要一个 Procfile。procfile 以 : 的格式声明进程类型,后跟命令。这里,我们使用 web 进程类型,它从 Heroku 的路由器接收外部 HTTP 流量。命令是 python3 bot.py,它告诉 Heroku 执行 python 文件,就像您通常在本地处理 python 文件一样。因此,您的 Procfile 应该包含这样一行:

web: python3 bot.py

确保 Procfile 没有任何文件扩展名,如。txt 在后面,因为行不通。

创建您的 Heroku Webapp

将这三个文件放在同一个目录中,我们现在将创建 Heroku Webapp。

  1. 登录/ 创建一个 Heroku 账号。
  2. 安装 Heroku CLI 。如果您没有安装 Git,请先安装 Git ,然后再继续使用 Heroku CLI。
  3. 安装后,您可以在终端/命令提示符下使用 heroku 命令。转到 python 文件所在的目录,然后输入:
heroku login

一个新的窗口将在你的浏览器中打开,提示你登录,所以只需点击按钮。

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

4.登录后,返回命令行。输入

heroku create

创建您的新 webapp。在这里,heroku 将为您的 webapp 分配一个名称以及指向您的 webapp 的链接,其格式应该是【https://yourherokuappname.herokuapp.com/.将 URL 粘贴到 bot.py 代码中

updater.bot.setWebhook('[https://yourherokuappname.herokuapp.com/'](https://yourherokuappname.herokuapp.com/') + TOKEN)

对您的 bot.py 文件进行所有更改后,它看起来应该类似于以下内容(当然,使用您自己的 Telegram bot 令牌和 heroku 应用程序名称):

5.接下来,在命令行中输入

git init
git add .
git commit -m "first commit"
heroku git:remote -a YourAppNamegit push heroku master

第一行创建了一个新的 Git 存储库。第二行告诉 Git,您希望在下一次提交中包含对特定文件的更新。然后第三行提交更改。在第四行中,将“YourAppName”更改为 heroku 应用程序的名称。最后,第五行将所有内容推送到服务器。

然后,您应该会看到以下消息:

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

特别是,它会说检测到一个 Python 应用程序,并使用 pip 在 requirements.txt 文件中安装所需的库。然后,它将读取指定要执行 bot.py 文件的 Procfile。

原来如此!一旦它完成执行,你可以简单地去电报和信息/开始你的机器人。它现在应该按照您期望的那样运行。

由于你在 heroku 上使用免费计划,机器人将在 30 分钟不活动后休眠。所以,如果你在使用它超过 30 分钟后才开始使用它,那么你要期待机器人会花几秒钟来响应你的/start。除此之外,机器人几乎会瞬间做出反应~

如果你的机器人停止响应该怎么办

我注意到,在大约 24 小时不活动后,机器人停止响应(因为我们使用的是 Heroku 的免费版本),所以如果您想“唤醒”机器人,一种方法是对其中一个文件进行更改(例如,将 procfile 中的 python3 更改为 python,反之亦然),然后用下面的代码行提交更改:

git add .
git commit -m "changing python3 to python in Procfile"
git push heroku master

您应该再次看到关于 Python 应用程序被检测到的消息,并且一旦它完成执行,您的 bot 现在应该恢复了!

如何在 AWS 上部署气流:最佳实践

原文:https://towardsdatascience.com/how-to-deploy-airflow-on-aws-best-practices-63778d6eab9e?source=collection_archive---------10-----------------------

在 AWS 上部署气流对于没有 DevOps 经验的人,也就是几乎所有从事数据工作的人来说,都是一个相当大的挑战。

TL;DR;

我创建了一个 repo,按照软件工程最佳实践在 AWS 上部署气流。如果你不想读这篇文章,你可以直接去那里。但我确实描述了一些你可能会觉得有用的东西。

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

荷兰 Zaandijk Zaanse Schans|照片由 Wim van 't EindeUnsplash 上拍摄

运行 docker-compose 命令和 voíla,您就有了在本地环境中运行的 Airflow,并且您已经准备好开发一些 Dag 了。一段时间后,您已经为在生产环境中部署 Dag(和气流)做好了准备。然后你开始搜索如何在 AWS 上部署气流的说明。以下是您可能会发现的内容:

  • 没有关于气流文件的说明。
  • 有些帖子,像这个,教你如何在 AWS ECS 上部署。相当有趣的方法。问题是,整个教程都是基于通过在 AWS 控制台上点击来创建资源。相信我;您不希望在生产环境中部署时走这条路。想象一下创建三个不同的环境(开发、试运行和生产)并不得不重复该过程三次的噩梦。现在想象一下更新环境并使它们保持同步。想象一下,你可以很容易地花一整个星期来修复一个错误,这个错误是由一个被错误删除的资源引起的。
  • 另一篇文章相对较新,采用了更好的方法,但它仍然使用 AWS CLI 创建资源(如 ECS 集群)。比控制台上的点击式稍好一点,但仍不能用于生产。
  • 其他文章,可能会提到使用基础设施作为代码,这将解决上述问题。但是,它们在技术细节和实现上都非常肤浅。因此,尽管提供了很好的概述和最佳实践,但对于没有 DevOps 经验的人来说,它们并不实用。
  • GitHub上的这个回购可能是你在遵循软件工程最佳实践的 AWS 上正确实现 Airflow 的最接近的方式。但它仍然缺乏一些基本的东西,如 web 服务器和工作人员的自动缩放,或者配置设置的方法,如 RDS 实例类型,而不必挖掘 Terraform 代码。

你可能会在你的谷歌搜索的第二页上看一下,但是如果一个好的结果没有出现在第一页上,那么这可能意味着它不存在。

入门指南

只需克隆 repo ,遵循一些说明并安装自述文件中描述的要求,然后运行:

make airflow-deploy

这将向您的 AWS 帐户部署一个 Airflow 实例!

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

搞定了。您将在启用自动缩放的 AWS ECS 上部署 Airflow。图片由作者提供,气流用户界面的打印屏幕。

它如何帮助您遵循最佳实践?

service.yml 文件

该回购使用 AWS Cloudformation 实现所有基础设施。在/cloud formation目录中,您将找到创建运行 Airflow 所需的基础设施的所有模板。好的一面是你不需要担心学习 Cloudformation 来做简单的部署,因为在根中有一个service . yml来帮助你。

假设您想要将特定 IP(如您的办公室 IP)列入白名单,以便访问 Airflow UI。您唯一需要做的事情就是修改 service.yml 中的几行代码:

添加要加入白名单的 IP 地址列表。默认情况下,所有服务将对所有 IP 开放(0.0.0.0/0)。

如果你想改变气流数据库实例类型,你也可以去 service.yml :

很容易改变你的气流的元数据数据库引擎版本,更新实例类型等。

你要的只是气流工作者的 CPU 和内存?微调自动缩放? service.yml 是一站式商店。

轻松微调气流服务的自动缩放规则。

在 AWS Secrets Manager 中管理密码

不要硬编码你的密码是软件工程 101。但是有时候,如果没有硬编码,很难在运行时自动部署和创建密码。在这个气流回购中,我们使用 AWS Secrets Manager 来帮助我们解决这个问题。

  • 气流元数据数据库

我们的 Postgres 数据库将保存气流元数据,是需要管理员用户名和密码的资源之一。使用 AWS Secrets Manager,在部署时会创建一个强随机密码,并将其附加到集群。要获得密码值,您必须登录到您的 AWS 帐户,并转到 Secrets Manager。

Cloudformation 代码将为您创建一个强数据库密码。创建数据库时会引用用户名和密码。

也可以用 Secrets Manager 实现自动密码轮换,但是这个项目没有实现。

  • 费尔内键

Airflow 使用 Fernet 密钥对保存在元数据数据库中的密码(如连接凭证)进行加密。该部署在部署时生成一个随机的 Fernet 密钥,并将其添加到 Secrets Manager 中。然后,它在气流容器中作为环境变量被引用。

自动缩放已启用

将气流投入生产的最大挑战之一是处理资源管理。如果出现使用高峰,如何避免 web 服务器崩溃?或者,如果某个特定的日常工作需要更多的 CPU/内存,该怎么办?

自动缩放为您解决了这些问题。在这个存储库中,您可以轻松地配置阈值,并且可以放心,您的基础架构将根据需求进行伸缩。

轻松部署到不同的环境

在生产设置中,您会希望将代码部署到不同的环境中。假设你需要:制作,舞台和开发。

这个 repo 允许您通过更改一个环境变量将相同的代码部署到不同的环境中,这可以在您的 CI/CD 管道上自动推断出来。要改变环境,请执行以下操作:

***export ENVIRONMENT=dev; # this will deploy airflow to dev environment
make airflow-deploy;***

更新 Dag 而不触及基础架构

Airflow 的美妙之处在于能够将工作流写成代码。这意味着您更改 DAGs 代码的频率要比更改基础设施的频率高得多。通过这种气流部署,您将向 Dag 提交更改,它不会尝试为您重新部署基础架构。

您唯一想做的事情是构建一个新的气流图像,将其推送到 ECR,然后更新您的 ECS 服务以加载最新的图像。为此,只需运行:

***make airflow-push-image;***

这里的情况并非如此,但是您甚至可以将 Dag 放在单独的存储库中。这将使基础设施与软件更加分离。

标记您的资源

标记资源将使我们能够轻松地创建自动警报、确定所有权和跟踪基础架构成本。这就是为什么这个气流储存库会标记所有资源。

当在云上运行多个服务时,标记资源是一个关键的实践。

你这边应该怎么做?

您应该将部署流程添加到 CI/CD 管道中。为了运行一些自动化测试,我使用 GitHub Actions(但是您的公司可能使用其他工具,如 CircleCI 或 Jenkins)。

您可以遵循类似的过程来自动化您的部署和测试。看看测试工作流程来获得一些灵感。

这要花多少钱?

在采用默认配置的 AWS 上运行气流(同时考虑到集群没有纵向扩展)每天应该花费 5 到 7 美元。这取决于您正在部署的区域。

通过降低 service.yml 上的 CPU 和内存以及改变工人的最小数量,可以进一步降低成本。默认设置将允许气流在需要增加资源之前运行相当多的 Dag。微调并找到最适合您的用例的方法。

我希望这篇文章(和资源库)能帮助你轻松地生产气流。如果您有任何问题、建议或要求,请通过 LinkedIn 联系我,或在回购上打开问题。此外,欢迎您打开 PRs 并与该项目合作!

如何使用脸书先知机器学习模型将自动交易机器人部署到 AWS Lambda(无服务器)

原文:https://towardsdatascience.com/how-to-deploy-an-automated-trading-bot-using-the-facebook-prophet-machine-learning-model-to-aws-1182c603e280?source=collection_archive---------35-----------------------

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

AWS Lambda“设计者”这篇文章的算法概述

在这篇文章中,我将介绍我的无服务器投资算法,使用 AWS Lambda,脸书先知作为 ML 模型,以及我的自定义 Lambda 层。

我把这篇文章分为“我为什么要这么做”和“技术方法”两部分。如果你想跳过“为什么”的部分,可以直接跳到技术部分。

我为什么要在 AWS Lambda 中部署机器学习模型?

**1。可靠性:**算法将独立于其他系统、更新、…

**2。性能效率:**我可以在一个(小)系统上运行几个算法,彼此独立。

3。成本节约: AWS 允许每月320 万计算秒,基本上让我免费运行我所有的算法。

我一直在寻找一种方法,首先确保我的投资机器人肯定会执行,因为如果交易方向错误,没有及时取消,失败的执行可能会花费很多钱。此外,我想避免让我的计算机一直运行,并确保几个算法可以彼此相邻运行,而不会影响或延迟它们的执行。

此外,让一个投资算法运行而不用担心操作系统更新、硬件故障和断电等,这是一个很好的想法,这是无服务器技术的一般优势。

现在,我可以运行算法的几个变体来测试算法的变化,并且可以确定它将运行。另一件好事?AWS 提供了大约 100 万次免费的 Lambda 调用,这让我可以在其免费层中运行整个架构。

投资算法

我将在我的网站 www.datafortress.cloud 上的另一篇文章中更深入地解释该算法,但我的典型投资算法设置包括:

  1. 使用用 python 编写的开源回溯测试框架 Backtrader 测试算法
  2. 将成功的算法转换成包含 run()方法的单个 python 文件,该方法返回已经完成的投资
  3. 将 python 文件传输到 AWS Lambda,在这里我用 AWS Lambda 的 lambda_handler 函数调用 run()函数

在这个示例算法中,我根据当前价格是高于还是低于由脸书的先知模型预测的趋势线来做出投资决定。我从肖恩·凯利那里得到了灵感,他写了一个关于如何利用预言家和反向交易者的反向交易者设置。

在这个设置中,我的股票范围是通过从 SPY500 指数中选择在过去 X 个时间步中获得最高回报的前 20 只股票来计算的。

数据来源是雅虎财经,使用的是免费的 yfinance 库,作为我选择的算法经纪人,我选择了羊驼网

在我的设置中,算法将在每天下午 3 点执行一次,或者在交易时间每 15 分钟执行一次。

将脸书先知部署到 AWS Lambda 时遇到的问题

AWS Lambda 预装了一些 python 库,但正如许多人可能知道的那样,这在默认情况下是非常有限的(这对 Lambda 的承诺来说是合理的)。尽管如此,Lambda 允许安装私有包,这对于较小的包来说非常容易(参见官方文档),但是如果处理大小超过 250 Mb 的包,就变得有点复杂了。不幸的是,脸书的 prophet 模型超出了这个界限,但幸运的是亚历山大·巴甫洛夫·马采诺夫通过减少包的大小解决了这个问题,而马克·梅斯处理了编译问题,使其可以在 AWS Lambda 上运行。

通过使用层,可以将非默认库添加到 AWS Lambda 中,层包含所有需要的包。如果导入了某个图层,您可以像在本地设置中一样,在 python 函数中导入包。

如何(技术)

最后,让我来解释一下你到底是如何做到这一点的。不耐烦的人可以看看这个 TLDR,或者下面更详细的版本。

TLDR;

  1. 你将需要一个 Lambda 层,上传我的(下载)包含先知,金融,…到一个 S3 桶(私人访问)
  2. 选择 AWS Lambda,创建一个函数,添加一个层,然后粘贴到您的 S3 对象 URL 中
  3. 将你的 lambda_function.py 粘贴到 lambda 编辑器中(或使用我的)
  4. 设置环境变量(可选)
  5. 要么通过单击“测试”手动运行它,要么前往 CloudWatch -> Rules -> Create Rule 并设置“计划执行”以在指定的时间间隔运行它

详解:

1.为 AWS Lambda 创建自定义层

你可以使用我的 Lambda 层,其中包含脸书先知、NumPy、熊猫、羊驼-交易-API 、yfinance ( GitHub )或者使用 Marc 给出的解释来编译你自己的层。

使用我的 Lambda 图层

  1. 从我的 Github repo 下载包含所有包的 zip 文件(链接)。
  2. 由于你只能直接上传层到 Lambda 直到 50 Mb 的大小,我们将首先需要上传文件到 AWS S3。
  3. 创建一个 bucket 并将下载的 zip 文件放入其中。访问可以保持私密,不需要公开!将 URL 复制到您的文件中(例如https://BUCKETNAME.s3.REGION.amazonaws.com/python.zip)。
  4. 登录 AWS,进入 Lambda-> Layers(EU central Link)。
  5. 点击“创建层”,给它一个匹配的名称,并选择“从亚马逊 S3 上传文件”,并复制第 3 步的代码到其中。运行时选择 Python 3.7。单击创建。

编译自己的 Lambda 图层

遵循 Marc 的指示。

2.设置 AWS Lambda 函数

  1. 打开 Lambda 功能仪表板( EU central Link )并点击“创建功能”
  2. 保留“从头开始创作”复选框,并给它一个合适的名称。
  3. 在“运行时”中,选择 Python 3.7,其余保持不变,点击“创建函数”。
  4. 在“设计器”选项卡的概述中,您将看到 Lambda 函数的图形表示。点击它下面的“图层”框,点击“添加图层”。如果你正确地设置了层,你将能够在下面的对话框中选择它。最后,点击“添加”。
  5. 在“设计器”标签中,选择你的 Lambda 函数。如果向下滚动,您将看到一个名为“lambda_function.py”的文件中的默认 python 代码片段。如果你的代码结构和我的一样( Link ),你可以用 run()函数执行你的函数。如果一个 Lambda 函数被调用,它将执行 lambda_handler(事件,上下文)函数,你可以从这个函数调用 run()函数。当然,您可以重命名所有的文件和函数,但是为了这个项目的简单性,我让它保持原样。
  6. 请随意粘贴我的功能并测试它。
  7. 单击“Test”应该会成功执行,否则,它会在对话框中显示错误。

3.在 AWS Lambda 中使用环境变量

你不应该在你的代码中把你的用户和密码留为明文,这就是为什么你应该总是使用环境变量!幸运的是,Lambda 也使用它们,并且可以很容易地用 python os 包调用它们。例如,在我的脚本中,我使用 os.environ[‘ALPACAUSER’]调用用户变量。当向下滚动到代码编辑器下方时,可以在 Lambda 函数主屏幕中设置环境变量。

4.在指定的时间间隔触发 AWS Lambda 函数

无服务器和 AWS Lambda 的概念是建立在当触发事件发生时执行一个功能的思想上的。在我的设置中,我希望在交易时间(周一至周五)每隔 15 分钟调用一次该函数。幸运的是,AWS 使用 CloudWatch 服务提供了一种无需运行服务器就能触发事件的方法。

  1. 前往 CloudWatch ( 欧盟中央联系)。
  2. 在左侧面板中,选择“事件”和“规则”。
  3. 点击“创建规则”,并选择“时间表”而不是“事件模式”。在这里,您可以使用简单的“固定比率”对话,或者创建一个 cron 表达式。我正在使用https://crontab.guru/(免费)来创建 cron 表达式。我对上述用例的 cron 表达式是“0/15 13–21?周一至周五"。
  4. 在右侧面板中,选择“添加目标”并选择您的 Lambda 函数。它将自动添加到 Lambda 中。
  5. 最后点击“配置细节”,给它一个名字,然后点击“创建规则”。

5.(可选)日志分析、错误搜索

如果你做到了这一步,你就应该完成了!但是如果你想检查一切是否正常,你可以使用 CloudWatch 来查看 Lambda 函数的输出。前往 cloud watch-> Logs-> Log groups(EU central Link)并选择您的 Lambda 函数。在这个概述中,您应该能够看到函数的输出。

如果你喜欢这篇文章,请留下评论或者到我的博客 www.datafortress.cloud 来激励我😊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值