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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

在 Binder 和 Google Colab 上渲染 OpenAI 健身房环境

原文:https://towardsdatascience.com/rendering-openai-gym-envs-on-binder-and-google-colab-536f99391cc7?source=collection_archive---------18-----------------------

关于解决一个乏味(但重要)问题的笔记

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

在 Google Colab 或 Binder 中远程渲染 OpenAI envs 很容易(一旦你知道了配方!).

我目前正在使用我的新冠肺炎强制隔离来扩展我的深度学习技能,完成了来自 Udacity深度强化学习纳米学位 。当在远程服务器上训练时,我几乎立刻就遇到了让我的模拟正确渲染的乏味问题。

特别是,让 OpenAI Gym 环境在远程服务器上正确渲染,比如那些支持流行的免费计算设施的服务器,如 Google ColabBinder 比我预期的更具挑战性。在这篇文章中,我列出了我的解决方案,希望我可以节省其他人的时间和精力来独立解决这个问题。

Google Colab 序言

如果你希望使用 Google Colab,那么这个部分就是为你准备的!否则,您可以跳到活页夹前言的下一节。

安装 X11 系统依赖项

首先,您需要安装必要的 X11 依赖项,特别是 Xvfb ,它是一个可以在没有显示硬件和物理输入设备的机器上运行的 X 服务器。您可以在 Colab 笔记本中安装系统依赖项,方法是在 install 命令前面加上一个感叹号(!),它将在自己的 Bash shell 中运行该命令。

**!**apt-get install -y xvfb x11-utils

安装其他 Python 依赖项

现在您已经安装了 Xvfb,您需要安装一个 Python 包装器pyvirtualdisplay,以便在 Python 中与 Xvfb 虚拟显示交互。你还需要为 OpenGL : PyOpenGLPyOpenGL-accelerate 安装 Python 绑定。前者是实际的 Python 绑定,后者是一组可选的 C (Cython)扩展,为 PyOpenGL 3.x 中的常见操作提供加速。

**!**pip install pyvirtualdisplay**==**0.2.* \
             PyOpenGL**==**3.1.* \
             PyOpenGL-accelerate**==**3.1.*

安装开放式健身房

接下来,你需要安装 OpenAI 健身房包。请注意,根据您感兴趣的健身房环境,您可能需要添加额外的依赖项。因为我要在下面的演示中模拟 LunarLander-v2 环境,所以我需要安装box2d extra 来启用依赖于 Box2D 物理模拟器的健身房环境。

**!**pip install gym**[**box2d**]==**0.17.*

为了简单起见,我将所有的软件安装步骤收集到一个代码块中,您可以将其剪切并粘贴到您的笔记本中。

%%bash*# install required system dependencies*
apt-get install -y xvfb x11-utils*# install required python dependencies*
pip install gym**[**box2d**]==**0.17.* \
            *pyvirtualdisplay***==**0.2.* \
            *PyOpenGL***==**3.1.* \
            PyOpenGL-accelerate**==**3.1.*

在背景中创建虚拟显示

现在已经安装了所有需要的软件,您可以创建一个虚拟显示器(即在后台运行的显示器),OpenAI Gym Envs 可以连接到该显示器进行渲染。您可以通过确认DISPLAY环境变量的值还没有被设置来检查当前是否没有显示。

**!***echo* *$DISPLAY*

下面单元格中的代码在背景中创建了一个虚拟显示,您的健身房 env 可以连接到该显示进行渲染。您可以随意调整虚拟缓冲区的size,但在使用 Xvfb 时必须设置visible=False

这个代码只需要在你的笔记本上运行一次就可以开始显示。

使用 pyvirtualdisplay 启动 Xvfb 虚拟显示

在笔记本上运行上述代码后,您可以再次回显环境变量DISPLAY的值,以确认您现在有一个正在运行的显示。

**!***echo* *$DISPLAY # should now be set to some value*

为了方便起见,我将上述步骤收集到两个单元格中,您可以复制并粘贴到您的 Google Colab 笔记本的顶部。

活页夹序言

如果您希望使用活页夹,那么这一部分就是为您准备的!

不需要额外安装!

不像 Google Colab,使用 Binder 你可以烘焙所有需要的依赖项(包括 X11 系统依赖项!)放入绑定器实例所基于的 Docker 映像中。这些配置文件可以位于 Git repo 的根目录中,也可以位于一个binder子目录中(这是我的首选)。

binder/apt.txt

需要定义的第一个配置文件是用于安装系统依赖项的apt.txt文件。您可以创建一个适当命名的文件,然后列出您想要安装的依赖项(每行一个)。经过一段时间的反复试验,我发现了下面的成功组合。

freeglut3-dev
xvfb
x11-utils

binder/environment.yml

第二个配置文件是用于定义 Conda 环境的标准environment.yml文件。如果你对 Conda 不熟悉,那么我建议你看看我最近写的关于Conda使用 Conda 管理特定项目环境的文章。

*name: null channels:
  - conda-forge
  - defaults dependencies:
  - gym-box2d=0.17
  - jupyterlab=2.0
  - matplotlib=3.2
  - pip=20.0
  - pip:
    - -r file:requirements.txt
  - python=3.7
  - pyvirtualdisplay=0.2*

binder/requirements.txt

最后需要的配置文件是 Conda 使用的requirements.txt文件,用于安装任何额外的 Python 依赖项,这些依赖项不能通过使用pip的 Conda 通道获得。

*PyOpenGL==3.1.*
PyOpenGL-accelerate==3.1.**

如果你有兴趣学习更多关于 Binder 的知识,那就去看看 BinderHub 的文档,这是 Binder 项目背后的底层技术。

在背景中创建虚拟显示

接下来,您需要在背景中创建一个虚拟显示器,健身房 env 可以连接到该显示器进行渲染。您可以通过确认DISPLAY环境变量的值尚未设置来检查当前是否没有显示。

***!***echo* *$DISPLAY**

下面单元格中的代码在背景中创建了一个虚拟显示,您的健身房 env 可以连接到该显示进行渲染。您可以随意调整虚拟缓冲区的size,但在使用 Xvfb 时必须设置visible=False

这段代码只需要在每个会话中运行一次就可以开始显示。

启动 Xvfb 虚拟显示与使用 Google Colab 完全一样!

运行上面的单元格后,您可以再次回显DISPLAY环境变量的值,以确认您现在有一个正在运行的显示。

***!***echo* *$DISPLAY**

演示

只是为了证明上面的设置像宣传的那样有效,我将运行一个简短的模拟。首先我定义了一个Agent,它从一组可能的动作中随机选择一个动作,然后定义一个函数,它可以用来创建这样的代理。然后我将代码打包,模拟一个开放的人工智能健身房环境中的一集。注意,实现假设所提供的环境支持rgb_array渲染(不是所有的健身房环境都支持!).

模拟“代理”与支持 RGB 数组渲染的 OpenAI Gym 环境交互

目前,在模拟过程中似乎有相当数量的闪烁。不完全确定是什么导致了这种不良行为。如果你有任何改进的想法,请在下面留下评论。如果我找到一个好的解决方法,我一定会相应地更新这篇文章。

使用 Python 渲染视频文本

原文:https://towardsdatascience.com/rendering-text-on-video-using-python-1c006519c0aa?source=collection_archive---------6-----------------------

使用 moviePy 库的动手机器学习项目

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

雅各布·欧文斯在 Unsplash 上的照片

在这篇文章中,我将向你展示如何使用 Python 向你的视频添加文本。乍一看,这听起来很难,但是相信我,这比你想象的要容易得多,而且很酷。这将是一个简单的练习,我们将能够看到机器学习如何在现实生活中使用。如果你看看我的其他文章,你会发现我喜欢动手做项目。我觉得这是练习我们编码技能,提升自己的最好方式。当你做一点研究时,你会在网上找到一些项目想法。但是我强烈建议你自己进行头脑风暴,写下你个人的项目想法,然后开始研究如何实现它们。让我们回到我们的项目。

目录

  • 入门
  • 第一步:导入库
  • 第二步:定义你的视频
  • 第三步:创建你的文本
  • 最后一步:在视频上渲染文字

入门指南

正如你可以理解的标题,这个项目,我们将需要一个视频记录文件。它甚至可以是你对着镜头说话的录音。使用名为 *MoviePy,*的库,我们将向视频记录中添加文本。

首先,我们将导入库,我将向您展示如何安装它们。在第二步中,我们将定义我们将用于项目的视频,它可以是一个短视频。在第三步中,我们将定义一个文本变量,它将是添加到视频中的文本。最后,我们将渲染视频记录上的文本。如果您准备好了,让我们从安装库开始吧!

图书馆

我们将为这个项目使用一个库,但要进行文本渲染,我们还需要安装另一个模块。该库名为 MoviePy,安装方法如下:

pip install moviepy

你可以从官方文档页面了解更多关于 moviepy 的信息。

我们需要安装的第二个模块叫做 ImageMagick。如果没有此模块,您可能会在将文本渲染到视频录制时出现错误。为了安装 ImageMagick,我使用了 Homebrew,这是一个用于 macOs 和 Linux 设备的软件包管理器。如果您使用不同的操作系统,可以在线搜索“如何安装 ImageMagick”。

brew install imagemagick

你可以从官方的文档页面了解更多关于 imagemagick 的信息。

MoviePy 是一个可以读写所有最常见的音频和视频格式的库,包括 GIF。如果您在安装 MoviePy 库时遇到问题,请尝试安装 ffmpeg。Ffmpeg 是一个领先的多媒体框架,能够解码、编码、转码、复用、解复用、流式传输、过滤和播放人类和机器创造的几乎任何东西。

现在,我们应该开始在代码编辑器中编写代码了。我们将从导入库开始。

步骤 1-导入库

import moviepy.editor as mp

是的,这就是我们完成任务所需要的。抓紧时间,让我们进入下一步。

第二步——定义你的视频

在这一步,我们将定义一个名为“my_video”的变量。然后使用 moviepy 库的特殊方法,我们将定义我们的视频文件。此外,我想保留视频的音频,这就是为什么视频的值为 True。

my_video = mp.VideoFileClip(“data/video_test.mov”, audio=True)

顺便说一下,有许多视频格式,其中一些可以被列为:

  • MP4 (mp4、m4a、m4v、f4v、f4a、m4b、m4r、f4b、mov)
  • 3GP (3gp、3gpp2、3g2、3gpp、3gpp 2)
  • OGG (ogg、oga、ogv、ogx)
  • WMV (wmv、wma、asf*)

请确保您的路径正确,并且您的视频格式工作正常。如果您在此步骤中遇到问题,请尝试将您的视频转换为不同的格式。

在我们进入下一步之前,让我们定义视频的宽度和高度。我们将需要这些渲染成视频文本。别担心,这很容易。

w,h = moviesize = my_video.size

第三步——创建你的文本

在这一步,我们将为我们的文本定义一个新的变量。我把它叫做“我的文本”。使用 TextClip 方法,我们将能够创建文本。

my_text = mp.TextClip(“The Art of Adding Text on Video”, font=’Amiri-regular’, color=’white’, fontsize=34)

如你所见,我们甚至可以玩参数。我们可以自定义我们的文本,这真的很酷。文本字体、文本颜色和字体大小可以根据您的喜好进行更改。

现在,我们将定位视频中的文本。我们也可以为我们的文本设计一个背景。您可以试验参数,看看它是如何工作的。背景颜色、背景不透明度和文本位置是一些参数。

txt_col = my_text.on_color(size=(my_video.w + my_text.w, my_text.h+5), color=(0,0,0), pos=(6,’center’), col_opacity=0.6)

最后一步—在视频上渲染文本

太好了!你坚持到了最后一步。这一步就是奇迹发生的地方。

动画

首先,我们将定义一个名为“text_mov”的新变量,我们可以在其中添加一些动画。文本在视频上的移动。玩参数就能找到自己喜欢的结果。这是我们制作动画的代码行:

txt_mov = txt_col.set_pos( lambda t: (max(w/30,int(w-0.5*w*t)),max(5*h/6,int(100*t))) )

翻译

最后,是时候渲染我们视频上的文本了。多亏了 moviepy 库,我们将使用名为“CompositeVideoClip”的方法为我们进行渲染。如前所述,如果你在这一行遇到错误,我强烈推荐安装 imageMagickffmpeg 模块。这是让奇迹发生的台词:

final = mp.CompositeVideoClip([my_video,txt_mov])

导出您的结果

差不多了,看看最后的效果如何,我们导出视频吧。我们将把它保存为一个新的视频文件。导出真正酷的是你可以调整视频格式,甚至每秒帧数。下面是导出渲染视频的前 5 秒的代码:

