深度学习:张量和张量流简介
了解最受欢迎的深度学习库!
图片来自 Unsplash
介绍
本文的目标是涵盖以下主题:
- 张量介绍
- 图表、变量和操作
- 使用 TensorFlow 解决问题
什么是张量流
TensorFlow 是由 Google 开发和维护的一个框架,它使数学运算能够在 CPU 或 GPU 上以优化的方式执行。我们将专注于 GPU,因为这是我们训练深度神经网络的最快方法。
为什么是 Tensorflow?
- 因为它的灵活性和可伸缩性
- 因为它受欢迎
按作者分列的数字
使 TensorFlow 成为最受欢迎的深度学习库的关键功能是:
- TensorFlow 使用张量来执行操作。
- 在 TensorFlow 中,首先定义要执行的活动(构建图),然后执行它们(执行图)。这允许该过程被优化到手边的任务,大大减少了计算时间。
- TensorFlow 支持代码并行运行或在一个或多个 GPU 上运行。
好吧,但是张量是什么?
虽然张量是物理学家发明的,用来描述相互作用,但在人工智能领域,张量可以简单地理解为数字的容器。
按作者分列的数字
让我们现在就把这一切付诸实践。我们将使用 python 编写一些张量代码,以便更好地理解它们是什么以及它们是如何工作的。
实践中的张量
假设我们想存储一个学生的平均成绩。我们将使用一个 0D 张量,它只是一个简单的数或标量。
import numpy as nptensor_0D = np.array(5)
print("Average grade: \n{}".format(tensor_0D))
print("Tensor dimensions: \n{}".format(tensor_0D.ndim))
现在让我们尝试存储该学生所学的每门课程的分数。我们可以用 1D 张量来做到这一点:
tensor_1D = np.array([4,6,8])
print("Subject grades: \n{}".format(tensor_1D))
print("Tensor dimensions: \n{}".format(tensor_0D.ndim))
但是,等等……如果我们想存储学生每门学科的每次考试的分数,该怎么办呢?如果每个科目有 3 次考试,我们该怎么做呢?
通过使用 2D 张量!正如我们之前看到的,它是一个矩阵。
**# 2D Tensor (matrix)**
tensor_2D = np.array([[0, 1, 1], # Subject 1
[2, 3, 3], # Subject 2
[1, 3, 2]]) # Subject 3
print("Exam grades are:\n{}".format(tensor_2D))print("Subject 1:\n{}".format(tensor_2D[0]))print("Subject 2:\n{}".format(tensor_2D[1]))print("Subject 3:\n{}".format(tensor_2D[2]))print("Tensor dimensions: \n{}".format(tensor_2D.ndim))
我们现在希望存储四个季度的科目成绩(每年一次),这样将来需要时就可以更容易地访问它们,你不这样认为吗?你认为我们该如何组织他们?
如果我们给 2D 张量增加一个维度来表示四分之一会怎么样?
我们会得到一个三维张量(三维矩阵或立方体)。
tensor_3D = np.array([[[0, 1, 1], # First quarter
[2, 3, 3],
[1, 3, 2]],
[[1, 3, 2], # Second quarter
[2, 4, 2],
[0, 1, 1]]])
print("Exam grades per quarter are:\n{}".format(tensor_3D))print("First quarter:\n{}".format(tensor_3D[0]))print("Second quarter:\n{}".format(tensor_3D[1]))print("Tensor dimensions: \n{}".format(tensor_3D.ndim))
如果我们在张量中增加一个维度,这样我们就可以得到每个学生每门学科每学期的成绩,会怎么样?
它将是一个 4D 张量(3D 矩阵向量或立方体向量)。
tensor_4D = np.array([[[[0, 1, 1], # Jacob
[2, 3, 3],
[1, 3, 2]],
[[1, 3, 2],
[2, 4, 2],
[0, 1, 1]]],
[[[0, 3, 1], # Christian
[2, 4, 1],
[1, 3, 2]],
[[1, 1, 1],
[2, 3, 4],
[1, 3, 2]]],
[[[2, 2, 4], # Sofia
[2, 1, 3],
[0, 4, 2]],
[[2, 4, 1],
[2, 3, 0],
[1, 3, 3]]]])
print("The grades of each student are:\n{}".format(tensor_4D))print("Jacob's grades:\n{}".format(tensor_4D[0]))print("Christian's grades:\n{}".format(tensor_4D[1]))print("Sofia's grades:\n{}".format(tensor_4D[2]))print("Tensor dimensions: \n{}".format(tensor_4D.ndim))
所以我们可以无限地增加张量的维数,来存储更多的数据。
为了让您了解张量在深度学习领域的使用频率,最常见的张量类型有:
- 三维张量:用于时间序列。
- 4D 张量:用于图像。
- 5D 张紧器:与视频一起使用。
通常,其中一个维度将用于存储每种数据类型的样本。例如,对于图像:
如果我们想要存储 224x224 像素的 64 幅 RGB 图像,我们将需要一个 3D 矩阵向量,或者同样的,一个 4D 张量。我们需要多少维度?
我们有 64 幅 224 像素 x 224 像素 x 3 通道(R、G、B)的图像。
因此:(64,224,224,3)
如果你想更深入地了解张量或更多的例子,这里有一个非常好的资源:用猫说明的张量
我们之前说过,在 TensorFlow 中,首先定义要执行的操作,然后执行它们。为了做到这一点,你使用一个图表。
什么是图形?
a + b 求和的一个简单例子。
按作者分列的数字
这是一个更复杂的例子,现在,你不需要完全理解,但这只是其中的一小部分。
张量流付诸实践
首先我们需要定义和理解 TensorFlow 的一些基本概念(从现在开始 TF):
- tf。图:表示一组 tf。操作
- tf。运算:运算是由我们定义的方程式决定的吗
- tf。张量:我们存储 tf 结果的地方。操作
一开始,tf。图形对我们来说是透明的,因为有一个默认的图形,其中添加了我们定义的所有操作。它被称为 tf.get_default_graph()。
**# We import the Tensorflow package and matplotlib for the charts** import tensorflow as tf
import matplotlib.pyplot as plt
%matplotlib inline
先说一些很简单的,仅仅是 Tensorflow 中的一个简单乘法。
**# Variables definition**
x = tf.constant(6)
y = tf.constant(8)**# Operations definition**
result = tf.multiply(x, y)
print(result)
如你所见,它没有给我们返回结果。到目前为止,它所做的就是创建网络。
举个例子,就像坐车一样。现在我们已经把它组装好了,但是它仍然没有完成它的设计,移动。为此,我们应该打开它。为此,我们将使用 tf。会话()。
sess = tf.Session()
output = sess.run(result)
print(output)
为了能够可视化该图,我们应该定义几个函数。
from IPython.display import clear_output, Image, display, HTMLdef strip_consts(graph_def, max_const_size=32):
"""Strip large constant values from graph_def."""
strip_def = tf.GraphDef()
for n0 in graph_def.node:
n = strip_def.node.add()
n.MergeFrom(n0)
if n.op == 'Const':
tensor = n.attr['value'].tensor
size = len(tensor.tensor_content)
if size > max_const_size:
tensor.tensor_content = "<stripped %d bytes>"%size
return strip_defdef show_graph(graph_def, max_const_size=32):
"""Visualize TensorFlow graph."""
if hasattr(graph_def, 'as_graph_def'):
graph_def = graph_def.as_graph_def()
strip_def = strip_consts(graph_def, max_const_size=max_const_size)
code = """
<script>
function load() {{
document.getElementById("{id}").pbtxt = {data};
}}
</script>
<link rel="import" href="[https://tensorboard.appspot.com/tf-graph-basic.build.html](https://tensorboard.appspot.com/tf-graph-basic.build.html)" onload=load()>
<div style="height:600px">
<tf-graph-basic id="{id}"></tf-graph-basic>
</div>
""".format(data=repr(str(strip_def)), id='graph'+str(np.random.rand()))iframe = """
<iframe seamless style="width:1200px;height:620px;border:0" srcdoc="{}"></iframe>
""".format(code.replace('"', '"'))
display(HTML(iframe)
现在我们将展示之前定义的图表:
正如我们所见,该图由两个常量类型的节点和一个运算符类型(乘法)的节点组成。然而,他们的名字并不十分具有指示性。让我们改变这一点:
x2 = tf.constant(5.0, name='x2')
y2 = tf.constant(6.0, name='y2')result = tf.multiply(x2, y2)# Let's see what it looks like now:
show_graph(tf.get_default_graph().as_graph_def())
一旦我们执行了操作,我们应该关闭会话,用 sess.close()释放资源。
最后,我们还可以向 the GPU 表明我们希望它执行操作。为此,我们可以打印可用设备的列表:
from tensorflow.python.client import device_libdef get_available_devices():
local_device_protos = device_lib.list_local_devices()
return [x.name for x in local_device_protos]print(get_available_devices())
我们将选择 GPU:0,并执行[3 ^ 3]乘以[2 ^ 2]的乘法运算,结果可能是 3x3 +2x2 = 12。让我们来看看:
通过使用 with ___ as __:我们让 python 自己释放 TF 会话的资源:
with tf.Session() as sess:
with tf.device("/GPU:0"):
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
product = tf.matmul(matrix1, matrix2)
output = sess.run(product)
print(output)
现在让我们创建一个在-5 和 5 之间平均稀疏的 32 个值的 1D 张量:
n_values = 64
x = tf.linspace(-5.0, 5.0, n_values)sess = tf.Session()
result = sess.run(x)print(result)
除了 sess.run(_)之外,还有其他评价张量的方法
x.eval(session=sess)
我们需要始终记住结束会议:
sess.close()
我们还可以使用交互式会话,这可以帮助我们不必不断地调用。运行()以执行结果:
sess = tf.InteractiveSession()
x.eval()
现在我们来看一个 tf。操作,为此,我们将使用“x”来创建和可视化高斯分布。它的公式是:
sigma = 1.0
mean = 0**# To implement the gaussian distributio formula**:
g1d = (tf.exp(tf.negative(tf.pow(x - mean, 2.0) / (2.0 * tf.pow(sigma, 2.0)))) *
(1.0 / (sigma * tf.sqrt(2.0 * 3.1415))))**# to check that this operation has been succesuflly included in our tf.Graph**
if g1d.graph is tf.get_default_graph():
print('All good')
plt.plot(g1d.eval())
# to see the dimensions
print(g1d.get_shape())
print(type(g1d.get_shape()))print(g1d.get_shape().as_list())print(type(g1d.get_shape().as_list()))
有时候,在执行返回变量值的操作之前,我们不知道变量的维数。对于这些情况,我们可以使用 tf.shape(variable ),它返回一个张量,在运行时计算结果的维数。
这被称为“静态形状”和“动态形状”,其中静态形状的计算考虑了张量的维度和所涉及的操作,以及执行时的动态。
如果我们将 x 定义为“占位符”会发生什么?一个占位符就像一个储备,它表明那里会有一个张量,但没有必要在那个时刻定义它。例如,通过定义:
x = tf.placeholder(tf.int32, shape=[5])
我们知道 x 将持有一个 1D 五维张量,这一点由 x.get_shape()所证实:
print(x.get_shape())
但是我们不知道什么价值观会形成它,直到我们告诉它。
占位符和变量的区别:
变数
它们用于容纳在培训过程中学习到的参数。
因此,这些值是从训练中获得的-它们需要分配一个初始值(可以是随机的)
占位符
为数据保留空间(例如,为图像中的像素)
它们不需要为 start 赋值(尽管它们可以)
获得的值 5 是 x 维度的静态值。但是,如果我们对 x 应用一个 tf.unique()会发生什么呢?
y, _ = tf.unique(x)
print(y.get_shape())
所发生的是 tf.unique()返回 x 的唯一值,这些值最初是未知的,因为 x 被定义为一个占位符,占位符直到执行时才需要定义,正如我们之前所说的。事实上,让我们看看如果我们给“x”输入两个不同的值会发生什么:
with tf.Session() as sess:
print(sess.run(y, feed_dict={x: [0, 1, 2, 3, 4]}).shape)
print(sess.run(y, feed_dict={x: [0, 0, 0, 0, 1]}).shape)
看那个!y 的大小根据 tf.unique()返回的内容而变化。这叫做“动态形状”,它总是被定义的,它永远不会通过回答返回一个问题。因此,TensorFlow 支持类似 tf.unique()的操作,这些操作可能会产生大小可变的结果。
现在你知道了,每次你使用输出变量的运算,你都需要使用 tf.shape(变量)来计算张量的动态形状。
sy = tf.shape(y)**# Returns a list with the dimensions**
print(sy.eval(feed_dict={x: [0, 1, 2, 3, 4]}))
print(sy.eval(feed_dict={x: [0, 0, 0, 0, 1]}))**# We access the dimension of interest**
print(sy.eval(feed_dict={x: [0, 1, 2, 3, 4]})[0])
print(sy.eval(feed_dict={x: [0, 0, 0, 0, 1]})[0])
现在,我们可以在考虑操作的输出大小之后执行操作,我们在第一个实例中并不知道输出的大小。
print(tf.shape(y).eval(feed_dict={x: [0, 1, 4, 1, 0]}))
print(type(tf.shape(y).eval(feed_dict={x: [0, 1, 4, 1, 0]})))print(tf.stack([y, y[::-1], tf.range(tf.shape(y)[0])]).eval(feed_dict={x: [0, 1, 4, 1, 0]}))
现在让我们看看 2D 的高斯分布
g1d_r = tf.reshape(g1d, [n_values, 1])
print(g1d.get_shape().as_list())
print(g1d_r.get_shape().as_list())# We multiply the row vector of the 1D Gaussian by the column to obtain the 2D version
g2d = tf.matmul(tf.reshape(g1d, [n_values, 1]), tf.reshape(g1d, [1, n_values]))# To visualize it
plt.imshow(g2d.eval())
查看我们的 tf 中包含的操作列表。图表
ops = tf.get_default_graph().get_operations()
print([op.name for op in ops])
结论
一如既往,我希望你喜欢这篇文章,并且你已经学习了张量和张量流的基础知识以及它们是如何使用的**。**
如果你喜欢这篇文章,那么你可以看看我关于数据科学和机器学习的其他文章 这里 。
如果你想了解更多关于机器学习和人工智能的知识 请在 Medium 上关注我,敬请关注我的下一篇帖子!
深度学习很容易
意见
企业通过深度学习创造价值有多容易
很长一段时间以来,深度学习一直是新闻中的热门话题。这有很好的理由——最重要的理由是它通过软件提供的附加值。今天,我们将探索这些年来深度学习变得多么容易,以及这对就业市场意味着什么。
丹尼尔·明戈金在 Unsplash 上的照片
让我先做一个大胆的免责声明——这篇文章不适用于深度学习的研究部分。然而,这篇文章确实适用于实际的深度学习。我所说的“实用”是指利用深度学习库来解决特定的业务问题。
今天,我们将探索在没有雇用任何深度学习工程师的情况下,这些公司可以在深度学习方面做些什么。所有的工作都可以由软件开发人员或领域专家来完成——归结起来就是点击几下鼠标。
这里的目的是测试深度学习工程师是否变得过时,并测试入门级深度学习工作所需的技能水平——所有这些都是根据 2020 年的标准。
但是我们如何测试呢?好问题。让我们在下一节看一个具体的例子。
具体的例子
“没有数据,你只是另一个有观点的人”——威廉·爱德华·戴明说,我非常同意。我不指望你相信你读到的一切——我知道我不会。这就是为什么我准备了一个具体的、简单易懂的展示,让你无可争议。
让我把你介绍给乔。
乔在一家医院的一个部门工作,该部门处理肺部疾病和一般肺部疾病。缺少医学专家,工作不断出现。医务人员超负荷工作,疲惫不堪,因此容易出错。
我不是医学专家,所以如果我在这里说错了什么,请原谅我——这是最重要的整体概念。
为了减轻团队的负担,Joe 决定使用深度学习来“外包”重复的任务,比如说,肺部图像分类。最终的结果是,Joe 的医疗团队应该有更多的时间从事这项工作的人的方面。唯一的问题是——乔对深度学习一无所知。
Joe 在网上搜索并找到了一些 AutoML 工具——比如苹果的 CreateML。碰巧他也有一台 Mac 电脑。太好了!
经过进一步的研究,Joe 发现 CreateML 对很多任务都很有用——图像分类就是其中之一:
太棒了。Joe 在医院工作,所以获取数据不成问题。他的团队已经收集并标记了几千张图片,准备插入到 CreateML 中。
现在我无法访问他们的图像,所以我将使用肺炎肺部图像数据集进行演示。该数据集包含超过 5000 张(非常)不同大小的肺部图像——这对深度学习实践者来说是一个问题,但对 CreateML 来说不是问题。
Joe 的下一步是开发一个预测模型。在阅读了一两篇文章之后,他熟悉了训练/测试/验证分割的概念,所以他以那种方式组织数据。结果是 CreateML 以同样的方式工作:
只需拖放即可——其他一切都是自动处理的
乔现在可以点击那个大而醒目的 Run 按钮,开始训练过程。在我的机器上花了大约 1 个小时完成,但结果是在测试集上产生了 85%的准确率(以前看不到的数据):
我不知道医学专家的分类有多少次是错的,但 85%肯定是一个很好的起点!
我以前在这个 Pneuomina 数据集上工作过(用 PyTorch ),在测试集上只获得了 83.5%的准确率。这里的召回值非常高,大约为 99.5%,这意味着如果图像被分类为受感染,我们可以 99.5%确定它确实被感染了。
简单来说,这个模型不太可能对阳性病例进行错误分类。该数据集的问题是类别不平衡-负面案例比正面案例多约 2 倍-这影响了模型的整体预测能力(准确性)。
然而,85%是坚如磐石的,至少一开始是这样。当然,乔和他的医疗团队是一个虚构的人,但我希望你能明白。
这对就业市场意味着什么?
这是否意味着深度学习工作将成为过去?一点也不,但你还是应该有所顾虑。
试着像做生意一样思考一下。如果一个免费工具可以胜过新手深度学习实践者,你会雇佣他们吗?我知道我不会。还有, CreateML 模型很容易将模型部署到 iOS 和 macOS 上,但是通过一些手工操作,模型可以部署到任何地方。
像 CreateML 这样的工具是为软件开发人员设计的——让他们更容易在应用程序中使用机器学习。这并不意味着取代人,但人们只能假设,除了这些工具可以提供的解决方案之外,很大一部分公司并不需要更复杂的解决方案。
另外,你能指望新手知道如何处理模型部署吗?没有,但是您的软件开发和 DevOps 团队可以轻松处理这项任务。
那么深度学习实践者的目的是什么呢?嗯,通过专业知识和领域知识来超越像这样的工具。初级从业者可能做不到这一点。这也是为什么领域内大部分职位都是资深的原因。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
如何让深度学习使用逻辑
理解大脑如何导航环境可以帮助人工智能解决复杂的问题
亚历山德鲁-波格丹一世·吉塔在 Unsplash 上拍摄的照片
在这篇文章中,我将展示深度学习无法理解逻辑和结构,并指出由神经科学启发的潜在解决方案。这很重要,因为世界上大多数有价值的问题都需要逻辑地解决,但现代深度学习在这方面很大程度上失败了。
合乎逻辑是什么意思?
从统计学的角度来说,逻辑类似于在给定一组观察值的情况下对预测的极端信心。在纯粹的逻辑世界中,1 + 1 = 2 总是正确的,而在更随机的非逻辑系统中,1 + 1 = 2 可能只在 90%的情况下是正确的。
有些逻辑产生于我们对世界结构的理解,比如物理定律。举个例子,如果你丢了一个球,然后你希望它会掉到地上。然而,在一个非结构化的世界中,一切皆有可能,这使得预测未来变得困难。例如,股票市场是一个非结构化的世界。我父亲从 5 月份就开始关注 Novax Pharma,但他不可能预测到首席执行官会卖掉他的股票,使其价格暴跌。
统计学家可能会说,我们生活在一个随机和无组织的世界,但宇宙中也有许多方面是可预测和符合逻辑的,如物理、数学和科学。逻辑性让我们能够规划未来,并形成具体的路径来帮助我们达到目标。几乎所有值得解决的难题都需要运用推理和逻辑。
纯深度学习是学不到逻辑的
深度学习能否实现逻辑的圣杯? DeepMind 在他们 2019 年的论文中提出了这个问题,他们在论文中实现了一个变压器模型来解决数学问题[1]。他们的结果令人印象深刻;该模型在简单的加法、减法、除法和乘法中达到了 90%以上的准确率。但是当混合操作时,性能下降到 50%,这表明该模型只是猜测解决方案,而不是一步一步地解决问题。
在深度学习中还有其他例子,模型或代理人非常擅长他们的任务,以至于他们产生了逻辑和推理的幻觉。
OpenAI 的 GPT-2 语言模型可以生成类似人类的文章,但更仔细的检查表明,它的输出没有逻辑结构,只是模仿它在训练数据中被训练的内容。例如,该模型有时会写到水下发生的火灾。
DeepMind 和 OpenAI 开发的分别用于玩星际争霸 2 和 DotA 2 的视频游戏代理在各自的游戏中击败了顶级职业游戏玩家,但大多使用纯粹的机械技能和执行良好的攻击,而不是策略。例如在 DotA 2 中,如果目标的生命值低于阈值,玩家可以采取一个动作立即杀死另一个玩家,否则伤害很小甚至没有。不可否认,在阈值以上使用它是一个错误,但 OpenAI 的 DotA 2 bot 一直在这样做。当人类对手使用仅靠机械技能无法克服的模糊策略时,DeepMind 为《星际争霸 2》开发的 AlphaStar 会持续倾斜并输掉比赛。
一些人认为,如果接受更长时间的训练,这些特工可能会克服上述缺陷。这可能是真的,但是这些问题通常不会出现在普通玩家身上。很明显,这些智能体缺少一种使它们像人类一样聪明的成分。
神经科学给了我们答案
早在二月份,我偶然发现了莱克斯·弗里德曼对理论神经科学家杰弗瑞·霍金的采访。在采访中,霍金斯描述说,神经科学家正在假设人类空间导航的神经机制也可能是人类导航抽象概念的能力的原因。我是说,为什么不呢?从逻辑上来说,解决问题与空间导航使用相同的原理,因为两者都需要规划从起点到终点的路线。
2018 年,DeepMind 恰好实现了世界上第一个使用神经基底进行空间导航的智能体(称为网格细胞)[2]。代理的任务是在迷宫般的环境中导航,网格细胞的参与教会了代理始终选择捷径并在原始捷径受阻后创建新的捷径。这是一个令人难以置信的壮举,网格细胞的最初发现者评论说这是“机器人学中众所周知的困难”。然而,最重要的是,他们的实验发现,智能体中使用的神经网络通过仅让网络估计智能体每次移动时在迷宫中的位置和朝向,发展了类似网格细胞的属性。简而言之,他们的发现表明自我意识(在这种情况下是空间自我意识)是解决任何导航问题的关键因素。对于我们大多数人来说,这不应该是一个惊喜,因为评估我们相对于目标的位置对于实现目标是至关重要的。**
这是这篇文章的惊人想法。我们一直在通过最小化预测误差来训练深度学习模型(例如,分类图像是猫还是狗等等),但如果我们最小化其自我意识误差,模型是否有可能理解这个世界的结构并导航抽象概念?
实现自我感知的人工智能
假设自我意识是人工智能逻辑解决问题的必要成分之一,我们将如何实现它?网格细胞论文中有一些要点:
- “自我意识”的错误是真实情况和代理人自己预测的位置和方向之间的差异。
- 基本事实的位置和方向(代理的自我意识)由神经激活信号表示,当代理处于唯一的位置和方向时,每个单元都会触发。
- 网格单元相对于代理的位置和它的方向以规则的间隔被激活
- 当模型训练以最小化自我意识的损失时,网格单元激活正好在最终线性层之前出现。
总之,只要我们确定它所处的环境,并尽量减少对其坐标和方向预测的误差,“自我意识”就会完全脱离训练。不幸的是,涉及网格单元的实验只在空间导航上进行过,所以还不清楚它是否适用于非空间系统。
但我心里确实有一个实验。自然语言处理中的一个研究热点是理解如何教授一个模型来捕捉因果关系。我之前提到的关于 GPT-2 写的关于水下发生火灾的例子是一个混淆因果关系和相关性的例子。仅仅因为有句子说水经常灭火并不意味着火影响水。学会在单词嵌入的向量空间中导航的网格细胞会更好地捕捉这种关系吗?
结论
虽然上面的实验是推测性的,这篇文章可能完全是一场虚惊,但不可否认的是深度学习已经撞上了一堵墙,对于研究社区来说,一个值得前进的方式是探索新的想法(哎呀,感谢明显队长!).在我的计算机科学论文项目期间,我探索了知识图在赋予神经网络推理能力方面的潜力。这是一个很酷的概念,但由于图形的内在限制,这个项目失败了。
在写这篇文章的时候,我正暂停深度学习,专注于我最后一年的教育,所以我将火炬传递给你。对于那些厌倦了优化现有架构或被这一想法吸引的人,我强烈建议你看看 DeepMind 关于 grid cell 的论文,并将其应用于非空间应用。谁知道呢,你可能会发现一个比现有架构性能更好的新架构。但是如果你是,记住你是从这里听到的。
[1] D. Saxton,E. Grefenstette,F. Hill,和 P . Kohli,分析神经模型的数学推理能力 (2019),ICLR 2019
[2] A. Banino 等人工智能体中使用网格状表示的矢量导航 (2018),Nature 26,1。
深度学习不是解开奇点的钥匙
深度学习改变了人工智能领域,但它不会给我们人工通用智能——下面是原因。
D eep 学习是使用神经网络来解决近似、回归或分类任务。这个工具已经成为展示智能代理的突出设备,但它并不具备结构化推理的明显潜力。这篇文章强调了深度学习的惊人的优势,将其放在我们试图解决的的背景下。
神经网络的规范图像。来源—作者。
神经网络是使人工智能实用化的第一个工具——它们现在被用于许多领域(见这篇impact 综述)。上一次单一技术试图在行业中引起引人注目的变化是 专家系统 ,在那里,计算机科学家和专业人士的协同作用将他们的知识提取到树状搜索算法中,以供重复使用。这种方法的问题在于,它无法解读训练集的言外之意——它只是重复给定的内容,因此公司不再花钱制作它们。它给了我们第一个艾的冬天。
机器学习:人工智能的子领域,任务是从状态空间的部分观察中对新数据做出决策。
关于 AI 的状态,神经网络改变了什么?他们有能力概括(或记忆)一个状态空间到适度概括的程度。你问什么是神经网络?逼近任何有限的输入数据集都是一个长时间的非线性函数和矩阵运算的交织过程*。如果你想知道更多,我会让你观看这个由格兰特·桑德森制作的神奇的 视频和系列。有许多方法来描述它,但是在本文的上下文中,仅仅把它想成一个高维函数近似器就足够了。*
在讨论神经网络时,记住机器学习的目标是什么是很重要的。 机器学习是关于做决策,人工智能是关于做推理能力。 做第一件事可以启用第二件事,但这不是一个充分的准则。
奇点是什么?
Vernor Vinge 在 1993 年的一篇文章 中创造了“奇点”,即将到来的技术奇点 ,它标志着人类从占主导地位的超级智能时代的结束。现在,人工智能领域的顶尖科学家在争论它何时会出现,我暂时弃权。最终,问题是,需要什么工具或发现来让计算机绕过人类智能。答案不是深层网络。
来源——作者 CS188 课程,http://ai.berkeley.edu。
反对深度学习的理由
为什么深度学习不会超越人类的智力——缺乏真正的概括?最近的研究已经讨论了神经网络是如何简单地记忆训练集的,其间有轻微的插值。这解释了转换数据的困难、分布变化的困难以及增加数据集大小的好处。深度网络是最好的近似工具,因为它们可以跨越有限数据的任何领域:计算机视觉、动态系统、音频处理等等。他们无法准确预测系统何时在复杂的习性中扩展,如身体智能或抽象造句,这是人类大脑的奇迹。
把神经网络的预测能力看作是解决人类水平智能的必要组成部分,但是对于是否足以证明超级智能的存在并没有说什么。
将深度学习与符号人工智能相结合
人脑是一个 20W 的通用智能系统的存在。计算机最终可以做到(也许在更高的功率下)。象征性人工智能的经典领域试图使用更高级的数学和基于推理的构造来创造智能系统。符号人工智能旨在使计算机能够推理和提取知识,而不是记忆和预测。也就是说,深度学习已经实现了如此多的自动化任务(图像识别、时间序列预测等),因此这些推理系统可以采取非常不同的方法。在深度学习浪潮之外获得资金要困难得多,但正是研究人员展示了下一个平台(可能利用深度学习),这将通过建设性的推理能力彻底改变该领域。
人工智能社区需要记住有时会偏离正道。来源—作者。
强化学习是深度学习的展示
强化学习近年来已经成为深度学习能力的一个戏剧性展示——在各种游戏中展示戏剧性的概括和发现能力( 1 、 2 、 3 、…)。它如此成功的原因是它们是游戏。它们是不同比例的玩具样品。RL 的进步表明,我们可以将一个报酬近似问题框架化为一个回归问题。
[GAE-舒尔曼,莫里茨,莱文,约旦,阿比勒,ICLR 2016]
这是如此令人兴奋的原因——潜力。当我们将更多真实世界的问题公式化为复杂的近似问题时,deep-RL 任务将会更出色。现在的障碍是系统和数据科学。
考虑一下新上市的初创公司 Covariant.ai ,他们正在用深度学习进行物流革命(当然,也在幕后尝试 RL——伯克利的 source friends。)
Lex Friedman 对深度学习的位置做了一个很好的总结——学习专家在互联网上的人数越来越多,请欣赏!
更多?订阅我关于机器人、人工智能和社会的时事通讯!
一个关于机器人和人工智能的博客,让它们对每个人都有益,以及即将到来的自动化浪潮…
robotic.substack.com](https://robotic.substack.com/)
深度学习,认识聪明的汉斯
一篇关于 DNNs 犯下的隐藏错误,为什么它们真的不是错误的文章,还有一匹德国马。
基拉·奥德·海德在 Unsplash 拍摄的照片
【1900 年左右,一位德国农民做出了一个惊人的声明:他教会了一匹马基本的算术,甚至识字和拼写!事实上,在公开演示中,这匹名为“聪明的汉斯”的马能够通过一连串的蹄子敲击正确地回答主人的所有问题。
当时柏林大学的心理学家 Oskar Pfungst 不太相信这种动物真的拥有类似人类的能力,他设计了一系列实验来证明这位农民的说法是错误的。1907 年,他发表了关于这个问题的著名报告,做出了令人惊讶的观察:只有当提问的实验者知道答案时,聪明的汉斯才会给出正确的答案!
这匹马实际上并没有学会通过计算或阅读来解决问题,而是通过识别实验者身体语言中的微妙线索来判断出它所期望的答案。
时至今日,心理学研究中(人或动物)测试对象的行为受实验者预期影响的现象被称为“聪明的汉斯现象”。通常,要特别注意防止受试者在没有解决实际问题的情况下给出正确的答案。
等等。我以为这篇文章是关于深度学习的?
事实上,在现代尖端的深度学习系统(甚至是简单回归)中,我们遇到了同样的问题!当数据中存在与正确结果高度相关的特征(如实验者的肢体语言)时,可能会出现聪明的汉斯现象,或传统统计学文献中的虚假相关性,但不是答案正确(如正确计算)的原因。
Lapuschkin 等人最近在《自然》杂志上发表的一篇文章漂亮地说明了这种效应确实发生在现代深度学习模型中,例如图像识别或玩雅达利游戏。(更多示例见下文。)
那么,我们为什么要关心模型使用什么信息呢?模型终究是在输出正确的答案。
对你的训练和测试数据来说是这样的。
但是它在部署时仍然正确吗?它会因为依赖错误的特性而轻易被愚弄吗?
例如,想象你有一个区分狼和哈士奇的算法,但它主要是通过图像中出现的雪来区分狼和哈士奇。或者,想象一下你想要识别火车和船只(例如,给定 PASCAL VOC 2012 数据集),但是你的算法实际上学会了识别水和铁轨。这对任何严肃的应用程序来说都是灾难。如果你注意的话,你可以在文献中找到很多例子:
- 基于孩子的存在识别“父亲”。
- 根据手术标记识别黑色素瘤。
- 学习手握哑铃作为关节概念。
- 把穿红色衣服的亚洲人归类为乒乓球。
- 将 领带与男性联系起来,将红润的脸颊与涂口红联系起来。
- 根据微笑和戴眼镜预测年龄。
现在,你仍然可以争辩说,它并没有那么糟糕;毕竟网络正确地解决了任务,只是问题没有以好的方式提出——只是修复数据!如果你这样做了,你是在一个很好的公司。莱昂·博图(Léon Bottou)是目前在脸书人工智能公司工作的著名研究员,他认为修正我们的问题陈述可以走很长的路。
这有什么大不了的?为什么聪明的汉斯类型的错误如此糟糕,以至于我们必须独立于典型的分类错误来关心它们?
事实是,发现你的网络是否犯了聪明的汉斯类型的错误真的不容易,准确地说是*,因为*它们没有反映在分类错误中。基本上,你必须依赖于一个无偏差的数据集或者一个足够高质量的测试集。从上面的例子来看,不太令人放心。
如果你正在使用可解释性方法,并且知道要寻找什么,你可能通过查看网络实际使用的功能来发现聪明的汉斯类型的错误。但是对于大数据集,这是不可行的。研究人员开始以可扩展的方式解决这个问题,但是还有很长的路要走。
作为研究人员和实践者,重要的是要意识到聪明的汉斯类型的错误,并知道从哪里开始(试图)发现它们。除此之外,祝你好运!
希望你学到了有用的东西!
物体检测的深度学习方法:R-CNN 解释
R-CNN 目标检测算法,从原始论文一步一步讲解
来源:Matthijs Hollemans 的博客
介绍
CNN 已经被广泛用于图像分类。但是检测图像中的对象并在它们周围绘制边界框是一个很难解决的问题。为了解决这个问题,2014 年发表了 R-CNN 算法。在 R-CNN 之后,它的许多变体如 Fast-R-CNN 、Fast-R-CNN和 Mask-R-CNN 出现了,它们即兴完成了对象检测的任务。要了解最新的 R-CNN 变种,对 R-CNN 有一个清晰的认识是很重要的。一旦理解了这一点,那么所有其他的变化就很容易理解了。
这篇文章将假设读者熟悉 SVM,使用 CNN 和线性回归的图像分类。
概观
R-CNN 论文【1】发表于 2014 年。这是第一篇表明 CNN 可以在对象检测中产生高性能的论文。该算法以下列方式进行对象检测:
来源:原创论文
- 该方法将图像作为输入,并从图像中提取大约 2000 个区域提议(上图中的步骤 2)。
- 然后,每个区域提议被扭曲(整形)成固定大小,作为 CNN 的输入。
- CNN 为每个区域提议提取一个固定长度的特征向量(上图中的步骤 3)。
- 这些特征用于使用类别特定的线性 SVM 对区域方案进行分类(上图中的步骤 4)。
- 使用边界框回归来细化边界框,使得对象被该框正确地捕捉。
现在这篇文章将深入解释模型如何被训练以及它如何预测边界框的细节。
计算区域建议
地区提案|来源:作者图片
区域建议是可能包含对象的边界框。这些由 4 个数字(x,y,h,w)的元组表示。(x,y)是边界框中心的坐标,( h,w)分别是边界框的高度和宽度。这些区域建议由一种叫做选择性搜索【2】的算法计算。对于一幅图像,提取大约 2000 个区域提议。
训练 CNN 特征提取器;
基于 CNN(VGG 16 台)的特征提取器|来源: Pinterest |由作者编辑
**预训练网络:**为了训练 CNN 进行特征提取,像 VGG-16 这样的架构用来自 imagenet 数据的预训练权重初始化。具有 1000 个类别的输出层被切断。因此,当一个区域提议图像(扭曲到 224x224 大小)被传递到网络时,我们得到一个 4096 维的特征向量,如上图所示。这样,每个区域提议由 4096 维特征向量表示。
下一步是用区域建议图像微调网络的权重。为了理解这一点,我们将引入一个称为交集/并集或 IoU 得分的新指标。
并集上的交集
为了衡量分类模型的性能,我们通常使用准确度、召回率、精确度等指标。但是如何衡量物体检测的性能。在对象检测中,我们必须评估两件事:
- 边界框在图像中定位对象的能力。换句话说,预测的边界框有多接近地面真实。
- 边界框是否正确分类了被包围的对象
IoU 分数衡量预测框与实际情况的接近程度。它是地面真实值和预测框的公共面积与这两个框所包围的总面积的比率。
来源: Gitbook
在最左边的图像中,可以看到预测框不接近真实情况,因此 IoU 得分仅为 35%,而在最右边的图像中,预测框与真实情况框完全重叠,因此获得了 95%的非常高的值。IoU 值从 0 到 1 不等。
**微调网络:**为了微调模型,用 N+1 个类(softmax 层)替换具有 1000 个类的输出层,模型的其余部分保持不变。n 是对象被分类的不同类别的数量,加上背景类别的 1。
接下来,微调需要数据。IoU > 50%的区域提案被视为该目标的积极类别,其余被视为背景。在上面的球图像中,IoU 分数为 35%的区域提案将被标记为背景,而其余的方框将被标记为球。这些图像(区域提议)被扭曲(调整大小)到与 CNN 兼容的尺寸,在 VGG 16 的情况下是 224x224。使用这些图像,网络的权重被微调。
特定于培训班的 SVM
一旦获得了每个区域建议的 4096 维特征,下一个任务是为每个类别训练一个二元 SVM。例如,如果检测模型要检测三个不同的对象——猫、狗和人,那么需要为每个类训练三个 SVM。
**数据准备:**属于特定类别的所有对象提议被分离。该类别的手动标记的地面实况图像被认为是正类别,而对于该类别具有 IoU < 30%的对象提议被认为是负类别。对每个类别做同样的事情,并且训练 N 个 SVM 模型以将每个区域提议分类成 N 个类别。
包围盒回归
来源:我的起点网站 |作者编辑
由选择性搜索[2]算法预测的区域提议边界框可能无法捕获整个对象。为了微调预测的边界框,使用边界框回归。
通过选择性搜索[2]算法考虑地面真实区域建议 G 和预测区域建议 P。
为了使 G 比例不变的预测,进行以下变换,使得回归的目标是 t.
转换方程
来源: Pinterest |作者编辑
回归模型的输入是来自 CNN 的最后一个池层的特征。我们每类训练 4 个回归模型,目标为 t ,输入特征为 CNN 的最后一个池层特征,以学习回归参数 w。
回归方程式
这里*是(x,y,w,h)的占位符,phi§是对应于方案 P 的最后一个池化图层要素。因此,要预测地面实况 G,我们可以使用回归方程根据区域方案 P 计算 t,然后将 t 和 P 的值代入变换方程以获得 G。
预言;预测;预告
一旦 R-CNN 的不同部分被训练,接下来的部分是进行对象检测。
来源:作者图片
- 拍摄输入图像,并使用选择性搜索[2]算法,为图像获得大约 2000 个区域提议。
- 每个区域建议图像被扭曲成 224x224 的固定大小。
- 这些区域提议图像然后被传递到训练的 CNN 以获得所有 2000 个区域提议的 4096 维特征向量,这导致 2000×4096 维矩阵。
来源:作者图片
3.每个区域的提案都使用每个类别的 SVM 进行分类。通常对于 N 个类,SVM 权重(4096 维)以矩阵的形式堆叠,并与特征矩阵相乘。这将产生一个矩阵,该矩阵为区域提案所属的每个类别分配一个分数。
4.该建议被分配到得分最高的类别。因此,图像中的所有 2000 个区域提议或边界框都标有类别标签。
5.在那些众多的边界框中,许多是多余的和重叠的边界框,需要被移除。为了实现这一点,使用了非最大抑制算法。
非最大抑制算法:
来源:非最大压制博客
非最大抑制是一种贪婪算法。它一次只对一个类有效。对于一个特定的类,它选择使用 SVM 获得最高分数的盒子。然后,它计算属于该类的所有其他边界框的 IoU 分数。IoU 分数大于 70%的框被移除。换句话说,具有非常高重叠的边界框被移除。然后选择下一个最高得分框,依此类推,直到该类别的所有重叠边界框都被移除。对所有的类都这样做,以获得如上所示的结果。
6.一旦获得标记的边界框,下一个任务是使用回归来微调框的位置。
通过回归微调区域建议|来源:作者图片
在训练期间,为每个类训练 4 个回归模型。因此,对于特定的包围盒,区域建议图像通过 CNN 以获得要传递给回归模型的特征 P。回归模型输出比例不变的坐标(dx§,dy§,dw§,dh§)。这些坐标与区域建议坐标(Px,Py,Pw,Ph)相结合,使用以下公式获得调整后的最终坐标(Gx,Gy,Gw,Gh)。
原始论文的结果
R-CNN 物体探测结果|来源:原创论文
结论
R-CNN 虽然擅长检测对象,但也有不足之处。
- 这种算法很慢,在图像上执行对象检测大约需要 47 秒。
- 训练不是一步到位的。不同的部分有不同的模式,这使得培训过程非常耗时。
这些缺点在 R-CNN 后来的改进中得到解决,这些改进是 Fast-RCNN、Fast-RCNN 和 Mask-RCNN。对 R-CNN 有很好的理解,有助于轻松直观地理解 R-CNN 的其他变种。
参考
- R.吉希克、j .多纳休、t .达雷尔和 j .马利克。丰富的特征层次,用于精确的对象检测和语义分割。2014 年在 CVPR。
- Uijlings,Jasper & Sande,K. & Gevers,T. & Smeulders,Arnold。(2013).物体识别的选择性搜索。国际计算机视觉杂志。104.154–171.10.1007/s 11263–013–0620–5。
深度学习模型实现:分类变量的嵌入
利用嵌入探索美国房价和移民模式
对于许多复杂的预测问题,深度学习(DL)方法(如 CNN、NLP 和全连接网络)提供了最高水平的性能。这通常以理解解释特征在预测结果中的作用为代价。虽然基于统计方法的机器学习(ML)方法提供了多种技术,包括变量选择、相对重要性和某些情况下的模型系数,以了解预测器的作用(如本系列的第 1 部分中所讨论的),但在 DL 方面实现类似见解的潜力还没有得到充分探索。而且,由于所涉及的复杂性,这种情况很可能会持续下去。然而,有一些方法可以获得一些关于众所周知的黑盒中发生了什么的线索。例如,在图像的 CNN 分析中,类别激活地图是一种识别图片的哪些区域在其分类中最活跃或最有影响力的方法。
嵌入
对于时间序列或其他结构化数据,嵌入为分类特征提供了标准的一键编码或“虚拟”变量表示的替代方法,可以洞察它们对因变量的影响模式(郭和 Berkhahn2016 )。嵌入矩阵与模型拟合一起被估计,并且它们的维数通常被选择为稍微小于变量的基数,例如,表示一周中各天的嵌入矩阵可以具有 7×4 的维数,从而允许每一天由 4 维嵌入向量来表示。这允许沿着 4 个维度来捕捉模式和各天之间的相似性或差异。
一个例子:房地产时间序列
我想看看我是否能从 DL 模型中估计嵌入,以及产生的模式是否是可解释的。当美国经济分析局(BEA)最近开始发布美国各县的 GDP 数据时,我开始对在这种地理粒度级别上还能找到什么类型的数据感兴趣。我热爱所有与房地产有关的事情,当时我还不是一个能接触到 MLS 信息的活跃的代理人。幸运的是,有 Zillow 研究公司。尽管 Zillow 在该网站上提供的信息会随着时间的推移而变化,但去年他们提供了从 2010 年 1 月 1 日到 2018 年 1 月 1 日期间约 1260 个美国县的调整后销售价格数据。各县提供的其他房地产数据包括销售计数、降价百分比、Zillow 房屋价值指数(ZHVI)、Zillow 天数、每月房源和以前止赎房屋的销售百分比。所有这些功能每月都有。我收集了美国各县的其他数据,包括 GDP(2015-2018,BEA),人口模式,失业和贫困,家庭收入,县商业模式和美国人口普查地区和部门(2010-2018,美国人口普查局)。这些数据每年记录一次。我还从美联储经济数据(2010-2018,FRED)中获得了月度优惠利率。
我的目标是使用 fastai 库来预测美国各县的年度月度调整销售价格。我拟合了一个具有两个完全连接层的 DL 模型,其中分类变量使用嵌入来表示。最终模型在预测下一年的调整后销售价格时实现了 8%的验证均方根百分比误差。你可以在这里看到适合和如何提取嵌入的代码。一旦提取,嵌入矩阵与原始数据合并回计算主成分(PCs)。地理变量的前两个 PCs 的图表如下,从最细到最细:州、部门和地区。这些会引出我们可以解读的东西吗?让我们来了解一下!
状态
作者图片
状态嵌入沿 PC1 的布局显示了一些我们可能预期的聚类(例如 CT 和 RI、NY 和 NJ)和异常值(例如 CA、HI),但在其他方面显得相当复杂。让我们使用美国人口普查部门和地区来进行更高层次的分组(你可以在这里看到这些)。
美国人口普查部门
作者图片
这里事情变得有趣了!沿着 PC1,除了南大西洋分部之外,其它地方都相当不错。沿着 PC2,我们有一些最初看起来不协调的分组,至少从地理角度考虑。东/北/中南部以及南大西洋与山区划分在一起,新英格兰/中大西洋与它们的海岸相对,太平洋。这些领域有什么共同点?
从供求及其对价格的影响来考虑,让我们看看美国的移民模式。虽然人口普查局也有这种类型的信息,但我发现了一个有趣的来源(来自应该知道的人!)是北美搬家服务。你可以在这里查看他们过去十年的互动迁徙地图。在美国大选的前一个月,我有点希望他们选择不同的颜色而不是红色和蓝色来区分各州是主要向外还是向内(!)但这是一张迷人的地图。在他们的网站上,你可以滑动滚动条来查看 2011 年至 2019 年每年的数据,并将鼠标悬停在每个州上来查看其出境和入境统计数据,以及财产税百分比。
有趣的是,我们看到了与上述嵌入描述的模式的一致性,美国人口普查部门东南中、南大西洋和山地有更多的向内迁移,新英格兰(至少是 CT)、中大西洋和太平洋部门经历了更多的向外迁移。该模式的一个例外是东北中心区,虽然与其他入境区组合在一起,但似乎有更多的出境移民。
还有一个最小的美国人口普查分组需要考虑:地区。
美国人口普查地区
作者图片
如上图所示,美国的四个人口普查区域将人口普查划分折叠起来。根据我们已经研究过的迁移模式,PC1 可能会根据迁移模式及其对房价的影响对这些地区进行排序。在过去的十年中,美国南部地区的房价涨幅无疑是最大的。真正有意思的是 PC2!虽然其他三个地区基本上在这个轴上一起崩溃,但西方与其他地区截然不同。虽然在过去十年中,南部、东北部和中西部地区的入境或出境移民模式在内部相当一致,但西部人口普查区合并了太平洋地区和山区的不同移民动态。
最后
通过一点额外的工作,分类变量的嵌入可以从 DL 模型拟合中提取出来,并且可以提供一些关于预测变量影响我们预测结果的能力的方式的见解。嵌入还可以被提取并用作其他类型的建模的协变量,例如 ML 策略,并且可以提供比传统虚拟或一个热编码参数化更小的基数。
用于自动摘要的深度学习模型
NLP 的下一件大事?
来源:作者
也许是所有 NLP 任务中最有帮助的
超过四分之一世纪以来,我们已经能够通过使用几个相关的关键字查询搜索引擎来搜索网络。如果没有这样的工具,互联网将只是无用的数据垃圾场。1998 年,谷歌的 PageRank 算法 重新定义了我们对搜索结果相关性的预期。最近一些 语义处理 已经被添加到这个魔法中,帮助引擎解释用简单语言表达的查询。在不太遥远的将来,我们也许可以通过与搜索引擎进行简短的对话来确定文档,就像我们与书商进行对话一样。尽管在书商和搜索引擎之间有一个重要的区别。如果你犹豫应该读哪本书,你可以试着让书商用几句话给你总结一下。
在传统的基于规则的 NLP 方法中,这种摘要任务看起来已经完全遥不可及,并且在可预见的将来,它也被认为是不现实的。但是,随着 NLP 深度学习模型的最新进展,事情正在慢慢发生变化。现在想象一下,在你最喜欢的搜索引擎的输入框旁边有一个下拉列表,可以让你设置给定文档的自动摘要的长度。比如说,1 句话,10 句话或者一页纸的总结。那会有帮助吗?事实上,它很有可能很快被证明是如此有用,以至于可能变得无处不在。除了改进文档搜索,它还可以帮助许多其他任务。例如,它可以帮助科学家跟上医学或人工智能等领域令人眼花缭乱的出版物。更通俗地说,它可以帮助为网上商店制作 简短的产品描述 ,这些商店的商品目录太大,人工无法处理。自动摘要应用的更多例子在这里描述为。
对于像小说这样有几百页的大文档,这种通用的摘要工具仍然属于科幻小说的范畴。然而,由于深度学习模型令人惊讶的灵活性,对可以用几句话概括一两页文档的工具的等待可能不会太长,至少在特定的知识领域内。本文的目的是描述最近的数据集** [ 1 , 2 ,深度学习架构 [ 3 , 4 , 5 ,它们让我们更接近目标。**
困难的任务
总结任务很困难,原因有很多,其中一些与其他 NLP 任务相同,例如翻译:
- 对于给定的文档,不存在客观上最好的摘要**。一般来说,他们中的许多人会认为同样好。**
- 很难准确定义什么是好的总结,以及我们应该用什么分数来评估它。
- 好的训练资料早就被稀缺的和昂贵的给收集了。
人类对摘要的评价是主观的,包括对风格、连贯性、完整性和可读性的判断。不幸的是,目前还不知道既容易计算又忠实于人类判断的分数。胭脂分数是我们所拥有的最好的分数,但是我们将会看到它有明显的缺点。ROUGE 只是计算机器生成的摘要和人类编写的参考摘要共有的字数,即 n 克。更准确地说,它报告了相应的召回的组合:
和精度**😗*
ROUGE- n 中报道的组合是他们的几何平均值(称为 F1 分数)。尽管 ROUGE 分数没有如实地反映人类的判断,但是它具有计算简单的优点,并且它考虑了与多个摘要相关联的一些灵活性,这可以通过重新排列有效摘要中的单词来产生。
有两种类型的摘要系统:
- ****摘录摘要系统从源文档中选择多个片段来组成摘要。这种方法的优点是保证了生成的摘要在语法上是正确的。总的来说,提取系统的 ROUGE 得分较高,比我们接下来讨论的选项更可靠。
- 另一方面,抽象概括系统生成自己的单词和句子来重新表达原文的意思,就像人类作家会做的那样。它们可以被视为试图保留意义的压缩系统。后一种系统显然更难开发,因为它涉及到解释信息和包含外部知识的能力。
我们将在下面描述这两种情况。
更多更好的数据
**直到最近,用于训练摘要模型的主要数据集是 CNN /每日邮报数据集 ,它包含 300,000 个新闻文章的例子和它们的多行摘要。然而,一项详细的检查[ 1 ]揭示了这个数据集中的各种限制,这些限制可能会对系统执行文本摘要的能力的评估产生偏见。例如,结果表明有用的信息在数据源中分布不均匀,即大部分在文档的开头。此外,许多摘要包含源代码的大片段。这当然不是教系统如何产生好的抽象摘要的最好方法。
但最近事情发生了变化。例如, 大专利数据集 [ 1 ]包含 130 万个专利文档及其摘要,缓解了上述大部分缺点。**
一种为训练摘要模型产生不断增长的数据集的新方法使用了在国际科学会议上给出的谈话的视频记录。这里的基本假设是,这些抄本为产生高质量的科学论文摘要提供了一个良好的起点。成绩单本身并不直接是一篇论文的总结。相反, TalkSumm 方法【2】的作者提出通过从演讲中呈现的论文中检索一系列相关句子来创建摘要。一个句子被认为是相关的,取决于说话者在她的谈话中使用了多少单词来描述它,假设她在任何给定的时间点脑子里都有论文的给定句子。
巧妙的架构和改进的成本函数
在本节中,我们将描述最近为摘要任务开发的 3 个神经网络模型。这里的目的当然不是完整的,而仅仅是为了说明为解决这个基本的自然语言处理问题而提出的各种想法。
使学习这种任务成为可能的基本神经网络架构是 Seq2Seq 架构 、 LSTM 递归神经网络 (RNN)、 BERT 和 变压器 模型以及 注意机制 。
图 1 :基本 Seq2Seq 编解码架构,注意。 x _i 是输入令牌嵌入,a_i^t 是步骤 t 的注意力权重, h _ i 是上下文向量, h ^t 是通过用注意力权重对上下文向量进行加权得到的步骤 t 的句子嵌入, s i 是解码器状态, x ’ i 最后,p^t_vocab 是固定词汇在时间 t 的概率分布,(来源:作者)。
对于不熟悉这些话题的读者,我们推荐上面的链接,这些链接将为他们提供很好的介绍。图 1 显示了 Seq2Seq 架构,它将一个令牌序列转换成另一个长度可能不同的序列。它定义了我们在讨论 Seq2Seq 时要参考的向量。
图 2 : BERT 作为变压器架构的编码器部分。转换器背后的核心思想是注意力机制的智能实现,允许计算在 GPU 上高效并行化,这是经典 RNN 无法实现的。每个输入向量 x _ j 是一个令牌嵌入和一个位置嵌入的和。输出 h _ i 是上下文感知令牌嵌入(来源:作者)。
图 2 描绘了一个变压器网络,在嵌入和隐藏向量之间具有自我关注依赖性。粗略地说,转换器将令牌嵌入序列 x _ i 转换成另一个上下文感知嵌入序列 h _ i 。输入向量 x _ i 通常也包括位置信息。与 RNN 网络相比,这是必需的,因为变压器中的输入具有排列对称性。
不结巴地总结
我们提出的第一个架构解决了抽象的摘要任务[ 3 ]。将普通 Seq2Seq 架构应用于总结的早期尝试揭示了这种简单方法的许多问题:
- 原始文档中的事实细节,如日期、地点或电话号码,在摘要中经常被错误地复制。
- 一个有限的词汇表阻止了一些像专有名词这样的词被考虑进去。
- 源片段的不必要重复经常发生,换句话说模型倾向于口吃。
图 3 显示了这些不想要的行为的例子。[ 3 中的作者提出了两个对普通 Seq2Seq 的改进来缓解这些缺点。
图 3 :最后一节“Pointer-Gen + Coverage”包含了[3]中提出的系统的输出。摘要中使用的片段用蓝色表示,事实错误用红色表示,不必要的重复用绿色表示(来源)。
首先,为了克服有限的词汇限制,他们允许网络直接从源中复制一个单词,并在需要时在摘要中使用。做到这一点的精确机制被称为指针网络**。请记住,在普通的 Seq2Seq 网络中,解码器在每个时间步长 t 计算固定有限词汇中的单词 w 的概率分布p^t_ vocab(w)。像往常一样, p ^ t _vocab 通过 softmax 层计算,该层将注意力上下文向量 h ^ t 和解码器状态 s _ t 作为输入。在指针网络中,计算一个附加的复制概率 p _copy,它表示一个字应该从源复制而不是由解码器生成的概率。使用具有 h ^ t 、 s _ t 和 x _ t 矢量作为输入的 s 形层来计算概率 p copy(参见图 1)。哪个单词实际上应该被复制是由解码器在时间 t 对源中的每个单词wII^t确定的。将所有这些放在一起,模型产生单词 w 的全部概率由以下混合给出:**
第二,为了避免重复相同的片段,作者在每个时间步 t 定义了一个覆盖向量** c ^ t ,该覆盖向量估计直到时间 t 源中的每个单词从解码器接收到的关注量:**
这个覆盖向量然后被用在网络内的两个不同的地方。首先,它用于通知负责计算注意力权重 a ^ t _ i 的注意力机制(除了通常对字 w _ i 和解码器状态 s _ t 的编码器上下文向量 h _ i 。解码器因此知道它已经注意的单词。其次,它用于校正损失函数。请记住,在时间步长 t 时,权重a^tI是放在单词 w _ i 上的注意力,而c^tI是这个单词在过去受到的注意力。如果单词 w _ i 在时间 t 比它在过去已经受到的关注更多,也就是说,如果a*t*_*I*>*c*t_I,那么成本函数应该惩罚 c 的大值为了惩罚对重复单词的注意,在时间步长 t 时,在损失函数中定义一个附加项作为输入标记的总和:
这然后被添加到(用附加的超参数)训练集中目标词 w ^*_ t 的通常负对数似然中:
使用和不使用这些额外技巧的结果如图 3 所示。
作为语境化句子序列的文档
我们的下一个例子展示了为提取摘要任务定义新 SOTA 的最新想法。它直接基于导致 2018 年
BERT 模型 的一个关键思想,即基于一个 变压器 编码器的巧妙预训练任务的迁移学习。让我们再深入一点,总结一下文档摘要的 HIBERT 架构[ 4 ]。
基本的观察是,抽取分类可以铸为一个句子标注问题**:简单训练一个模型,识别文档中的哪个句子应该保留,组成摘要!为此,HIBERT 架构使用两个嵌套的编码器转换器,如图 4 所示。**
图 4:HIBERT 架构包含两个 Transformer 编码器的层次结构,用于将文档中的每个句子分类为摘要的一部分或不是摘要的一部分(来源:作者)。
底部的第一个 Transformer 编码器是一个经典的句子编码器**,它将组成文档第 k 句的单词序列( w _0^ k , w 1^ k ,…,wj^k)转换为嵌入h的句子该向量通常被识别为句尾标记< EOS >上方的上下文向量。******
位于顶部的第二个 Transformer 编码器是一个文档编码器**,它将句子嵌入序列( h _1、 h _2、…、 h _ D) 转换为一个文档感知句子嵌入序列 ( d _1、 d _2、…、D*这些嵌入又被转换成概率序列( p _1、 p _2、…、 p _ D ),其中 p _ j 是第 j 句应该是摘要的一部分的概率。***
从头开始训练这样一个复杂的层次网络是不切实际的,因为它需要大量不切实际的文档摘要对。众所周知,训练这样一个数据量有限的复杂网络的最佳策略是使用迁移学习**。为此,首先在辅助任务上对 HIBERT 体系结构进行预训练,该辅助任务包括预测在大型文档语料库中随机屏蔽(15%)的句子:**
掩蔽句子预测任务的一个例子。
图 5 显示了用于这个屏蔽句子预测任务的架构。它在 HIBERT 架构之上添加了一个 Transformer 解码器,以便将嵌入了 d _ k 的文档感知语句转换为被屏蔽的第 k 个语句的单词序列( w _0^ k 、 w 2^ k 、…、w j ^ k )。为了在步骤 i 生成单词,解码器使用其上下文 h _ i 和来自文档编码器的嵌入 d _ k 的文档感知语句。
图 5 :用于屏蔽语句预测任务的架构。在 HIBERT 架构的顶部添加了一个句子转换解码器,以使用其文档感知嵌入 d _ k 中封装的信息来恢复被屏蔽句子的单词(来源:作者)。
以这种方式训练的网络收集了大量的语义知识,而不需要任何扩展的标记过程。在第二阶段,利用它在预训练任务中学习到的内容,网络在实际的目标任务上进行微调,即作为句子二进制标记任务的摘要,如图 4 所示。
这个屏蔽句子预测任务显然在句子层面上让人想起用于预训练原始 BERT 模型的屏蔽语言模型** (MLM)。请记住,MLM 的任务在于恢复句子中随机屏蔽的单词。**
强化学习来拯救
正如我们前面所解释的,总结任务的一个核心问题是缺少唯一的最佳总结。ROUGE score 在某种程度上考虑到了这一点,因为它忽略了生成的摘要中单词的顺序(或 n -grams)。因此,我们实际上希望最小化的成本函数应该类似于这个胭脂分数,或者至少最终的损失函数应该包括这样一个项。这就是我们在这里展示的上一部作品[ 5 中遵循的策略,同样涉及抽象概括。
像 ROUGE 这样的分数的问题是,对于解码器生成的任何单词序列( w _1,…, w _ j ),它相对于网络的参数θ是恒定的,因此使得反向传播不可能。这种情况并不是没有希望的,因为从生成器*定义的联合概率分布 p_theta ( w _1、…, w _ j )中采样的句子( w _1、…, w _ j 的胭脂分数的期望值实际上是一个可微的接下来的路就很清楚了。只要将期望值定义的损失最小化:*
实际上,我们可以将 Seq2Seq 模型的生成器视为一个强化学习** (RL)代理,其在时间步 t 的动作是根据内部状态 s _ t 生成一个字 w _ t ,该字封装了来自先前动作的历史。从现在开始,我们只需要打开一本关于 RL [ 13 ]的书,学习如何最小化 L _RL。RL 中的一个基本结果,被称为政策梯度定理,陈述了 L _RL 的梯度:**
在哪里
最后一个索引 j 是< EOS >令牌的索引。加强算法用生成器计算的分布pθ(w 1,…,w_ 1,…, w _j】)的单个样本来近似上述期望:
实际上,像 ROUGE 这样的分数可能具有大的方差**,这阻碍了梯度下降的收敛。好在我们可以通过比较 ROUGE( w _1、…、 w _ j )和一个独立于( w _1、…、 w _ j )的基线 b 来提升收敛速度。这不会改变 L _RL 的梯度,这一点很容易验证,但它可以显著降低方差[ 13 ],从而显著提高收敛性:**
因此,主要问题是找到一个适当的基线。我们正在讨论的工作中的想法是,让基线 b 等于生成器在推理时实际生成的单词序列的 ROUGE 分数。请记住,这是由解码器的 softmax 在每一步 t 计算的连续最大化条件概率的单词序列:
基线 b 的这种选择称为自我临界序列训练** (SCST)。因此,总的来说,钢筋损失项为:**
在哪里
我们可以看到,这个损失项促使p_θ生成单词序列( w _1、…, w _ j ),其胭脂分数大于解码器当前生成的序列的胭脂分数。
在损失函数中包括这样的 SCST 强化学习项有两个好处。首先,促使构造 L _RL 的原因是,它使得在随机梯度下降训练过程中使用像 ROUGE 这样的不可微分数成为可能。第二个好处是,它还可以治疗所谓的曝光偏差**。暴露偏差来自典型的教师强制程序,该程序通常用于训练 Seq2Seq 模型。该过程使用来自训练集的基础真值字( w 1,…, w * j )来训练解码器 RNN,而在推断时间,解码器当然必须使用其自己生成的令牌,这可能因此导致错误的累积。基线 b 的 SCST 选择相当于使用在推断时间实际看到的分布来训练解码器。*
使用的最终损失函数是强化学习** 损失 L _RL 和标准最大似然 目标 L _ML 的加权和。前者考虑到了摘要的非唯一性,至少在某种程度上是这样,但它本身肯定不是模型产生可读消息的动机。另一方面,后者更喜欢可读的句子,因为它基本上定义了一个语言模型。**
为了避免重复,作者还使用了一种增强的注意力机制,这种机制涉及到一个指针网络,类似于我们在第一个例子[ 3 中描述的那个。
下一步是什么?
我们在上一节中描述的三个模型都使用深度学习,因此实现了一种纯粹的统计方法来完成摘要任务。最近的研究也试图找到更好的损失函数。例如, 朗诵会 的研究人员探索了一个有趣的想法,即一个好的总结应该在原文允许的范围内回答问题。总的来说,这些模型对于短文档确实出奇地有效。但是,我们可以合理地期望建立一个系统,使用仅仅依赖于处理大量文本数据的技术,在一页中总结 300 页的小说吗?这远非显而易见。原则上,摘要应该能够利用真实世界的知识来理解要摘要的文档或书籍。尽管语言模型本身不太可能捕捉到这样的常识,而这些常识更有可能是由感官经验收集的。建立有用的摘要工具的一个短期可能性是将它们的范围缩小到已经有知识基础或本体的特定专业领域。一个更激进的步骤是建立一个具有更好的“真实世界理解”的系统,这个步骤可能来自于多模态学习器**,它被设计来聚合音频、视频和文本模态,例如电影。沿着这条道路已经取得了可喜的成果。**
感谢
在此,我要感谢 Thomas Scialom ,他是朗诵会的研究员,他好心地与我分享了他的知识,让我注意到他在 GitHub [ 16 上的总结摘要页面。这帮助我启动了对深度学习摘要模型的探索。
参考
- E.Sharma,C. Li,L. Wang, BIGPATENT:一个用于抽象和连贯摘要的大规模数据集 (2019),arXiv:1906.03741。
- G.Lev,m . shmu Eli-朔伊尔,J. Herzig,A. Jerbi,D. Konopnicki, TalkSumm:一种基于会议会谈的科学论文摘要的数据集和可扩展标注方法 (2019),arXiv:1906.01351。
- A.见 Peter J. Liu,Ch。d .曼宁,直奔主题:用指针生成器网络进行总结 (2017),arXiv:1704.04368。
- X.张,魏,周,【面向文档摘要的层次双向变换器文档级预训练】 (2019),arXiv:1905.06566 .
- R.保卢斯,c .熊,R. Socher,抽象概括的深度强化模型 (2017),arXiv:1705.04304。
- C.林、、胭脂一包自动评价总结。**
- 南 J. Rennie,E. Marcheret,Y. Mroueh,J. Ross,V. Goel,用于图像字幕的自我临界序列训练 (2016),arXiv:1612.00563。
- G.Genthial, Seq2Seq 带关注和光束搜索 (2017),博客。
- C.Olah , 了解 LSTM 网络 (2015),博客。
- J.Alammar, The Illustrated BERT,ELMo and Co. ,博客。
- J.Alammar,图文并茂的变形金刚,博客。
- D.Bahdanau,K. Cho,Y. Bengio,联合学习对齐和翻译的神经机器翻译 (2016),arXiv:1409.0473。
- R.萨顿和 a .巴尔托,强化学习:导论 (2018),麻省理工学院出版社,麻省剑桥。
- T.Scialom,S. Lamprier,B. Piwowarski,J. Staiano,答案联合起来!增强摘要模型的无监督度量 (2019),arXiv:1909.01610。
- 南 Palaskar,J. Libovick,S. Gella,F. Metze,【How2 视频的多模态抽象摘要 (2019),arXiv:1906.07901。
- T.Scialom,总结概括 (2019),GitHub。
深度学习——不仅仅是大公司
如何使用深度学习,即使是小数据集
弗兰基·查马基在 Unsplash 上拍摄的照片
当你在研究深度学习算法时,你几乎总是需要大量的数据来训练你的模型。这是不可避免的,因为像 RNN 或 GRU 这样的深度学习算法需要数据,为了收敛,它们需要公平的数据份额。但是如果没有足够的数据呢?这种情况并不罕见,事实上,在研究工作中,你可能每天都要处理它,或者即使你正在研究一个新的领域/产品,那里还没有很多可用的数据。你怎么处理这个?我能应用机器学习吗?我能利用深度学习的最新进展吗?
有两种可能的路径可供我们选择,我将在下一节中介绍它们——数据路径和模型路径。
数据分支
这听起来可能有点显而易见,但有时我们会错过这种解决方案解决小数据问题的能力——我说的是数据增强。数据扩充背后的想法是——某个点(在超空间中)附近的点代表类似的行为。例如:一个狗的图像增加了对比度或亮度仍然是一个狗的图像。
要对表格数据集使用数据扩充,有多种方法可用,例如:
- 随机过采样
- 基于聚类的过采样
- 合成少数过采样技术(SMOTE)
再来详细说说 SMOTE。为了简化,我们可以将 SMOTE 背后的概念定义为“物以类聚”,这在数据方面的减少意味着在多维空间中彼此接近的数据点表示相似的行为,因此它们可以被近似为数据集的新数据点。
当从一个较大的集合中合成几个样本时,这种技术最有效。但是,一旦你超过了某个近似合成样本的阈值,样本的可能性就开始发散。因此,在实现这一点时,你必须记住这一点。
但是,一旦你超过了某个近似合成样本的阈值,样本的可能性就开始发散。
再来说说图像中的数据增强。看下面的图片,它们都代表一只鹦鹉,但它们都不同,因为图像的人口统计数据,如对比度、亮度等。,从单个图像变为 12 个图像,数据量增加了 12 倍。
演职员表:【https://github.com/albumentations-team/albumentations
当然,我们还可以应用旋转、镜像和裁剪来增加可用的图像数据集。为此,有几个可用的库,如 OpenCV、PyTorch 和 TensorFlow。另一个也很有趣的是蛋白,你可以在这个 Colab 笔记本上看到它的运行。
数据扩充的生成模型
生成模型已经证明了对数据分布的超级有用的理解,以至于今天这些模型是数据扩充任务的主要工具。
用于数据扩充的生成模型的一些最广为人知的应用可以恢复如下:
LSTM 的文本生成——除了用于预测模型,RNN 和 LSTM 的能够学习问题的序列,然后为文本生成等问题领域生成新的完全合理的序列。但它们在地理位置数据生成方面也非常强大。
用于图像生成的可变自动编码器(VAE)—深度生成模型越来越受欢迎。VAE 架构非常直观且易于理解,由两个神经网络组成——一个编码器和一个解码器,其中编码器将每个记录映射到 z 维标准分布。
用于表格数据生成的生成对抗模型 —由两个网络组成——一个鉴别器和一个生成器,GANs 已被证明在学习数据集分布和复制数据增强方面非常强大。它们的应用相当广泛,从图像到规则数据生成,从表格数据到时间序列。
模型路径
到目前为止,我们研究了调整我们的数据量本身,但是,如果我们调整模型本身,我们也可以通过小数据集获得更好的结果。有几种方法可以实现这一点,接下来我将描述它们。
迁移学习
迁移学习已经成为研究者甚至业界人士的首选策略。你在 Kaggle 上看到的几乎所有模型都以这样或那样的方式利用迁移学习。它不仅减少了训练次数,而且在小数据集上也工作得很好。
例如,您可以使用像 ResNet、InceptionV3 这样的预训练模型,只训练最后一层(冻结其余部分),而不是在图像分类任务中从头开始训练您的 CNN 模型,这样您的任务将只需原来训练时间的一半即可完成。
迁移学习过程中需要微调,这将涉及超参数优化和多层冻结(根据需要)。这里是一个使用 Tensorflow2.0 的预训练 CNN 的transfer learning 实现。
余弦损失
另一种已被证明有效的技术是将损失函数从交叉熵改为一种称为余弦损失的新方法。
什么是余弦损失? 余弦损失是通过考虑余弦相似性和
- f_theta(x)代表模型参数
- Psi(y)表示类别标签的独热码编码向量
- σ_cos 表示两个向量之间的余弦相似度。
这个在这篇论文里有详细解释。在分类过程中使用余弦损失代替了传统的交叉熵等方法,模型的准确性有了很大的提高。在所有小数据集上,使用余弦损失获得的分类精度大大优于 softmax 后的交叉熵,在 CUB 和 NAB 数据集上,最大相对改进为 30%和 21%。
虽然小数据集是一个现实,并且对大多数研究人员和组织来说是一个明显的问题,但是为了解决这个问题,在这个领域已经做了很多改进。在这里,我给你留下一些在这个领域已经完成的最惊人的研究:
- 全景成像上的动脉粥样硬化颈动脉斑块:使用深度学习的小数据集自动检测 : 本文将 R-CNN 模型应用于 65 幅图像的数据集上,取得了显著的灵敏度和特异性分数。
- 通过对小数据的深度学习进行肺部 CT 影像征象分类 : 本文采用甘氏进行数据扩充,并应用基于 CNN 的模型,达到约 91%的准确率
- 生物医学图像分析中小样本深度学习综述 : 本文分析了处理小样本生物医学图像数据的不同方法,并对它们进行了比较
最后但并非最不重要的一点是,由于 COVID 已经存在并长期存在,研究人员正在寻找利用现有基础设施检测它们的更好方法。COVID 是一种相当新的疾病,这使得被感染和检测的人的数据集非常小。
他们在 4000 张病毒性和细菌性肺炎的胸部 x 光片上使用了预先训练好的 CNN 模型,其中 122 张属于新冠肺炎。这证明了小数据集的用例以及在这种情况下利用预训练模型的合理性。他们报告的 AUC 分数约为 0.997,令人印象深刻。
本文解释了生成模型的使用,该模型通过针对胸部 X 射线的有限数据集的微调深度迁移学习来扩充数据。这里使用的预训练模型包括 ResNet、GoogLeNet、AlexNet 和 SqueezeNet,数据集为 5863 张胸部 x 光片。该论文的结论是,ResNet 的性能优于其他达到约 99%准确率的产品。
结论
我们在这篇文章中看到,有两种主要方法可以解决小数据集问题,一种是通过调整数据部分,另一种是利用模型固有的功能和使用不同的损失函数。不同的策略可以很容易地应用,并提高整体 ML 模型的质量,同时使其有可能受益于深度学习算法的力量。然而,如果我们想要产生有价值的 ML 模型,我们不应该忘记与每一种方法相关的权衡。
我们帮助人工智能的早期采用者改进和生成高质量的数据,以便他们能够成为明天的行业领导者
深度学习预算:450 美元 eGPU vs 谷歌 Colab
Colab 对于开始深度学习来说是非凡的,但它如何与 eGPU +超极本相抗衡?
深度学习很贵。即使是最简单的任务,GPU 也是必不可少的。对于希望获得最佳按需处理能力的人来说,一台新电脑的价格将超过 1500 美元,而借用云计算服务的处理能力,在大量使用的情况下,每个月的费用很容易超过 100 美元。这对企业来说绝对没问题,但对普通个人来说,这意味着更多。
正因为如此,2 个月前,我进行了第一次重大采购,以给自己合理的计算能力。我已经有了一台配有小 GPU 的旧 XPS 15(GTX 960m,只是不合适),所以我决定买一台 Razer core + NVIDIA GTX 1080,我立即拥有了大约 4 倍于我以前的处理能力,价格不到 450 美元(我买的都是二手的)。这是一个如此巨大的转变,以至于我写了一篇中型文章详细描述了整个过程和结果(你可以在这里看到)。
这篇文章很受欢迎,但是我的许多读者和同事问我一个问题,“这和 colab 相比如何?”对于所有这些,我会回答说,我听说有人喜欢它,但我从来没有考虑过。毕竟,一个免费的 GPU 能有多好?
在我进入结果之前,我将给出一个关于 Colab 本身的小背景。Colab 是谷歌研究院开发的一款产品,让任何人都能执行 Python 代码。它完全在浏览器中运行,并使用 google drive 作为其主要文件存储。这使得它很容易被共享,并且完全在云中。(你可以点击查看 colab 的精彩介绍)
问题是计算资源没有保证,这意味着你基本上得到了谷歌目前没有使用的东西。Colab 表示,大多数时候,这意味着分配的 GPU 将从 Nvidia K80s、T4s、P4s 和 P100s 中选择。另一个问题是,如果您暂时不使用 Colab,它会将这些资源分配给其他人。在我的测试中,这不是很宽容。甚至在我带我的狗去洗手间的时候,我也经历了超时。如果您让某个东西运行,做其他事情,并且在完成时没有保存结果,这可能会很烦人。最后一个缺点是运行时间有 12 小时的限制。大多数人不应该担心这一点,但是对于大型项目,调优可能需要一段时间,这可能会很麻烦。
现在我已经解释了什么是 Colab,我可以解释我是如何测试它的。与我在上一篇文章中用来测试我的 eGPU 的类似,我使用了 AI 基准,这是一个非常简单但功能强大的 python 库,它利用 Tensorflow 在 19 个不同的部分上运行 42 个测试,为 GPU 提供了很好的通用 AI 分数。接下来,我初始化了一个运行时 15 次,每次都运行 AI benchmark,记录结果以及分配的 GPU——我得到了 K80 10 次,P100 4 次,T4 1 次(我从未得到 P4,但它的性能应该比 T4 略差)——下面是速度结果!
Colab 结果
正如你所看到的,结果有很大的差异,顶级 GPU 比他们可以指定的最慢的 GPU 快近 4 倍,但对于一个免费的 GPU 来说,它们都是惊人的。我很惊讶这些都是免费的。它们都提供 12g 以上的内存,对于大多数项目来说足够了,当 P100 被分配时,它的速度接近全新的 RTX 2070。即使是最慢、最常见的 K80,其性能也比 GTX 1050 Ti 略差,后者仍然是一款 150 美元的 GPU。
这与我的 eGPU 相比如何?老实说,它堆叠得非常好。下面是我的 1080 设置绘制在旁边时的相同图形!
科 lab vs GTX 1080 eGPU
在中等情况下,Colab 将为用户分配一个 K80,GTX 1080 的速度大约是它的两倍,这对 Colab 来说不是特别好。然而,有时,当 P100 被分配时,P100 是绝对的杀手级 GPU(再次为免费)。因为 P100 是如此之大,当比较一般情况时,您可以看到两个结果没有太大的不同,我的 eGPU 平均只提高了 15%左右。
eGPU 与 Colab 平均值
因此,如果你想进入机器学习领域(或者想升级你目前的设置),你应该怎么做?我个人的建议是,如果你只是想涉足机器学习(至少是开始),参加一个初级的机器学习课程,或者并不总是需要计算资源,Colab 绝对是一个不用动脑筋的人。它免费提供计算机是巨大的。
然而,如果您觉得受到 Colab 产品的限制,可能需要更快的速度,随时了解您的资源,需要长时间的训练,想要使用非 python 语言,或者计划使用 GPU 来完成机器学习任务以外的任务,eGPU(或专用 GPU)可能会更适合您!
我也不想在结束这篇文章时不提到 Colab Pro。每月支付 10 美元,您就可以获得更高的使用限制,并优先使用速度更快的处理器。如果你喜欢 Colab,但担心它的速度和使用限制,它是云计算的一个很好的替代品,价格也很实惠!
如果你喜欢这篇文章,请随时关注我,阅读我写的更多内容,或者请将我作为推荐人,这样我就可以继续制作我喜欢的内容。
[## 我是如何用 eGPU 将我的旧笔记本电脑变成机器学习超级明星的
以新电脑的零头成本改造超极本的惊人简单之旅
towardsdatascience.com](/how-i-turned-my-older-laptop-into-a-machine-learning-superstar-with-an-egpu-66679aa27a7c) [## 为什么雷电 3 如此重要?(以及苹果为什么喜欢它们)
无论您是将它用于 eGPU 和机器学习、游戏,还是用于外部显示器…没有它的生活可能…
towardsdatascience.com](/why-is-thunderbolt-3-such-a-huge-deal-and-why-apple-loves-them-614542d32dc2) [## 合并/连接熊猫数据帧的最有效方法
为什么几乎每个人都写得很低效
towardsdatascience.com](/the-most-efficient-way-to-merge-join-pandas-dataframes-7576e8b6c5c)
编辑:2011 年 11 月 25 日——在的这篇文章中,我使用一台连接速度更快的新笔记本电脑测试了我的 eGPU,看到了更好的 AI 成绩,使它与 Colab 相比更具竞争力。
结合时间序列和表格数据的深度学习。
图片来源:取消快照
我们经常发现自己处于这样一种情况,即我们想要在模型中利用不同特性的组合。模型的输入数据是时间序列和表格数据的混合。在这种情况下,设计一个深度学习模型是一个有趣的问题。
一个示例场景是:您有来自 fitbit 等设备的数据,并且您想要预测任何给定时刻的睡眠阶段:
你混合了:
时间序列输入:
- 心率序列
- 呼吸频率序列
表格特征:
- 睡眠开始后的时间
- 代表这种用户睡眠模式的个性化嵌入
和许多其他功能。
解决这个问题的一种方法是将其视为多模态深度学习。
多模态学习——在研究之门上的照片
在谷歌研究这里引入了“广泛和深度学习”
广泛而深入的学习——谷歌博客上的照片
那么我们该如何着手呢?
- 通过 RNN 或 LSTM 或 1D CNN 传递时间序列序列,并捕获隐藏状态或 CNN 嵌入作为序列的表示。
- 将每个序列的嵌入与其他表格特征连接起来。
一些有趣的决定需要考虑:
对于多个时间序列输入序列:
- 你是否将序列视为独立的,并在后期融合/连接表示(后期融合)?
- 还是把它们当做多通道输入,每个时间序列作为一个通道(早期融合)?
一般来说,晚期融合似乎比早期融合工作得更好,并且当不同的输入序列长度不同时,也不需要填充输入。然而,它确实依赖于问题空间和输入序列的相关性。
一般来说,RNN 似乎更适合较短的序列,双向 LSTM 更适合较长的序列。在后期融合中,你可以混合搭配 RNN/LSTM/1d 有线电视新闻网的不同序列。
下面是一个示例模型实现(用 pytorch 编写):
该实施例使用具有后期融合的 2 层比迪 LSTM。
对于每个时间序列特征(特征 1 和特征 2 ),我们也有基线值,因此我们有融合层,其中我们融合了序列的表示(LSTM 的隐藏状态)和基线值。然而,该融合层不是必需的,并且在没有基线值的情况下不是必需的。
class TestModel(nn.Module):
def __init__(self):
super().__init__()
self.input_size = 70
self.hidden_size = 8
self.num_layers = 2
self.output_dim = 2
self.lstm_feature_1 = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True,
bidirectional=True)
self.lstm_feature_2 = nn.LSTM(self.input_size, self.hidden_size, self.num_layers, batch_first=True,
bidirectional=True)
self.fc_feature_1 = nn.Linear((self.hidden_size * 2) + 1, 1)
self.fc_feature_2 = nn.Linear((self.hidden_size * 2) + 1, 1)
self.fc = nn.Linear(4, self.output_dim)
def forward(self, f, device=None):
if not device:
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
x_f1, f1, x_f2, f2, f3, f4 = f
# x_f1 is feature_1_seq
# f1 is feature_1_baseline
# x_f2 is feature_2_seq
# f2 is feature_2_baseline
# f3 and f4 are tabular features
x_f1 = x_f1.view(x_f1.shape[0], 1, -1)
h0_f1, c0_f1 = self.init_hidden(x_f1, device)
h_t_f1, c_t_f1 = self.lstm_feature_1(x_f1, (h0_f1, c0_f1))
x_f1 = h_t_f1
x_f1 = x_f1.view(x_f1.shape[0], -1)
x_f2 = x_f2.view(x_f2.shape[0], 1, -1)
h0_f2, c0_f2 = self.init_hidden(x_f2, device)
h_t_f2, c_t_f2 = self.lstm_feature_2(x_f2, (h0_f2, c0_f2))
x_f2 = h_t_f2
x_f2 = x_f2.view(x_f2.shape[0], -1)
x_f1 = torch.cat((x_f1, f1), 1)
x_f1 = self.fc_feature_1(x_f1)
x_f2 = torch.cat((x_f2, f2), 1)
x_f2 = self.fc_feature_2(x_f2)
x = torch.cat((x_f1, x_f2, f3, f4), 1)
x = self.fc(x)
x = F.log_softmax(x, dim=1)
return x
def init_hidden(self, x, device):
batch_size = x.size(0)
h0 = torch.zeros(self.num_layers * 2, batch_size, self.hidden_size).to(device)
c0 = torch.zeros(self.num_layers * 2, batch_size, self.hidden_size).to(device)
return h0, c0
如果你曾处理过一个涉及类似输入方式的问题:我很想听听你对你有用的东西或者你尝试过的其他方法。
动态图上的深度学习
时态图网络
由迈克尔布朗斯坦 — 8 分钟阅读
许多现实世界的问题涉及各种性质的交易网络以及社会互动和参与,这些问题是动态的,可以建模为图表,其中节点和边随着时间的推移而出现。在这篇文章中,我们描述了时态图网络,这是一个在动态图上进行深度学习的通用框架。
用合成数据改善机器学习中的大规模不平衡数据集
到亚历山大·沃森 — 6 分钟阅读
我们将使用合成数据和 SMOTE 中的一些概念来提高欺诈、网络安全或任何极少数类别分类的模型准确性
照片由 Florian Olivo 在 Unsplash 上拍摄
用人工智能玩毁灭:深度 Q 学习的多目标优化
由阿德里安·许 — 13 分钟读完
在线学习方法是一个动态的算法家族,为过去十年强化学习的许多最新成就提供了动力。在线学习方法属于强化学习方法的基于样本的学习类别,允许简单地通过重复观察来确定状态值,消除了对显式转换动态的需要。
丹·史沫特莱在 Unsplash 上的照片
让你的机器学习模型进入现实世界
由保罗调 — 10 分钟读出
过去几年中一个令人兴奋的发展是产品中机器学习的扩散。我们现在看到最先进的计算机视觉模型被部署在手机上。最先进的自然语言处理模型正被用来改进搜索。
巨型图上的深度学习
简单可扩展图形神经网络
由迈克尔·布朗斯坦 — 12 分钟阅读
迄今为止,阻碍图形神经网络在工业应用中广泛采用的挑战之一是难以将它们扩展到大型图形,如 Twitter follow graph。节点之间的相互依赖性使得将损失函数分解成单个节点的贡献具有挑战性。在这篇文章中,我们描述了一个在 Twitter 上开发的简单的图形神经网络架构,它可以处理非常大的图形。
夏琳·钱布利斯:从心理学到自然语言处理和应用研究
通过琥珀色滕 — 18 分钟读取
在过去的十年中,人们对数据科学的兴趣呈指数级增长,越来越多的人开始转向该领域。2020 年,关于转入数据科学职业的文章和 YouTube 视频比比皆是。然而,对于许多人来说,关于这种转变的许多关键问题仍然存在:你如何从社会科学背景进入数据科学?心理学等领域中哪些最重要的技能可以应用于数据科学?
Opte 项目发布的一个图形可视化,一个互联网的试验性地图
什么是图论,为什么要关心?
通过 Vegard Flovik — 13 分钟读取
对你来说,图论可能听起来像一个令人生畏的抽象话题,那么你为什么还要花时间去读一篇关于它的文章呢?然而,尽管听起来可能不太适用,但图论实际上有大量有用和重要的应用!在这篇文章中,我将试着简单解释一下这些应用程序是什么。在这样做的时候,我会尽我所能让你相信,至少对这个话题有一些基本的了解,对于解决你可能遇到的一些有趣的问题是有用的。
Feliphe Schiarolli 在 Unsplash 上拍摄的照片
视频通话数十亿无互联网
由 P.K .米什拉 — 11 分钟阅读
过去的这个周末,我看到一篇新闻文章,提到数百万印度学生被困在家里,无法使用互联网或在线教育。事实上,超过一半的世界人口仍然没有任何互联网连接。虽然这种数字鸿沟已经在美国显现出来,特别是在冠状病毒疫情封锁期间的儿童教育方面,但这个问题在亚洲和非洲要严重得多,那里只有不到五分之一的人连接到互联网。
照片由 Unsplash 上的 66 north 拍摄
知识表示和推理用答案集编程
由娜塔莉·库斯特——8 分钟读完
在工业和科学领域,计算问题的数量似乎是无限的。对来自大量可用数据的新见解有着巨大的需求。为了获得这些知识,专门的人使用各种编程语言来设计和实现算法。
图形的深度学习:卷积是你所需要的
图卷积网络及其应用介绍
0.动机
你有没有想过为什么深度神经网络(DNNs)比传统的机器学习模型(嗯,有时候)更好?当然也有很多例外,在表格数据上,梯度推进机器优于全连接神经网络。在 DNNs 的独特特征中,我不认为非线性变换使它们从传统的 ML 模型中脱颖而出。许多传统的 ML 模型,如决策树和 SVM,也能够处理数据空间中的非线性。我很少遇到一个简单的全连接 DNN 在任何基准上都达到了最先进的性能。
真正使 DNNs 区别于传统 ML 模型的是那些支持参数共享的专用神经网络层,例如时间的递归层和空间的卷积层。有了这些专门的神经元层,DNN 作为自动特征提取器蓬勃发展,以取代手工设计的特征。LSTM 和 GRU 等递归层利用数据的时间依赖性,非常适合文本和语音,而卷积层利用空间平移不变性,适用于文本(Conv1D)、图像(Conv2D)和 3D 图像(Conv3D)。
但是没有时间或空间结构的数据怎么办?许多类型的数据实际上都有底层的图形结构,包括:
- 社交:社交媒体如脸书、推特以及引文网络等。
- 知识:知识可以组织成图, Google 的知识图可以更好的检索相关搜索结果;维基百科的文章也可以通过超链接连接成图。
- 生物学:蛋白质和基因可以分别根据它们的物理或调控相互作用组织成图,如蛋白质-蛋白质相互作用网络和基因调控网络。
鉴于图的普遍性,我们是否可以开发神经网络层,利用图的拓扑来更好地表示和推断图中的节点?
1.图形的深度学习
2019 年,图形神经网络(GNNs)正式成为 NeurIPS 2019 的热门研究课题。但是它的起源要追溯到更早。
一些将深度学习应用于图表的早期尝试受到了开创性的 Word2vec 模型的启发(米科洛夫等人)。2013) 在文字嵌入。我们知道,Word2vec 通过使用向量表示预测大型语料库中任何给定单词的上下文,来学习低维空间中的单词嵌入。与图中的节点不同,单词是按顺序出现的,因此每个单词只有两个邻居。但在某种意义上,一个句子可以被认为是一个以单个单词为节点的路径图。如果我们能把一个图形转换成一个序列,或者多个序列,我们就可以采用自然语言处理的模型。
为此, DeepWalk(佩罗齐等人。2014) 使用随机漫步将图展平为序列,随机漫步是一种随机过程,随机漫步通过沿着相邻节点移动来遍历图。更具体地,DeepWalk 使用从截断的随机行走获得的局部信息,通过将随机行走访问的节点视为句子的等价物来学习潜在表示。同样,node 2 vec(Grover&lesko vec 2016)模拟有偏随机游走,可以高效地探索多样的邻域。
由 node2vec 生成的 les missérables 同现网络,标签颜色反映同质性(图 3 来自Grover&lesko vec 2016
DeepWalk 和 Node2vec 都以智能方式将图转换为序列,以应用神经方法对序列进行建模,但是没有开发神经机制来直接使用图中的局部邻域信息。
2.图上的卷积
也许研究人员的动机是与图中的相邻节点共享参数,而不是采用递归,图像中常用的卷积现在在图上也是可能的。
根据定义,卷积是对两个函数( f 和 g )的数学运算,产生第三个函数,表示一个函数的形状如何被另一个函数修改。直观地说,你可以把卷积想象成沿着一个函数移动另一个函数,它们重叠的区域就是最终的卷积函数。
显然,根据一位深度学习大师和他的拙劣描述,卷积比你想象的要常见得多:
玩笑归玩笑,我们如何将卷积应用于图形呢?
理论上,卷积运算可以在空间(欧几里德)域或频谱(频率)域中进行。图的局部邻域信息不容易在空间域表示,图的卷积是在谱域进行的。
根据卷积定理,全图卷积包括对图的拉普拉斯矩阵()𝐿进行特征分解,然后对图进行傅立叶变换:
全图形卷积正向传递
这里,上标(I)表示神经网络层, H 是𝑁× F_i 特征矩阵( N :图中的节点数; F_i :图层特征数量I);W(F _ I×F _ { I+1 })为权重矩阵;U(N×N)是 L. 的特征向量
然而,计算全图卷积代价太大,于是研究人员开发了局部卷积方法来近似全图卷积。图形卷积的一般正向传递可以写成:
局部图形卷积正向传递
其中前向传递函数 f 采用来自前一层的特征和图邻接矩阵*(通常是归一化的或变换的)来表示图的邻域信息,然后应用诸如 ReLU 的非线性激活函数𝜎(⋅来传播到下一层。*
在这里,我们重点关注两种早期开发的近似方法:
- Defferrard 等人 NIPS 2016 :切比雪夫多项式基滤波器
切比雪夫多项式基滤波器的前向传递
,其中 T_k (⋅)是切比雪夫多项式函数,𝑘定义了 k 阶邻域,𝐿̃是由其最大特征值归一化的拉普拉斯矩阵。
- Kipf &威灵 ICLR 2017 :本地汇集过滤器:
图卷积网络的正向传递
,其中𝐴̂是对称归一化邻接矩阵。
3.图卷积网的应用
由于图在许多类型的真实世界数据中普遍存在,GCNs 也可以用于解决各种问题。这些应用程序可以分为以节点为中心的问题和以图形为中心的问题。
3.1.GCNs 的以节点为中心的应用(学习图中节点的标签或表示):
- 半监督节点分类:利用图结构和节点特征来预测未标记节点的标签。示例包括在文档的引用网络上预测文档分类,其中仅标注引用网络中的文档子集(节点)。
- ***节点表示学习:*给定一个图和一个节点的特征矩阵,学习图中节点的低维表示。前面提到的 DeepWalk 和 Node2vec 都是为此应用程序开发的。
3.2.GCNs 的以图形为中心的应用(学习给定节点特征和图形结构的图形的标签或表示)
- 图形信号处理(分类/回归):给定一个具有 N 个节点的固定图形( G ,以及一个特征矩阵X*(M个实例由 N 个特征构成),目标是学习一个函数 f 来对那些 M 个实例做出预测: y = 这本质上是监督学习的一个特例,可以将特征组织成一个图。这也是图像分类的图等价:其中像素被组织成二维网格,并且卷积(CNN)被应用于空间域。图形信号处理的一个实例,由 Dutil 等人演示。2018 ,将 GCNs 应用于基因表达数据(由 N 个基因组成的 M 个样本的矩阵),连同基因网络(由 N 个基因组成的代表调控关系的图)一起预测单个基因的表达水平。*
- 图的表征学习:给定一组图,目标是学习图的潜在表征: f ( G )。小分子化合物的化学结构可以被视为图形,其中原子是节点,键是边。GCNs 可用于学习分子指纹( Duvenaud et al )。,2015 ),这样的分子图表示也可以用来预测分子性质( Ryu 等)。,2018 )。
有机化合物可以表示为由化学键(边)连接的原子(节点)的图形
4.GCN 对 MNIST 在图形信号处理问题上的实验
Defferrard 等人(2016) 在优秀的老 MNIST 手写数字分类数据集上设计了一个有趣的实验,以展示 GCNs 的效用。他们没有在原始空间中组织像素,而是创建了一个网格图,使用最近邻将像素连接到原始欧几里得空间中的邻居。然后,该 2D 网格图可以用于表示 gcn 的那些像素的相同空间信息。在这里,我复制了他们的 2D 网格,并对图做了一些可视化处理,以及它的邻接矩阵 A 和度矩阵 D 。请注意,网格图的四个角有一些伪像。
GCN 使用的全网格图
他们的实验发现,在对数字进行分类时,GCN 利用 2D 网格图获得了与经典 CNN 相当的性能。受此实验的启发,我非常好奇潜在的图形结构是否会影响 GCN 的预测性能。具体来说,我们是否可以从数据集本身创建一些有意义的图表来为标注的预测提供信息?
训练集中的平均数字和数字特定的图形(第 2 行:修剪的网格;第 3 行:相关图)
因此,我创建了 20 个上面可视化的像素图:第一行绘制了来自训练集的平均位数;第二行是通过使用平均信号修整完整的 2D 网格图创建的图(数字特定的修整网格图);第三行是根据来自各个数字的像素之间的相关性构建的图(特定于数字的像素相关性图)。
为了设置我的实验,我使用了来自speck tral的 GCN 层来实现我的简单 GCN,它有 10 个图形卷积滤波器,后面是输出层。首先,我用完全相同的 2D 网格和没有任何图形的 GCN 获得了 GCN 的基线性能,以显示我的 GCN 模型确实在工作,并且与没有图形卷积机制的模型相比,实现了更好的性能:
基线模式 MNIST 分类任务的测试集精度:全网格、空图的 GCN 模式;和全连接(FC)网络
接下来,我将完整的 2D 网格切换到不同数字形状的修剪网格。从下表中可以看出,与全网格(0.932)相比,GCNs 的性能下降了一点点(平均为 0.920),这有点出乎意料,因为神经网络现在只能看到组织成网格的像素的子集,其余的是分散的。也许让我有点惊讶的是,虽然 2D 网格被修剪成单个数字的形状,但 GCNs 并没有获得识别相应数字的卓越能力。
用修剪网格和相关图对 20 个 GCN 模式的 MNIST 分类的测试集精确度
我没有修剪网格图,而是考虑从数据本身构建要素(像素)的相似度图,看看这是否能提高性能。对于任何数据集来说,这可能是一种更通用的方法,即使要素之间没有基础的图表结构。通过连接训练集中各个数字实例中具有高相关性的像素,我创建了那些特定于数字的相关图,并发现它们有助于提高 GCN 模型的预测精度(跨数字平均为 0.935)。然而,这些数字特定的相关图也没有更好地识别它们各自的数字。
结论:
GCNs 对于图形信号处理问题非常有用,并且当与特征图结合时,可以潜在地提高神经网络对表格数据的适用性。
感谢阅读!如果你有兴趣,这篇文章中描述的实验的 Jupyter 笔记本可以在这里找到:【https://github.com/wangz10/gcn-playground
主要参考文献:
- Defferrard 等人(2016):具有快速局部频谱滤波的图上的卷积神经网络
- Kipf & Welling (2017):使用图卷积网络的半监督分类
- 泽维尔·布列松:图上的卷积神经网络
- 托马斯·基普夫:图卷积网络
- 如何用图卷积网络在图上做深度学习
图的深度学习:成功、挑战和下一步
图形神经网络的下一步是什么?
这是 系列帖子 中的第一篇,我将在这里讨论图形深度学习领域的演变和未来趋势。
图的深度学习,也称为几何深度学习(GDL) [1],图表示学习(GRL),或关系归纳偏差[2],最近已经成为机器学习中最热门的话题之一。虽然图形学习的早期工作可以追溯到至少十年[3]如果不是二十年[4],但毫无疑问,过去几年的进展使这些方法从一个小众领域成为了 ML 社区 T11 的焦点,甚至成为了大众科学出版社的焦点(其中Quanta Magazine为流形 T15、T16 药物发现 T17 和 T18 蛋白质科学 T19 的研究发表了一系列关于几何深度学习的优秀文章)。
图形是强大的数学抽象,可以描述从生物学和高能物理学到社会科学和经济学等领域的复杂关系和相互作用系统。由于如今这些领域中的一些领域产生的图形结构数据量非常巨大(突出的例子是 Twitter 和脸书等社交网络),尝试应用在其他数据丰富的环境中非常成功的深度学习技术是非常诱人的。
很大程度上依赖于应用程序的图形学习问题有多种风格。一个二分法是在节点方式的和图方式的问题之间,其中前者试图预测图中各个节点的属性(例如识别社交网络中的恶意用户),而后者试图对整个图进行预测(例如预测分子的溶解度)。再者,和传统的 ML 问题一样,我们可以区分监督和非监督(或自监督)设置,以及直推式和归纳式问题。
与图像分析和计算机视觉中使用的卷积神经网络类似,在图上有效学习的关键是设计具有共享权重的局部操作,在每个节点和它的邻居之间传递消息。与处理网格结构数据的经典深度神经网络相比,一个主要区别在于,在图形上,这种操作是置换不变的,即独立于相邻节点的顺序,因为通常没有对它们进行排序的规范方式。
尽管他们做出了承诺,也有一系列图形表示学习的成功故事(其中我可以自私地列举出 Twitter 收购了我和我的学生一起创立的基于图形的假新闻检测初创公司 Fabula AI 的),但迄今为止,我们还没有看到卷积网络在计算机视觉方面取得的巨大成功。在下文中,我将尝试概述我对可能原因的看法,以及该领域在未来几年将如何发展。
像 ImageNet 这样的标准化基准无疑是计算机视觉中深度学习的关键成功因素之一,有些人甚至认为对于深度学习革命来说,数据比算法更重要。在图形学习社区中,我们还没有和 ImageNet 在规模和复杂性上类似的东西。2019 年推出的 Open Graph Benchmark 可能是朝着这个目标的第一次尝试,试图在有趣的真实世界图结构数据集上引入具有挑战性的图学习任务。障碍之一是,从用户活动中产生多样化和丰富图表的科技公司不愿意分享这些数据,因为担心隐私法,如 GDPR。一个值得注意的例外是 Twitter,作为 RecSys 挑战赛的一部分,它在某些隐私保护限制下向研究社区提供了 1.6 亿条推文的数据集以及相应的用户参与度图。希望以后有很多公司效仿。
在公共领域可用的软件库在深度学习的“民主化”和使其成为一种流行工具方面发挥了至关重要的作用。如果说直到最近,图形学习实现主要是一堆写得很差且很少测试的代码,那么现在已经有了像 PyTorch Geometric 或 Deep Graph Library (DGL) 这样的库,它们是在行业赞助的帮助下专业编写和维护的。在 arxiv 上出现一个新的图形深度学习架构几周后,看到它的实现并不罕见。
可扩展性是限制工业应用的关键因素之一,这些工业应用通常需要处理非常大的图(想想拥有数亿个节点和数十亿条边的 Twitter 社交网络)和低延迟约束。直到最近,学术研究团体几乎忽略了这一方面,文献中描述的许多模型完全不适用于大规模设置。此外,图形硬件(GPU)与经典深度学习架构的幸福婚姻是推动它们共同成功的主要力量之一,但它不一定最适合图形结构数据。从长远来看,我们可能需要专门的图形硬件[7]。
动态图是文献中很少涉及的另一个方面。虽然图是对复杂系统建模的一种常见方式,但这种抽象往往过于简单,因为现实世界的系统是动态的,会随着时间的推移而演变。有时是时间行为提供了关于系统的关键见解。尽管最近取得了一些进展,设计能够有效处理连续时间图的图神经网络模型仍然是一个开放的研究问题。
已知更高级的结构如基序、graphlets 或单纯复合物在复杂网络中很重要,例如在生物学应用中描述蛋白质-蛋白质相互作用。然而,大多数图形神经网络仅限于节点和边。将这样的结构结合到消息传递机制中可以给基于图的模型带来更大的表达能力。
对图形神经网络表达能力的理论理解相当有限。常见的情况是,在某些设置中使用图形神经网络可以显著提高性能,而在其他设置中几乎没有差异。目前还不完全清楚图形神经网络何时以及为什么工作良好或失败。这个问题很困难,因为人们既要考虑底层图的结构,又要考虑图上的数据。对于只涉及图连通性的图分类问题,最近的工作表明,图神经网络等价于 Weisfeiler-Lehman 图同构测试【8】(一种启发式方法,用于解决图论中的一个经典问题,即确定两个图在其节点排列上是否相同)。这种形式主义揭示了为什么,例如,图神经网络在不能通过这种简单测试来区分的非同构图的实例上失败。超越 Weisfeiler-Lehman 等级测试,同时保持使图形神经网络如此有吸引力的低线性复杂度是一个开放的研究问题。
图神经网络在存在噪声数据或遭受敌对攻击时的鲁棒性和有保证的性能[9]是另一个有趣且基本上未开发的研究领域。
应用程序也许是这个领域最令人满意的部分。从事图形学习多年后,我已经和粒子物理学家[10]、临床医生[11]、生物学家和化学家[12]交了朋友——如果我们没有在他们各自的领域进行应用研究,我是不可能认识这些人的。如果我要打赌图形深度学习在未来几年可能产生最大影响的一个领域,我会指出结构生物学和化学。在这些领域中,基于图的模型既可以用作分子的低级模型[5],也可以用作它们之间相互作用的高级模型[13,11]。将这些结合起来可能是达到对制药行业有用的水平的关键——我们看到了这方面的初步迹象,今年早些时候,图形神经网络被用于发现一种新的抗生素[14]或预测蛋白质之间的相互作用[12]。如果图形深度学习实现了它的承诺,那么传统上非常漫长且极其昂贵的发现、开发和测试新药的过程可能永远不会变了。
[1] M. M. Bronstein 等人几何深度学习:超越欧几里德数据 (2017),IEEE 信号处理杂志 34(4):18–42。
[2] P .巴塔格利亚等人,关系归纳偏差、深度学习和图网络 (2018),arXiv:1806.01261。
[3] F. Scarselli 等.图形神经网络模型(2008),IEEE 神经网络汇刊 20(1):61–80 .
[4] A .屈希勒尔,c .戈勒(1996 年)。使用结构驱动的递归神经网络在符号域中进行归纳学习。Künstliche Intelligenz。
[5] J. Gilmer 等人,量子化学的神经信息传递 (2017),ICML。
[6] A. Wissner-Gross,数据集超过算法 (2016)。
[7] C.-Y .桂等…关于图形处理加速器的调查:挑战与机遇 (2019),arXiv:1902.10130。
[8] K. Xu 等图神经网络到底有多强大? (2019),ICLR。
[9] D. Zügner 等人,图数据对神经网络的对抗性攻击 (2018),Proc .KDD。
[10] N. Choma 等人ice cube 信号分类的图形神经网络 (2018),Proc .ICMLA。
[11] K. Veselkov 等人 HyperFoods:食品中抗癌分子的机器智能图谱 (2019),科学报告 9。
[12] P .盖恩萨等人利用几何深度学习从蛋白质分子表面破译相互作用指纹 (2020),自然方法 17:184–192。
[13] M. Zitnik 等人用图卷积网络建模多药副作用 (2018),生物信息学 34(13):457–466。
[14] J. Stokes 等.抗生素发现的深度学习方法(2020),细胞,180(4)。
A 中文翻译 本帖由 刘止庸 提供。另见 丹麦语版 。对图形深度学习感兴趣?参见我的 博客 关于走向数据科学, 订阅我的 帖子,获取 中等会员 ,或者关注我的 推特 。
点云深度学习:在 Google Colab 中实现 PointNet
点网是一种简单有效的点云识别神经网络。在本教程中,我们将使用 PyTorch 实现它。
1.介绍
3D 数据对于自动驾驶汽车、自主机器人、虚拟和增强现实至关重要。与用像素阵列表示的 2D 图像不同,它可以表示为多边形网格、体积像素网格、点云等。
图片来自:用 PyTorch 中的一张 2D 图片创建 3D 模型
在今天的计算机视觉和机器学习中, 90%的进步只处理二维图像。
1.1.点云
点云是一种广泛使用的 3D 数据形式,可以由深度传感器产生,如激光雷达和 RGB-D 相机。
它是 3D 物体最简单的表示**:仅点于 3D 空间**,无连通性。点云也可以包含点的法线。
几乎所有的 3d 扫描设备都会产生点云。
可以捕捉点云的设备(Iphone 11、华硕 Zenfone AR、索尼 Xperia XZ1)。图片来自:本课程
此外,最近苹果推出了带有激光雷达扫描仪的 Ipad Pro,可以测量 5 米以外的周围物体的距离。
1.2.点云深度学习
所以,让我们想想如何处理点云。CNN 对图像非常有用。我们能把它们用于 3D 吗?
想法:将 2D 卷积推广到规则三维网格
图片来自: arxiv 论文
这个其实管用。
主要的问题是**低效表示:**大小为 100 的立方体素网格将有 1,000,000 个体素。
1.3.点网
但是如果我们尝试处理点云呢?
有三个主要的约束:
- 点云是无序的。算法必须对输入集的排列不变。
- 如果我们旋转椅子,它还是椅子,对吗?网络必须是不变的 刚性变换 。
- 网络应该捕捉点之间的相互作用。
PointNet 的作者介绍了一种考虑了所有这些特性的神经网络。它设法解决分类,部件和语义分割任务。来实施吧!
图片来自: arxiv 论文
2.履行
在本节中,我们将使用 PyTorch 从 Google Colab 中的原始论文重新实现分类模型**。**
你可以在https://github . com/nikitakaraevv/pointnet/blob/master/nbs/pointnet class . ipynb找到完整笔记本
2.1.资料组
在原始论文中,作者在 ModelNet40 形状分类基准上评估了 PointNet。它包含来自 40 个对象类别的 12,311 个模型,分为 9,843 个训练模型和 2,468 个测试模型。
为了简单起见,让我们使用同一个数据集的较小版本: **ModelNet10。**它由来自 **10 个类别的对象、**3991 个用于训练的模型和 908 个用于测试的模型组成。
在物体识别中,3D 形状是一个至关重要但严重未被充分利用的线索,主要是因为缺乏一个好的通用…
3dvision.princeton.edu](http://3dvision.princeton.edu/projects/2014/3DShapeNets/)
想直接开始训练别忘了打开 GPU
让我们导入必要的库:
我们可以将数据集直接下载到 Google Colab 运行时:
这个数据集由组成。关闭包含由顶点和三角面表示的网格的文件。顶点只是三维空间中的点,每个三角形由 3 个顶点索引组成。
我们将需要一个函数来读取**。关闭**文件:
完整网格看起来是这样的:
啮合其中一个**。关闭**文件。使用创建 plotly
如你所见,这是一张🛏床
但是如果我们去掉人脸,只保留 3D 点,它看起来就不再像一张床了!
网格顶点
实际上,曲面的平坦部分不需要任何点来构建网格。这就是为什么点主要位于床的角度和圆形部分。
2.2.点取样
因此,由于点不是均匀分布在物体表面的,我们的点网很难对它们进行分类。(尤其是知道这个点云看起来连床都不像)。
这个问题的解决方案可能非常简单:让我们在物体的表面上均匀地采样点。
我们不应该忘记脸可以有不同的区域。
因此,我们可以将选择特定面的概率与其面积成比例分配。这是可以做到的:
我们的网络架构中将会有密集层。这就是为什么我们希望点云中有固定数量的点。让我们从构建的分布中抽取人脸样本。之后,我们在每个选择的面上采样一个点:
一些面可以有多个采样点,而另一些面根本没有采样点。
由网格曲面上的采样点创建的点云
这个点云看起来更像一张床!🛏
2.3.增加
让我们想想其他可能的问题。我们知道物体可以有不同的大小,可以放在我们坐标系的不同部分。
因此,让我们将物体平移到原点,从其所有点中减去平均值,并将的点归一化到一个单位球。为了在训练期间增加数据,我们围绕 Z 轴随机旋转对象,并添加高斯噪声,如本文所述:
这是标准化的同一张床,带有旋转和噪音:
添加噪声的旋转点云
2.4.模型
好了,我们已经完成了数据集和预处理。让我们考虑一下模型架构。该架构及其背后的关键思想已经得到了很好的解释,例如,在本文中:
PointNet 是 3D 感知领域的开创性论文,将深度学习应用于点云,用于对象分类和…
medium.com](https://medium.com/@luis_gonzales/an-in-depth-look-at-pointnet-111d7efdaa1a)
我们记得结果应该是对输入点的不变排列和几何变换,比如刚性变换。
图片来自: arxiv 论文
让我们在 PyTorch 中开始实现它:
首先,我们的张量会有大小(batch_size, num_of_points, 3)
。在这种情况下,具有共享权重的 MLP 只是具有大小为 1 的内核的 1-dim 卷积 。
为了确保对变换的不变性,我们将 T-Net 预测的 3x3 变换矩阵应用于输入点的坐标。有趣的是,我们不能通过三维矩阵对 3D 空间中的翻译进行编码。无论如何,我们已经在预处理中将点云平移到原点。
这里重要的一点是输出矩阵的初始化。我们希望它默认为 identity,开始训练时没有任何转换。因此,我们只需在输出中添加一个单位矩阵:
在应用 MLP 后,我们将使用相同但 64 维的 T 网来对齐提取的点特征。
为了提供**置换不变性,**我们将对称函数(max pooling)应用于提取和转换的特征,因此结果不再依赖于输入点的顺序。
让我们把它们结合在一起:
然后,让我们用输出端的最后一个 MLP 和*LogSoftmax将它们打包在一个类中:*
最后我们将定义损失函数**。正如我们使用 LogSoftmax 获得稳定性 *,*一样,我们应该使用 NLLLoss 而不是 CrossEntropyLoss。此外,我们将添加两个正则化项,以使变换矩阵接近正交( AAᵀ = I ) :
2.5.培养
****最后一步!我们可以用一个经典的 PyTorch 训练循环。这肯定不是最有趣的部分,所以让我们省略它。
同样,带有训练循环的完整 Google Colab 笔记本可以在此链接 后找到 。
我们就来看看在 GPU 上训练 15 个纪元后的结果吧。培训本身大约需要 3 个小时,但是根据 Colab 分配给当前会话的 GPU 类型,培训时间可能会有所不同。
通过一个简单的训练循环,在 13 个时期后可以达到 85% 的总体验证准确度,相比之下,在原始作品中对于 40 个类,该准确度为 89%。这里的要点是实现完整的模型,而不是真的获得最好的分数。因此,我们将把调整训练循环和其他实验作为练习。****
有趣的是,我们的模型有时会混淆梳妆台和床头柜,厕所和椅子,书桌和桌子,这很容易理解(厕所除外):
3.最后的话
你做到了!🎉🎊👏
你实现了 PointNet ,这是一个深度学习架构,可以用于各种 3D 识别任务。尽管我们在这里实现了分类模型,但是分割**、正常评估或其他任务只需要对模型和数据集类进行微小的修改。**
完整的笔记本可在https://github . com/nikitakaraevv/point net/blob/master/nbs/point net class . ipynb获得。
感谢您的阅读!我希望这篇教程对你有用。如果是这样,请在评论中告诉我。顺便说一句,这是我的第一篇媒体文章,所以我将非常感谢您的评论或私信反馈!
参考资料:
[1] Charles R. Qi,,Kaichun Mo,Leonidas J. Guibas, PointNet:用于三维分类和分割的点集深度学习 (2017),CVPR 2017
[2]亚当·康纳-西蒙斯,点云深度学习 (2019),麻省理工学院计算机科学&人工智能实验室
[2] Loic Landrieu,3D 点云的语义分割 (2019),巴黎东方大学—机器学习与优化工作组
[4] Charles R. Qi 等,用于 3D 数据上对象分类的体积和多视图 CNN(2016),
深度学习优化器——难?不是。[1]
让优化器更容易理解
你说优化?—哇,伙计,那是一些超级复杂的数学;对吗?对吗?不对!大多数人回避优化算法,因为它们大多是通过在 PyTorch 或 TensorFlow 中编写一行代码来实现的。然而,对于神经网络训练来说,优化算法通常是训练模型中最有影响力的因素。他们对如何更新权重、模型学习什么和丢弃什么有完全的发言权。
深度学习是当今最先进的技术之一。这真的不难理解为什么这么多人对人工智能或神经网络感兴趣。互联网上大量的课程材料使得新手很难选择一种正确的教学方法。因此,大量对人工智能感兴趣的人很少知道基础知识。
深入主题,深度学习涉及许多方式和上下文的优化。深度学习中最难的优化问题之一是神经网络训练。与神经网络训练相关联的优化围绕寻找减小损失函数 J(θ)的参数 θ 。
在数学优化和决策理论中,损失函数或成本函数是一个函数**,它将一个事件或一个或多个变量的值映射到一个实数上,直观地表示与该事件相关的一些“成本”——https://en.wikipedia.org/wiki/Loss_function**
人们最常犯的一个错误是他们不能区分优化和反向传播。这确实令人困惑,所以让我给你解释一下。在反向传播中,我们计算梯度,并且不基于这些梯度更新权重。我们只是计算梯度。在优化过程中,我们根据计算的梯度和我们选择的优化算法来更新权重。因此,优化算法因网络而异,但反向传播保持不变。
神经网络中的优化不同于在各种机器学习模型中观察到的优化。在最大似然模型中,我们已经能够仔细地设计目标函数,使得损失函数是凸的,从而优化问题变得相当容易。然而,在训练神经网络时,由于以下普遍面临的问题,事情变得复杂和失控:
- 神经网络具有高维凸优化问题。结果,我们经常遇到零梯度的鞍点。鞍点的问题是,当从一个横截面观察它们时,我们得到一个局部最小值,而从另一个横截面,我们得到一个全局最大值。
鞍点 v/s Minima—https://commons . wikimedia . org/wiki/File:Minima _ and _ Saddle _ point . png
2.最优化的问题并不以鞍点结束。目标函数导数中的悬崖是与训练相关联的另一个优化问题。由于几个重量相乘,我们有陡峭的区域,称为悬崖。当算法在这样的悬崖之前时,它可能采取太大的步骤,并且可能跳下悬崖,从而扰乱算法的正常流程。
3.如果局部表面不指向全局最小值,则基于局部梯度计算的优化失败。当成本函数导数包含某个“悬崖”并且不能穿越它时,可能会发生这种情况。它可能在更高维度的空间中穿行,但是在训练期间花费的过多时间会使网络太慢。
4.在神经网络中也观察到“消失”和“爆炸”梯度的问题。当神经网络涉及相同矩阵的重复乘法(如在 RNNs 中)导致具有高指数的矩阵时,出现消失和爆炸梯度。当执行矩阵的特征分解以获得特征值时,任何不接近 1 的特征值将爆炸(如果大于 1)或消失(如果小于 1 ),产生消失和爆炸梯度的问题。
因此,我们可以看到,如果我们试图优化和训练一个神经网络,我们可能会面临许多问题。幸运的是,我们已经准备好了一些优化算法,这些算法是研究人员经过数月甚至数年的工作后留给我们的。我将讨论非常流行的 SGD 优化算法。(随机梯度下降)
签名于
随机梯度下降可能是深度学习中最常用的优化算法之一。要理解随机梯度下降,就必须理解什么是梯度下降。梯度下降意味着沿着梯度的斜坡移动。你是如何“移动”的?
梯度下降算法首先决定斜率指向哪个方向。然后它向降低斜率迈出了一步。这背后的直觉是,我们最终寻求最小化成本函数,我们可以在斜率为零的地方得到最小值。但是,嘿——一个最大值也有零斜率!这就是为什么我们使用海森矩阵。海森矩阵存储了成本函数的二阶导数,帮助我们区分最大值和最小值。
现在,主要有三种类型的梯度下降—
- 批量梯度下降:在这种类型的梯度下降中,在评估所有训练样本之后更新权重。
- 在线训练:在这种类型的梯度下降中,一旦一个训练样本被评估,权重就被更新。训练样本是随机选择的。
- 小批量梯度下降(SGD):小批量梯度下降结合了两个世界的优点。在这种情况下,我们从训练样本中随机抽取一小批样本,并在评估后更新权重。然后我们对另一个小批量样品进行取样,这个过程一次又一次地重复。
现在,我们知道权重是根据我们定义的学习率更新的。然而,在编写 SGD 优化算法时,我们必须记住的一个最重要的因素(你通常不会)是,学习速率必须随着时间的推移而降低。
需要降低学习率,因为 SGD 使用小批量。从训练数据中采样小批量,并且这种数据采样导致噪声的存在。即使我们到达最低限度,噪音也不会消失。因此,我们需要密切监控学习率,以使模型收敛。
为什么用 SGD 而不用梯度下降(批量)?
神经网络需要大量数据才能正常工作。与机器学习模型相比,即使在简单的分类器中也需要更多的训练数据。对大量的训练样本使用梯度下降在计算上将是非常昂贵的,并且将成倍地增加学习时间。SGD 和使用基于小批量的模型的主要特征之一是每次更新的学习时间不会随着训练数据的增加而增加。这是非常有用的,因为我们最终可以突破梯度下降对我们可以使用的训练数据大小的限制。
我希望这篇文章有助于打破优化算法的概念及其在深度学习领域的必要性。如果有任何问题,请在评论区告诉我:)
**参考:**深度学习作者:伊恩·古德菲勒、约舒阿·本吉奥、亚伦·库维尔(2017)
自然语言处理(NLP)的深度学习管道
NLP、无监督机器学习和深度学习概念在无标签文本数据上的实际实现。
照片由 Unsplash 上的 h heyerlein 拍摄
在本文中,我将探索自然语言处理(NLP)的基础知识,并演示如何实现一个管道,该管道将传统的无监督学习算法与深度学习算法相结合,以训练无标签的大型文本数据。因此,主要目标是演示如何建立管道,以促进原始文本数据的收集和创建,预处理和分类未标记的文本数据,最终在 Keras 中训练和评估深度学习模型。
阅读完本教程后,您将能够执行以下操作:
- 如何通过 Twitter API 和 Tweepy Python 包从 Twitter 收集数据
- 如何用 pandas 高效地读取和清理大型文本数据集
- 如何使用基本的自然语言处理技术预处理文本数据并生成特征
- 如何对未标记的文本数据进行分类
- 如何在 Keras 中训练、编译、拟合和评估深度学习模型
在我的 GitHub 中找到我的带有 Python 代码的 Jupyter 笔记本。
卷起袖子,我们有很多工作要做,让我们开始吧……
数据
在做这个项目的时候,美国 2020 年大选即将到来,对与即将到来的选举相关的推文进行情感分析,以了解在选举日之前大约两周 Twitter 世界中正在讨论的观点和话题是有意义的。Twitter 是一个未经过滤的意见的伟大来源,而不是我们从主要媒体渠道看到的典型的过滤新闻。因此,我们将通过使用 Twitter API 和 python 包 Tweepy 从 Twitter 收集 tweets 来构建我们自己的数据集。
步骤 1:数据收集
先决条件
在开始使用来自 Twitter 的流数据之前,您必须具备以下条件:
- Twitter 帐户和 Twitter API 消费者密钥(访问令牌密钥、访问令牌秘密密钥、消费者密钥和消费者秘密密钥)
- 安装在您的 Jupyter 笔记本中的 Tweepy 软件包
设置 Twitter 帐户和检索您的 Twitter API 消费者密钥超出了本文的范围。如果你在这些方面需要帮助,看看这个帖子。
Tweepy 可以通过 Jupyter 笔记本中的 pip install 进行安装,下面一行代码就可以完成。
# Install Tweepy
!pip install tweepy
安装完成后,继续将软件包导入您的笔记本电脑。
1.1 设置数据流管道
在这一节中,我将向您展示如何使用 Twitter API、Tweepy 和一个自定义函数来设置您的数据流管道。我们可以通过三个步骤实现这一目标:
- 设置您的 Twitter API 消费者密钥
- 设置 Twitter API 授权处理程序
- 编写一个自定义函数来监听和流式传输实时推文
# Twitter API consumer keys
access_token = " insert your key here "
access_token_secret = " insert your key here "
consumer_key = " insert your key here "
consumer_secret = " insert your key here "# Twitter API authorization
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)# Custom function that streams data from Twitter (20,000 tweets at most per instance)
class MyStreamListener(tweepy.StreamListener):
"""Function to listen and stream Twitter data"""
def __init__(self, api=None):
super(MyStreamListener, self).__init__()
self.num_tweets = 0
self.file = open("tweets.txt", "w")def on_status(self, status):
tweet = status._json
self.file.write( json.dumps(tweet) + '\n' )
self.num_tweets += 1
if self.num_tweets < 20000:
return True
else:
return False
self.file.close()def on_error(self, status):
print(status)
1.2 开始直播推文
既然环境已经设置好了,您就可以开始从 Twitter 流式传输实时推文了。在此之前,确定一些你想用来收集你感兴趣的相关推文的关键词。由于我将发布与美国大选相关的推文,我选择了一些相关的关键词,如“美国大选”、“特朗普”、“拜登”等。
我们的目标是收集至少 400,000 条推文,使其成为足够大的文本数据,一次性收集所有这些数据的计算量很大。因此,我将建立一个管道,以高效地传输数据。请注意上面的自定义函数,它将在每个块中最多监听和传输 20,000 条 tweets。因此,为了收集超过 40 万条推文,我们需要运行至少 20 个区块。
下面是代码如何寻找用于监听和流式传输实时推文到熊猫数据帧的块:
# Listen and stream live tweets
listener = MyStreamListener()
stream = tweepy.Stream(auth, listener)
stream.filter(track = ['US Election', 'election', 'trump', 'Mike Pence', 'biden', 'Kamala Harris', 'Donald Trump', 'Joe Biden'])# Read the tweets into a list
tweets_data_path = 'tweets.txt'
tweets_data=[]
tweets_file_1 = open(tweets_data_path, 'r')# Read in tweets and store in list: tweets_data
for line in tweets_file_1:
tweet = json.loads(line)
tweets_data.append(tweet)# Close connection to file
tweets_file_1.close()# Print the keys of the first tweet dict
print(tweets_data[0].keys())# Read the data into a pandas DataFrame
names = tweets_data[0].keys()
df1 = pd.DataFrame(tweets_data, columns= names)
如上所述,为了收集 400,000 条推文,您必须运行上述代码至少 20 次,并将收集的推文保存在单独的 pandas dataframe 中,该 dataframe 将在以后连接起来,以将所有推文整合到单个数据集。
1.3 将所有数据块组合成一个数据集
# Concatenate dataframes into a single pandas dataframe
list_of_dataChunks = [df1, df2, df3, df4, df5, df6, df7, df8, df9, df10, df11, df12, df13, df14, df15, df16, df17, df18, df19, df20]
df = pd.concat(list_of_dataChunks, ignore_index=True)# Export the dataset into a CSV file
df.to_csv('tweets.csv', index=False)
现在,您已经将组合数据集导出到 CSV 文件中,您可以在接下来的数据清理和可视化步骤中使用它。
我已经捐赠了我创建的数据集,并在 Kaggle 中公开。
第二步:数据争论
在本节中,我们将清理刚刚收集的数据。在可视化数据之前,必须清理数据集并将其转换为可以高效可视化的格式。给定具有 440,000 行的数据集,必须找到一种有效的方法来读取和清理它。为此,pandas chunksize 属性可用于将 CSV 文件中的数据以块的形式读入 pandas 数据帧。此外,我们可以指定感兴趣的列的名称,而不是读取包含所有列的数据集。使用 chunksize 和更少量的感兴趣的列,大型数据集可以非常高效和快速地读入数据帧,而不需要其他替代方案,例如在集群上使用 PySpark 的分布式计算。
为了将数据集转换成可视化所需的形状,将应用以下基本 NLP 技术:
- 提取仅有的英语推特
- 删除重复项(如果有)
- 删除丢失的值(如果有)
- 标记化(将推文分成单个单词)
- 将单词转换成小写
- 删除标点符号
- 删除停用词
- 删除网址,“twitter”和其他缩写词
我将遵循以下方法来实现上述步骤:
- 编写一个自定义函数来标记推文
- 编写另一个自定义函数,对数据应用上述所有清理步骤。
- 最后,读取数据块,并在读取数据块时,通过自定义函数将这些争论步骤应用于每个数据块。
让我们看看所有这些都在起作用…
# Function to tokenize the tweets
def custom_tokenize(text):
"""Function that tokenizes text"""
from nltk.tokenize import word_tokenize
if not text:
print('The text to be tokenized is a None type. Defaulting to blank string.')
text = ''
return word_tokenize(text)# Function that applies the cleaning steps
def clean_up(data):
"""Function that cleans up the data into a shape that can be further used for modeling"""
english = data[data['lang']=='en'] # extract only tweets in english language
english.drop_duplicates() # drop duplicate tweets
english['text'].dropna(inplace=True) # drop any rows with missing tweets
tokenized = english['text'].apply(custom_tokenize) # Tokenize tweets
lower_tokens = tokenized.apply(lambda x: [t.lower() for t in x]) # Convert tokens into lower case
alpha_only = lower_tokens.apply(lambda x: [t for t in x if t.isalpha()]) # Remove punctuations
no_stops = alpha_only.apply(lambda x: [t for t in x if t not in stopwords.words('english')]) # remove stop words
no_stops.apply(lambda x: [x.remove(t) for t in x if t=='rt']) # remove acronym "rt"
no_stops.apply(lambda x: [x.remove(t) for t in x if t=='https']) # remove acronym "https"
no_stops.apply(lambda x: [x.remove(t) for t in x if t=='twitter']) # remove the word "twitter"
no_stops.apply(lambda x: [x.remove(t) for t in x if t=='retweet']) # remove the word "retweet"
return no_stops# Read and clean the data
warnings.filterwarnings("ignore")
use_cols = ['text', 'lang'] # specify the columns
path = 'tweets.csv' # path to the raw dataset
data_iterator = pd.read_csv(path, usecols=use_cols, chunksize=50000)
chunk_list = []
for data_chunk in data_iterator:
filtered_chunk = clean_up(data_chunk)
chunk_list.append(filtered_chunk)
tidy_data = pd.concat(chunk_list)
在这种情况下,块大小是 50,000,这就是熊猫如何读取每个块中的 50,000 条推文,并在读取下一批推文之前对它们应用清理步骤,等等。
在此过程之后,数据集将变得干净,并为可视化做好准备。为了避免每次打开笔记本时执行数据争论步骤,您可以简单地将整齐的数据导出到一个外部文件中,以便将来使用。对于大型数据集,将其导出到 JSON 文件比导出到 CSV 文件更有效。
# Explort the tidy data to json file for ease of use in the next steps
tidy_data.to_json('tidy_tweets.json', orient='table')
这些整洁的数据看起来是这样的:
步骤 3:探索性数据分析(可视化)
既然数据是干净的,让我们可视化并理解我们的数据的本质。我们可以关注的几个明显的事情如下:
- 每条推文的字数
- 一条推文中单词的平均长度
- Unigram
- 二元模型
- 三元模型
- Wordcloud
似乎每条推文的字数在 1 到 19 个词之间,平均在 10 到 12 个词之间。
推特中一个单词的平均字符数似乎在 3 到 14 个字符之间,平均出现在 5 到 7 个字符之间。人们可能会在 Twitter 设定的 280 个字符的限制内,选择简短的词语来以最佳方式表达自己的观点。
Unigram
正如所料,“特朗普”和“拜登”这两个词主导了 10 月 15 日至 10 月 16 日期间发布的 2020 年美国大选相关推文。
二元模型(最常出现的一对连续单词)
三元模型(三个单词的最常见序列)
Wordcloud
通过可视化数据,注意单词没有被词条化。词汇化是将单词转换成基本形式或词典形式的过程。这是 NLP 和机器学习中常用的技术。因此,在下一步中,我们将使用以下代码对令牌进行符号化。
# Convert tokens into format required for lemmatization
from nltk.corpus import wordnet
def get_wordnet_pos(word):
"""Map POS tag to first character lemmatize() accepts"""
tag = nltk.pos_tag([word])[0][1][0].upper()
tag_dict = {"J": wordnet.ADJ,
"N": wordnet.NOUN,
"V": wordnet.VERB,
"R": wordnet.ADV}return tag_dict.get(tag, wordnet.NOUN)# Lemmatize tokens
lemmatizer = WordNetLemmatizer()
tidy_tweets['lemmatized'] = tidy_tweets['text'].apply(lambda x: [lemmatizer.lemmatize(word, get_wordnet_pos(word)) for word in x])# Convert the lemmatized words back to the text format
tidy_tweets['tokens_back_to_text'] = [' '.join(map(str, l)) for l in tidy_tweets['lemmatized']]
现在,让我们将符号化的标记保存到另一个 JSON 文件中,以便在管道的下一步中使用。
# Explort the lemmatized data to json file for ease of use in the next steps
tidy_tweets.to_json('lemmatized.json', orient='table')
方法
在进行预处理和建模的步骤之前,让我们回顾并明确我们在管道中的下一个步骤的方法。在我们可以预测一条推文属于哪个类别之前,我们必须首先用类别来标记原始推文。请记住,我们从 Twitter 上以原始推文的形式传输我们的数据,因此数据并没有标记出来。因此,实施以下方法是合适的:
- 用 k-means 聚类算法标记数据集
- 训练深度学习模型来预测推文的类别
- 评估模型并确定潜在的改进
步骤 4:标记未标记的文本数据并预处理
在这一部分,我们的目标是给推文贴上两个标签,分别对应积极或消极的情绪。然后进一步预处理,将标注后的文本数据转换成可以进一步用于训练深度学习模型的格式。
有许多不同的方法来对未标记的文本数据进行分类,这些方法包括但不限于使用 SVM、分层聚类、余弦相似度甚至亚马逊 Mechanical Turk。在这个例子中,我将向您展示另一种更简单的,也许不是最准确的,对文本数据进行分类的快速而又麻烦的方法。为此,我将首先对 VADER 进行情绪分析,以确定推文是积极的、消极的还是中立的。接下来,我将使用一个简单的 k-means 聚类算法,根据从推文的积极、消极和中立程度得出的计算复合值对推文进行聚类。
4.1 创造情绪
让我们先来看看数据集
列“tokens_back_to_text”是转换回文本格式的词汇化标记,我将使用 tidy 数据集中的此列来创建 VADER 包中的 SenitmentIntensityAnalyzer 情感。
# Extract lemmatized text into a list
tweets = list(df['tokens_back_to_text'])# Create sentiments with SentimentIntensityAnalyzer
**from** **vaderSentiment.vaderSentiment** **import** SentimentIntensityAnalyzer
sid = SentimentIntensityAnalyzer()
sentiment = [sid.polarity_scores(tweet) **for** tweet **in** tweets]
下面是情绪的前 5 行
4.2 用 k-means 聚类对未标记数据进行标记
现在,我将使用上述数据帧中的“复合”列,并将其输入 k-means 聚类算法,以 0 或 1 分别代表“消极”或“积极”情绪。也就是说,我会将相应复合值大于或等于 0.05 的推文标记为积极情绪,而小于 0.05 的值将被标记为消极情绪。这里没有硬性规定,只是我如何设置我的实验。
下面是如何用 python 中的 scikit-learn 中的 k-means 聚类算法实现文本标注工作。记住,给标签和原始数据框都指定相同的索引,在那里你有你的推文/文本。
*# Tag the tweets with labels using k-means clustering algorithm*
**from** **sklearn.cluster** **import** KMeans
kmeans = KMeans(n_clusters=2, random_state=0).fit(compound)
labels = pd.DataFrame(kmeans.labels_, columns=['label'], index=df.index)
标签计数
查看 0 和 1 的标签计数,注意数据集是不平衡的,其中超过两倍的推文被标记为 1。这将影响模型的性能,因此我们必须在训练模型之前平衡数据集。
此外,我们还可以借助一种称为“潜在狄利克雷分配”的强大 NLP 算法,从每个类别中识别推文的主题,这种算法可以提供负面和正面推文中主题的直觉。稍后,我将在另一篇文章中展示这一点。现在,为了这个练习,让我们使用类别 0 和 1。所以现在,我们已经成功地将我们的问题转化为监督学习问题,接下来我们将继续使用我们现在标记的文本数据来训练深度学习模型。
第五步:建模
我们有一个相当大的数据集,有超过 400,000 条推文,超过 60,000 个独特的单词。在如此大的数据集上训练具有多个隐藏层的 rnn 在计算上是繁重的,如果你试图在 CPU 上训练它们,可能需要几天(如果不是几周的话)。训练深度学习模型的一种常见方法是使用 GPU 优化的机器来获得更高的训练性能。在本练习中,我们将使用预装了 TensorFlow 后端和 CUDA 的 Amazon SageMaker p2.xlarge 实例。我们将使用 Keras 接口到张量流。
让我们开始吧,我们将应用以下步骤。
培训步骤
- 对数据集进行标记化、填充和排序
- 用 SMOTE 平衡数据集
- 将数据集分成训练集和测试集
- 训练简单神经网络和 LSTM 模型
- 评估模型
数据集必须转换成数字格式,因为机器学习算法不理解自然语言。在对数据进行矢量化之前,我们先来看看数据的文本格式。
tweets.head()
5.1 对数据集进行标记化、填充和排序
*# prepare tokenizer* tokenizer = Tokenizer() tokenizer.fit_on_texts(tweets)*# integer encode the documents*
sequences = tokenizer.texts_to_sequences(tweets)*# pad documents to a max length of 14 words* maxlen = 14 X = pad_sequences(sequences, maxlen=maxlen)
5.2 用 SMOTE 平衡不平衡的数据
**from** **imblearn.over_sampling** **import** SMOTE
**from** **imblearn.under_sampling** **import** RandomUnderSampler
**from** **imblearn.pipeline** **import** Pipeline*# define pipeline*
over = SMOTE(sampling_strategy=0.5)
under = RandomUnderSampler(sampling_strategy=0.8)
steps = [('o', over), ('u', under)]
pipeline = Pipeline(steps=steps)*# transform the dataset*
X, y = pipeline.fit_resample(X, labels['label'])*# One-hot encoding of labels*
**from** **keras.utils.np_utils** **import** to_categorical
y = to_categorical(y)
从上面 0 和 1 之间的数据分布可以看出,与以前相比,现在的数据看起来相当平衡。
5.3 将数据分为训练集和测试集
既然数据已经平衡,我们就可以将数据分成训练集和测试集了。我将收集 30%的数据集进行测试。
# Split the dataset into train and test sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=43)
5.4 培训注册护士
在这一部分,我将向您展示如何实现 RNN 深度学习架构的几个变体,3 层 SimpleRNN 和 3 层 LSTM 架构。默认情况下,SimpleRNN 和 LSTM 图层的激活函数都设置为“tanh ”,所以让我们保留其默认设置。我将使用所有 65,125 个唯一单词作为词汇表的大小,将每个输入的最大长度限制为 14 个单词,因为这与 tweet 中的最大单词长度一致,并将嵌入矩阵的输出维度设置为 32。
SimpleRNN
脱落层将用于强制正则化项以控制过度拟合。由于我的数据集被标记为二进制类,我将使用二进制交叉熵作为损失函数。就优化器而言,Adam optimizer 是一个不错的选择,我将准确性作为衡量标准。我将在训练集上运行 10 个时期,其中 70%的训练集将用于训练模型,而剩余的 30%将用于验证。这不能和我们放在一边的测试设备混淆。
*# SimpleRNN*
model = Sequential()
model.add(Embedding(input_dim = vocab_size, output_dim = output_dim, input_length = maxlen, embeddings_constraint=maxnorm(3)))
model.add(SimpleRNN(output_dim=output_dim, return_sequences=True, kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(SimpleRNN(output_dim=output_dim, return_sequences=True, kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(SimpleRNN(output_dim=output_dim))
model.add(Dense(2,activation='softmax'))
型号汇总如下:
SimpleRNN 模型结果如下— 10 个历元:
LSTM
3 层 LSTM 模型将使用漏失层进行训练。我将在训练集上运行 10 个时期,其中 70%的训练集将用于训练模型,而剩余的 30%将用于验证。这不能和我们放在一边的测试设备混淆。
# LSTM
model.add(Embedding(input_dim = vocab_size, output_dim = output_dim, input_length = maxlen, embeddings_constraint=maxnorm(3)))
model.add(LSTM(output_dim=output_dim, return_sequences=True, kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(LSTM(output_dim=output_dim, return_sequences=True, kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(LSTM(output_dim=output_dim, kernel_constraint=maxnorm(3)))
model.add(Dense(2,activation='softmax'))
型号汇总如下:
LSTM 模型结果如下— 10 个历元:
第六步:模型评估
现在,让我们绘制模型随时间变化的性能图,并查看它们在 10 个时期的精度和损失。
简单:精度
简单:损失
请注意训练精度,SimpleRNN 模型很快开始过度拟合,并且由于相同的原因,验证精度具有很高的方差。
LSTM:精确度
LSTM:损失
从 LSTM 的精度和损失图来看,模型过度拟合,验证精度不仅方差高,而且由于同样的原因下降很快。
结论
在这个项目中,我试图演示如何建立一个深度学习管道,来预测与 2020 年美国大选相关的推文的情绪。为此,我首先通过 Twitter API 和 Tweepy 包抓取原始推文,创建了自己的数据集。
超过 440,000 条推文通过 Twitter API 传输,并存储在一个 CSV 文件中。在争论和可视化数据之后,传统的聚类算法,在这种情况下是 k-means 聚类,被用来给推文贴上两个不同的标签,代表积极或消极的情绪。也就是说,在用数据训练深度学习模型之前,该问题被转换成监督学习问题。然后数据集被分成训练集和测试集。
随后,训练集分别用于训练 SimpleRNN 和 LSTM 模型,并使用每个时期模型性能的损失和精度曲线进行评估。总的来说,这两个模型都表现出应有的性能,并且根据从精度图中看到的情况,可能会过度拟合数据,因此,我为下一步提出以下建议。
建议:
- 找到另一种方法或不同的学习算法来标记数据集
- 尝试亚马逊机械土耳其人或地面真相来标记数据集
- 尝试不同的 RNN 建筑
- 对 RNN 架构执行更高级的超参数调整
- 执行交叉验证
- 使数据成为多类问题
本项目/教程中练习的技能:
- 如何通过 Tweepy 和 Twitter API 高效地从 Twitter 收集数据
- 如何有效地处理大型数据集
3.如何构建深度学习架构,编译并适应 Keras
4.如何将基本的自然语言处理概念和技术应用于文本数据
同样,在我的 GitHub 中找到我的带有 Python 代码的 Jupyter 笔记本,在这里,让我们在 LinkedIn 上连接。
享受深度学习:)我很想听到你的反馈和建议,所以请使用鼓掌按钮或在下面的部分评论。
谢谢大家!
在线参考和有用资料:
深度学习-为数据集准备图像
获取数据集图像的简单方法
每当我们开始一个机器学习项目时,我们首先需要的是一个数据集。数据集将是您培训模型的支柱。您可以自动或手动构建数据集。在这里,我将分享关于手动过程。
什么是数据集?
数据集是满足您的 ML 项目需求的特定数据的集合。数据的类型取决于你需要训练的人工智能的类型。基本上,你有两个数据集:
- 训练
- 测试
分别为 90%和 10%的成分
每当你训练一个定制模型时,重要的是图像。是的,当然图像在深度学习中起着主要作用。你的模型的准确性将基于训练图像。所以,在你训练一个定制模型之前,你需要计划**如何获取图像?**在这里,我将分享我关于获取数据集图像的简单方法的想法。
从谷歌获取图片
是的,我们可以从谷歌上获取图片。使用 下载所有图片 浏览器扩展我们可以在几分钟内轻松获得图片。你可以在这里查看关于这个扩展的更多细节!各大浏览器都有。遗憾的是,Safari 浏览器不支持该扩展。
一旦你使用这个扩展下载图像,你会看到下载的图像在一个文件夹中,文件名是随机的。我们可以重命名文件或删除。png 文件,使用下面的 Python 脚本。
将活动选项卡中的所有图像保存为. zip 文件。轻松保存来自 Instagram、谷歌图片等的照片。
chrome.google.com](https://chrome.google.com/webstore/detail/download-all-images/ifipmflagepipjokmbdecpmjbibjnakm)
从下载的图像文件夹中删除 png。
重命名您的图像文件
从视频中获取图像
这里我们有另一种方法来为数据集准备图像。我们可以很容易地从视频文件中提取图像。 Detecto 给出了从视频中获取图像的简单解决方案。更多信息参见 探测器 。
pip3 install detecto
使用下面的代码,我们可以从视频文件中提取图像。
使用你的一组图像
您可以拍摄将用于训练模型的对象的照片。重要的是要确保你的图像不超过 800x600。这将有助于您的数据集训练更快。
我准备了一个视频,并解释了上述过程。请查看下面的视频博客。
为数据集准备图像的视频博客
结论
作为一名 ML noob,我需要找出为训练模型准备数据集的最佳方法。希望这能有用。我的最终想法是为这个过程创建一个 Python 包。😃
是的,我会想出我的下一篇文章!