final.subclip(0,17).write_videofile(“data/text_add_result.mov”,fps=24,codec=’libx264')

分享结果

恭喜你。你已经创建了一个程序,在不使用任何视频编辑软件的情况下,在视频上呈现自定义文本。看到机器学习如何应用在我们的日常生活中,这真的很酷。希望你喜欢阅读这篇文章并参与这个项目。如果你今天学到了新东西,我会很高兴。从事像这样的动手编程项目是提高编码技能的最好方式。

如果您在执行代码时有任何问题,请随时联系我

关注我的博客走向数据科学以获得灵感。谢谢你,

相关内容

[## 使用 Python 从视频中提取语音

使用 Google 语音识别 API 的简单实用项目

towardsdatascience.com](/extracting-speech-from-video-using-python-f0ec7e312d38) [## Python 中的简单人脸检测

如何使用 OpenCV 库检测图像中的人脸

towardsdatascience.com](/simple-face-detection-in-python-1fcda0ea648e)

重新排序熊猫数据框列:否定标准解决方案

原文:https://towardsdatascience.com/reordering-pandas-dataframe-columns-thumbs-down-on-standard-solutions-1ff0bc2941d5?source=collection_archive---------6-----------------------

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

图片来源:“Via Design Pickle”——更多关于属性

简化更改数据帧列顺序过程的解决方案

更新,2021 年 2 月,请看下面 YouTube 上的教程。

介绍

成千上万的博客文章、stackoverflow.com 线程、quora.com 文章或其他资源展示了在 Pandas 数据框架中移动列(改变它们的顺序)的类似标准方法。

本文首先提供了示例数据。根据示例数据,文章传达了两个好的 但不完美的标准解决方案。本文讨论了这些好的但不完美的标准解决方案的局限性。最后,有一个修正的解决方案,它避免了标准解决方案中固有的一些限制。

示例数据

import pandas as pd# Write some example data
df = pd.DataFrame({'names':['Al','Myke','Lovie','Dash'], 
                   'Grade': [6,7,6,6],
                   'Teacher':['Ogna','Hayes','Stoltz','Edens'],
                   'Score':['A+','A-','B','C'],
                   'Room':['Green','Red','Blue','Yellow'],
                   'Hobby':['Coins','Stamps','Coins','Cards']})

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

示例数据帧

标准解决方案(好)

以新的所需顺序显式列出列

对最常发布的列进行重新排序的解决方案是将 DataFrame 设置为等于其自身,但以新的所需顺序显式命名列:

# Reset DataFrame with columns in desired order
df = df[['names','Score','Room','Grade','Teacher','Hobby']]

或者简单地评估具有以新的期望顺序明确命名的列的数据帧:

# Evaluate the DataFrame with columns in desired order
df[['names','Score','Room','Grade','Teacher','Hobby']]

除非有几十或几百列,否则这种标准解决方案工作得很好。假设您有一个包含数十或数百列的数据框架,而您只希望移动一列。为了移动一列而显式列出所有列是低效的。列出所有列也是有问题的,因为对相关代码库的其他方面的更改可能会导致错误。对其他列名的添加、删除或修改会破坏标准解决方案的早期实现。

利用简便的熊猫方法

的另一个标准解决方案是将pd.drop()pd.insert()方法配对。此选项的主要限制是,它仅在一次将一列移动到特定位置时有效。

mid = df['Hobby']
df.drop(labels=['Hobby'], axis=1, inplace = True)
df.insert(1, 'Hobby', mid)
df

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

爱好从索引位置 5 移动到索引位置 1。

修订的解决方案(更好)

仍然不完美,但对于许多用例来说,可能是更好的选择。

如果您有许多列,它们彼此不相邻,并且您想要将它们全部移动到另一个特定列之后的新位置,该怎么办?也许您还想同时对列进行重新排序。以下是完成该任务的解决方案。

def movecol(df, cols_to_move=[], ref_col='', place='After'):

    cols = df.columns.tolist() if place == 'After':
        seg1 = cols[:list(cols).index(ref_col) + 1]
        seg2 = cols_to_move
    if place == 'Before':
        seg1 = cols[:list(cols).index(ref_col)]
        seg2 = cols_to_move + [ref_col]

    seg1 = [i for i in seg1 if i not in seg2]
    seg3 = [i for i in cols if i not in seg1 + seg2]

    return(df[seg1 + seg2 + seg3])

实施:

df = movecol(df, 
             cols_to_move=['Score','Grade'], 
             ref_col='Room',
             place='After')
df

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

“分数”和“等级”列都颠倒了它们的顺序,移到了“房间”后面的索引位置。

[## 加入我的介绍链接媒体-亚当罗斯纳尔逊

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

adamrossnelson.medium.com](https://adamrossnelson.medium.com/membership)

结论

概括地说,数据管理很难。在合并多个数据源之后,拥有一个可以快速排序和重新排序列的方法是很方便的。

这样做是对未来审查你的工作的科学家的一种常见的礼貌。如果我们把最重要的栏目放在左边,其他人会花更少的时间寻找必要的信息来理解我们的工作。当我们知道我们将返回到我们的工作中以供将来参考时,这个额外的步骤对我们自己也是有帮助的。

感谢阅读

如果你喜欢我要说的话,可以在:adamrossnelson.medium.com找到更多。

感谢阅读。把你的想法和主意发给我。你可以写信只是为了说声嗨。如果你真的需要告诉我是怎么错的,我期待着尽快和你聊天。推特:@ adamrossnelson| LinkedIn:亚当·罗斯·纳尔逊 |脸书:亚当·罗斯·纳尔逊

视频教程

重新排序列,YouTube 上的教程。2021 年 2 月新增。

在疫情期间修复损坏的模型(或不修复)

原文:https://towardsdatascience.com/repairing-broken-models-or-not-during-a-pandemic-63ec1ade6897?source=collection_archive---------62-----------------------

当你有一个基于多年工作的惊人模型,突然被全球疫情破坏了,你会怎么做?

在如此多的系统中出现如此巨大的中断,很难知道如何处理现有的模型。这里有一些适应的方法——以及一些你可能而不是尝试修复那些模型的原因。

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

照片由杰米街Unsplash 拍摄

当你有一个惊人的,甚至获奖的,基于多年工作的模型,突然被一个全球性的疫情破坏了,你会怎么做?

听起来熟悉吗?

好吧,如果你在卡内基梅隆大学的德尔菲研究小组,你会振作起来,继续创造性地思考下一个大问题。

2019 年,美国疾病控制和预防中心(CDC)将德尔福集团命名为国家流感预测卓越中心,此前三年,他们的预测系统在 CDC 创建的流感预测挑战中赢得了最高的准确性。但在 3 月份,鉴于流感模型将受到新冠肺炎疫情的显著影响,CDC 要求研究人员将注意力从流感上转移,转而尝试预测新冠肺炎的传播。德尔福小组已经以多种方式进行了调整,包括重新考虑他们模型中的“社交焦虑”信号,以及他们对未来几周的预测能力。(阅读更多关于他们的改编这里这里。)

传染病模型并不是现在唯一需要重新发明的。任何试图对零售、供应链、医疗保健、教育或几乎任何行业进行预测的人都面临着数据中突然出现的戏剧性行为。有时这是积极的方向:例如,视频游戏行业的人们可能会对他们现在看到的用户和游戏时间的创纪录数字感到非常满意。有时候,数据的变化并不那么积极。

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

那么,如何修复一个破碎的模型来应对这些戏剧性的转变呢?在我们的 Alteryx 社区和社交媒体的上,已经有一些关于这个挑战的有趣讨论。在这里,我将讨论已经出现的几种可能的策略,每一种都有其自身的复杂性,再加上一种应该会让我们对人类的世界观感觉良好的策略。

添加新的模型特征并使用实时数据

尝试将当前情况整合到模型中的一种方法是添加尝试说明疫情现实情况的要素。也许这是一个捕捉一个城市在社交距离指令下的天数的特征,包括学校和企业关闭。也许这是一个已知感染新冠肺炎病毒的城市人口百分比的特征(承认这些数据是不完整的,因为测试和未知或无症状病例的不一致)。然而,这些可能很难选择、定义和保持更新,因此它们的价值可以忽略不计;随着这些变化的出现,现在也很难验证它们的有用性。

另一个策略是获取尽可能接近实时的数据。当然,这可能也是说起来容易做起来难。但是想象一下,很快有一天,一些不准确的社交媒体模因传播说一种受欢迎的食物治愈了新冠肺炎,并且对该产品产生了抢购。如果你不立即知道突然流行,你将无法维持供应。此时,拥有可重复的自动化工作流程对于帮助您跟上事件的发展速度非常重要。

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

调整预测方法

在许多领域,为 2019 年夏季生成的预测对于截然不同的 2020 年夏季不会非常有用。对于那些处理时间序列数据和预测的人来说,一种在预测中更重视最近数据的方法目前可能是合适的。例如,如果对一种产品的需求突然上升,最近的增长不会立即消失,但随着消费者行为慢慢恢复正常,更有可能会随着时间的推移而逐渐减少。

例如,Prophet 是一个针对 R 或 Python 的免费公开的预测包这篇文章和 Alteryx 工作流程展示了一个使用 Prophet 预测工具和在 Alteryx 中配置趋势变化点的例子。变点被定义为时间序列值突然改变的时刻。确定这些对数据有重大影响的时刻,并将它们合并到您的模型中是至关重要的。(请注意,根据 Prophet 文档,“默认情况下,仅为时间序列的前 80%推断变点,以便有足够的跑道来预测未来趋势,并避免在时间序列结束时过度拟合波动。”这种行为可以用最初的 Prophet 参数中的changepoint_range来改变,但是如果你使用上面提供的宏,不需要进一步定制,你必须确保你的改变点在你的时间序列的前 80%之内。)

另一种可能性是尝试用卡尔曼滤波器平滑时间序列数据,这也许可以更好地处理由这一重大经济事件的“外源冲击”引起的波峰和波谷。R 中的[KFAS](https://cran.r-project.org/web/packages/KFAS/index.html)包可用于该目的,如本例所示。然而,即使是这种方法也不足以适应如此戏剧性的转变。

使用模拟

经济建模者有时使用衰退和复苏的 V-U-L 曲线来考察未来的可能性。《哈佛商业评论》最近的一篇文章展示了这些模型在过去的大流行中是如何应用于经济的,并可能在今天发生。这是想象可能未来的一种方式,尽管思考悲观的“L”情景是困难的。

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

从左到右,可视化 V、U 和 L 衰退和复苏。图片来自 维基媒体

这些情景可以为开发模拟不同可能性的模型提供一个框架。虽然多年来模拟在计算上是昂贵和令人生畏的,但现在不再是这样了。正如这些研究人员所指出的:

…我们现在拥有(并且可以轻松执行)有效的统计程序,实际上消除了我们的结果精度的任何令人苦恼的不确定性;毕竟,由于真实系统本身大多是随机的,所以模拟可以以现实的方式捕捉系统的变化,同时仍然可以产生所需的精确结果。

疫情可能比这些作者考虑的大多数情况更加极端,但是模拟可能仍然有一些用处,即使它们不能“消除”不确定性。

模拟可以包含关于疫情对您的情况的影响的不同假设,然后比较评估它们的不同结果。Alteryx Designer 中的模拟采样工具可用于以多种方法采样或模拟数据。引导一个时间序列——模拟多个与原始数据相似的时间序列——可以帮助解释更大的不确定性。对这些序列中的每一个拟合一个模型将产生不同的估计参数和随机误差项。结合这些模型的预测将创建更大的预测区间,并显示更大范围的可能结果。

蒙特卡洛模拟在这一时刻的效用也是最近 Reddit 帖子讨论的主题,讨论如何应对疫情对预测的挑战,受访者对其潜在价值有分歧,特别是因为蒙特卡洛方法假设数据均匀分布。这个[PyMC3](https://github.com/pymc-devs/pymc3)包提供了一个 Python 工具包(这里有一个教程)。r 也有许多模拟工具,包括包[MonteCarlo](https://cran.r-project.org/web/packages/MonteCarlo/index.html),它有一个有用的插图

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

无论你尝试什么方法,预测都不会像通常那样有用。围绕你的预测传达大量的不确定性是个好主意。你的听众需要意识到这些置信区间比平常更加重要。

选择你前进的道路

唉,在这样一个不确定的时期,没有单一的解决方案来修复一个曾经被珍视、现在已经破碎的模型,或者产生完美的预测。但这一时刻证明了人类的智慧和敏感性——以及领域专业知识——在数据分析中的重要性。

现在,精心设计一个新模型的每一个参数可能不是对你的时间和精力的最好利用。现在有如此多的未知,依靠有根据的、深思熟虑的人类预测可能更有效。

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

这一时刻使人的投入在开发分析策略中的重要性变得更加明显。如果工具只是被输入相同的数据,并按照正常情况下的相同方式设计,它们将会失灵。正如麦吉尔大学组织行为学助理教授 Matissa Hollister 最近在世界经济论坛博客上写的:

人类可以辨别算法可能失败的地方和历史训练数据可能仍然与解决关键和及时的问题相关的情况,至少在更多的当前数据可用之前。…尽管新冠肺炎的特殊性质是独特的,并且劳动力市场的许多基本规则不运行,但仍然有可能确定应用人工智能工具的有价值的途径,尽管可能受到小心限制。

正如霍利斯特所建议的,我们仍然可以谨慎地使用我们的建模技能。即使是最好的模型也不知道这个奇怪的新时代的许多微妙之处。例如,毫无疑问,现在不仅人们购买的食物种类发生了变化,而且他们购买食物的具体地点也发生了变化。在一个小的,不太繁忙的社区杂货店购物可能比在高速公路上的巨型超市与大众混在一起更有吸引力。这两种环境对害怕疾病的顾客的相对吸引力很难量化并整合到一个模型中。

我们可能经常觉得人类不太擅长相互理解,但在这次疫情中,我们可以识别模型可能忽略的数据中的情感和生活方式的细微差别。因此,虽然我们可以调整我们的数据选择和模型设计,但也是时候利用人类的同情心和专业知识来指导决策和创造解决方案。

这篇文章名为 ,最初发表于 Alteryx 社区数据科学博客 。在 Alteryx 数据科学门户 找到更多资源。

变分自动编码器中的“重新参数化”技巧

原文:https://towardsdatascience.com/reparameterization-trick-126062cfd3c3?source=collection_archive---------6-----------------------

在本文中,我们将学习“重新参数化”技巧,它使变分自动编码器(VAE) 成为反向传播的合格候选。首先,我们将简要讨论自动编码器及其普通变体带来的问题。然后,我们将直接跳到文章的核心——“重新参数化”技巧。

注意 :这篇文章是 而不是 一个教你关于自动编码器的指南,所以我会在需要的时候简单介绍一下。如果你想了解更多关于 Autoencoders 的知识,那么你可以查看这些文章

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

一个变分自动编码器( 来源 )

自动编码器:它们做什么?

自动编码器是一类生成模型*。它们允许我们 压缩 一个大的输入特征空间到一个小得多的空间,这个空间以后可以被重建。一般来说,压缩对学习质量有很大的影响。*

我们人类有惊人的压缩能力——我们能够学习简洁的东西,以后我们可以在需要时轻松地扩展它们。例如,通常情况下,你不需要记住一个特定概念的所有细节;你只需要记住关于它的特定点,然后你试着在这些特定点的帮助下重建它。

因此,如果我们能够在一个低得多的维度空间中表示高维数据,并在以后重建它,这对于许多不同的场景都非常有用,如数据压缩、低维特征提取等。

普通自动编码器

用一些代码来解释更容易—

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

浅层自动编码器网络

我们有一个非常基本的网络:

  • 将一个 784-d 向量输入网络。
  • **将矢量压缩成 32 维矢量(编码器)。
  • **从 32-d 矢量重建原始的 784-d 矢量(解码器)。

下图可能会让这个想法更加清晰——

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

浅层自动编码器网络示意图

就结果而言,这个网络在良好的旧 MNIST 数据集上训练时,可以产生以下结果(笔记本可在此处获得):

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

当在 MNIST 图像上训练时来自上述网络的预测

输出看起来没那么糟糕,但是这个网络容易出现一些问题

  • 网络的编码器无法知道它应该如何将输入数据点编码成潜变量*(读取压缩)。这迫使潜在变量的表示以 不在乎 关于输入数据点的结构多。当然,在网络的末端有一个损失函数(典型地, L2 )告诉它预测与原始数据点有多远。但是它仍然没有考虑输入数据点应该被压缩的方式。因此,潜在变量中非常小的变化都可能导致解码器产生非常不同的输出。*
  • 确定潜在变量的维数是另一个考虑因素。在这种情况下,我们使用 32-d。用一个更高维的向量来表示潜在变量,我们可以提高生成的图像的质量,但只能提高到一定程度。第一个问题仍然存在。

第一个问题似乎比第二个问题更有问题,因为我们可以用不同的维度进行实验,并观察预测的质量。那么,如何解决这个问题呢?

可变自动编码器:编码、采样、解码和重复

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

VAE 的语义学( 来源 )

为了缓解普通自动编码器中存在的问题,我们转向变型编码器。它引入网络的第一个变化是,输入数据点被映射到 多元正态分布,而不是直接将输入数据点映射到潜在变量。 这种分布限制了编码器在将输入数据点编码成潜在变量时的自由裁量权。同时,它在网络中引入了,因为我们现在是从一个概率分布中的个采样点。**

正态分布由均值(𝜇)和方差(𝜎)参数化,这与变分自动编码器的情况完全相同(有一些“变化”)。所以,一步一步——

  • VAE 中的每个数据点将被映射到均值和 log_variance 向量,这些向量将定义该输入数据点周围的多元正态分布。
  • 从这个分布中抽取一个点作为潜在变量返回。
  • 这个潜在变量被馈送到解码器以产生输出。

这使得网络被迫学习更平滑的表示。 还确保潜在变量的微小变化不会导致解码器产生大不相同的输出,因为现在我们是从连续分布中采样。另一方面,由于这种采样过程本质上是随机的,解码器输出开始变得更加多样。

下面是一个浅 VAE 的示意图

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

浅 VAE 示意图

*如图所示,我们在网络中引入了另一个中间密集层。穿着 VAE。meanlog-variance是*可学习的参数。上图中的Lambda层代表采样操作,定义如下:

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

在 TensorFlow 中编码 VAE 的采样操作

因此,如果输入数据点要通过采样(在通过神经网络后)映射到潜在变量𝑧,它必须遵循以下等式:

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

哪里,𝑠𝑖𝑔𝑚𝑎=𝑒𝑥𝑝(𝑧_𝑙𝑜𝑔_𝑣𝑎𝑟/2).

通过对方差取对数,我们迫使网络具有自然数的输出范围,而不仅仅是正值(方差只有正值)。这使得潜在空间的表现更加平滑。

你一定在质疑这个小术语epsilon,它在这里有什么意义?我们一会儿会处理这件事。

现在,在我们最终讨论“重新参数化”技巧之前,我们需要回顾一下用于训练 VAE 的损失函数。这是因为我们最终反向传播损失函数的梯度,并且当在 VAE 中发生时,“重新参数化”技巧实际上有助于反向传播过程。

VAE 损失

回想一下上一节,VAE 试图了解潜在空间的分布。因此,除了考虑解码器产生的重构输出,我们还需要确保潜在空间的分布是良构的。摘自用 Python 进行深度学习(作者 Franç ois Chollet)(第一版,300 页)—

通过两个损失函数训练 VAE 的参数:迫使解码样本匹配初始输入的重建损失,以及帮助学习良好形成的潜在空间并减少对训练数据的过拟合的正则化损失** 。**

**正则化损失通过 **Kullback-Liebler 发散来处理。GANs in Action (作者 Jakub Langr 和 Vladimir Bok)(第一版,第 29 页)中可以找到对 KL 背离的出色解释

[……]kull back–lei bler 散度(KL divergence),又名相对熵**,是两个分布的交叉熵与其自身熵之差**。对于其他人,想象画出两个分布,它们不重叠的地方将是与 KL 散度成比例的区域。****

对于 KL 散度的选择,这里有一个更精确的数学处理,你可能会发现这个讲座是有用的

对于重建损失,我主要看到了以下两种选择—

  • L2 损失
  • 二进制交叉熵(用于将数据点的每个特征与重构输出中的值进行比较)

现在,我们可以继续讨论我们一直期待讨论的“重新参数化”技巧。

用反向传播训练 VAE

能够更新的参数。使用反向传播的 VAE,我们需要考虑到里面的采样节点本质上是随机的。我们可以计算采样节点相对于meanlog-variance矢量的梯度(采样层中使用了meanlog-variance矢量)。

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

一小部分来自我们的 VAE 网

还记得取样层的小家伙epsilon吗?那实际上 重新命名了 我们的 VAE 网。这允许meanlog-variance向量仍然作为网络的可学习参数,同时仍然通过epsilon保持整个系统的随机性。

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

VAE 网络有无“重新参数化”的伎俩( 来源 )

其中,𝜙代表了网络试图了解的分布。

epsilon仍然是一个具有非常低值的随机变量(从标准正态分布中采样),从而不会导致网络从真实分布中偏离太多这里可以肯定地重申,网络仍在学习分布𝜙(由 *mean* *log-variance* 向量参数化)。这种想法实际上允许 VAE 以端到端的方式进行训练,是由金玛等人在他们名为自动编码变分贝叶斯的论文中提出的。

结论

所以,文章到此结束,感谢你的阅读!自动编码器是生成模型的第一等成员,甚至在开发 GANs 中找到它们的应用(开始)。解开 VAEs 在强化学习领域也非常相关( DARLA:改善强化学习中的零投迁移)。VAEs 是一种将贝叶斯推理与深度学习结合起来的发现,鼓励不同的研究方向。

以下是我用来写这篇文章的参考资料,如果你有兴趣了解更多关于自动编码器的知识,你一定要去看看

你可以通过推特( @RisingSayak )和我联系。

用 GPT-3 取代我的 git 备忘单

原文:https://towardsdatascience.com/replacing-my-git-cheat-sheet-with-gpt-3-69223e58626f?source=collection_archive---------35-----------------------

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

像 git 一样,学习驾驶手动变速器会很困难(图片 shutterstock.com)

使用 GPT-3 从我想做的事情的英文描述中生成 git 命令

有些基本技能,如果你年轻时就学会了,会很容易,但如果你不得不在以后的生活中掌握它们,就会变得莫名其妙。例如,对于一个学习驾驶自动档汽车的人来说,驾驶手动档汽车似乎异常困难。然而,如果您不是伴随着 git 成长起来的,那么与掌握 git 命令行界面相比,“驾驶操纵杆”的挑战就相形见绌了。在本文中,我将描述如何利用 OpenAI 的 GPT-3 从英语语言描述中生成 git 命令。

git 的伟大之处(和不那么伟大之处)是什么

Git 是一项基础技术,也是对现代软件开发的杰出贡献。它还有一组命令,这些命令看起来似乎是故意随意和不一致的。

“尽管 Git 有很多优点,但我一直对命令行中除了最简单的操作之外的任何操作都缺乏清晰度感到沮丧。见鬼,即使是最简单的动作也比实际需要的要难。”出自丹尼尔·埃克伦德的

我到了晚年才明白。在我在 IBM 的职业生涯中,我使用过各种代码控制/版本控制系统,包括古老的 CMVC 和 Clearcase,它们相当容易使用,但仍然是那个时代 IBM 软件中的神秘事物。这两个系统都没有让我为 git 的精彩世界做好准备。

面对 git 语法的挑战,我做了 21 世纪任何有自尊的软件开发人员都会做的事情。我将我最常用的 git 命令保存在一个 Word 文档中,并描述了这些命令的作用。当我需要重复一个特定的 git 咒语时,我可以查看这个 Word 文档,看看我以前是否做过,并尝试找出语法。听起来很棒,对吧?不幸的是,我现在遇到了在个人和工作环境中保持这个文档同步的问题,随着它变得越来越大,我冒着失去更基本的 git 命令的风险。

如果有什么方法可以用一个智能助手代替我的 git 备忘单,将我的英语语言描述翻译成 git 命令就好了…

GPT-3 和吉特:天作之合

当我尝试使用 GPT-3 将简单的 COBOL 函数转换成 Python 时(没有成功),我简直是在摆弄我那愚蠢的 git 备忘单。我仍然认为这是一个好主意,但我已经忘记了太多的 COBOL,无法拿出像样的例子。因此,如果 COBOL 到 Python 不是 GPT-3 的一个好用例,那么什么是呢?如果有一个实际的问题,我必须用英语作为输入,用一些命令作为输出来解决…

答案就在我眼前——使用 GPT 3 将英语描述翻译成 git 命令。

git assistant——一个简单的 Python 程序,用于从英文描述中获取 git 命令

我写了一个简单的 Python 程序, git assistant ,让 GPT-3 提供与我想要 git 做的事情的英语描述相对应的 git 命令。该程序由一个循环组成,该循环提示用户输入,用输入调用 GPT-3 API,并返回 GPT-3 对相应 git 命令的预测:

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

GPT-3 得到一个英文描述并返回一个 git 命令

为了启动这个泵,我向 GPT-3 提供了一小组英文文本描述的例子和相应的 git 命令:

下面是一个运行 git assistant 的会话示例。GPT-3 的响应列在“输出:”之后

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

与 git 助手的会话

结果并不完美。例如,对“将更改合并到当前分支”的响应重复了 3 次。也就是说,git assistant 足够好,我可以退休我的 git 备忘单了。

结论

Git 是一个使用非常广泛的应用程序的例子,它的语法有些晦涩难懂。我在本文中已经展示了,通过一些提示,GPT-3 可以很好地从英语语言描述中生成 git 命令。我现在使用这个简单的 git 助手来提醒我 git 语法,让我不必参考 git 命令的静态备忘单。

您可以在本报告中找到本文中描述的代码:

你可以在这里找到一段视频,演示本文中描述的代码:https://www.youtube.com/watch?v=MoLfVG-8Z5A&t = 13s

用 R 替换 PowerPoint

原文:https://towardsdatascience.com/replacing-powerpoint-with-r-b96661928ed4?source=collection_archive---------29-----------------------

如果你正在做一个分析性的演示,用 R Markdown 创建的演示来代替 PowerPoint 是一个好主意,原因有三。

  1. 交互性:R Markdown 使您能够生成交互式幻灯片。拥有交互式图表更有趣,应该会让你的演示对象参与进来。
  2. 文档:您编写的用于生成分析的代码可以存储在幻灯片中(它可以打开/关闭),并作为您的分析方法的文档。没有必要编写您的方法或包含您用来创建可视化的数据截图,因为 R 会为您呈现它们。
  3. 自动化:如果您必须频繁地使用新数据(如月报或周报)进行相同的演示,那么您可以将相同的代码应用于不同的数据,从而节省您的时间和精力。

创建演示文稿

要用 R 创建一个演示文稿,您需要 R Studio IDE,如果您有,就可以开始使用。要开始点击文件>新建文件> R 降价,这将生成下面的弹出窗口。

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

创建新的 R Markdown 文件

在左侧面板选择“演示”后,您会看到 4 个演示类型选项(如果您使用的是 R Studio 1.0,您将看不到 PowerPoint)。虽然这篇文章是关于不使用 PowerPoint 的,但是结合 R 使用它仍然是一个巨大的进步。只有 HTML 输出允许交互结果,所以在我看来,这是最好的选择,尽管如果你选择制作 PowerPoint 或 PDF,文档和自动化的好处是不变的。在这个例子中,我将选择 Slidy。

在您创建的新 R Markdown 文件中,前几行是 YAML,这是一种用于声明环境或配置变量的文件格式。这个 YAML 将告诉我们关于演示文稿的事情——标题、作者、日期和输出。我将把标题改为“财务报告”,日期改为“r 系统”。Date()` "将使报告始终具有当前日期。

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

YAML 降价

写作降价

Markdown 是一种轻量级的标记语言,它基本上意味着文本的格式与文本写在同一个文档中。这类似于 HTML 的工作方式。以下是减价的原则,涵盖了你需要的大部分东西。HTML 和 CSS 可以应用到您的文档中进行进一步的定制。

  • 幻灯片:新的幻灯片将以一些标签开始。单个#生成一个

    标记,##生成一个

    标记,###生成一个

    标记,依此类推。

  • 链接:可以包含在链接文本

  • 图像:要插入图像,请键入!备选文本

  • 加粗:要使文本加粗,把它放在星号之间,像这样:加粗的单词

  • 斜体:要将文本设为斜体,请将其放在两个星号之间:*斜体文本 *

  • 列表:无序列表可以用*来创建,用+来创建。只需输入“1”就可以创建有序列表,这在您必须向列表中插入新项目时很有帮助,因为您不必重新编号。

  • 块引号:要包含块引号,只需在段落开头加上>。

编写代码

您的代码将以内联或代码块的形式编写。内联代码可以和你的 markdown 一起写,我们在写 r Sys 的时候已经看到了一个例子。日期()`在 YAML。要使用内联代码,只需确保将 R 代码写在反勾号内,而不是撇号内,反勾号与大多数键盘上的波浪号共享同一个键。

代码块是编写大部分代码的地方。每个代码块都以三个反斜杠和一组大括号开始,其中设置了编程语言、代码块名称和显示选项。一个代码块将以三个反斜线结束。以下是您可能需要的主要显示选项:

  • echo:隐藏代码。
  • eval:不运行代码。
  • 包含:运行代码,但不显示代码或输出。常见的用例是在一个块上加载包并隐藏它。
  • error:隐藏错误消息。
  • 缓存:缓存结果以供将来渲染。如果您经常在幻灯片之间切换,这很有用。
  • 图形宽度:调整图形宽度。
  • 身材高度:调整身材高度。

呈现演示文稿

要呈现您的演示文稿,请单击屏幕顶部的“编织”。这将生成您的演示文稿,以及可以在浏览器中打开的幻灯片的 HTML 文件。记住,作为一个 HTML 文档,你可以根据自己的需要编写 CSS 样式,比如改变字体或背景颜色。

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

经过渲染的演示

插入交互式可视化效果

交互性是 R Markdown 在 PowerPoint 上最明显的优势。虽然自动化和文档化可能会节省您的时间,并使您的工作更清晰,但交互性是演示时真正令人惊叹的因素。

使用下面的 quantmod 和 highcharter 包,我在一个有一些交互功能的图上显示谷歌的股票价格。这比您可能在 Excel 中对同一图表进行截图并复制/粘贴到 PowerPoint 中要令人印象深刻得多。它也比你期望的用传统的数据软件花费更少的工作,下面两行单独渲染了这个图。

x <- getSymbols("GOOG", auto.assign=FALSE) highchart(type="stock") %>% hc_add_series(x)

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

HIghcharter 烛台图表

添加更多高级交互功能(例如,允许您更改正在查看的股票),需要您学习 R package Shiny,它可以帮助您快速构建 web 应用程序。如果你希望你的演示文稿需要大量关于类似数据的图表或幻灯片,添加 Shiny 可以解决这个问题,但使用 htmlwdigets 包可以快速实现基本的交互功能。

用 Detectron2 复制 Airbnb 的舒适度检测

原文:https://towardsdatascience.com/replicating-airbnbs-amenity-detection-with-detectron2-28f33704d6ff?source=collection_archive---------25-----------------------

成分:1 个检测器 2,38,188 个开放图像,1 个 GPU。模特培训时间:18 小时。人类时间:127 小时。

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

计算机视觉驱动的舒适性检测的工作流程示例。图片来源:https://www.airbnb.com/rooms/2151100

几个月前,我在读到了 Airbnb 工程团队的一篇文章,描述了他们如何使用计算机视觉来检测照片中的便利设施。

这篇文章读起来像一个食谱。机器学习的秘诀。

像任何初露头角的厨师(或机器学习者)一样,我决定复制它,并加入一些我自己的味道。

等等。

什么是便利设施?

想想房间里有用的东西。比如厨房里的烤箱或者浴室里的淋浴。

为什么在图像中检测这些会有帮助?

这就是业务用例出现的地方。你会经常看到在 MNIST(手写数字的照片)等数据集上建立的计算机视觉模型教程,但很难将这些问题转化为商业用例(除非你是从事检测手写数字业务的邮政服务人员)。

如果你看过 Airbnb 的网站,那里有很多房子和住宿的照片。除了这些地方,还有基于文本的描述细节的细节。比如你看的房子里有没有按摩浴缸。

举个例子怎么样?

假设你想在 Airbnb 上列出你的家。你可以上传一些照片,并填写一些细节。但是很有可能,因为你非常了解自己的位置,你可能会错过一些东西。

这就是自动舒适度检测可以发挥作用的地方。

当你将图片上传到 Airbnb 时,计算机视觉机器学习模型会查看这些图片,试图找到每张图片中的关键设施,并将它们自动添加到你的清单中。

当然,它可以在实际运行之前向您验证它的预测是否正确。但是让它自动发生将有助于确保每个列表上的信息尽可能地被填写。

拥有尽可能详细的信息意味着人们可以根据特定的标准来搜索地点。因此,这对年轻夫妇在按摩浴缸和壁炉前度过一个美好的周末后,可以找到他们想要的东西。

A note to the reader, treat this article as a high-level narrative of what happened mixed with a splash of tech. For the nerds like me, the code is available in the [example Google Colab Notebook](https://dbourke.link/airbnbcode).

为期 42 天的项目:边做边学

在开始这个项目之前,我就像一个拿着一套没动过的刀的厨师。或者在我的情况下,一个还没有使用过检测器 2权重&偏差流线或者大部分 PyTorch 的机器学习工程师(这些都是机器学习工具)。

我发现在建造东西的时候,我对事物了解得最多。你可能也一样。

所以我打开了一个概念文档,写下了一些标准,并在我的白板上列出了一个 6 周的大纲。

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

从左到右:一个简单的 42 天项目模板我放在我桌子前面的墙上,所有的日记风格的项目笔记在观念和我的松散绘制的白板指南。

为什么是 6 周?

因为 42 天看起来足够完成一件有意义的事情,但又不至于占据你的生活。

总之。

我想我会花 6 周左右的时间(每天 3 个小时)用我一直想尝试的工具复制 Airbnb 的便利设施检测。

最坏的情况是,我学了一些东西,如果都失败了,也就 6 周。

最好的情况是,我学到了一些东西,并开发了一个非常酷的机器学习应用程序。

不管怎样,都会有一个故事要讲(你正在读它)。

分解它

这个有趣的小图形打破了实验中的主要步骤。

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

我用来复制 Airbnb 舒适度检测的配方,从数据收集和预处理开始,然后是建模和实验跟踪,最后是应用程序的构建和部署。

有时文字比充满其他图像的图像更容易阅读。

用 Detectron2 复制 Airbnb 的舒适度检测方法:

  1. 使用 downloadOI.py(用于从打开的图像中下载特定图像的脚本)收集数据。
  2. 使用 preprocessing.py(一个自定义脚本,具有将打开的图像图像和标签转换为 Detectron2 样式数据输入的功能)预处理数据。
  3. 检测器 2 的模型数据。
  4. 使用权重和偏差跟踪建模实验。
  5. 使用 Streamlit 创建面向用户的应用程序。
  6. 部署应用程序和模型与 Docker,GCR(谷歌容器注册)和谷歌应用引擎。

我们将使用这些来驱动文章的其余部分。让我们开始吧。

数据收集:从打开的图像中下载 Airbnb 目标图像和标签文件

  • 成分: 1 个下载脚本,4 个标签文件,38,000+ x 个打开的图像
  • 时间: 1 周
  • 费用: $0
  • 器皿 : Google Colab,本地机

像所有机器学习项目一样,它从数据开始,也从数据结束。

Airbnb 的文章提到,为了建立他们的概念证明,他们使用了 32k 公共图像和 43k 内部图像。

唉,第一个路障。

当然,除了 2016 年对一个技术支持角色的电话面试,我与 Airbnb 内部没有任何联系,所以内部图像不在讨论范围内。

好消息是他们使用的 32k 公共图片来自 Open Images (一个巨大的免费开源资源,包含来自 600 多个不同类别的数百万张图片)。

然而,如果你打开图片,你会发现有超过一百万张不同的图片。

那交易是什么?

Airbnb 为什么只用 32k?

好问题。

这是因为他们只对与其业务用例相关的图像感兴趣(包含公共设施的房间的图像)。

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

Airbnb 的目标类别(30 种便利设施类型,摘自原始文章)与来自 600 个不同类别的 190 多万张图像的开放图像数据库。

我想,知道了 Airbnb 最关心的目标类别,肯定有办法只从你关心的开放图像中下载图像(而不是整个 190 万+500 GB+的数据集)。

原来是有的。

经过一番搜索,我从 LearnOpenCV 找到了一个关于如何从目标类列表中下载图片的很好的指南。

具体来说,是一个名为 downloadOI.py 的脚本,它允许您定义您要查找的类以及来自哪个数据集。

让我们看一个例子。

!python3 downloadOI.py --dataset "validation" --classes "Kitchen & dining room table"

这一行写着,“从开放图像的验证集中获取包含厨房和餐厅桌子的图像。”

运行上面的代码行将目标类中的所有图像下载到与目标数据集同名的文件夹中。

# What your image folder(s) look like after using downloadOI.pyvalidation <- top file 
│   kitchen_&_dining_room_table_image_1.jpg <- image 1
│   kitchen_&_dining_room_table_image_2.jpg <- image 2
|   ... <- more images...

LearnOpenCV 脚本中最初的 downloadOI.py 运行得非常好,它甚至可以在下载图像时生成标签。但是经过一点试验,我发现这些标签与 Detectron2 不兼容。

因此,我取消了下载时的标签创建,并将脚本修改为只下载图像。我决定编写自己的标签创建代码。

能够下载图像:检查。

现在来看看标签。

开放图像标签更容易访问,可以通过点击开放图像下载页面上的特定下载链接或运行以下代码来下载(花絮:滚动到下载页面的底部查看关于标签的信息)。

# Open Images training dataset bounding boxes (1.11G)
!wget https://storage.googleapis.com/openimages/2018_04/train/train-annotations-bbox.csv

# Open Images validation dataset bounding boxes (23.94M)
!wget https://storage.googleapis.com/openimages/v5/validation-annotations-bbox.csv

# Open Images testing bounding boxes (73.89M)
!wget https://storage.googleapis.com/openimages/v5/test-annotations-bbox.csv

# Class names of images (11.73K)
!wget [https://storage.googleapis.com/openimages/v5/class-descriptions-boxable.csv](https://storage.googleapis.com/openimages/v5/class-descriptions-boxable.csv)

数据收集的第一阶段获得了以下文件。

  • 来自开放图像训练、验证和测试集的 1 类(咖啡机)图像。
  • 训练(train-annotations-bbox.csv)、验证(validation-annotations-bbox.csv)和测试(test-annotations-bbox.csv)设置包围盒图像标签。
  • 不同打开图像类别的描述(class-descriptions-boxable.csv

为什么只有 1 节课?

我的计划是从小处着手。获取数据预处理和使用 1 个类的 Detectron2 模型,然后在需要时扩展。

数据准备:将打开的图像数据和标签输入到 Detectron2 样式的输入中

  • 成分: 5 个预处理功能,4 个标签文件,38,000+ x 个打开的图像,Detectron2 文档
  • 时间: 1 周+/- 1 周
  • 成本: $0
  • 器具 : Google Colab,本地机器

这里的技巧是将我的数据文件(一些标签 CSV 和几个图像文件夹)重新混合到 Detectron2 样式标签中。

我发现如果你想在 Detectron2 中使用你自己的自定义数据,你需要把它转换成一个字典列表。其中每个字典是与 1 幅图像相关联的信息。

让我们看一个例子。

Detectron2 将一个字典列表作为输入。如果您想使用自己的自定义数据,您必须将标签格式化为这种样式。

现在,这些字段分别是什么意思?

  • annotations(列表):一幅图像上的所有注释(标签),一幅图像可能有不止一个。对于对象检测(我们的用例),它包含:
  • bbox(int 列表):边界框的像素值坐标。
  • bbox_mode ( 枚举)bbox中像素值的顺序和比例详见文档。
  • category_id (int):物体类别在bbox内的数值映射,例子{'coffeemaker':0, 'fireplace':1}
  • file_name (str):目标图像的字符串文件路径。
  • height (int):目标图像的高度。
  • width (int):目标图像的宽度。
  • image_id (int):唯一图像标识符,在评估期间用于识别图像。

如果你想用 Detectron2 建立你自己的物体检测模型,你需要为你的每一张图片安装一个。

正如我们将在后面看到的,我对这个项目的第一个主要目标是获得一个运行在定制数据上的小模型(总是从小模型开始)。

从小处着手意味着为 1 类图像(咖啡机)编写数据准备功能,并确保它们与 Detectron2 一起工作。

获取图像 id

从开放图像下载数据的好处是每个图像都有一个唯一的标识符。

例如,1e646e27c250cd56.jpg是一张咖啡机的图片,其唯一标识符1e646e27c250cd56不同于开放图像中的所有其他图像。

所以我写了一个名为get_image_ids()的函数,它将遍历一个文件夹并返回该文件夹中所有唯一图像 id 的列表。

这意味着我知道我正在处理的所有图像。

格式化现有注释文件

为什么拥有唯一图像 id 列表会有所帮助?

原因如下。

当您从打开的图像下载标签文件并使用 pandas 导入它们时,它们看起来像这样。

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

打开图像的验证标签的示例。参见 Colab 上的完整代码和示例笔记本。

看到 ImageID 列了吗?在那里,我们可以匹配从打开的图像中下载的图像 id 列表。

但是等等。

为什么要这么做?

两个原因。

首先,我们需要额外的信息,比如 XMin、XMax、YMin 和 YMax 坐标(我们很快就会看到这样的例子)。

第二,从打开的图像中下载注释文件会导致我们获得数据库中每个图像的注释,但是我们只对目标图像的注释感兴趣。

您可能已经注意到 LabelName 列有一些奇怪的值,如/m/0cmf2/m/02xwb,事实证明,这些也是代码。

这就是神秘的class-descriptions-boxable.csv发挥作用的地方。

让我们来看看。

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

开放图像标签代码到人类可读类名的映射。

我不知道你怎么想,但是这个名字看起来比/m/0cmf2/m/02xwb好多了。

有了这些以及一个目标类列表,在我的例子中,只有咖啡机,开始时,我有了创造format_annotations()所需的所有材料。

在一个冗长的句子中,format_annotations()从打开的图像中下载一个现有的注释文件,比如,[validation-annotations-bbox.csv](https://storage.googleapis.com/openimages/v5/validation-annotations-bbox.csv)向其中添加一些有用的信息(比如人类可读的类名和每个类的数字分类 ID)并删除不需要的行(我们不关注的图像)。

来看一个小亮点。

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

运行 format_annotations()函数会添加 ClassName 和 ClassID 列,并删除不需要的标签行(查看更改后的索引值)。参见 GitHub 上的完整代码和示例笔记本。

运行这个函数负责标签字典的category_id部分。至于删除所有非咖啡机行,validation-annotations-bbox.csv从 303980 行减少到 62 行。

我们正在取得进展,但还没有完成。

将边界框像素值从相对值转换为绝对值

你可能想知道标签字典中的bbox_mode是什么意思。

如果没有,我会告诉你我是如何处理的。

bboxbbox_mode是舞伴。

再看一下打开的图像标签,您会看到 XMin、XMax、YMin 和 YMax 列。这些是图像上每个边界框的相对像素坐标。

相对像素坐标意味着要找到目标边界框的每个角出现的实际像素值,必须将 XMin、XMax 值乘以图像的宽度,将 YMin 和 YMax 值乘以图像的高度。

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

打开的图像带有 XMin、XMax、YMin 和 YMax 的相对像素值坐标。由于边界框是矩形或正方形的,知道左下角和右上角的坐标就足够了。

了解这一点很重要,因为 Detectron2 目前仅支持绝对像素值(相对像素值乘以高度或宽度的结果)。

顺序也很重要。

打开图像边界框的顺序为 XMin、XMax、YMin、YMax,但 Detectron2 需要 XMin、YMin、XMax、YMax。

这就是函数rel_to_absolute()的用武之地。

它使用图像的高度、宽度和现有边界框坐标,并使用它们将开放图像样式坐标转换为 Detectron2 样式坐标。

一旦我们完成了转换,bbox参数就会以bbox_mode ( BoxMode.XYXY_ABS)的形式出现。

创建图像词典(检测器 2 样式标签)

到目前为止,我们已经创建了一些辅助函数。是时候把所有的东西放在一起了。好消息是,我们已经完成了大部分繁重的工作。

倒数第二个(倒数第二个,是的,还有一个)助手函数是get_image_dicts()

它采用一个目标图像文件夹、一个相关的注释文件和一个目标类列表,然后使用上面的函数、get_image_ids()format_annotations()rel_to_absolute()加上一点自己的逻辑来创建 Detectron2 样式标签(一个字典列表)。

哇哦。那是一口。

在这一点上,提醒读者如果你想看到这一点,检查的例子谷歌 Colab 笔记本

现在,我们将继续这个故事。

哦,对了,关于get_image_dicts()还有一件事你应该知道,一旦它创建了图像字典列表,它会将它们保存到一个 JSON 文件中。这确保了我们以后可以使用它们。

get_image_dicts()将打开的图像和标签转换为 Detectron2 样式标签的示例用法(词典列表)。参见 GitHub 上的完整代码和示例笔记本。

我所说的稍后,是指当你用 Detectron2 注册一个数据集的时候。

出于某种原因,当您用 Detectron2 注册数据集时,数据集需要一些预处理,预处理必须用 lambda 函数完成,因此只能接受一个参数。

进入load_json_labels(),这是最后一个助手函数,它从目标图像文件夹中导入一个 JSON 文件(记住我们是如何保存它们的,以备后用)。

这里你要注意的技巧是,确保如果你将图像字典保存到文件并重新导入它们,你要确保bbox_mode被格式化为 Detectron2 风格的 BoxMode。

BoxMode 是一个 Python 枚举类型,一个特殊的类型,根据我的经验,它不能很好地保存到 JSON 中(你也许能在这里启发我)。

嘣。

数据预处理完成。我们所要做的就是用 Detectron2 注册我们的数据集,然后我们就可以开始建模了。

等等,为什么我们需要用 Detectron2 注册数据集?

现在,我不完全确定这一点。但是一旦这样做了,注册的数据集就变成了半不可变的(不能轻易改变)。

这似乎是一个防止未来数据集不匹配的好主意。

一个叫DatasetCatalog.register()...的小家伙,还有MetaDataCatalog.get()…(这是使用load_json_labels()的地方)然后我们出发去建模站。

建模和实验:从小处着手,不断迭代

  • **成分:**开放图像的小子集(3 类),开放图像的 10%子集(所有类)
  • 时间: 2 周+/- 2 天
  • 成本: $0
  • 器具:谷歌实验室,砝码&偏差,探测器 2 模型动物园

我们已经谈了很多了。但好消息是,一旦你准备好了数据集,Detectron2 会让建模阶段变得非常有趣。

在我开始之前,我必须提醒自己机器学习的第一条规则:从小处着手,经常实验,需要时扩大规模。

这看起来像什么?

还记得标签创建是如何从只为一类图像创建标签开始的吗?模特界也是如此。

为什么从小处着手?

你知道俗话说得好。如果船朝着错误的方向行驶,再用力划船也无济于事。

因此,我开始用 1 个类(咖啡机)获得一个 Detectron2 模型。

一旦成功了,我就把它扩大到 2 个班,然后是 3 个班。您必须知道,每次我这样做时,我都会发现我的预处理函数哪里出了问题,需要改进。其中一个主要问题是确保标签只为目标类创建,而不是来自开放图像的所有类。

在让探测器 2 和 3 个班级一起工作后,下一步是开始认真做模型实验。

你看,我在 Airbnb 的文章中读到,他们开始进行迁移学习,但没有取得多大成功,之后他们转向了谷歌的 AutoML。AutoML 工作,但他们说,限制是不能下载模型。

由于我的标准之一是避免使用 Google 的 AutoML(以修复模型可访问性限制),所以我没有使用它。

相反,我参考了 Detectron2 的模型动物园,这是一个与 COCO(上下文中的常见对象)数据集相关的模型集合,并发现已经有一些对象检测模型准备就绪。

太美了。

我的想法是,我将尝试每个预训练的对象检测模型,利用他们从 COCO 数据集学习的模式,用我自己的数据(一个小数据集)升级模式,看看它是否有效。

我照做了。

我从我想尝试的 Detectron2 模型动物园中定义了一个模型字典。

做了一个小实验。

# My first modelling experiment in pseudocode
for model in models_to_try: 
    with random_seed x
    do 3000 iterations 
    on classes coffeemaker, bathtub, tree house 
    save results to Weights & Biases

这个实验的目的是看哪个 Detectron2 对象检测模型在我的数据集上表现最好。我假设我可以通过控制除了模型之外的所有东西(因此是随机种子)来解决这个问题。

现在你可能想知道,你是如何决定这些模型的?

问得好。我看了模型动物园网页,选了它们。

好吧,那么,你是如何追踪你的实验结果的?

很高兴你问了。这就是权重&偏差出现的原因。weights&bias 是一个追踪深度学习实验的非凡工具,如果你还没有使用过,你应该使用它。

发生了什么事?

我做了实验。由于权重和偏见,结果是美丽的。

为什么?

因为模型显示他们正在学习一些东西(平均精度,一种评估物体检测模型的度量标准正在提高),并且每个模型之间没有任何奇怪的差异(意味着实验控制有效)。

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

我第一次重大实验的结果。每一根棒线都是权重和偏差的“运行”。实验名称可以在左侧看到,每个实验名称对应于 models_to_try 中不同模型的结果。你可以看到关于重量&偏差的完整项目实验。

然后呢?

为了缩小范围,看看我应该使用哪个模型来建立一个大狗模型(一个拥有所有数据并训练更长时间的模型),我假设了另一个实验。

我会从我的第一个实验中选取前两个模型,retina net _ R _ 50 _ FPN _ 1x(细雾-37 )和retina net _ R _ 101 _ FPN _ 3x(earthly-cloud-39),在一个更大的数据集(占所有数据的 10%)上训练它们一段合理的时间(大约 1000 次迭代),然后比较结果。

# My second modelling experiment in pseudocode
for model in top_2_models: 
    with random_seed x
    do 1000 iterations 
    on 10% of the total data 
    save results to Weights & Biases

然后,无论哪一个模型脱颖而出,都将成为大狗模型。

必须知道的是,由于我在自己设定的期限内(整个项目 42 天),快速试验是最重要的。

在 Airbnb 的文章中,他们提到他们一次训练他们的模型 5 天和 3 天。因为我总共花了 10 天时间做模特,所以我只有一次机会训练一个大狗模特。

到这个阶段,我已经从开放图像下载了完整的训练、验证和测试数据集。为了运行第二个主要实验,这次我决定在整个数据集的一部分上比较两个性能最好的模型(所有 30 个目标类,而不是只有 3 个类)。

数据集状态:

  • 34,835 张训练图像
  • 860 张验证图像
  • 2,493 张测试图像

当对小部分数据进行建模实验时,小部分数据与完整数据具有相同的分布是很重要的。

换句话说,如果您要对 10%的数据进行建模实验,请确保这 10%的数据与整个数据集具有相同的类分布。在 Airbnb 数据集的情况下,如果完整的数据集有大量楼梯的图像,但没有很多葡萄酒架的图像,则较小的版本应该反映这种关系。

我通过从完整的数据集中随机选择示例,并确保类的分布看起来相似,来拆分 10%的训练数据。

# Get 10% of samples from train dataset
small_dataset = full_dataset.sample(frac=0.1)

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

创建与原始训练集具有(大致)相同分布的训练数据的 10%子集。这样做意味着实验可以在较小的规模上运行,但仍然可以代表整个数据集可能发生的情况。对测试数据集进行了同样的处理。

我最后还将来自开放图像的验证和测试集合并成一个数据集val_test。这是因为 Airbnb 提到他们使用 10%的测试数据分割进行评估(75k 总图像、67.5k 训练图像、7.5k 测试图像)。

数据集状态:

  • 34,835 张训练图像
  • 3,353 个测试图像(原始验证和测试集图像合并)

准备好较小的代表性数据集后,我开始了第二个主要实验,确保跟踪权重和偏差方面的一切。

事实证明,两个模型都表现良好,这意味着应该上升的指标(平均精度)在上升,应该下降的指标(损失)在下降。尽管班级数量增加了 10 倍,但我的模型在学习(这是件好事)。

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

比较retina net _ R _ 50 _ FPN _ 1x(sleek-sound-45)和retina net _ R _ 101 _ FPN _ 3x(stilled-space ship-46)在 1000 次迭代中对总数据的 10%进行训练的结果。比仅在 3 个类上训练模型的结果更差(预期),但平均精度上升是一件好事。

基于我的第二个主要实验的结果,我最终决定retina net _ R _ 101 _ FPN _ 3x(高跷-飞船-46 )将升级为大狗模型状态。

训练大狗模型(根据所有数据训练的模型)

  • **成分:**38000+公开图片(Airbnb 的所有目标类)
  • **时间:**人类时间 3 天,计算时间 18 小时
  • 成本:$ 150–175 美元(每小时 1.60 美元 P100 GPU +多重故障+未充分利用的实例)
  • 器具:砝码&偏差,检测器 2retina net _ R _ 101 _ FPN _ 3x

Detectron2 的预训练模型是在大盆(一台有 8 个 GPU 的大狗电脑)上训练的。我没有 8 个 GPU(图形处理器,一种能够快速计算的计算机芯片),迄今为止,我所做的一切都是在谷歌 Colab (1 个 GPU)或我的本地计算机(没有 GPU)上完成的。

根据我之前的实验,用 10%的数据进行 1000 次迭代的训练,我知道使用 1 个 GPU 对整个数据集进行 100,000 次以上迭代的完整训练运行(摘自 Airbnb 的文章和 Detectron2 模型配置文件)需要大约 15 到 20 个小时。

有了这个信封背面的时间线计算,我想我真的只有一次机会来训练一只大狗模型。

最初,我打算做一些超参数调整(调整模型设置以获得更好的结果),但由于限制,没有像我希望的那样在这里花太多时间。

所以我决定只关注几个:

  • 学习率(模型在任一时刻试图提高其知识的程度)。
  • 小批量(模型一次看多少张图片)。

根据我的经验,除了模型本身的结构(图层等,反正已经由 Detectron2 决定了),这两个设置对性能影响最大。

我偶然发现了线性学习率缩放规则,读了更多关于它的内容,并决定将其应用于retina net _ R _ 101 _ FPN _ 3x模型的基础设置

线性学习率比例规则说,你的批量大小和学习率应该随着你使用的 GPU 的数量而增加和减少。

例如,由于我使用的是 1 个 GPU,而不是 Detectron2 最初的 8 个 GPU,如果遵守规则,我应该将最初的学习速率和小批量大小除以 8。

# Linear learning rate scaling rule
new_learning_rate = old_learning_rate/(new_num_gpus * old_num_gpus)

我相应地调整了设置,由于我使用的是迁移学习(不是从头开始训练),我将新的学习率除以 10。

为什么?

我在 Airbnb 的文章中读到,当他们尝试迁移学习时,他们将学习除以 10,作为一种预防措施,以免在新模型学习时,原始模型模式丢失得太快。

这在直觉上对我来说是有意义的,但是,我肯定有更好的方法或者更好的解释。如果你知道,请告诉我。

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

在 8 个 GPU 上训练的原始 Detectron2 RetinaNet 设置和从头开始更新,以反映在 1 个 GPU 上训练的线性学习率调度规则(较低的学习率和批量大小)并使用迁移学习(增加迭代次数和再次降低学习率)。

怎么样了?

好吧,18.5 小时,34,834 幅训练图像和 180,000 个训练步骤在 P100 GPU 上完成后,我的模型在保留的测试集上以 mAP(平均精度)得分 43.297% 结束。

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

在 P100 GPU 上使用预训练的检测器 2 retinanet_R_101_FPN_3x 模型进行 18 小时迁移学习的最终结果。AP 指标越高越好。请注意,有些类的结果比其他类高,这与它们在数据集中的示例数量相关(示例越多,得分越高)。参见完整训练跑步、设置和更多关于重量&偏差的内容。

低于 Airbnb 使用谷歌 AutoML 的 68%地图的结果,但高于他们使用迁移学习的结果。

不过应该指出的是,这些指标(我的和 Airbnb 的)实际上没有可比性,因为我们使用了不同的数据集,我只能访问公共数据,Airbnb 有公共和内部图像数据。

但是计量是计量,对吗?

对计算机视觉模型的真正测试是在实际图像上。让我们看看测试集中的几个(记住,模型以前从未见过这些)。

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

迁移学习训练的 Detectron2 模型的示例,根据开放图像对不可见图像进行舒适度预测。从左到右:厨房里的便利设施被收拾得很好,洗衣机很快就被发现,最后的酒架也被发现。注意:由于这些图像来自开放图像,其中许多不同于标准的 Airbnb 风格的图像。

我的卧室和厨房提供的一些定制图片怎么样?

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

经过充分训练的模型对我家周围的一些图像进行预测的例子。从左到右:我的床收拾得很好,模特也找到了厨房里的大多数便利设施,但很难从我的工作站中挑选出合适的东西(注意:右图中的许多物品不在培训集中)。

看到机器学习模型在股票数据上工作:嘿,这太酷了…

看到一个机器学习模型在自己的数据上工作:OMG 这是什么魔法???

建模完成后(在时间允许的情况下),是时候让它上线了。

应用构建和部署:Jupyter 中的定制模型很酷,但在网络上直播更酷

  • **成分:**完全训练好的定制机器学习模型
  • 时间: 4 天
  • 成本: $14 托管每天(我知道,我需要解决这个问题)
  • 器具 : Streamlit,Docker,Google 容器注册,Google 计算引擎

机器学习模型部署似乎仍然有点像黑暗艺术。

首先,在 Jupyter 笔记本上编码和写 Python 脚本是不一样的。然后你就有了你需要的不同的包,从数据科学库到 web 框架。然后你必须围绕你的模型建立某种用户可以与之交互的界面。一旦你做到了这一点,你在哪里举办呢?

对于任何初露头角的机器学习工程师来说,所有这些挑战都值得接受。

毕竟,如果一个模型只存在于 Jupyter 笔记本中,那么它是否存在呢?

如果你像我一样是一个 Jupyter 笔记本战士,好消息是,Streamlit 和 Docker 可以帮助你。

Streamlit 帮助你为你的机器学习和数据项目建立一个用户界面。更好的是,它也是用 Python 写的。如果你从未尝试过,花半天时间浏览所有的教程,你就可以搞定了。

现在码头工人。Docker 可以帮助你将所有文件(Streamlit 应用、机器学习模型和依赖项)打包成一个漂亮的小包(称为 Docker 映像)。一旦你得到了这个包,你可以把它上传到一个云服务器(例如 Google Cloud ),一切正常,它应该完全像在你的本地系统上那样运行。

所以你让一个训练有素的模型在笔记本上做预测?您部署它的工作流程可能是这样的(我就是这样做的):

  1. 创建一个类似于app的文件夹。这是您的 Streamlit 应用程序(一个 Python 脚本)、模型工件和所有其他所需文件的位置。
  2. 在新文件夹中创建一个全新的 Python 环境。您需要安装准系统依赖项,以便您的应用程序在此环境中运行。在我的例子中,我需要 Streamlit 和 Detectron2 的依赖项。
  3. 围绕您的模型构建一个 Streamlit 应用程序(Python 脚本)。
  4. 让 Streamlit 应用程序在本地工作。这意味着你可以在电脑上互动和查看应用程序的工作情况。
  5. 为您的环境和应用程序文件夹创建 Docker 映像。
  6. 将您的 Docker 图片上传到 Docker Hub 或 Docker 托管服务,如 Google Container Repository。
  7. 使用云提供商,如 Heroku、Google Cloud 或 AWS 来托管和运行您的 Docker 映像。

如果一切顺利,您应该会得到一个指向您托管的应用程序的 URL。

由于我使用了谷歌的应用引擎,我的结果是这样的:airbnb-amenity-detection.appspot.com

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

我的 Streamlit 应用程序在我的床的图像上运行的(加速)演示。参见 YouTube 上的全面部署和应用构建视频。

我们非常快速地介绍了应用程序的构建和部署。但是如果你有兴趣了解更多,我会查看以下资源(按顺序)。

标准和评估:比较我的模型和 Airbnb 的

我以一系列我想要达到的标准开始了这个项目。

我们来复习一下。

  • **✅的用户可以通过移动设备访问该应用。**这种做法可行,但不可行。尽管如此,它还是会滴答作响。
  • **🚫击败或至少等同于 Airbnb 的 50% mAP 的 MVP。**我的所有型号都没有达到或超过这个门槛。所以这是一个失败。
  • ✅修复了 Airbnb 使用的 AutoML 模型无法下载的痛点。我训练有素的 Detectron2 模型可供下载,任何人都可以使用。滴答。
  • 🚫通过某种方式找到模型最不确定的图像/类。你可以通过查看评估指标打印输出来做到这一点,但我想更多的是一个可视化功能,以实现对表现不佳的类/图像的主动学习方法。失败。
  • 💰**运行该模式的成本效益如何?**对于这一个,让我们拿出记事本。

在 Airbnb 看了一个关于机器学习的视频后,有人提到他们在网站上有超过 5 亿张图片(是的,超过 5 亿张)。对于我们的计算,让我们假设我们想要运行我们的模型跨越所有这些。

使用我训练的 retinanet_R_101_FPN_3x 模型和我使用的GPU(英伟达 P100)对每张图像进行预测大约需要 0.2s。

  • GPU 成本:1.46 美元/小时(美国中部 GPU),0.0004 美元/秒
  • 推断时间:0.2s/张,5 张/秒
  • 图像总数:5 亿
  • 总推理时间:100,000,000 秒(500,000,000/5)
  • 每幅图像的推理成本:0.000081 美元
  • 推理总成本:40,555.55 美元
  • 总推理时间(1 个 GPU):27778 小时(1160 天)。

当然,还需要更多的计算来看这个模型能增加多少价值。但是看到这些会让你知道 Airbnb 的所有图片需要多少概念证明。

很明显,在目前的状态下,在 Airbnb 的 5 亿多张图片上使用该模型可能是不可行的。

然而,这些数字也是使用谷歌云上 1 个租用的 GPU 计算出来的。如果一台本地机器有多个 GPU,成本(和时间)可以大大减少。

最后值得一看的对比是 Airbnb 在他们的文章中使用的最后一个。他们开始了他们的项目,作为一种建立他们自己的定制计算机视觉模型的方式,这将使他们免于使用第三方舒适性检测服务。

他们注意到,第三方舒适度检测服务只显示置信度超过 0.5 的预测结果(得分越高,模型对其预测越有信心)。所以为了进行公平的比较,他们修改了他们的 Google AutoML 模型来做同样的事情。

这样一来,Airbnb 的 Google AutoML 模型的结果从 68% 的地图变成了 46% 。看到这一点,我用我的模型做了同样的事情,发现结果从 43.2%35.3%

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

从左到右:Airbnb 的 Google AutoML 模型图在置信度 0.5 截断,第三方模型 Airbnb 试图以置信度 0.5 截断开始(来源:原创 Airbnb 舒适度检测文章),我训练的 Detectron2 模型在置信度 0.5 截断。**注意:**这些模型不能完全比较,因为我的模型是在不同的数据集上训练的(没有内部图像)。这个形象只是为了给出一个发人深省的对比。注 2: 至于我的条形图(最右边),我想我已经非常接近复制原件了,你不觉得吗?

扩展、潜在改进和要点

当然,这个项目并不完美。但我没想到会是这样。我是厨师,不是化学家。

我本想在 42 天结束前多做几件事,比如:

  • **超参数调谐。**尽管我的模型表现很好,但我并没有像我希望的那样做太多的超参数调整。如果我要这么做,我可能会求助于权重&偏差扫描(一种用于尝试、调整和跟踪超参数的工具)。有了调整后的超参数,谁知道呢,也许我的模型可以提高 1-5%。
  • **减少了推断时间。**正如在计算模型的业务用例成本时所看到的,为了大规模运行(在 Airbnb 的所有图像上),推理时间将需要大幅减少或使用更多的处理能力(更多的 GPU)。在进行这个项目 EfficientDet 时,发布了一个高效的对象检测算法。所以这可能是我接下来要尝试的。
  • **下载时创建的标签。**预处理 Open Images 数据以使用 Detectron2 需要几个步骤,这些步骤在下载图像时可能会自动执行。
  • 一个不那么花哨的应用(是我的错,不是 Streamlit 的)。我仍然习惯于部署我在 Jupyter 笔记本上写的代码。将来,我还想拥有自己的服务器,可以将 Docker 容器推送给其他人并与其他人共享。
  • 再培训渠道。如果添加了更多图像或类别,我如何轻松地重新训练模型?现在,这几乎需要重新运行整个项目。
  • **检验功能。**如果我想检查数据并查看厨房&餐桌的所有图像或预测低于某个置信度阈值的所有图像,我不能。这些类型的可视化功能对于进一步的数据探索是至关重要的(也许应该从一开始就构建)。
  • **哪些图像中有人物?**因为我用的是开放图片,所以很多图片里面都有人物。级联模型可以用来过滤掉不想要的图像风格,只关注与 Airbnb 用例相关的图像。

综上所述,这个项目实现了它的主要目标:边做边学。

我学到了一些我以前从未使用过的工具,更重要的是,我可以如何构建未来的项目。

主要的收获是,实验,实验,实验。

看看是怎么做的

尽管这篇文章很长,但它只是我在这个项目中采取的实际步骤的一个简短概述。

如果你想看到它们全部展开,你可以阅读观念中的我的项目笔记(日志风格)。

或者观看我创建的 YouTube 系列来配合它。

我创建的 YouTube 系列的第 8 部分是为了配合这个项目。

使用机器学习来预测衰退

原文:https://towardsdatascience.com/replicating-machine-learning-prediction-of-recessions-yazdani-2020-9b9500131c71?source=collection_archive---------27-----------------------

复制“衰退的机器学习预测”(亚兹达尼,2020 年)

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

可爱的北极熊在打招呼——在金融市场上,熊通常没那么可爱

包含所有代码的笔记本可以在这里找到。

我最近发现了一个关于从经济数据中预测美国衰退的有趣的演示。虽然我对这个话题并不完全惊讶,但吸引我眼球的是他们的模型的绝对难以置信的准确性。

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

最佳模型是 AUC 为 95 %的随机森林!!!

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

你看那个随机森林的 ROC 曲线!

我们谈论的是曲线下 95 %的区域,完美的灵敏度,和近乎完美的特异性。当然,他们一定犯了错误?文章本身是在付费墙后面的。尽管如此,这种表达提供了足够的信息用于复制。

他们是怎么做到的?

根据陈述,他们使用了非常基本的经济指标(联邦基金利率的差异,失业率等。)以及作为整体市场指标的 SP500(美国 500 家最大公司)月度价格差异。他们有时使用对数差异,因为这些差异更可能遵循正态分布。

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

这些是所使用的预处理步骤和特性

在他们的研究中,他们使用了 1959 年 1 月至 2019 年 12 月的月度数据。

我从哪里获得数据的快速总结:

Quandl:

  • 由 GDP 推断的衰退
  • 联邦基金利率
  • 工业生产指数
  • 非农工资
  • 失业率
# you can download the data like this -> might require API key
recession_data = quandl.get("FRED/USRECQP", collapse="monthly") fed_funds_data = quandl.get("FRED/FEDFUNDS", collapse="monthly")
indpro_data = quandl.get("FRED/INDPRO", collapse="monthly")
nonfarm_payroll_data = quandl.get("FRED/PAYEMS", collapse="monthly")
unemploy_data = quandl.get("FRED/UNEMPLOY", collapse="monthly")

市场观察

  • 500 先令

宏观趋势

  • 10 年期国债

关于宏观趋势,只有 1962 年开始的数据可用。因此,我将只考虑 1962 年开始的数据。

# load in merged data 
data = pd.read_csv("../data/replication_data.csv", index_col=0)# fill missing recession data
data["recession"] = data["recession"].fillna(method='ffill')

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

这是我们的目标——根据 GDP 推断的衰退

准备数据

数据准备非常简单。我们计算对数差和差。此外,我们在测试集上划分序列中的数据,从 1962 年开始,但在其他方面坚持演示中建议的结束日期。

# calculate logarithmic differences 
def log_diff(v): 
    log_diff = np.log(v/v.shift(1))
    return log_diff# preprocessing 
data["slope_yc"] = (data["ty10"] - data["fedfunds"]).diff()
data["fedfunds"] = data["fedfunds"].diff()
data["indpro"] = log_diff(data["indpro"]) 
data["nonfarm"] = log_diff(data["nonfarm"])
data["SP500"] = log_diff(data["SP500"])
data["ty10"] = (data["ty10"]).diff()
data["unemploy"] = log_diff(data["unemploy"])
data["recession"] = data["recession"].shift(1)

我们的列车周期是从1962–02 到 2006–12。

我们的测试周期为 2007 年 1 月至 2019 年 12 月。

# get x and y 
X = data.drop(['recession'], axis=1)
y = data["recession"]# divide in train test according to paper 
X_train, y_train = (X.loc["1962-02-28":"2007-01-01"], y.loc["1962-02-28":"2007-01-01"])
X_test, y_test = (X.loc["2007-01-01":], y.loc["2007-01-01":])

处理阶级不平衡

鉴于他们文章的完整标题是“衰退的机器学习预测:不平衡的分类方法”——衰退是一个非常罕见的事件,这一事实应该在充分拟合模型的过程中发挥主要作用。

首先,我们可能会问自己,这些衰退月份在数据中出现的频率有多高?

print(data["recession"].value_counts())0.0    612
1.0     83
Name: recession, dtype: int64

少数民族阶层只占 13.56 %!

那么你如何处理阶级不平衡呢?

有两种主要策略:

  1. 欠采样按顺序

使用欠采样,您从多数类中采样样本以匹配少数类。由于演示没有提到使用了哪种方法,我使用了随机欠采样

2.过采样

通过过采样,您可以将数据综合添加到少数类中,以匹配多数类。 SMOTE 是一种常用的过采样技术。

我将对训练数据使用过采样和欠采样来帮助拟合我们的模型,并将它们与原始数据进行比较。

## Sampling techniques

from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler

# oversample using SMOTE 
sm = SMOTE(random_state=42)
X_train_smote, y_train_smote = sm.fit_resample(X_train, y_train)

# undersample randomly
rus = RandomUnderSampler(random_state=42)
X_train_rnd, y_train_rnd  = rus.fit_resample(X_train, y_train)

我们得到了三组不同的火车。原始训练数据,一个带有 SMOTE 的过采样版本和一个随机欠采样版本。

train_test_pairs = {"Normal":(X_train, y_train), 
                    "SMOTE":(X_train_smote, y_train_smote), 
                    "Undersampling":(X_train_rnd, y_train_rnd)}

由于论文标题强调了这样一个事实,即这是一个不平衡数据的问题——幸运的是,衰退是一种罕见的事件——我预计这些抽样方法的得分会有很大不同。

符合我们的模型并进行评估

所以让我们比较三种采样方法——拟合一个随机森林,看看性能。

fig = go.Figure()
fig.add_shape(
    type='line', line=dict(dash='dash'),
    x0=0, x1=1, y0=0, y1=1
)

for label, pair in train_test_pairs.items(): 
    clf = RandomForestClassifier(max_depth=10, n_estimators=100, class_weight = "balanced_subsample", random_state=0)
    clf.fit(pair[0], pair[1])
    y_pred= clf.predict(X_test) 
    fpr, tpr, thresholds = metrics.roc_curve(y_test, clf.predict_proba(X_test)[:,1])
    auc = metrics.roc_auc_score(y_test, clf.predict(X_test))

    name = f"{label} (AUC={auc:.2f})"
    fig.add_trace(go.Scatter(x=fpr, y=tpr, name=name, mode='lines'))

fig.update_layout(
    xaxis_title='False Positive Rate',
    yaxis_title='True Positive Rate',
    yaxis=dict(scaleanchor="x", scaleratio=1),
    xaxis=dict(constrain='domain'),
    width=900, height=700
)
fig.show()

请击鼓……

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

击鼓!照片卢兹·门多萨在 Unsplash 上拍摄

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

不同抽样方法的 ROC 曲线

不错!我们可以看到,取样方法对报告的 AUC 分数有很大的影响。欠采样比 SMOTE 执行得更好,本文中也使用了欠采样。总的来说,我认为复制是成功的— 考虑到我丢失了前三年的数据,并且我没有调优任何超参数。

那么,假设我们能够预测衰退,我们能利用这些信息做什么呢?

衰退期间你应该把钱投到哪里

我想到了几个策略。为了研究这些策略,我将使用我们的模型中的预测来拟合训练期。

1)仅限间谍

SP500 指数将作为我们的基准,因为它通常被认为是美国市场的良好代表。

2)间谍减去衰退

在经济衰退期间,人们可能想减少风险,把钱拿出来放在一边——也许藏在枕头下?

3)间谍和 GLD

黄金似乎总是一个安全的选择。在衰退期间,人们可能会观察到挤兑。

4)间谍和 VIX

VIX 是根据 SP500 期权计算的波动指数。它通常也被称为恐惧指数,更高的波动性意味着不稳定的时期。

比较这些交易策略,并使用我们模型的预测,我们得到了以下测试期的图表:

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

根据测试集上的预测返回不同的策略

这一时期的主要衰退是在 2008 年到 2010 年之间。我们看到,与流行的观点相反,投资黄金实际上不是一个好主意。黄金似乎很容易受到市场总体走势的影响。在经济衰退期间将我们的资金撤出市场是好的,但这并没有给我们带来真正的优势。另一方面,对被动投资者来说,投资于波动指数(VIX) 似乎是真正的游戏规则改变者。随着经济衰退的到来,恐惧和波动增加,利润也增加。

未来一个月会出现经济衰退吗?

为了确定是否会出现衰退,我们可以获取更多类似这样的最新数据。

# features 
fed_funds_data = quandl.get("FRED/FEDFUNDS", collapse="monthly")
indpro_data = quandl.get("FRED/INDPRO", collapse="monthly")
nonfarm_payroll_data = quandl.get("FRED/PAYEMS", collapse="monthly")
unemploy_data = quandl.get("FRED/UNEMPLOY", collapse="monthly")
spy = yf.Ticker("^GSPC").history(period='1d', start='2019-1-1').Close.resample("M").mean()
ty10 = yf.Ticker("^TNX").history(period='1d', start='2019-1-1').Close.resample("M").mean()# subsetting recent data  
data = pd.DataFrame()
data["fedfunds"] = fed_funds_data.loc["01-01-2020":].Value
data["nonfarm"] = nonfarm_payroll_data.loc["01-01-2020":].Value
data["indpro"] = indpro_data.loc["01-01-2020":].Value
data["SP500"] = spy.loc["01-01-2020":]
data["ty10"] = ty10.loc["01-01-2020":]
data["unemploy"] = unemploy_data.loc["01-01-2020":].Value

# preprocessing 
data["slope_yc"] = (data["ty10"] - data["fedfunds"]).diff()
data["fedfunds"] = data["fedfunds"].diff()
data["indpro"] = log_diff(data["indpro"]).fillna(method="ffill") # no recent data
data["nonfarm"] = log_diff(data["nonfarm"])
data["SP500"] = log_diff(data["SP500"])
data["ty10"] = (data["ty10"]).diff()
data["unemploy"] = log_diff(data["unemploy"])

我们可以使用我们的模型来估计我们的模型在预测中的置信度。

data.dropna(inplace=True)
data["recession_proba"] = clf.predict_proba(data)[:,1]fig = go.Figure()
fig.add_scatter(x= data.index, y=data["recession_proba"], mode='lines', name="SPY long")
fig.update_layout(title_text="Probabilities of a Recession according to the model")
fig.show()

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

根据我们对训练数据的随机森林拟合,对衰退的信心

截至 9 月,我们的模型确信未来一个月不会出现衰退。我们可以看到,由于杰罗姆鲍威尔美联储利率的变化以及失业人数的上升,我们实际上在 4 月和 3 月遇到了更高的信心水平。

如果你发现任何错误,有任何问题,或者想要合作,请随时在 Linkedin 上联系我。

参考

亚兹达尼(2020)。衰退的机器学习预测:不平衡分类方法。《金融数据科学杂志》。演示幻灯片检索自:https://FDP institute . org/resources/Documents/webinars % 20 thought leadership % 20 pieces % 20 etc/Al % 20 yaz dani % 20 webinar % 20 July % 208,%202020.pdf

RepNet:计算视频中的重复动作

原文:https://towardsdatascience.com/repnet-counting-repeating-actions-in-a-video-bec1bdcec149?source=collection_archive---------26-----------------------

用于计数重复动作和估计视频中周期的最新模型的方法

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

克里斯·贾维斯在 Unsplash 上的照片

虽然我们大多数人都可以在锻炼或测量脉搏时计数,但如果能有一些东西为我们计数,甚至提供关于重复动作的有价值的信息,那就太好了。特别是对于周期较长的动作,如行星周期,或者周期太短的动作,如制造带。

谷歌研究和 DeepMind 团队最近在 2020 年 CPVR 发表的一篇名为计算时间:野外不可知视频重复计数的论文解决了这个有趣的问题。

他们采用一种非常“简单”的方法来识别和计数重复的动作,并最终预测动作的周期性。但作者发现的主要障碍是管理足够大的数据集来做到这一点。因此,本文[1]的主要贡献在于:

  • 释放计数:一个新的视频重复计数数据集,它比先前最大的数据集大 90 倍
  • 发布 RepNet :一种用于计数和测量“野外”视频中重复周期的神经网络架构[1],使其优于之前的最先进方法
  • 使用合成的、无标签的剪辑并生成可用于训练的增强视频

Countix 数据集

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

Countix 中的样本来自[1]

首先,作者提出了一个新的、巨大的带有重复动作的带注释视频数据集——因为现有的重复数据集太小了。

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

请看上图,它比较了新数据集: Countix 和现有的“基准测试”(只有 100 个样本!).Countix 有从野外拍摄的视频(如 YouTube ),团队通过众包收集注释。标注器“分割包含具有明确计数的有效重复的视频部分”[1]。并且它们也继续添加计数值。一个漂亮的过程最终产生了一个比之前的数据集大 90 倍的带注释的数据集。

你可以在这里下载 Countix

在这里看一看动力学

又一个数据集

除了 Countix(其剪辑来自 、动力学 )之外,作者还提出了一种很酷的方式,即从类似真实重复视频的普通视频中生成合成视频

简而言之,他们所做的是:

  • 从运动训练集中的真实视频中截取短片,并重复该视频片段一定次数。这固定了一个计数、周期,并产生一个重复的视频。
  • 为了保持“真实度,他们在重复片段前后预挂起并附加非重复片段。例如,一个女孩可以走进视频帧,进行一次旋转(就像在结果可视化部分的图像 1 的帧 3 中),然后走开。因此,这种方法将导致重复单次旋转的片段多次——保持开始和结束时的行走片段完好无损。
  • 请看下图中的第二帧。这种奇怪的变换是将摄像机运动增强应用于视频的结果。正如我们所知,在图像中,我们可以通过旋转、倾斜、通道转换二维图像来轻松执行图像增强。类似地,作者以时间方式对这些视频应用旋转、平移和缩放变换。时间时尚本质上意味着应用于每一帧的变换不是随机的,并且当播放视频时,它在变换的顺序和流程方面仍然有意义。这个确保了我们在第二帧中看到的一个流畅的、看似动画的视频

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

摄像机运动增强来自[2]

让我们训练吧

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

布莱恩·苏曼在 Unsplash 上拍摄的照片

模型架构由以下部分组成:

  • 编码器:包括一个特征提取器(基于 ResNet-50),一个 3D 卷积层(检测重复运动的不同部分),以及使用全局 2D 最大池的维数减少
  • **时间自相似性矩阵:**计算两个帧之间的成对相似性(或者,更准确地说,两个帧的编码嵌入)
  • **周期预测器:**使用相似矩阵来预测每帧的周期长度和周期性。该预测器由 32 个 3D conv 层、多头注意力转换器层和作为分类器的 2 个 FC 层组成

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

模型架构来自[1]

这款内容丰富的 Colab 笔记本 带你经历在本地视频和你的现场网络摄像头上执行模型和测试的每一步

可视化结果

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

图一。重复计数的应用[2]

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

速度和周期性来自[2]。这表明该模型甚至能够捕捉不同频率的重复运动;这可以告诉主体是减速还是加速。

接下来呢?

你能想出这种方法需要解决的事件或角度吗?这在现实世界中哪里可以工作?哪里没有?

本文提供了 RepNet 的以下实际应用:

  • 运动追踪:计数、速度等。
  • 依靠心电图视频
  • 天文和地球物理变化,如一天的长度或分析天体事件的卫星图像

参考资料:

[1]Dwibedi,Debidatta 等,“计算时间:野外的类不可知视频重复计数。”2020 年,IEEE/CVF 计算机视觉和模式识别会议论文集

链接到 PDF

[2]RepNet[1]的项目网页:https://sites.google.com/view/repnet

感谢您从头到尾的阅读!您可以通过 LinkedIn联系我,获取任何信息、想法或建议。

报告太长无法阅读?使用 NLP 创建摘要

原文:https://towardsdatascience.com/report-is-too-long-to-read-use-nlp-to-create-a-summary-6f5f7801d355?source=collection_archive---------12-----------------------

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

塞巴斯蒂安·赫尔曼在 Unsplash 上的照片

创建个人文本摘要的指南

你是否曾经有过多的报告需要阅读,而你只是想快速总结每份报告?你有没有遇到过这样的情况,每个人都只想读一份摘要而不是一份完整的报告?

在 21 世纪,摘要已经成为解决数据过载问题的一种非常有用的方法。在这个故事中,我将向您展示如何使用 Python 中的自然语言处理(NLP)创建您的个人文本摘要。

前言:创建个人文本摘要并不困难——初学者很容易做到!

什么是文本摘要?

这基本上是一个任务,生成一个准确的总结,同时保持关键信息,不失去整体意义。

有两种常见的总结类型:

  • 抽象概括 > >从原文生成新句子。
  • 摘录摘要 > >识别重要的句子,并使用这些句子创建摘要。

我应该使用哪种总结方法,为什么?

我使用提取摘要是因为我可以将这种方法应用于许多文档,而不必进行大量(令人生畏的)机器学习模型训练任务。

除此之外,提取摘要比抽象摘要给出更好的摘要结果,因为抽象摘要必须从原始文本生成新的句子,这是比数据驱动的方法更难提取重要句子的方法。

如何创建自己的文本摘要?

我们将使用单词直方图来排列句子的重要性,然后创建摘要。这样做的好处是,您不需要训练您的模型将它用于您的文档。

文本摘要工作流

下面是我们将遵循的工作流程…

导入文本> > > >清理文本并拆分成句子> >移除停用词> >构建词直方图> >排列句子> >选择前 N 个句子进行汇总

(1)样本文本

我使用了一篇名为**苹果以 5000 万美元收购人工智能初创公司的新闻文章中的文字来推进其应用程序。**你可以在这里找到原来的新闻文章

也可以从 my Github 下载文本文档。

(2)导入库

# Natural Language Tool Kit (NLTK)
import nltk
nltk.download('stopwords')
nltk.download('punkt')# Regular Expression for text preprocessing
import re# Heap (priority) queue algorithm to get the top sentences
import heapq# NumPy for numerical computing
import numpy as np# pandas for creating DataFrames
import pandas as pd# matplotlib for plot
from matplotlib import pyplot as plt
%matplotlib inline

(3)导入文本并进行预处理

有很多方法可以做到这一点。这里的目标是有一个清晰的文本,我们可以把它输入到我们的模型中。

# load text file
with open('Apple_Acquires_AI_Startup.txt', 'r') as f:
    file_data = f.read()

在这里,我们使用正则表达式来做文本预处理。我们将(A)用空格(如果有的话)替换参考号,即[1]、[10]、[20],(B)用单个空格替换一个或多个空格。

text = file_data
# replace reference number with empty space, if any..
text = re.sub(r'\[[0-9]*\]',' ',text) # replace one or more spaces with single space
text = re.sub(r'\s+',' ',text)

接下来,我们用小写字母(没有特殊字符、数字和额外的空格)形成一个干净的文本,并将其分割成单个单词,用于单词得分计算和单词直方图的形成。

形成干净文本的原因是算法不会将例如**“理解”理解**视为两个不同的单词。

# convert all uppercase characters into lowercase characters
clean_text = text.lower()# replace characters other than [a-zA-Z0-9], digits & one or more spaces with single space
regex_patterns = [r'\W',r'\d',r'\s+']
for regex in regex_patterns:
    clean_text = re.sub(regex,' ',clean_text)

(4)将文本分割成句子

我们使用 NLTK sent_tokenize() 方法将文本分割成句子。我们将评估每个句子的重要性,然后决定我们是否应该在总结中包含每个句子。

sentences = nltk.sent_tokenize(text)

(5)删除停止字

停用词是对句子没有多大意义的英语单词。可以安全地忽略它们,而不会牺牲句子的含义。我们已经在“(2)导入库”部分下载了一个带有英文停用词的文件。

这里,我们将获得停用词列表,并将其存储在 stop_word 变量中。

# get stop words list
stop_words = nltk.corpus.stopwords.words('english')

(6)建立单词直方图

让我们根据每个单词在整篇文章中出现的次数来评估它的重要性。

我们将通过(1)拆分 clean_text 中的单词,(2)删除停用词,然后(3)检查每个单词在文本中出现的频率。

# create an empty dictionary to house the word count
word_count = {}# loop through tokenized words, remove stop words and save word count to dictionary
for word in nltk.word_tokenize(clean_text):
    # remove stop words
    if word not in stop_words:
        # save word count to dictionary
        if word not in word_count.keys():
            word_count[word] = 1
        else:
            word_count[word] += 1

让我们绘制单词直方图,看看结果。

plt.figure(figsize=(16,10))
plt.xticks(rotation = 90)
plt.bar(word_count.keys(), word_count.values())
plt.show()

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

啊啊啊啊……看剧情有点难。让我们将其转换为水平条形图,并只显示前 20 个单词,下面有一个帮助函数。

# helper function for plotting the top words.
def plot_top_words(word_count_dict, show_top_n=20):
    word_count_table = pd.DataFrame.from_dict(word_count_dict, orient = 'index').rename(columns={0: 'score'})
    word_count_table.sort_values(by='score').tail(show_top_n).plot(kind='barh', figsize=(10,10))
    plt.show()

让我们展示前 20 个单词。

plot_top_words(word_count, 20)

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

从上面的剧情中,我们可以看到**‘ai’‘apple’**这几个字出现在顶部。这很有意义,因为这篇文章是关于苹果收购一家人工智能初创公司的。

(6)根据分数对句子进行排序

现在,我们将根据句子得分对每个句子的重要性进行排名。我们将:

  • 删除超过 30 个单词的句子,认识到长句子并不总是有意义的* *;
  • 然后,将构成句子的每个单词的得分(计数)相加,形成句子得分。

得分高的句子将构成我们的顶级句子。上面的句子将构成我们以后的总结。

** **注:**以我的经验来看, 2530 之间的任何字数都应该给你一个很好的总结。

# create empty dictionary to house sentence score    
sentence_score = {}# loop through tokenized sentence, only take sentences that have less than 30 words, then add word score to form sentence score
for sentence in sentences:
    # check if word in sentence is in word_count dictionary
    for word in nltk.word_tokenize(sentence.lower()):
        if word in word_count.keys():
            # only take sentence that has less than 30 words
            if len(sentence.split(' ')) < **30**:
                # add word score to sentence score
                if sentence not in sentence_score.keys():
                    sentence_score[sentence] = word_count[word]
                else:
                    sentence_score[sentence] += word_count[word]

我们将 sentence_score 字典转换成数据帧,并显示句子和分数。

注意 : dictionary 不允许你根据分数对句子进行排序,所以你需要将 dictionary 中存储的数据转换成 DataFrame。

df_sentence_score = pd.DataFrame.from_dict(sentence_score, orient = 'index').rename(columns={0: 'score'})
df_sentence_score.sort_values(by='score', ascending = False)

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

(7)选择排名靠前的句子进行总结

我们使用堆队列算法选择前 3 个句子并存储在 best_sentences 变量中。

通常 3-5 句话就足够了。根据你的文档的长度,随意改变要显示的顶部句子的数量。

在这种情况下,我选择了 3 ,因为我们的文本是一篇相对较短的文章。

# display the best 3 sentences for summary            
best_sentences = heapq.nlargest(**3**, sentence_score, key=sentence_score.get)

让我们使用循环函数的 print()来显示我们的总结文本。

print('SUMMARY')
print('------------------------')# display top sentences based on their sentence sequence in the original text
for sentence in sentences:
    if sentence in best_sentences:
        print (sentence)

这里是 我的 Github 的链接,来获取这个 Jupyter 笔记本。

下面是完整的 Python 脚本,您可以立即使用它来总结您的文本。

让我们来看看算法的运行情况!

以下是一篇题为苹果以 5000 万美元收购 AI 初创公司以推进其应用 的新闻文章的原文(原文可在此处找到**):

*In an attempt to scale up its AI portfolio, Apple has acquired Spain-based AI video startup — Vilynx for approximately $50 million.Reported by Bloomberg, the AI startup — Vilynx is headquartered in Barcelona, which is known to build software using computer vision to analyse a video’s visual, text, and audio content with the goal of “understanding” what’s in the video. This helps it categorising and tagging metadata to the videos, as well as generate automated video previews, and recommend related content to users, according to the company website.Apple told the media that the company typically acquires smaller technology companies from time to time, and with the recent buy, the company could potentially use Vilynx’s technology to help improve a variety of apps. According to the media, Siri, search, Photos, and other apps that rely on Apple are possible candidates as are Apple TV, Music, News, to name a few that are going to be revolutionised with Vilynx’s technology.With CEO Tim Cook’s vision of the potential of augmented reality, the company could also make use of AI-based tools like Vilynx.The purchase will also advance Apple’s AI expertise, adding up to 50 engineers and data scientists joining from Vilynx, and the startup is going to become one of Apple’s key AI research hubs in Europe, according to the news.Apple has made significant progress in the space of artificial intelligence over the past few months, with this purchase of UK-based Spectral Edge last December, Seattle-based Xnor.ai for $200 million and Voysis and Inductiv to help it improve Siri. With its habit of quietly purchasing smaller companies, Apple is making a mark in the AI space. In 2018, CEO Tim Cook said in an interview that the company had bought 20 companies over six months, while only six were public knowledge.*

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

…文本摘要如下:

*In an attempt to scale up its AI portfolio, Apple has acquired Spain-based AI video startup — Vilynx for approximately $50 million.
With CEO Tim Cook’s vision of the potential of augmented reality, the company could also make use of AI-based tools like Vilynx.
With its habit of quietly purchasing smaller companies, Apple is making a mark in the AI space.*

结论…还有最后一个提示

恭喜你!

您已经用 Python 创建了自己的文本摘要器。我希望这份总结看起来相当不错。

需要注意的是,我们在文档中使用了词频来对句子进行排序。使用这种方法的优点是,它不需要任何事先培训,可以处理任何文本。另一个技巧是,您可以根据自己的喜好进一步调整汇总器,基于:

*(1) **顶句数量:*这里简单的经验法则是,摘要的长度不要超过原文的 1/4——可以是一句话,一段话,也可以是多段话,取决于原文的长度和你获取摘要的目的。如果你要总结的文字比较长,那么可以增加顶句的数量;或者

*(2) **句子长度:*平均来说,今天一个句子的长度在 15 到 20 个单词.)之间。因此,限制你的总结者只采用长度超过 25-30 个单词的句子就足够了;但是,可以随意增减字数。

谢谢你读了这个故事。在 medium 上关注我,获得更多关于数据科学和机器学习的分享。

用 Python 表示分层数据

原文:https://towardsdatascience.com/represent-hierarchical-data-in-python-cd36ada5c71a?source=collection_archive---------20-----------------------

用 anytree 库解析简单的 JSON 表示

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

Edvard Alexander lvaag 在 Unsplash 上拍摄的照片

在计算机科学中,处理层次分类数据是非常常见的。应用范围从维基百科的类别到由聚类算法(如 HDBSCAN)生成的数据的层次结构,等等。

在这篇文章中,让我们从我的工作领域中的一个例子开始:如何正确分类连接到网络的设备。从“设备”的一般概念出发,我们可以定义两大类设备,称为“网络”和“计算机”。第一类可以进一步细分为“路由器”、“交换机”和“防火墙”(当然,为了简单起见,我省略了其他几类)。数据可以这样表示:

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

用于对联网设备进行分类的分类示例。

这种在层次结构中表示分类数据的方式——其自然适合的数据结构是一个——在技术上被称为 分类法 ,这个术语最初在生物学中用于对物种进行分类。分类的每个元素都是一个分类节点

如果想用人类可读的格式(如 JSON)来表示分类法,最常用的表示方法如下:

这种表示暴露了树的递归性质,但是随着分类的增长,由于大量的嵌套层次,它很快变得难以修改。在这篇文章中,我将展示 JSON 中的另一种表示,以及序列化它的 Python 代码。

分层数据的简单 JSON 表示

通过避免任何嵌套结构并将所有对象表示为按每个分类级别划分的平面列表,可以获得表示分类数据的另一种方法。这样,我们之前使用的分类示例如下所示:

和以前一样,每个节点可以包含任意数量的属性。上面的表示很容易在应用程序中解析和修改。然而,相对于前一个,它有一些缺点:

  • 它没有显示底层树的递归性质,因此部分地失去了人类的可读性。
  • 由于每个分类节点存储了字段,因此它占用了更多内存。

在为分层数据选择正确的表示法时,请考虑这些缺点。现在让我们看看如何用 Python 解析上面的分类法表示。

用 Python 解析分层数据

您肯定知道,说到可用库,没有哪种语言比 Python 更好。因此,有几个适合处理分类法的库就不足为奇了:

  • 最受欢迎的是[networkx](https://networkx.github.io/documentation/stable/)。尽管它是为更复杂的图结构而设计的,networkx很容易适应分类法,这只是图的一个特例。
  • 另一个不太受欢迎的图书馆是[anytree](https://anytree.readthedocs.io/en/latest/)。它实现了一个简单但功能丰富的树数据结构,并且经过了实战测试(它达到了版本 2.8.0,对于 Python 库来说并不常见)。这是我为这篇文章选择的库。
  • 其他库包括[binarytree](https://github.com/joowani/binarytree) just for 二叉树、 TreeSwift 等等。

现在让我们构建一个 TaxonomyParser 类的最小版本,用于反序列化 JSON 表示,并使用惟一的节点标识符在分类法中进行搜索。

这个类唯一需要的属性是root_key——用于快速检索根节点——和包含所有树节点的字典nodes,这些树节点由它们唯一的name索引。由于 JSON 文件中的平面表示,反序列化分层数据的代码(read_from_json方法)非常简单。

如果需要在分类法上实现更复杂的搜索条件,该怎么办?例如,假设每个节点包含一个带有正则表达式列表的regex属性。给定一个输入关键字,您希望查找正则表达式与该关键字匹配的所有节点。听起来很复杂?得益于anytree灵活的界面,这可以通过几行代码实现:

最后,如果您想将图形导出到标准。格式或作为 PNG 图像,anytree提供了所有你需要的:

总之,有了anytree库,解析和操作本文中呈现的平面表示中存储的分层数据变得非常容易。完整的代码可以在我的 Github 上找到。如果你喜欢这篇文章,并且有任何问题或意见,请不要犹豫,通过 LinkedIn 联系我。

使用 leav 表示您的地理空间数据

原文:https://towardsdatascience.com/represent-your-geospatial-data-using-folium-c2a0d8c35c5c?source=collection_archive---------24-----------------------

使用 python 可视化地图的过程

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

照片由瓦伦丁·安托努奇派克斯拍摄

作为数据科学社区的一部分,地理空间数据是最重要的数据类型之一。这些应用程序非常简单,比如“我的外卖订单现在在哪里?”和“送货员的最佳路径是什么?”一样复杂

是什么把我带到了叶城?

我最近在研究一个涉及大量 gps 坐标的数据科学问题。显然,这是一个非常基本的问题——我如何在我的 jupyter 笔记本上的地图上表示这些坐标?虽然我们知道 plotlygeopy底图完成了工作,但这是我第一次遇到leaf并决定试一试!

本文是一个关于使用 folium 表示数据的分步教程。

介绍

Folium 主要用于为浏览器生成交互式地图(在笔记本内或网站上)。它使用了 leaflet.js ,这是一个用于交互式地图的 javascript 库。

用一行程序实现它:用 Python 处理数据,然后通过 leav 在活页地图上可视化。

第一步: 在电脑上安装叶子,导入必要的包。

!pip install foliumimport numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import preprocessing
import scipy## for geospatial
import folium
import geopy

我们将使用来自太空的火:澳大利亚数据集。

第二步: 加载并检查数据集。

df = pd.read_csv("fire_archive_M6_96619.csv")

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

第三步: 找到坐标开始。

我们可以从数据集本身选取一组坐标,也可以使用 geopy 来实现这一目的。在这里,我们正在谈论澳大利亚的野火,所以我从墨尔本开始参考。

city = "Melbourne"
# get location
locator = geopy.geocoders.Nominatim(user_agent="My app") 
city = locator.geocode(city)
location = [city.latitude, city.longitude]
print(city, "\n[lat, long]:", location)

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

第四步: 在地图上绘图。

在地图上绘制点就像盖房子一样。你奠定了基础(这是你的背景地图),然后你在它的表面上添加点。

我们将首先奠定基础。

map_ = folium.Map(location=location, tiles="cartodbpositron",
                  zoom_start=8)
map_

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

你也可以通过参考这里的来玩 tileset 和 zoom。

现在我们在地图上标出这些点。我们将根据属性“类型”进行颜色编码,并根据火的“亮度”确定大小。所以让我们先把这些属性按顺序排好。

# create color column to correspond to type
colors = ["red","yellow","orange", "green"]
indices = sorted(list(df["type"].unique()))
df["color"] = df["type"].apply(lambda x: 
               colors[indices.index(x)])
## scaling the size
scaler = preprocessing.MinMaxScaler(feature_range=(3,15))
df["size"] = scaler.fit_transform(
               df['brightness'].values.reshape(-1,1)).reshape(-1)

我们最后用叶子在地图上添加点。

df.apply(lambda row: folium.CircleMarker(
           location=[row['latitude'],row['longitude']], 
           popup=row['type'],
           color=row["color"], fill=True,
           radius=row["size"]).add_to(map_), axis=1)

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

最后,我们向地图添加图例。我使用这个参考来添加一个图例。还有许多其他方法,但这是我发现的最简单的方法。

legend_html = """<div style="position:fixed; 
                    top:10px; right:10px; 
                    border:2px solid black; z-index:9999; 
                    font-size:14px;">&nbsp;<b>"""+color+""":</b><br>"""
for i in lst_elements:
     legend_html = legend_html+"""&nbsp;<i class="fa fa-circle 
     fa-1x" style="color:"""+lst_colors[lst_elements.index(i)]+"""">
     </i>&nbsp;"""+str(i)+"""<br>"""
legend_html = legend_html+"""</div>"""
map_.get_root().html.add_child(folium.Element(legend_html))#plot
map_

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

这是整段代码:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import preprocessing
import scipy
## for geospatial
import folium
import geopydf = pd.read_csv("fire_archive_M6_96619.csv")city = "Melbourne"
# get location
locator = geopy.geocoders.Nominatim(user_agent="My app") 
city = locator.geocode(city)
location = [city.latitude, city.longitude]
print(city, "\n[lat, long]:", location)map_ = folium.Map(location=location, tiles="cartodbpositron",
                  zoom_start=8)# create color column to correspond to type
colors = ["red","yellow","orange", "green"]
indices = sorted(list(df["type"].unique()))
df["color"] = df["type"].apply(lambda x: 
               colors[indices.index(x)])
## scaling the size
scaler = preprocessing.MinMaxScaler(feature_range=(3,15))
df["size"] = scaler.fit_transform(
               df['brightness'].values.reshape(-1,1)).reshape(-1)df.apply(lambda row: folium.CircleMarker(
           location=[row['latitude'],row['longitude']], 
           popup=row['type'],
           color=row["color"], fill=True,
           radius=row["size"]).add_to(map_), axis=1)legend_html = """<div style="position:fixed; 
                    top:10px; right:10px; 
                    border:2px solid black; z-index:9999; 
                    font-size:14px;">&nbsp;<b>"""+color+""":</b>        <br>"""
for i in lst_elements:
     legend_html = legend_html+"""&nbsp;<i class="fa fa-circle 
     fa-1x" style="color:"""+lst_colors[lst_elements.index(i)]+"""">
     </i>&nbsp;"""+str(i)+"""<br>"""
legend_html = legend_html+"""</div>"""
map_.get_root().html.add_child(folium.Element(legend_html))
#plot
map_

也可以在我的 Github 上找到。希望这篇文章有所帮助。

RDF*和 LPG 知识图上的表示学习

原文:https://towardsdatascience.com/representation-learning-on-rdf-and-lpg-knowledge-graphs-6a92f2660241?source=collection_archive---------10-----------------------

超越三元组的 GNNs

超关系公斤比三公斤编码更多的知识。我们采用了图 ML 的最新进展,并提出了一个 GNN 编码器和一个新的基准。

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

图片作者。

K 知识图(KGs)是现代自然语言处理和人工智能应用的基石——最近的工作包括问答实体&关系链接语言建模信息提取,甚至用强化学习播放文本 RPG。此外,知识管理已经在行业中被广泛采用,例如最近的知识图表会议(KGC)中的系列作品

三胞胎大战世界

传统上,kg 被编码为 <主语、谓语、宾语> (RDF)三元组,许多公开可用的 kg,如 DBpediaYAGO 最初遵循这种由表达逻辑形式支持的范式(还记得 DL 引用描述逻辑的时代吗?👵)和 RDF、OWL 之类的标准。

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

三重事实。爱因斯坦同时在两所大学上学吗?图片作者。

使用三元组,上面描述阿尔伯特·爱因斯坦上过哪些大学的例子可以编码为两个三元组:

*Albert Einstein, educated at, ETH Zurich
Albert Einstein, educated at, University of Zurich*

嗯,对于简单的应用程序来说,这看起来还不错,但事实证明我们的世界有点复杂,要把所有东西都放进三元组里。例如,两个三是不是意味着阿尔伯特·爱因斯坦同时在两个地方接受教育?或者他们授予他同样的学位?

事实上,爱因斯坦在苏黎世联邦理工学院获得了数学专业的学士学位,而在苏黎世大学获得了物理学专业的博士学位。

我们能有一种机制来更详细地表达事实吗?

**是的!**在 KG 世界中,至少有两种方法可以做到这一点——RDF *图标签属性图(LPG) 。它们都允许通过将辅助键-值(关系-实体)对附加到 KG 中的边来进一步实例化每个事实。并且这两者都已经得到了图形数据库市场上主要供应商的支持👍。

在 LPG 世界中,节点和边自然都可以有键值属性。 Neo4j 大概是 LPG 家族里最大牌的了。您可以使用(打开)密码查询 lpg。最近的新冠肺炎 KG 可作为 Neo4j 转储。

RDF最初由 Olaf Hartig 提出(他的博客是了解 RDF和相关技术的一个很好的起点),旨在缓解声名狼藉的 RDF 具体化机制的许多问题(查看 Frey 等人的调查以全面了解具体化),同时保留与 RDF 图相关的推理能力。在坚实的理论基础的支持下,RDF提供了一些用更多细节来丰富三元组的方法。您可以使用 SPARQL (SPARQL 的扩展,用于处理 RDF)查询 RDF图。 Apache JenaRDF4JN3.jsBlazegraphAnzoGraphStardogGraphDB 支持 RDF和 SPARQL

我们在 RDF*语法中的例子可以是这样的:

*<< Albert_Einstein educated_at ETH_Zurich >> 
      academic_degree Bachelor ;
      academic_major Maths .
<< Albert_Einstein educated_at University_of_Zurich >>
      academic_degree Doctorate ;
      academic_major Physics.*

超关系图还是超图?

对于这些 kg,什么是合适的术语?直到 Rosso 等人在他们最近的 WWW’20 工作中建议使用“超关系图”之前,一直有一个小的词汇缺口。尽管如此,术语“超图”还是有一个常见的误用。我们也想提倡“超关系”图。🤝

主要区别在于对事实的表述。超图假设有一个(命名的)超边统一几个实体:

*education(Albert Einstein, ETH Zurich, Bachelor, Mathematics)
education(Albert Einstein, University of Zurich, Doctorate, Physics)*

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

每个超边由 4 个节点组成。注意,我们丢失了与学术专业和学术学位相关的谓词。图片作者。

看起来像 n 元关系,对吗?🤨我们这里有几个问题:

  1. 我们丢失了分别与学士/博士和数学/物理相关的类型关系academic_degreeacademic_major。相反,超边缘的类型是一种抽象(或者是一种相当奇怪的语义混合🤯)的educated_atacademic_degreeacademic_major。如果一个事实还包含一个辅助谓词academic_supervisor呢?我们需要定义一个新的超边,比如说, education1() ,混合 4 那些随着谓词和限定词的数量呈指数级增长的关系。📈

2.此外,我们还失去了学位和专业的辅助特征,即它们旨在描述它们的三元组。例如,学士和数学是辅助工作阿尔伯特·爱因斯坦苏黎世联邦理工学院,因此,应该以这种方式对待。超边中的实体元组假定其元素同等重要。

也就是说,在接下来的部分中,我们将坚持使用超关系方法。

野外的超关系知识图

在 2020 年,大多数开放域知识群广泛使用超关系事实。 Wikidata 及其 Wikidata 语句模型是超关系 KG 的一个很好的例子。Wikidata 中的每个事实都是一个语句,包含一个主三元组和一组辅助限定符——实体关系对。使用 Wikidata 语句,我们的 Albert Einstein 示例可以像下面这样简单地建模:

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

超相关事实。图片作者。

在那些语句中,*(学术 _ 学位,学士)**(学术 _ 专业,数学)*是三重 <阿尔伯特·爱因斯坦,学历 _at,苏黎世联邦理工学院> 的限定词。

值得注意的是,Wikidata(通常是超关系范式)并不区分只在主三元组或限定符中使用的实体和谓词,即,

所有的谓词和实体都可以在三重术语或限定词中使用

(尽管在当前的 Wikidata 版本中,有些实体和关系只能在限定符中看到)。我们将在以下几节中使用该属性。

至于其他 kg,从 2018 年开始,DBpedia 的新版本包含类似于 Wikidata 中的具体化声明。YAGO 4 也采用了事实的 RDF*编码。🙌

Freebase 怎么样?🤔好吧,2020 年你可能不应该练习🧟‍♂️死灵术,因为免费基础不再被支持和更新。然而,Freebase 中的复合值类型(CVT)节点确实类似于三元组的具体化[但看起来更像 n 元关系]

图形表示学习

我们在这里的任务是学习超关系图的表示。

对于表示,我们指的是实体(节点)和关系(类型化边)嵌入。然后,嵌入可以用于下游任务,如链接预测、节点分类、实体对齐,以及更多可以用于 NLP、CV 和其他人工智能领域的任务。🍀

图形表示学习(GRL)是发展最快的领域之一🚀在机器学习领域,有一些文章(Michael Bronstein 的一系列帖子,【20】的评论( mineSergey’s)和neur IPS’19的论文)、书籍(作者、马和唐)、课程( CS224WCOMP 766😉)涵盖基础和高级主题。

在编码器-解码器范例中,编码器通常是 GNN(图形神经网络),而解码器是嵌入的函数,其返回与某个下游任务相关的值或向量,例如,实体成为给定的 <主语、谓语> 对的对象的概率。

三基 kg 有什么?

挺多的!😍

编码器:多关系 GNN 编码器家族,如 R-GCN ( Schlichtkrull 等人,ESWC 2018 )和 CompGCN ( Vashishth 等人,ICLR 2020 ),在消息传递框架内扩展了原有的图卷积网络(GCN) 算法。

解码器:实际上,传统的 KG 嵌入算法如 TransE、ConvE、RotatE 等都是用于链路预测任务的解码器的很好例子。最初,它们也可以被训练为直接端到端优化的仅解码器模型👉关于链路预测任务。

超关系 kg 有什么?

嗯,没那么多🤔(截至 2020 年秋季)

编码器:???

解码器:铰链 Rosso 等人提出的基于 CNN 的端到端超关系图上链接预测模型。

嗯,我们无法应对 GNN 编码器部分中如此耀眼的深渊🕳,并在我们最近的 EMNLP’20 论文“超关系知识图的消息传递”中提议⭐️凝视⭐️,该论文与 普里扬什·特里维迪高拉夫·马赫什瓦里里卡多·乌斯贝克延斯·莱曼 一起撰写

StarE 是一个多关系 GNN 编码器,它为超关系 kg 扩展了 CompGCN。

这个名字的灵感来自 RDF*😊StarE 的设计考虑了以下特点:

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

StarE 中聚合限定符的一个例子。图片作者。

  • 关系的显式建模,包括限定关系;
  • 限定词中的辅助实体和关系与主三元组中的实体和关系的分离;
  • 然而,任何实体和任何关系仍然可以用在主三元组以及限定词中;
  • 限定词顺序的排列不变性—它们不显示任何特定的顺序,可以自由地重新排列。也就是说,对于主三联 < <阿尔伯特·爱因斯坦来说,受教育于,苏黎世联邦理工学院> > 无论*(学术学位,学士)是在(学术专业,物理)*之前还是之后。

给爱好者一点数学知识👩‍🔬

让我们追踪关系感知 GNN 编码器在其邻域聚合方案中的演变:

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

消息传递算法。图片作者。

在 StarE 中,出现在节点uv之间的主三元关系h_r通过函数gamma()用限定符h_q的聚合向量来扩充,该函数可以是加权和、乘法、串联或任何其他二元函数(我们使用加权和)。

我们通过以下方式获得向量h_q:

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

也就是说,我们首先通过复合函数phi_q()将限定符关系和实体嵌入h_{qr}h_{qv}分别汇集到单个向量中,复合函数phi_q()可以是来自 KG 嵌入族的评分函数,例如 RotatE。然后,我们应用一个排列不变的聚合函数(sum,尽管我们也探讨了乘法)将任意数量的限定符汇集成一个向量,并最终通过一个转换矩阵将其投影W_q

由于所有的实体和关系通常可以在主三元组以及限定词中看到,W_q旨在学习实体和关系的限定词特定的表示。

我们仍然保留 CompGCN 组件:phi_()是一个类似于phi_q()的复合函数,但是现在它合并了一个具有丰富边表示的节点。W_{\lambda}是传入、传出和自循环关系的权重参数。

超关系 kg 的稀疏编码

出于效率原因,gnn 在稀疏矩阵上操作。对于基于多关系三元组的 kg,以下示例为三元组

*Q937, P69, Q11942
Q937, P69, Q206702*

可以用首席运营官格式表示为一个[2, num_edges]张量,并为边缘类型增加一行

[Q937, Q937]
[Q11942, Q206702]
[P69, P69]

带有限定符的超关系事实可以写成如下形式:

*Q937, P69, Q206702, P812, Q413, P512, Q849697
s, r, o, qr1, qv1, qr2, qv2, …, qrN, qvN*

其中前三个条目总是表示“主”三元组,随后的对是没有特定顺序的限定符(记住 Wikidata 中的顺序不变性)

在首席运营官矩阵的每个“列”可能有任意数量的限定符的情况下,超关系 kg 的稀疏表示是什么?在论文中,我们提出以下编码:

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

超关系知识的稀疏编码。图片作者。

也就是说,我们有两个首席运营官矩阵:

  1. 带有隐式列索引 k 的普通“三重”首席运营官
  2. 形状[3, num_qualifiers]的“限定符”首席运营官,其中第一行包含“三元”首席运营官中各列的索引,第二行包含限定符关系,第三行包含限定符实体。索引行将一列限定符连接到主三元组。也就是说,共享相同索引 k 的“限定符”首席运营官中的列属于“三元”首席运营官矩阵中的相同的第 k 个三元组。这允许我们在内存中为 KG 中的限定符的数量准备 O (q ),并且总内存为o(| edges |+| qualifiers |)⚖.️

我们需要谈谈数据集

我们简要地谈到了将超关系事实编码为一系列实体和关系。但是,是否已经有可靠的数据集来对这些千克进行实验了呢?传统上,KG 嵌入是在链接预测任务上评估的,而图 ML 任务包括节点分类、图分类、实体匹配等等。

到目前为止,只有两个链接预测数据集:由关等人提出的维基百科(wikipeople)——它是一个描述,嗯,人的维基数据的转储,以及由免费提供的 jf17k(T12)然而,我们发现了主要的缺点😞有了这两个人:

  • 维基人有太多带有文字(年份)的限定符。将文字视为另一种实体是不可取的,因为数字是连续的值,应该以这种方式处理(嗯,这是 KG 嵌入文献中文字的一个普遍问题🤔).也就是说,在大多数情况下,这样的限定符被简单地丢弃了。这导致数据集只有 2%的事实有限定符,而 80%的事实只有一个限定符对:/
  • JF17K 有测试装置泄漏。事实上,作者自己也发现了很多冗余的三联体,不推荐在实验中使用。HINGE 最初更多的是一个 n 元数据集,它通过辅助谓词将其转换成一种超关系格式。我们进行了进一步的研究,发现超过 40%的测试语句共享与训练集中相同的 (s,r,o) 主三元组。也就是说,在主体/客体预测任务中,简单的三重试探法可以胜过🏆我们在论文中展示的所有以前的超关系方法。

由于这两个数据集都不太适合评估超关系方法,我们根据以下准则对 Wikidata 中的 WD50K 进行了采样:

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

图片作者。

  • 保留类似 Wikidata 的限定符分布。在普通的 WD50K 中,大约 13%的语句有限定符(接近 Wikidata 中全部语句的 17%)
  • 所有限定符都是实体关系对,没有文字
  • 实体和关系可以在主三元组和限定词中看到
  • 99%的语句最多有 6 个限定符对

为了进一步的实验,我们采样了 3 个额外的数据集:

  • WD50K (33) —大约 33%的语句有限定符
  • WD50K (66) —大约 66%的语句有限定符
  • WD50K (100) —所有语句都有限定符

自然,这些数据集比原来的 WD50K 小,具有更多限定符特有的实体和关系。

凝视链接预测

在这一步,我们最终有了一个 StarE 编码器和合适的链路预测数据集用于实验。我们的主要研究问题是:

限定词有助于预测超关系事实的主语和宾语吗?

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

用于链路预测的 StarE +解码器。图片作者。

也就是说,给定主语、谓语和所有限定词,我们预测宾语,反之亦然。为此,我们将给定的事实线性化为如图所示的序列,并使用具有 avg 池和最终 FC 层的 2 层转换器作为解码器。

转换器还允许我们使用屏蔽的填充标记来输入不同长度的序列👺从自我关注的计算中。

为了进行比较,我们在同一任务中应用了仅解码器铰链和 2 层变压器,以测量 StarE 编码器是否带来任何好处。

事实证明的确如此。🎆

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

各种 WD50K 数据集上的主/客体预测精度。限定符越多,收益越大!图片作者。

我们观察🕵:

  • 与只有解码器的方法相比,StarE 极大地提高了链路预测性能;
  • 当数据集中有更多的限定符时,StarE 甚至更有效(性能差距更大);
  • 超关系方法确实有助于更好地预测给定限定符的主体和客体。

你需要多少限定词才能看到质量的提高?两个就够了😉

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

仅仅 2 个限定符就能带来明显的性能提升。图片作者。

我们的实验程序用特定的数字和交互式图表报告,这里用权重&偏差T4📈

所以外卖🔖致 KG 社区:

  1. 寻求将描述性限定词分配给图中更多的三重事实——越多越好
  2. 如果您指定了限定符,请添加 2 个或更多!

结论和资源

  • 超关系图比简单的三元组更接近现实,更详细地描述事实
  • RDF*和 LPG 提供了构建超关系知识库的方法
  • 超关系图不同于超图
  • 超关系 KGs 已经在使用了——无论是在开放领域 KGs 还是在工业领域
  • RDF*激励的 StarE——一种用于超关系 kg 的 GNN 编码器,可以与用于下游任务的解码器配对
  • 与只有解码器的方法相比,StarE 改进了链路预测
  • WD50K 数据集系列更好地捕捉了超关系 kg 上的链接预测的挑战

您可以在以下网址找到更多信息:

Our EMNLP’20 paper : 消息传递为超关系知识图 (arxiv 预打印)
代码 : Github Repo
数据集:Zenodo page
权重&偏向 Repor t: 此处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值