TowardsDataScience 博客中文翻译 2019(三十七)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

高级 Keras —构建复杂的定制损失和指标

原文:https://towardsdatascience.com/advanced-keras-constructing-complex-custom-losses-and-metrics-c07ca130a618?source=collection_archive---------1-----------------------

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

Photo Credit: Eyal Zakkay

TL;DR——在本教程中,我将介绍一个简单的技巧,它将允许您在 Keras 中构造自定义损失函数,该函数可以接收除y_truey_pred之外的参数。

背景— Keras 损失和指标

在 Keras 中编译模型时,我们向compile函数提供所需的损失和度量。例如:

model.compile(loss=’mean_squared_error’, optimizer=’sgd’, metrics=‘acc’)

出于可读性的目的,从现在开始我将集中讨论损失函数。然而,所写的大部分内容也适用于度量标准。

来自 Keras 的损失文件:

您可以传递现有损失函数的名称,也可以传递 TensorFlow/Theano 符号函数,该函数为每个数据点返回一个标量,并采用以下两个参数:

y_true :真标签。张量流/Theano 张量。

y_pred :预测。tensor flow/与 y_true 形状相同的 Theano 张量。

因此,如果我们想使用一个常见的损失函数,如 MSE 或分类交叉熵,我们可以通过传递适当的名称轻松做到这一点。

Keras 文档中提供了可用的损失指标列表。

自定义损失函数

当我们需要使用一个可用的损失函数(或度量)时,我们可以构造我们自己的自定义函数并传递给model.compile

例如,构建自定义指标(来自 Keras 的文档):

多参数损失/度量函数

您可能已经注意到,损失函数必须只接受两个参数 : y_truey_pred,它们分别是目标张量和模型输出张量。但是如果我们希望我们的损失/度量依赖于这两个之外的其他张量呢?

为此,我们需要使用函数闭包。我们将创建一个损失函数(使用我们喜欢的任何参数),它返回一个y_truey_pred的函数

例如,如果我们(出于某种原因)想要创建一个损失函数,将第一层中所有激活的均方值加到 MSE 上:

请注意,我们已经创建了一个返回合法损失函数的函数(不限制参数的数量),该函数可以访问其封闭函数的参数。

更具体的例子:

前面的例子是一个不太有用的用例的玩具例子。那么什么时候我们会想要使用这样的损失函数呢?

假设你正在设计一个可变的自动编码器。您希望您的模型能够从编码的潜在空间重建其输入。然而,你也希望你在潜在空间中的编码是(近似)正态分布的。

而前一个目标可以通过设计一个仅取决于你的输入和期望输出y_truey_pred的重建损失来实现。对于后者,你需要设计一个作用于潜在张量的损失项(例如 Kullback Leibler 损失)。为了让你的损失函数接近这个中间张量,我们刚刚学过的技巧可以派上用场。

示例用途:

这个例子是序列到序列变分自动编码器模型的一部分,更多上下文和完整代码请访问这个报告——Sketch-RNN 算法的一个 Keras 实现

如前所述,尽管示例是针对损失函数的,但是创建定制度量函数的工作方式是相同的。

撰写本文时的 Keras 版本:2.2.4

参考文献:

[1] Keras —损失

[2] Keras —指标

[3] Github 问题—向目标函数传递附加参数

使用管道估计器的高级模型构建

原文:https://towardsdatascience.com/advanced-model-building-using-the-pipeline-estimator-59581244386c?source=collection_archive---------27-----------------------

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

在本文中,我们展示了 sci-kit learn 中的 Pipeline 估计器如何用于高效的机器学习模型构建、测试和评估。我们将使用游轮数据集来说明我们的示例,以构建一个线性回归模型来推荐船只的船员人数。

在上一篇文章中( 使用协方差矩阵图进行特征选择和降维 ),我们已经展示了协方差矩阵图可以用于特征选择和降维。

使用游轮数据集cruise _ ship _ info . CSV**,**我们发现,在 6 个预测特征[’ 年龄’、吨位’、乘客’、长度’、舱室乘客密度 ]中,如果我们假设重要特征的相关系数为 0 那么目标变量“乘员”与 4 个预测变量:“吨位”、“乘客”、“长度、“车厢”强相关。 因此,我们能够将特征空间的维数从 6 降低到 4。

现在,假设我们想在新的特征空间上建立一个模型来预测船员变量。我们的模型可以用以下形式表示:

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

在本文中,我们展示了如何使用 scikit-learn 的管道估算器以有效的方式训练、测试和评估我们的模型。

什么是管道估算器?

流水线估计器是一种将几个估计器和转换器组合在一起的方法。这有助于我们编写高效的代码。在下图中,管道估计器在输入数据集中执行 3 项重要任务:(1)使用 StandardScaler() 转换器进行特征缩放;(2)使用 PCA() 变换器的特征工程和维数减少;以及(3)使用**线性回归()**估计器建立模型。

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

为什么要使用管道估算器?

作为数据科学家,重要的是我们要高效地编码。包含较少行的高效代码更容易捕捉可能存在的任何错误。所采用的流水线使得模型构建非常高效和健壮。

我们现在将考虑一个示例,该示例说明如何使用流水线估计器来构建、测试和评估线性回归模型,该线性回归模型用于基于 4 个预测变量,即“吨位”、“乘客”、“长度和“舱室”,来推荐船只的船员人数。

1.导入必要的库

import numpy as npimport pandas as pdfrom sklearn.metrics import r2_scorefrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.decomposition import PCAfrom sklearn.linear_model import LinearRegressionfrom sklearn.pipeline import Pipelinepipe_lr = Pipeline([('scl', StandardScaler()),('pca', 
                  PCA(n_components=4)),('slr', LinearRegression())])

2.读取数据集并选择预测值和目标变量

df=pd.read_csv("cruise_ship_info.csv")cols_selected = ['Tonnage', 'passengers', 'length', 'cabins','crew']X = df[cols_selected].iloc[:,0:4].values 

y = df[cols_selected]['crew'] sc_y = StandardScaler()train_score = []test_score =  []

3.使用管道估算器进行模型构建、测试和评估(交叉验证)

for i in range(10): X_train, X_test, y_train, y_test = train_test_split( X, y, 
                                  test_size=0.4, random_state=i) y_train_std = sc_y.fit_transform(y_train[:, 
                                     np.newaxis]).flatten() pipe_lr.fit(X_train, y_train_std) y_train_pred = sc_y.inverse_transform(pipe_lr.predict(X_train)) y_test_pred = sc_y.inverse_transform(pipe_lr.predict(X_test)) train_score = np.append(train_score, r2_score(y_train, 
                            y_train_pred)) test_score = np.append(test_score, r2_score(y_test, 
                            y_test_pred))

4.我们代码的输出

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

总之,我们已经展示了如何通过将几个基本的转换器和估计器组合在一起,使用非常少的代码行来使用管道估计器来构建、测试和评估机器学习模型。

参考

  1. 在具有高度相关特征的数据集上训练机器学习模型
  2. 使用协方差矩阵图进行特征选择和降维
  3. Raschka、Sebastian 和 Vahid Mirjalili Python 机器学习,第二版。帕克特出版社,2017 年。
  4. Benjamin O. Tayo,预测船只船员规模的机器学习模型https://github . com/bot 13956/ML _ Model _ for _ Predicting _ Ships _ Crew _ Size

PowerBI 中的高级 Python 可视化

原文:https://towardsdatascience.com/advanced-python-visualizations-in-powerbi-b64fe8602a8a?source=collection_archive---------4-----------------------

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

Image by author

如何利用最新的 Python-PowerBI 集成,将 Python 的高级视觉效果与原生数据钻取和 DAX 功能相结合

最新的 Python 可视化支持完善了 Power BI 中对 Python 的支持,使您能够使用 Python 脚本来准备数据集,在 Power BI 桌面中应用复杂的分析或机器学习,然后使用数百个开源 Python 可视化包中的任何一个在 Power BI 报告中绘制结果。

这种视觉效果随着报告中的交叉筛选而更新,并且可以与 DAX 功能相结合。这是一个强大的组合,它允许我们通过增加交互性来充分利用数据。

在 PowerBI 报告中创建 Python 视觉效果

可以通过从 Power BI Desktop 的 Visualizations 窗格中选择 Python 可视化图标来添加 Python 可视化,这会将占位符 Python 脚本添加到报表中。

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

必填字段可以从我们正在处理的数据集中添加到值窗格中,这在内部创建了一个 Pandas 数据框架。然后,我们可以使用 Matplotlib 和 Seaborn 等库编写自定义脚本来创建视觉效果。

本机 PowerBI 功能(如切片器、过滤器)可以在 python 可视化工具之上使用,以根据需要进行选择。视觉效果会动态更新。

创建径向条形图以可视化 IMdB 2016 电影数据集

这里有一个小教程,教你如何用 python 创建一个自定义的视觉效果,并添加切片器,让你对数据背后的故事有一个交互式的视觉体验。

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

IMdB 2016 movie database

该数据集由 2016 年 IMdB 评分为 6 分或更高的电影列表以及属性-预算、总收入、类型和分数组成。
这个数据集在 IMdB 和 kaggle 等其他地方公开。

使用 Matplotlib 在脚本中添加了一个自定义的径向条形图。它根据所应用的选择/过滤器动态地从数据帧中获取值。

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

用于选择流派、国家和分数范围的切片器直接添加到 PowerBI 中,并显示所选集的平均分数和总收藏数等指标。这使我们能够全面地探索数据,并根据需要做出推论。

代码片段:

# Import the libraries
from matplotlib import pyplot as plt
import numpy as npdataset.sort_values('genre', inplace=True) # Creating values (budget amount) for the bars
iN = len(dataset)
arrCnts = dataset['budget']/10000000theta=np.arange(0,2*np.pi,2*np.pi/iN)
width = (2*np.pi)/iN *0.9 # Plot size and proportions
fig = plt.figure(figsize=(20,18),frameon=False,dpi=200)

# Adding radial axes
ax = fig.add_axes([0.05, 0.05, 0.9, 0.9], polar=True)
bars = ax.bar(theta, arrCnts, width=width, bottom=15,color=dataset['Col'],alpha=0.65,edgecolor='yellow')
ax.set_xticks(theta)
plt.axis('off')
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)

bottom = 15
rotations = np.rad2deg(theta)
y0,y1 = ax.get_ylim()

# Adding radial tags
for x, bar, rotation, label in zip(theta, bars, rotations, dataset['name']):
    offset = (bottom+bar.get_height())/(y1-y0)
    lab = ax.text(0, 0, label, transform=None, 
             ha='center', va='center',alpha=0.5)
    renderer = ax.figure.canvas.get_renderer()
    bbox = lab.get_window_extent(renderer=renderer)
    invb = ax.transData.inverted().transform([[0,0],[bbox.width,0] ])
    lab.set_position((x,offset+(invb[1][0]-invb[0][0])/2.*2.7 ) )
    lab.set_transform(ax.get_xaxis_transform())
    lab.set_rotation(rotation) 

fig.tight_layout()
plt.show()---
This code should be pasted in the script and the visual must be updated.

python 支持的这一扩展作为一个强大的分析框架带来了许多可能性,无论是使用高级 python 库制作高级视觉效果还是复杂的机器学习算法,从而使 PowerBI 成为数据科学领域的必备工具。

看看我下一篇关于如何在 PowerBI 中制作直方图的博客吧!

https://sriharipramod . medium . com/advanced-python-visualizations-in-power bi-histograms-and-frequency-plots-66f 238684011

关于作者
斯里哈里·普拉莫德

从事人工智能产品和建筑技术的数据分析和决策科学专家。印度海得拉巴。

https://www.linkedin.com/in/sriharipramod/

深度卷积神经网络的高级课题

原文:https://towardsdatascience.com/advanced-topics-in-deep-convolutional-neural-networks-71ef1190522d?source=collection_archive---------6-----------------------

残差网络、显著图、扩张卷积等等。

“如果我们想让机器思考,我们需要教它们看”——费-

在整篇文章中,我将讨论卷积神经网络的一些更复杂的方面,以及它们如何与特定任务相关,如对象检测和面部识别。

本教程将讨论的主题有:

  • CNN 评论
  • 感受野和扩张的回旋
  • 显著图
  • 转置卷积
  • 经典网络
  • 剩余网络
  • 迁移学习

这篇文章是我的文章标题: 神经网络简单介绍 的自然延伸。如果你不熟悉卷积神经网络的思想和功能,我建议你在阅读本文其余部分之前先看看这个。

由于原始文章过长,我决定省略与对象检测和面部识别系统相关的几个主题,以及研究文献中目前正在试验的一些更深奥的网络架构和实践。我可能会在未来的一篇文章中更具体地讨论深度学习在计算机视觉中的应用。

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

You Only Look Once (YOLO) — 2016

所有相关代码现在都可以在我的 GitHub 存储库中找到:

[## 龙熊先生/CNN

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/mrdragonbear/CNNs)

CNN 评论

在我的原始文章中,我讨论了为什么全连接网络不足以完成图像分析任务的动机。CNN 的独特之处如下:

  • 比全连接网络的参数(权重和偏差)更少。
  • 对对象平移不变-它们不依赖于特征在图像中出现的位置。
  • 可以容忍图像中的一些失真。
  • 能够归纳和学习特征。
  • 需要网格输入。

卷积层由滤波器、特征图、激活函数构成。这些卷积层可以有效。

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

如果已知输入中的层数、 nᵢ 、该级中的滤波器数量、 f 、步长大小、 s 以及图像的像素尺寸、 p (假设是正方形),我们就可以确定给定卷积块的输出层数。

池层用于减少过度拟合。完全连接的图层用于将空间和通道要素混合在一起。在整个图像上绘制了特征图之后,每个过滤层对应于该图像,这就是提取特征的方式。

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

知道输入和输出层的数量很重要,因为这决定了构成神经网络参数的权重和偏差的数量。网络中的参数越多,需要训练的参数就越多,这导致训练时间更长。训练时间对于深度学习非常重要,因为它是一个限制因素,除非你可以访问强大的计算资源,如计算集群。

下面是一个示例网络,我们将计算其参数总数。

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

在这个网络中,卷积滤波器有 250 个权重和 10 个偏置项。我们没有最大池层的权重。在 max-pooling 层之后,我们有 13 × 13 × 10 = 1,690 个输出元素。我们有一个 200 节点的全连接层,因此全连接层中共有 1,690 × 200 = 338,000 个权重和 200 个偏置项。因此,我们总共有 338,460 个参数要在网络中训练。我们可以看到,大多数训练参数出现在完全连接的输出层。

CNN 的每一层都学习越来越复杂的过滤器。第一层学习基本的特征检测过滤器,例如边缘和拐角。中间层学习检测物体部分的过滤器——对于人脸,他们可能会学习对眼睛和鼻子做出反应。最后一层有更高的表现:他们学习识别不同形状和位置的完整物体。

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

Feature maps showing increasing resolution of features through different convolutional layers of a neural network.

对于那些在继续之前需要更直观地了解卷积神经网络的人来说,看看这个三维表示可能会有所帮助:

[## 卷积神经网络的三维可视化

编辑描述

加利福尼亚洲](http://scs.ryerson.ca/~aharley/vis/conv/)

在下一节中,我们将更详细地讨论卷积层感受野的概念。

感受野和扩张的脑回

感受野被定义为输入空间中特定 CNN 特征所关注的区域(即受其影响)。在一个 5 × 5 的输入图上应用一个内核大小为k =3T5×3,填充大小为 p = 1 × 1,步距为 s = 2 × 2 的卷积 C ,我们将得到一个 3 × 3 的输出特征图(绿色图)。**

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

在 3 × 3 特征图的顶部应用相同的卷积,我们将得到 2 × 2 特征图(橙色图)。

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

让我们在一维中再次观察感受野,没有填充,步幅为 1,核大小为 3 × 1。

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

我们可以跳过其中的一些连接,以创建一个扩展的卷积,如下所示。

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

这种扩展卷积的工作方式与正常卷积类似,主要区别在于感受野不再由连续像素组成,而是由其他像素分隔的单个像素组成。下图显示了将扩展卷积图层应用于图像的方式。

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

Dilated convolution

下图显示了二维数据的扩展卷积。红点是 3 × 3 滤波器的输入,绿色区域是每个输入捕捉的感受野。感受野是每个输入(单元)对下一层的初始输入所捕获的隐含区域。

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

使用扩张卷积背后的动机是:

  • 通过以更高的分辨率处理输入来检测细节。
  • 更广泛的输入视图,以获取更多上下文信息。
  • 运行时间更快,参数更少

在下一节中,我们将讨论使用显著图来检查卷积网络的性能。

显著图

显著图是一种有用的技术,数据科学家可以用它来检查卷积网络。它们可以用来研究神经元的激活模式,以了解图像的哪些特定部分对特定特征很重要。

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

让我们想象一下,给你一张狗的图片,让你给它分类。这对于人类来说非常简单,但是,深度学习网络可能没有你聪明,可能会将其归类为猫或狮子。它为什么这样做?

网络可能错误分类图像的两个主要原因是:

  • 训练数据中的偏差
  • 没有正规化

我们想了解是什么让网络给出某个类作为输出——一种方法是使用显著图。显著图是一种测量给定图像中特定类别的空间支持度的方法。

“当图像 I 通过我的网络时,找出负责具有分数 S©的类 C 的像素”。

我们如何做到这一点?我们差异化!对于任意一个函数 f(x,y,z) ,我们可以通过求变量 x,y,z 在任意一个特定点 (x₁,y₁,z₁) 对这些变量的偏导数,来求变量x,y,z对该点的影响。类似地,为了找到负责的像素,我们对类 C 取分数函数 S ,并对每个像素取偏导数。

这很难自己实现,但幸运的是,auto-grad 可以做到这一点!该过程工作如下:

  1. 通过网络转发图像。
  2. 计算每门课的分数。
  3. 对于除类别 C 之外的所有类别,强制最后一层的分数 S 的导数为 0。对于 C ,将其设置为 1。
  4. 通过网络反向传播这个导数。
  5. 渲染它们,你就有了你的显著图。

注意:在步骤#2 中,我们没有使用 softmax,而是将其转换为二元分类并使用概率。

这里有一些显著图的例子。

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

我们如何处理彩色图像?获取每个通道的显著图,或者取最大值、平均值,或者使用所有 3 个通道。

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

概述显著图功能的两篇优秀论文是:

有一个与本文相关的 GitHub 库,我在其中展示了如何生成显著图(这个库可以在这里找到)。下面是 Jupyter 笔记本中的一段代码:

**from** **vis.visualization** **import** visualize_saliency
**from** **vis.utils** **import** utils
**from** **keras** **import** activations

*# Utility to search for layer index by name.* 
*# Alternatively we can specify this as -1 since it corresponds to the last layer.*
layer_idx = utils.find_layer_idx(model, 'preds')plt.rcParams["figure.figsize"] = (5,5)
**from** **vis.visualization** **import** visualize_cam
**import** **warnings**
warnings.filterwarnings('ignore')

*# This corresponds to the Dense linear layer.*
**for** class_idx **in** np.arange(10):    
    indices = np.where(test_labels[:, class_idx] == 1.)[0]
    idx = indices[0]

    f, ax = plt.subplots(1, 4)
    ax[0].imshow(test_images[idx][..., 0])

    **for** i, modifier **in** enumerate([**None**, 'guided', 'relu']):
        grads = visualize_cam(model, layer_idx, filter_indices=class_idx, 
                              seed_input=test_images[idx], backprop_modifier=modifier)        
        **if** modifier **is** **None**:
            modifier = 'vanilla'
        ax[i+1].set_title(modifier)    
        ax[i+1].imshow(grads, cmap='jet')

这段代码导致生成以下显著图(假设安装了相关的库vis.utilsvis.visualization)。如果您想更全面地了解实现过程,请查看笔记本。

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

在下一节中,我们将讨论通过使用转置卷积进行上采样的想法。

转置卷积

到目前为止,我们所看到的卷积要么保持其输入的大小,要么使其变小。我们可以用同样的技术使输入张量变大。这个过程被称为上采样。当我们在一个卷积步骤内进行时,它被称为转置卷积分数步长

注意:一些作者在卷积反卷积时称之为上采样,但该名称已被以下文章中概述的不同概念所采用:

https://arxiv.org/pdf/1311.2901.pdf

为了说明转置卷积是如何工作的,我们将看一些卷积的示例。

第一个例子是没有填充的典型卷积层,作用于大小为 5 × 5 的图像。卷积后,我们得到一个 3 × 3 的图像。

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

Image taken from A. Glassner, Deep Learning, Vol. 2: From Basics to Practice

现在我们来看一个填充为 1 的卷积层。原始图像是 5 × 5,卷积后的输出图像也是 5 × 5。

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

Image taken from A. Glassner, Deep Learning, Vol. 2: From Basics to Practice

现在我们来看一个填充为 2 的卷积层。原始图像是 3× 3,卷积后的输出图像也是 5 × 5。

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

Image taken from A. Glassner, Deep Learning, Vol. 2: From Basics to Practice

当在 Keras 中使用时,例如在可变自动编码器的开发中,这些是使用上采样层实现的。希望,如果你以前见过这个,现在可以理解这些卷积层如何通过使用转置卷积来增加图像的大小。

在下一节中,我们将讨论一些经典网络的架构。这些网络中的每一个在某种意义上都是革命性的,推动了深度卷积网络的发展。

经典网络

在这一部分,我将回顾 CNN 的一些经典架构。这些网络被用于深度学习领域的一些开创性工作,并经常用于迁移学习目的(这是未来文章的主题)。

第一项提出类似于卷积神经网络的研究是由 Kunihiko Fukushima 在 1980 年提出的,被称为 NeoCognitron1,他的灵感来自于哺乳动物视觉皮层的发现。福岛将 NeoCognitron 应用于手写字符识别。

到 20 世纪 80 年代末,发表了几篇论文,大大推进了该领域的发展。反向传播的想法首先由 Yann LeCun 于 1985 年在法语中发表(这也是由其他研究人员独立发现的),随后不久由 Waiber 等人在 1989 年发表了 TDNN——用反向传播训练的类似卷积的网络的发展。最初的应用之一是由 LeCun 等人在 1989 年使用应用于手写邮政编码识别的反向传播。

LeNet-5

与当前实践相比,LeNet-5 的公式有点过时。这是在 20 世纪末深度学习的萌芽阶段开发的第一批神经架构之一。

1998 年 11 月,LeCun 发表了他最著名的论文之一,描述了一种用于文档识别的“现代”CNN 架构,称为 LeNet1。这不是他的第一次迭代,事实上,这是 LeNet-5,但这篇论文是谈论 LeNet 时经常引用的出版物。

它使用卷积网络,然后是池层,最后是完全连接的层。网络首先从高维特征开始,并在增加信道数量的同时减小其尺寸。这个网络中大约有 60,000 个参数。

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

LeCun, Yann, et al. “Gradient-based learning applied to document recognition.” Proceedings of the IEEE 86.11 (1998): 2278–2324.

AlexNet

AlexNet 架构是深度学习中最重要的架构之一,引用次数超过 25,000 次——这在研究文献中几乎是闻所未闻的。AlexNet 由多伦多大学的 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 于 2012 年开发,在 2012 年 ImageNet 大规模视觉识别挑战赛(ILSVRC)中击败了竞争对手。

该网络在 ImageNet 数据集上进行训练,该数据集是一个由 1000 个不同类别组成的 120 万个高分辨率(227x227x3)图像的集合,使用数据扩充。该模型的深度比当时任何其他网络都大,并使用 GPU 进行了 5-6 天的训练。该网络由 12 层组成,利用了 dropout 和 smart optimizer 层,是首批实现 ReLU 激活功能的网络之一,该功能至今仍被广泛使用。该网络有超过 6000 万个参数需要优化(约 255 MB)。

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

Alex Krizhevsky, Ilya Sutskever, and Geoffrey E Hinton, “Imagenet classification with deep convolutional neural networks,” in Advances in neural information processing systems, pp. 1097–1105, 2012

这个网络通过展示 CNN 令人印象深刻的表现和潜在的好处,几乎单枪匹马地启动了人工智能革命。该网络以 15.3%的 top-5 误差赢得了 ImageNet 大赛,比第二名低了 10.8 个百分点以上。

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

ImageNet results from 2011 to 2016. Source

我们将讨论剩余的赢得 ILSVRC 的网络,因为其中大多数都是处于深度学习研究前沿的革命性网络。

ZFNet

这个网络是由纽约大学的马修·泽勒和罗布·弗格斯引入的,他们以 11.2%的错误率赢得了 2013 年的 ILSVRC。该网络减小了过滤器的尺寸,并被训练了 12 天。

本文提出了一种可视化技术,称为“去卷积网络”,它有助于检查不同的特征激活及其与输入空间的关系。

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

VGG16 和 VGG19

Simonyan 和 Zisserman(牛津)于 2014 年引入了 VGG 网络。这个网络在固有的简单性和结构上是革命性的。它由 16 或 19 层(因此得名)组成,总共有 1.38 亿个参数(522 MB),使用 3×3 卷积滤波器,仅使用相同的填充和 1 的跨距,以及 2×2 最大池层,跨距为 2。

作者表明,两个 3×3 滤光器具有 5×5 的有效感受野,并且随着空间尺寸减小,深度增加。这个网络被训练了两到三个星期,现在仍然习惯于这样——主要用于迁移学习。该网络最初是为 2014 年的 ImageNet 挑战赛开发的。

  • ImageNet 挑战赛 2014;16 或 19 层
  • 1.38 亿个参数(522 MB)。
  • 卷积层使用“相同的”填充和步距 s = 1。
  • 最大池层使用过滤器大小 f = 2,跨距 s = 2。

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

Karen Simonyan and Andrew Zisserman, “Very deep convolutional networks for large-scale image recognition,” 2014.

谷歌网(第一版)

谷歌网络是由 Szegedy 等人(谷歌)于 2014 年推出的。该网络击败了 VGG 架构,成为 2014 年 ILSVRC 的赢家。该网络引入了初始模块的概念——具有不同滤波器大小的并行卷积层。

这里的想法是,我们不知道哪个滤波器尺寸是最好的,所以我们只是让网络来决定。初始网络是通过连接其他初始模块而形成的。它包括几个 softmax 输出单元,以加强正则化。这是一个在未来架构开发中非常重要的关键思想。

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

GoogLeNet (Inception-v1) architecture.

另一个有趣的特性是,最终没有完全连接的层,而是用一个平均池层来代替。移除这种完全连接的层导致网络的参数比 AlexNet 少 12 倍,使其训练速度快得多。

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

GoogLeNet Architecture.

剩余网络

第一个残差网络是由何等人(微软)在 2015 年提出的。该网络在多个类别中赢得了 ILSVRC 2015。这个网络背后的主要思想是剩余块。该网络允许开发非常深的神经网络,其可以包含 100 层或更多层。

这是革命性的,因为到目前为止,深度神经网络的发展受到消失梯度问题的抑制,该问题发生在跨越大量层传播和繁殖小梯度时。

作者认为,优化残差映射比原型神经架构更容易。此外,如果需要,残余块可以决定“自行关闭”。让我们比较一下普通网络和剩余网络的网络结构。简单网络结构如下:

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

剩余网络结构如下所示:

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

Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun, “Deep residual learning for image recognition,” in The IEEE Conference on Computer Vision and Pattern Recognition (CVPR), June 2016.

描述该网络的方程是:

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

有了这个额外的连接,渐变可以更容易地向后传播。它成为一个灵活的模块,可以扩展网络的容量,或者简单地转换成一个不影响训练的身份函数。

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

Example training of an 18- and 34-layer residual network.

残差网络顺序堆叠残差块。

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

想法是允许网络变得更深,而不增加训练的复杂性。

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

剩余网络实现具有卷积层的块,这些卷积层使用“相同”填充选项(即使在最大池化时)。这允许该块学习身份函数。

设计者可能想要减小特征的尺寸并使用“有效的”填充。—在这种情况下,快捷路径可以实现一组新的卷积层,从而适当减小尺寸。

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

这些网络可能会变得巨大和极其复杂,它们的图表开始看起来类似于描述电厂功能的图表。这是这样一个网络的例子。

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

Source: He2016

将 ImageNet 以前的获胜者的误差值与 ResNet 公式的误差值进行比较,我们可以看到性能有明显的提高。Alexnet (2012)取得了 15.3%的前 5 名误差(第二名为 26.2%),其次是 ZFNet (2013)取得了 14.8%的前 5 名误差(特征的可视化),其次是 GoogLeNet (2014),误差为 7.8%,然后是 ResNet (2015),首次实现了 5%以下的准确率。

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

密集网络

最初由黄等人在 2016 年提出,作为 ResNet 哲学的激进扩展。每个块使用每个先前的特征地图作为输入,有效地连接它们。这些连接意味着网络有 L(L+1)/ 2 个直接连接,其中 L 是网络的层数。人们可以将该架构视为一个展开的递归神经网络。

每一层都将自己的 k 特征地图添加到这个状态中。增长率决定了每一层对全局状态贡献多少新信息。这里的想法是,我们在每个点都有所有可用的先前信息。与直觉相反,这种架构减少了所需参数的总数。

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

A 5-layer dense block with a growth rate of k = 4. Each layer takes all preceding feature-maps as inputs.

该网络的工作原理是通过将每一层与每一层直接连接,允许每一层最大限度的信息(和梯度)流动。这样,DenseNets 通过特征重用来挖掘网络的潜力,这意味着不需要学习冗余的特征映射。DenseNet 层相对较窄(例如,12 个过滤器),并且它们仅添加一小组新的特征地图。

DenseNet 架构通常具有优于 ResNet 架构的性能,可以用更少的总体参数实现相同或更好的精度,并且网络更容易训练。

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

Performance comparison of various ResNet and DenseNet architectures.

网络公式一开始可能有点混乱,但它本质上是一种 ResNet 架构,分辨率块被密集块所取代。密集的连接具有正则化效果,这减少了对具有较小训练集大小的任务的过度适应。

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

Simplified DenseNet architecture schematic.

请务必注意,DenseNets 不会将图层的输出要素地图与输入要素地图相加,事实上,它们会连接它们:

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

特征图的维度在一个块内保持不变,但是滤波器的数量在它们之间变化,这被称为增长率 k.

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

下面是密集网络的完整架构。当我们以完整的分辨率来看网络时,它是相当复杂的,这就是为什么通常以抽象的形式更容易可视化(就像我们上面所做的)。

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

Full architectural layout of a DenseNet.

关于 DenseNet 的更多信息,我推荐下面这篇文章。

[## DenseNet

许多论文:

towardsdatascience.com](/densenet-2810936aeebb)

网络总结

正如我们所看到的,在短短几年的时间里,我们已经从 ImageNet 数据集(如果您记得的话,该数据集由 120 万张图像组成)上约 15%的错误率降至约 3–4%的错误率。如今,最先进的网络能够相当稳定地保持在 3%以下。

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

在我们能够为这些网络获得满分之前,还有相当长的路要走,但在过去十年中,进步的速度是相当惊人的,从这一点应该可以明显看出为什么我们目前正在经历一场深度学习革命——我们已经从人类具有高级视觉识别能力的阶段发展到这些网络具有高级视觉能力的阶段(人类无法在 ImageNet 数据集上达到 3%)。

这推动了机器学习算法向各种需要大量使用图像分析的商业领域的过渡,如医学成像(检查大脑扫描,x 射线,乳房 x 线扫描)和自动驾驶汽车(计算机视觉)。图像分析很容易扩展到视频,因为这只是每秒钟多个图像帧的快速连续,尽管这需要更多的计算能力。

迁移学习

迁移学习是一个重要的话题,它绝对值得有一篇专门的文章。然而,现在,我将概述迁移学习背后的基本思想,以便读者能够做更多的研究,如果他们感兴趣的话。

如何在 CPU 上做一个可以在几个小时(几分钟)内训练好的图像分类器?

通常情况下,图像分类模型可能需要几个小时、几天甚至几周的时间来训练,尤其是在非常大的网络和数据集上训练时。然而,我们知道谷歌和微软等公司有专门的数据科学家团队,他们花了数年时间开发用于图像分类的特殊网络——为什么不直接使用这些网络作为自己图像分类项目的起点呢?

这是迁移学习背后的思想,使用预先训练的模型,即具有已知权重的模型,以便将它们应用于不同的机器学习问题。显然,仅仅单纯地转移模型是没有帮助的,您仍然必须根据您的新数据来训练网络,但是通常会冻结以前的层的权重,因为这些是更一般化的特征,在训练期间可能不会改变。与随机初始化网络(Keras 中训练网络时的默认情况)相反,您可以将此视为生成预初始化网络的一种智能方式。

通常,迁移学习中使用的学习速率比典型的网络训练中使用的学习速率要小,因为我们本质上是在调整网络。如果使用大的学习率,并且网络中的早期层没有冻结,迁移学习可能不会提供任何好处。通常,在迁移学习问题中只训练最后一层或最后几层。

迁移学习最适用于相当一般的问题,并且在线上有免费的网络可用(例如图像分析),当用户可用的数据集相对较小,不足以训练神经网络时,这是一个相当常见的问题。

总结一下主要思想:网络的早期层学习低级特征,可以通过在后期和完全连接的层改变权重来适应新的域。

这方面的一个例子是使用 ImageNet 训练任何复杂的大型网络,然后在几千个热狗图像上重新训练网络,你就会得到。

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

Hotdog or NotHotDog: https://youtu.be/ACmydtFDTGs (offensive language and tropes alert)

迁移学习涉及的步骤如下:

  1. 获取现有网络权重
  2. 解冻“头部”完全连接的层,并在您的新图像上训练
  3. 解冻最新的卷积层,并以非常低的学习速率从先前训练的权重开始训练。这将改变最新的层卷积权重,而不会触发大的梯度更新,如果我们没有进行#2,就会发生这种情况。

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

(Left) Typical imported network to be utilized for transfer learning, (right) newly tuned network with the first four convolutional blocks frozen.

要了解更多信息,我推荐几篇其他的媒体文章:

[## HBO 的硅谷如何用移动 TensorFlow、Keras & React Native 打造“不是热狗”

我们如何打败最先进的技术来建立一个现实生活中的人工智能应用。

medium.com](https://medium.com/@timanglade/how-hbos-silicon-valley-built-not-hotdog-with-mobile-tensorflow-keras-react-native-ef03260747f3)

最终意见

恭喜你坚持到这篇文章的结尾!这是一篇涉及深度学习多个方面的长文。读者现在应该已经做好了充分的准备,可以开始深入研究卷积学习和计算机视觉文献。我鼓励读者对我在这里讨论的主题做更多的个人研究,这样他们可以加深他们的知识。

我在下一节中添加了一些进一步阅读的链接,以及一些我在本文中借用图片的研究文章的参考资料。

感谢阅读,深度学习快乐!

延伸阅读

参考文献

Yann LeCun、Leon Bottou、Yoshua Bengio 和 Patrick Haffner,“基于梯度的学习在文档识别中的应用”,IEEE 会议录,第 86 卷,第 11 期,第 2278-2324 页,1998 年。

Alex Krizhevsky、Ilya Sutskever 和 Geoffrey E Hinton,“深度卷积神经网络的图像网络分类”,载于《神经信息处理系统进展》,第 1097–1105 页,2012 年

卡伦·西蒙扬和安德鲁·齐泽曼,“用于大规模图像识别的深度卷积网络”,2014 年。

、陈强和严水成,“网络中的网络”,2013 年。

Christian Szegedy、、Jia、Pierre Sermanet、Scott Reed、Dragomir Anguelov、Dumitru Erhan、Vincent Vanhoucke 和 Andrew Rabinovich,“用卷积更深入地研究”,载于 2015 年 IEEE 计算机视觉和模式识别会议论文集,第 1–9 页。

施洛夫、弗洛里安、德米特里·卡列尼琴科和詹姆斯·菲尔宾。" Facenet:人脸识别和聚类的统一嵌入."IEEE 计算机视觉和模式识别会议论文集,第 815-823 页。2015

Long,j .,Shelhamer,e .,和 Darrell,T. (2014 年)。语义分割的全卷积网络。从 http://arxiv.org/abs/1411.4038v1取回

Chen,l-c .,Papandreou,g .,Kokkinos,I .,Murphy,k .,& Yuille,A. L. (2014 年)。基于深度卷积网和全连通条件随机场的语义图像分割。 Iclr ,1–14。从 http://arxiv.org/abs/1412.7062取回

于,冯,科尔敦,伏(2016)。基于扩张卷积的多尺度上下文聚合。 Iclr ,1–9。http://doi.org/10.16373/j.cnki.ahr.150049

Oord,A. van den,Dieleman,s .,Zen,h .,Simonyan,k .,Vinyals,o .,Graves,a .,… Kavukcuoglu,K. (2016)。WaveNet:原始音频的生成模型,1–15。从 http://arxiv.org/abs/1609.03499取回

Kalchbrenner,l . Espeholt,k . Simon Yan,Oord,A. van den,Graves,a .,& Kavukcuoglu,K. (2016 年)。线性时间内的神经机器翻译。 Arxiv ,1–11。从 http://arxiv.org/abs/1610.10099 取回

神经网络高级主题

原文:https://towardsdatascience.com/advanced-topics-in-neural-networks-f27fbcc638ae?source=collection_archive---------5-----------------------

一些高级神经网络主题的介绍,如快照集、丢失、偏差校正和循环学习率。

本文将介绍神经网络中使用的一些更高级的主题,并将涵盖神经网络研究中仍在讨论的几个重要主题。

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

Source: Train 1, get M for free.

本文将涉及的主题有:

  • 迁移学习
  • 调整学习率
  • 如何解决过度拟合
  • 辍学
  • 修剪

您可以访问下面的前几篇文章。第一个为那些不熟悉的人提供了神经网络主题的简单介绍。第二篇文章涵盖了更多的中间主题,如激活函数、神经结构和损失函数。第三篇文章着眼于更高级的方面,如动量、自适应学习率和批量标准化。第四篇文章是关于神经网络中超参数调整的深入教程。

[## 神经网络简介

神经网络的详细概述,有大量的例子和简单的图像。

towardsdatascience.com](/simple-introduction-to-neural-networks-ac1d7c3d7a2c) [## 神经网络体系结构综合介绍

神经架构、激活函数、损失函数、输出单元的详细概述。

towardsdatascience.com](/comprehensive-introduction-to-neural-network-architecture-c08c6d8e5d98) [## 神经网络优化

涵盖优化器,动量,自适应学习率,批量标准化,等等。

towardsdatascience.com](/neural-network-optimization-7ca72d4db3e0) [## 神经网络中超参数调整简单指南

关于超参数优化的分步 Jupyter 笔记本演练。

towardsdatascience.com](/simple-guide-to-hyperparameter-tuning-in-neural-networks-3fe03dad8594)

迁移学习

想象一下,你在一家小公司工作,计算资源有限,但被要求开发一种最先进的算法来对不同植物物种的图片进行分类。对于任何试图开发利用计算机视觉(面向视觉的机器学习)的商业解决方案的公司来说,这都是一个相当普遍的问题。

在这种情况下,你(至少)有两个问题。你可以访问的数据量也可能是有限的,计算能力也是有限的。显然,用几十个 GPU 连接一个 150 层的深度神经网络,并训练一个模型几个星期来区分你目前拥有数据的最简单的 1000 种植物物种,以创建你的初创公司的最小可行产品的算法,这是不可行的。

在这种情况下,你能做些什么让生活变得轻松一点呢?

幸运的是,谷歌和微软等几家公司已经发布了针对图像识别进行优化的最先进的神经网络架构。这些公司拥有大量的资源和专业知识,所以你可以相信这些模型比你自己设计的任何内部模型都有更好的性能。

然而,有一个问题是,这些算法训练的数据可能没有(事实上,没有)在你想用算法区分的 1000 种植物物种上训练过。

但是,有一个解决办法:转移学习。转移学习就是将学习从一个模型转移到另一个模型,该模型检查的数据与原始模型的数据非常相似。在这种情况下,原始模型用于一般的图像识别(通常在 CIFAR 数据集上),这非常接近我们正在尝试做的事情。然后,我们可以根据自己的数据重新训练网络的最后几层,以便针对我们的特定应用对模型进行微调。

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

The weights from a pre-trained model are loaded into the architecture of the new model. Weights from the output layers are trained whilst the other network layers are frozen. The resulting model will be fine-tuned for the required application.

那么这是如何工作的呢?我们首先使用 Keras 构建原始模型的架构,然后加载训练好的网络的模型权重(你需要先下载这些;它们通常以.h5格式出现)。

我们需要做的第二件事是通过设置图层的trainable=False参数来冻结初始图层的权重。这样做的原因是卷积神经网络(用于处理图像)的初始层包含关于图像的原始信息,如线条、边缘、形状和其他低级特征的解释。随着我们深入网络,对象变得更加复杂和高级,这是网络开始更清楚地区分图像质量的地方。

这里的想法是,我们不试图教网络检查图像,因为它已经被谷歌或微软训练得很好。我们只需要针对我们的用例对它进行微调。

因此,我们可以在输出端将完全连接的网络层(或其子集)设置为可训练的,也许最终的卷积层(如果我们有足够的数据)也是可训练的,然后根据我们的数据训练网络。

这一过程具有需要较少数据来训练模型的额外好处,因为网络可训练参数的数量是网络中参数总数的一小部分。

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

The input layers (e.g. layers 1–4) have relatively little impact on the output for transfer learning as compared with the later layers of the network (e.g. layers 6 and 7).

迁移学习只有在被分析的两个数据集非常相似时才有效。因此,迁移学习最常用于图像识别或语音识别,其中网络可以被训练用于图像的一般识别或声音或给定语言的一般识别。与从头开始训练整个网络相比,使用迁移学习训练网络所需的数据和计算时间要少得多。

请参见“**进一步阅读”**部分的开源文献文章,以更详细地研究迁移学习。

修剪

模型修剪试图在深度神经网络的各种连接矩阵中引入稀疏性,从而减少模型中非零值参数的数量。

单词*‘修剪’*来自决策树中的使用,在决策树中,树的分支被修剪,作为模型正则化的一种形式。类似地,神经网络中被认为不重要或很少激活的权重可以从网络中移除,而几乎没有任何后果。事实上,大多数神经元对模型性能的影响相对较小,这意味着即使消除大量参数,我们也可以实现高精度。

随着神经架构和数据集变得越来越大,为了获得合理的模型执行时间,减少网络中的参数数量变得越来越重要。

研究论文*进行修剪,还是不进行修剪:探索修剪对模型压缩的功效研究了神经网络作为稀疏度(实际上是去除神经元的百分比)的函数的性能,并发现即使减少网络中 75%的神经元,模型性能也不会受到显著影响。事实上,参数数量减半只会降低 0.1%的精度。*

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

修剪通常在卷积神经网络中进行,然而,由于卷积模型中的大多数参数出现在完全连接的(普通的)神经层中,大多数参数从网络的这一部分中被消除。

在深度神经网络中有多种执行修剪的方式。最常见的方式是权重剪枝**。权重修剪根据权重的大小对权重进行排序,因为权重较大的参数更有可能触发,因此更有可能是重要的。**

另一种方法是单元修剪**,它将权重矩阵中的所有列设置为零,实际上删除了相应的输出神经元。这里,为了实现稀疏度 k% ,我们根据它们的 L2 范数对权重矩阵的列进行排序,并删除最小的 k% 。**

**第三种更先进的方法是使用 **Fischer 修剪,依赖于 Fischer 信息。这产生了一个称为 Fischer-Rao 范数的范数,该范数可用于对参数进行排序。人们怀疑费歇尔信息和参数冗余之间存在联系,这就是为什么这种技术似乎产生良好的结果。你可以在这里阅读更多关于费歇尔修剪:

** [## 修剪神经网络:最近的两篇论文

我想简要强调最近两篇关于修剪神经网络的论文(声明,其中一篇是我们的):克里斯特斯…

www.inference.vc](https://www.inference.vc/pruning-neural-networks-two-recent-papers/)

要查看在标准 VGG16 网络上修剪的代码实现,我推荐阅读这篇优秀的文章:

[## 修剪深度神经网络,使其快速而小巧

我的 PyTorch 实现[1611.06440 修剪卷积神经网络进行资源有效的推断]…

雅各布吉尔. github.io](https://jacobgil.github.io/deeplearning/pruning-deep-learning)**

调整学习率

正如您可能从自己的神经网络冒险经历以及其他文章和研究文献中认识到的那样,学习率是神经网络训练的一个非常重要的部分。

学习速率本质上决定了网络学习的“速度”,它决定了运动的步长。更高的学习速率导致更快的学习,但是收敛更困难并且通常不稳定。较小的学习速率导致较慢的学习,并且尽管收敛是可能的,但它可能仅在过多的时期之后发生,这在计算上是低效的。

显然,对于给定的神经架构,在这两者之间有一个最佳点——这是唯一的,并且是神经损失表面的函数。然而,由于我们正在训练网络,神经架构是动态的,并且不断变化,从而导致最佳学习速率的失真。除了这种时间依赖性之外,最佳点还具有空间依赖性,因为损失表面上的某些位置可能具有非常陡或非常浅的梯度,这使得问题更加复杂。

那么,我们如何选择一个能给我们带来最佳效果的学习速率呢?显然,我们可以使用一个恒定的学习速率,但是如果我们这样做,当我们达到次优的结果时,我们不能抱怨。

获得更好结果的唯一方法是使用动态学习速率,该速率试图利用最佳学习速率的空间和时间变化。这不是一项简单的任务,但是已经开发了几种技术来完成这项任务。

神经网络的循环学习率

周期性学习率是不言自明的,它们本质上是振荡的——它们来回振荡。循环学习率的主要用途是避免局部极值点,尤其是尖锐的局部极小值(过拟合)。鞍点在高维度中是丰富的,收敛变得非常慢,如果不是不可能的话。因此,如果我们使用纯粹递减的学习速率,很容易陷入单一位置,尤其是在更高维度。

*循环学习率周期性地提高学习率。这有短期的负面影响,但有助于实现长期的有益效果。*

降低学习速度仍然有助于减少错误。这可以通过使用阻尼循环学习率来实现,该学习率随着时间慢慢衰减到零。

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

Examples of cyclical learning rates

虽然这是一个很好的想法,但它没有告诉我们应该设置什么样的学习率方案以及这些学习率的大小。

估计学习率

怎样才能得到一个好的学习率估计值?这看起来很复杂,但实际上并不太难。

首先,我们可以从一个小的学习率开始,然后在每一批中成倍地增加。同时,我们可以计算验证集的损失函数。这也适用于寻找循环学习率的界限。

下图显示了作为时期函数的指数增长的学习率。

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

Exponentially increasing learning rate across epochs.

同时,我们计算每个学习率的损失函数。

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

Loss function as a function of learning rate.

我们可以看到,在这两个极端之间有一个悬崖区域,在这个区域中,学习在稳定地减少和稳定地发生。这是我们希望在培训过程中确保我们留在的地区。

带热重启的 SGD

热重启是一个非常简单的想法:在指定的次数后重启学习。例如,学习率最初从 0.1 开始,随时间呈指数下降。在 30 次迭代之后,学习率调度器将学习率重置为与时段 1 相同的值,然后学习率调度器重复相同的指数衰减。每次在重置学习率之前记录最佳估计值。

这个想法类似于循环学习率,除了学习率图通常看起来更像锯齿波,而不是对称和循环的。

需要注意的是,重新开始不是从零开始,而是从最后一次估计开始,并且学习率增加。因此,重启提供了与循环学习率相同的大部分好处,例如能够避开极端的局部极小值。

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

Warm restarts with cosine annealing done every 50 iterations of Cifar10 dataset.

快照集:培训 1,免费获得 M

快照集是一个很棒的主意,如果你感兴趣,我建议你阅读一下的研究论文

集合网络比单个网络更加健壮和精确。它们构成了另一种类型的正则化技术。新颖之处在于训练单个神经网络,但获得 M 个不同的模型。想法是收敛到 M 不同的局部最优值并保存网络参数。

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

Left: Illustration of SGD optimization with a typical learning rate schedule. The model converges to a minimum at the end of training. Right: Illustration of Snapshot Ensembling. The model undergoes several learning rate annealing cycles, converging to and escaping from multiple local minima. Source.

对于那些经验丰富的数据科学家来说,您可能还记得,开发用于分类目的的集成或混合模型通常会提供优于任何单个模型的结果,尽管要确保这一点需要几个要求,例如模型之间相对较高的相关性。这在某种程度上只是该技术在神经网络上的延伸。

那么它是如何工作的呢?

在每个训练周期结束时,模型达到关于训练损失的局部最小值。因此,在提高学习率之前,我们对模型权重进行“快照”。训练完 M 个周期后,我们有 M 个模特快照, f₁,f₂,.。。,每一首都会用在最后的合奏中。在集合模型中,我们取所有快照的平均值,并使用它来获得我们的结果,实现具有平滑参数的神经网络,从而减少总噪声,并因此减少总误差。

需要强调的是, M 快照的总训练时间与使用标准时间表训练模型的时间相同。这意味着我们有一个简单的方法来获得神经网络的集合,而不需要任何额外的训练成本**。**

然而,快照集不是完美的,可以选择不同的初始化点或超参数选择,这可能收敛到不同的局部最小值。尽管这些局部最小值在平均误差方面表现相似,但它们可能不会犯同样的错误。

集成方法训练许多神经网络,然后通过多数投票或平均预测输出进行优化-这与平均权重并使用这些权重进行预测相反。最终集合由优化路径的快照组成。

下面的结果显示了用于测试神经网络模型的几个公共数据集上的快照集成的结果。

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

Error rates (%) on CIFAR-10 and CIFAR-100 datasets. All methods in the same group are trained for the same number of iterations. Results of the ensemble method are colored in blue, and the best result for each network/dataset pair are bolded.

从结果可以清楚地看出,快照集合性能优于标准模型,以及循环集合和丢弃模型。

Polyak-Ruppert 平均法

鉴于快照集和 Polyak 平均之间的相似性,我认为最好包括这一点。Polyak 平均是解决刺激快照集使用的不稳定学习问题的另一种方法。该消息使用在训练运行接近结束时看到的多个模型的平均重量。

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

The motivation behind Polyak averaging — gradient descent with a large learning rate is unable to converge effectively to the global minimum.

假设在 t 迭代中,你有参数θ,θ等。然后,我们可以对这些参数进行时间平均,以获得真实参数的更平滑的估计值。

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

这可以通过几种不同的方式加以利用:

  • 在接近训练运行结束的几个不同时期使用来自相同模型的权重(如上所述)。
  • 将来自多个模型的权重用于它们各自的训练运行(整体平均而不是时间平均)。
  • 使用来自快照的权重,然后平均这些权重用于集合预测(集合和时间平均的混合方法)。

Polyak 平均保证在凸环境下强收敛。然而,在非凸曲面中(通常是这种情况),参数空间在不同区域会有很大不同。在这种情况下,平均就没那么有用了。在这种情况下,通常考虑指数衰减平均值:

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

根据所选的α值,将额外的权重放在最新的参数值或较旧的参数值上,由此较旧参数的重要性随时间呈指数衰减。

希望您清楚 Polyak 平均和快照集之间的区别和相似之处。它们只是平滑明显存在于神经网络的不稳定学习过程中的随机误差的不同方式。

在此可以找到应用于神经网络的 Polyak 平均的一个很好的演示:

** [## 如何在 Keras (Polyak 平均)中计算神经网络模型权重的集合

神经网络的训练过程是一个具有挑战性的优化过程,经常无法收敛。这可以…

machinelearningmastery.com](https://machinelearningmastery.com/polyak-neural-network-model-weight-ensemble/)**

如何解决过度拟合

深度神经网络中的过度拟合是如此普遍,以至于你永远无法真正相信你从一个经过训练的网络中获得的结果是最佳结果。鉴于它们的普遍存在,我们将研究一些方法来解决神经网络中的过度拟合问题。

估算师

点估计是试图对一些感兴趣的量提供单一的“最佳”预测:

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

从频率主义者的角度来看,θ是固定的但未知的,数据是随机的。这意味着我们的估计量是一个随机变量。每个随机变量都容易受到偏差和方差的影响。

  • ****偏差:预期值与真实值的偏差。
  • ****方差:与预期估计值的偏差。

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

诊断偏差-方差

那么我们如何在神经网络中分析这种偏差-方差权衡呢?

在高维空间中,我们不能绘制决策曲线来检验偏差-方差。相反,我们通过计算错误值来推断训练集和验证集的错误来源。为了确定偏差,我们需要一个基线,比如人类水平的表现。

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

****贝叶斯错误率是随机结果的任何分类器的最低可能错误率,类似于不可约误差。对于所有的意图和目的,贝叶斯误差是我们从一个完美的模型中剔除所有可避免的偏差和方差后所能获得的最小误差。

我们可以分析和比较训练集和验证集上的错误,以推断错误的原因,无论它是由于可避免的偏差还是可避免的方差(我们不太可能获得贝叶斯错误率)。

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

正交化是我们可以使用的另一种技术;它旨在分解过程以调整神经网络性能。它假设误差来自不同的来源,并使用系统化的方法来最小化它们。

Mc.ai 对这个用来调谐收音机的旋钮有一个奇妙的比喻。收音机的设计者努力确保一个特定的旋钮控制信号的一个特定方面,如音量或频率。如果没有多个参数同时变化,调谐到特定的无线电频率并获得您想要的声音会容易得多。

早期停止也是一种流行的正则化机制,但是耦合了偏差和方差误差。

减少偏差的其他更明显的方法是训练更大的模型(增加模型的可解释性),训练更长的时间(达到收敛),或者调整神经架构或执行广泛的超参数搜索。

减少方差的明显方法是获得更多的数据,使用正则化机制(早期停止是一种流行的正则化技术,它结合了偏差和方差误差)。

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

能够分析网络结果并确定问题是由偏差还是变化引起的,这对于排除网络故障以及提高网络性能非常有帮助。例如,如果您正在努力解决差异问题,并试图运行网络更多的纪元,这显然不会有所帮助。然而,在这种情况下,添加更多的数据或正则化是更谨慎的方法。

辍学

到目前为止,与我在本文中讨论的其他项目相比,你们中的大多数人可能更熟悉辍学。辍学很容易实现,但更难掌握其背后的哲学。

Dropout 是深度神经网络的一种正则化技术。它在训练时使用,随机消除一些单元的输出。这有助于防止网络过于依赖单个神经元,从而有助于防止过度拟合。相反,这些知识被传播到所有的神经元上,以帮助获得一个更健壮的网络。在测试时,所有的神经元都存在,并且它们的触发概率是成比例的,因为在训练时存在比以前更多的神经元。

丢弃可以与其他正则化技术(如 L2、批量归一化等)结合使用。).

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

****目的:防止特征检测器对一组神经元的共同适应,避免过拟合。

  • 它迫使神经元在给定的总体群体行为下,独立地发展个体角色。
  • 训练权重被鼓励分布在神经网络中,因为没有神经元是永久的。

****解释:训练示例提供来自不同的、随机采样的架构的梯度。

直接实施:

  • 训练时:随机消除一些单位的输出。
  • 测试时:所有单元都存在。

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

反向辍学

对于测试时的正常退出,你必须通过退出率 p 来调整激活,因为你没有退出任何神经元,所以你需要在训练时匹配期望值。

**对于反向丢失,缩放在训练时应用,但反之亦然。首先,通过丢失因子 p,丢失所有激活,其次,通过反向丢失因子 1/p 缩放它们。

倒辍有一个好处,就是你在测试的时候什么都不用做,这样推理起来更快。

由于这种更快的推断,大多数当前的实现使用反向下降:

  • 在训练期间进行加权。
  • 测试时不需要重新称重。

特别地,对于层 l

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

Inverted dropout — weights are scaled at training time as opposed to testing time, the opposite of traditional dropout.

初始化策略

神经网络的权重初始化已经在我的一些其他文章中讨论过了,但是在这里有必要简单地重申一下。

在具有小学习率的凸问题中,无论什么初始化,收敛都是有保证的(尽管可能很慢)。

然而,在非凸区域初始化更为重要。一些参数初始化可能不稳定,并且可能不收敛。神经网络没有被很好地理解为具有原则性的、数学上很好的初始化策略,因此经常使用试探法来选择一组合理的起始权重,从这些权重中训练网络。

对于具有 m 个输入和 n 个输出的全连接层,我们可以从以下均匀分布中进行采样,以获得我们的初始权重:

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

或者,流行的 Xavier 初始化使用以下参数进行均匀分布。

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

Xavier 初始化是考虑到网络由没有非线性的矩阵乘法组成而导出的,并且在实践中似乎表现良好。

有关权重初始化方案的完整列表,请查看 Keras 文档的初始化器部分这里。有一打或两个初始化器,也可以使用你自己的自定义初始化器。请参见进一步阅读部分的参考资料。

最终意见

感谢您的阅读,我希望您发现这篇文章很有见地。如果你喜欢这篇文章,请留意我将来关于神经网络的文章。

其他与全连接神经网络相关的高级主题,我将在未来的文章中涉及,读者可能会感兴趣:

  • 批次/层/实例/组规范化
  • 张量处理单元
  • 下拉连接
  • 部分池化
  • 随机深度
  • 断流器
  • 混合
  • 明凯/MSRA 初始化

时事通讯

关于新博客文章和额外内容的更新,请注册我的时事通讯。

** [## 时事通讯订阅

丰富您的学术之旅,加入一个由科学家,研究人员和行业专业人士组成的社区,以获得…

mailchi.mp](https://mailchi.mp/6304809e49e7/matthew-stewart)

进一步阅读

神经网络重要文章

修剪文章

重量初始化

  • 理解训练深度前馈神经网络的困难。
  • Saxe 等人在 2013 年提出的深度线性神经网络中学习的非线性动力学的精确解。
  • Sussillo 和 Abbott 2014 年为训练非常深的前馈网络进行随机行走初始化。
  • 深入研究整流器:在 ImageNet 分类上超越人类水平的性能,何等,2015。
  • krhenbüHL 等人,2015 年,卷积神经网络的数据相关初始化。
  • 你需要的只是一个好的 init,Mishkin 和 Matas,2015。
  • 修正初始化:无归一化的残差学习,张等,2019。
  • 彩票假说:寻找稀疏、可训练的神经网络,Frankle 和 Carbin,2019 年。**

如何建立一个先进的推荐引擎

原文:https://towardsdatascience.com/advanced-use-cases-for-recommendation-engines-4a420b14ab4e?source=collection_archive---------4-----------------------

当快速简单的协同过滤已经不够好的时候该怎么办。

知道你的起点

重要的是要记住,你不应该从推荐引擎的高级用例开始。在快速简单地实现版本 1 之后,你的推荐引擎变得非常适合你的业务问题、产品和用户。为了构建这样一个定制的模型,您将需要来自版本 1 的反馈循环和基线来决定您的推荐引擎的改进方向。对于定制的解决方案,敏捷是成功实现这一目标的最佳方法。实际上,这意味着在您开始任何版本 2 的工作之前,您已经构建了版本 1.1、1.2 和 1.3。

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

[OC]

对于第 1 版推荐引擎,根据您的起点,您有多种选择:

  • 如果您了解您的产品或者您的产品有丰富的元数据,您可以首先构建一个简单的规则引擎来捕获业务逻辑。考虑到敏捷和实用的交付焦点,知道什么时候不需要机器学习是很重要的。
  • 如果您碰巧也认识您的用户,那么您甚至可以使用一些基本的用户细分来个性化您的规则引擎,例如 RFM。
  • 但是大多数时候你对你的用户和产品不够了解,甚至一无所知。你所拥有的只是来自用户与你的网站或产品互动的行为点击流数据。在这种情况下,您应该考虑使用协同过滤来构建您的第 1 版推荐引擎。此使用案例在中有详细说明:

[## 如何快速简单地构建推荐引擎

第 1 部分:简介,如何在一周内投入生产,之后去哪里

towardsdatascience.com](/how-to-build-a-recommendation-engine-quick-and-simple-aec8c71a823e)

您迈向版本 2 的道路

祝贺您,在您部署了推荐引擎的第 1 版之后,是时候庆祝您的成就了!你的第一个推荐引擎已经上线了,它的表现足够好,利益相关者希望你改进它,而不是让它下线。🎉

不幸的是,对于如何从这里改进你的推荐引擎,没有什么灵丹妙药。你将慢慢地构建一个高度定制的解决方案,而现实中的成功之路看起来更像是一场火的洗礼。你将通过大量的实验和从失败中学习来交付解决方案。),可能是迫于利益相关者、你的老板和愤怒的用户越来越大的压力。

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

[OC]

您将在版本 1 中面临的问题:

  • 新内容和用户的冷启动问题
  • 偏向于点击诱饵内容:良好的响应指标,随后在漏斗中急剧下降
  • 您的建议在质量和数量之间难以取舍
  • 巴特 UX
  • ETL 和 elasticsearch 集群的昂贵费用

让我们看看我们在第 1 部分中实际构建了什么,以及它与更复杂的推荐系统相比如何:

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

[OC]

我们从最简单的模型开始:基于项目到项目共现的推荐引擎。就如何解释分数而言,这个模型非常类似于一个分类器,我们距离个性化的项目排名还有很长的路要走。这是一个常见的误解,当将推荐整合到产品中时,假设分数反映了个性化的排名或考虑/相关性分数,这可能会损害用户体验。

使您的模型有状态,以获得更好的模型评分

如果你按照前面的步骤用 Elasticsearch 构建了一个快速简单的协同过滤推荐系统,那么你的第 1 版模型可能并不完美,但在某种程度上是可行的。在改变整个实现之前,尝试简单地改进当前版本的评分请求可能是值得的。

你在第 1 部分中构建的是一个无状态模型。无状态模型不记得也不关心之前的事件。每个用户交互和评分请求都是完全独立的。因此,无状态模型非常容易管理,例如,允许在简单的负载平衡器后面进行水平扩展。

这提供了第一个明显的改进:将一个状态合并到您的模型中。用户与网站上的一系列产品和内容进行互动。向您的模型添加一个状态内存允许您使用一个交互系列为用户查询 Elasticsearch,这扩展了匹配的可能性。一方面,您可以简单地使用它来扩展前台数据集中潜在的同现数量。另一方面,您可以在更复杂的规则中使用它来过滤相关的推荐,例如删除用户以前已经看过的推荐。

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

[OC]

但是,您希望避免向模型本身添加状态。理想情况下,您总是将状态管理器从模型的其余部分中分离出来。状态管理器应该是一个独立的微服务,它使用某种形式的缓存来丰富来自网站或应用程序的无状态传入请求。将状态作为独立的微服务来管理是一个很好的设计原则,也是我之前在博客中提到的 Rendezvous 架构设计的一部分(我在那篇博客中称之为模型数据丰富器):

[## 生产中数据科学的会合体系结构

如何构建一个前沿的数据科学平台来解决数据科学中的真正挑战:生产化。

towardsdatascience.com](/rendezvous-architecture-for-data-science-in-production-79c4d48f12b)

Redis 是处理推荐系统状态的一个很好的解决方案。它速度快,重量轻,在任何云中都是完全托管的服务,例如 Redis 的 AWS ElasticCache。下面的代码使用一个滑动窗口 TTL 来存储用户交互,并自动从缓存中删除旧的交互。请随意根据您的需求进行调整:

[## 简·泰希曼/ redis_user_interaction_cache

GitLab.com

gitlab.com](https://gitlab.com/jan-teichmann/redis_user_interaction_cache)

这个选项的好处:你获得了更大数量的同现信号,并且有机会过滤掉用户已经看过的推荐。这可以在不增加额外工作的情况下提高数量和质量。

这个选项的缺点:不要期待奇迹:你仍然只是用同样的原始数据工作。回报是递减的,你能从同样的数据中获得的附加值也是有限的。

添加越来越多的数据

因为你只能从相同的数据中获得如此多的额外价值,所以我们有另一个明显的方法来改进我们的推荐系统。你的用户可能会以多种不同的方式与你的网站、应用和产品互动:

  • 搜索产品
  • 查看产品详情
  • 购买产品和退货
  • 评价和分享产品
  • 参与营销,使用折扣代码

你的推荐引擎的第一个版本只使用了一个用户交互,并且基于隐式反馈来最大化推荐质量的信号量。加入额外的数据是值得的,特别是为了提高推荐的质量和获取所需的业务逻辑。

最简单的选择是,按照与第一个指标完全相同的逻辑,向现有的 Elasticsearch 集群添加一个额外的文档类型。Elasticsearch 中的文档类型类似于 RDBs 中的表。然后,对每种文档类型分别运行两个并行查询,这两个查询可以独立调整,以反映度量的质量。您可以通过调整 Elasticsearch 的 significant_terms 聚合中的“min_doc_count”设置或切换用于定义重要推荐的统计数据来实现这一点。您可以阅读文档中的可用选项,并查看我的另一篇文章中的代码示例:

[## 如何快速简单地构建推荐引擎

第 1 部分:简介,如何在一周内投入生产,之后去哪里

towardsdatascience.com](/how-to-build-a-recommendation-engine-quick-and-simple-aec8c71a823e)

此选项的优势:易于实施,因为您只需重新利用现有的解决方案和代码,将额外的数据作为独立的文档类型接收。这为在弹性搜索推荐的基础上构建复杂的规则引擎提供了广泛的选择,以纳入所需的业务逻辑,例如,对促销的偏好。

这个选项的缺点:增加了弹性搜索集群的成本。

随着您向模型中添加越来越多的指标,您将会注意到,不仅您的 Elasticsearch 集群的成本失控,您的规则引擎中处理信号的时间和 CPU 资源也同样急剧增加。您的规则引擎将信号转换成最终的建议开始变得非常复杂。对规则引擎的回顾可能会得出这样的结论:您正在处理数据之间的复杂关系,对于这些用例有更好的解决方案:可能是时候考虑一个图形数据库了!

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

Apache Tinkerpop 3 logo. Fair usage

图形数据库是高度相关数据的完美解决方案,例如大量的关系以及复杂的关系。graph DB 将这些关系具体化为图中的边,从而大大加快了基于数据(节点)之间的关系的查询速度,而不是在每个查询中动态地解决这些关系。graph DBs 有许多供应商,给出任何建议都超出了这篇博客的范围。这可能是一篇即将发表的博文的主题。

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

Taken from the Apache Tinkerpop documentation: https://tinkerpop.apache.org/docs/current/tutorials/the-gremlin-console/ Fair usage

此选项的优势:可以快速处理复杂的关系,用复杂的业务逻辑打开复杂的用例。

这个选项的缺点是:你必须将你的推荐逻辑转换成图形查询。

改善您的用户定义

协同过滤建立在用户交互数据中的共现之上。如果你的企业没有一个强大的单一用户定义,那么就很难创建一个好的记录长期用户交互的历史矩阵。

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

Recreation of illustration in “Practical Machine Learning, Ted Dunning & Ellen Friedman, O’Reilly 2014

结果,在根据用户交互的历史建立的同现矩阵中将有少得多的信号。

当您的用户使用多种设备,并且没有动力创建帐户或登录以使用您的服务时,可能会出现这种情况。如果你的网站上有很大比例的匿名流量,那么看看一个概率模型来识别一段时间内跨设备的单个用户是值得的。

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

Public domain image, Pxhere

Gartner 将跨设备识别(XDID)称为值得关注的新兴技术,数据科学可以提供帮助。识别用户的不同选项有:帐户登录、Cookie 识别、设备指纹识别和 IP 匹配。

IP 匹配是较低质量的概率选项,用于识别单个用户。然而,IP 是跨设备可用的。与 4G 网络或公共 Wifi 一样,动态共享 IP 也存在问题。无论如何,IP 是最可行的选择。我写了一整篇关于使用 IP 和时间戳的图表来匹配单个用户和 Spark 的 GraphX 引擎的文章:

[## 使用 GraphX 跨设备为匿名用户匹配单个用户标识

如何实现概率会话相似性来为跨设备和匿名用户创建单个用户 ID…

towardsdatascience.com](/single-userid-matching-for-anonymous-users-across-devices-with-graphx-72fe111ac44b)

这个选项的好处:跨设备匹配单个用户可以显著提高同现信号的质量,并且具有远远超出单独推荐的用例。

这个选项的缺点:单用户匹配本身就是一个复杂的话题。这既是一个有趣的数据科学问题,也是一个难以解决的数据工程挑战。

批量计算信号

到目前为止,我们一直使用 Elasticsearch 作为后端,实时计算推荐信号。这在建议路线图的早期阶段很有价值,可以进行灵活的实验,例如在数量和质量之间进行权衡。以这种方式使用 Elasticsearch 的缺点是每个查询都有很大的 CPU 开销。如果协同过滤对您的使用情况很有效,那么最好选择一个更好的协同过滤算法,并批量计算推荐信号,而不是匆忙计算。这样,我们只将 Elasticsearch 作为向用户提供推荐的表示层。

我们可以简单地批量计算项目-项目共现信号。这可以通过 CLI 中存在的 Mahout 的 spark-itemsimilarity 实现来完成。这使得调用 Mahout 库中的 spark 程序并为其提供相关数据的路径变得非常简单。你可以在 Mahout 网站上找到详细的文档。您还可以看到 Mahout 的解决方案架构与我们的相似之处。我们使用 Elasticsearch 而不是 Solr 和 Redis 作为用户交互的缓存。其余部分遵循完全相同的解决方案架构。

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

https://mahout.apache.org/docs/latest/algorithms/recommenders/

**spark-itemsimilarity Mahout 1.0****Usage: spark-itemsimilarity [options]****Input, output options**-i <value> | --input <value>Input path, may be a filename, directory name, or comma delimited list of HDFS supported URIs (required)-i2 <value> | --input2 <value>Secondary input path for cross-similarity calculation, same restrictions as "--input" (optional). Default: empty.-o <value> | --output <value>Path for output, any local or HDFS supported URI (required)**Algorithm control options:**-mppu <value> | --maxPrefs <value>Max number of preferences to consider per user (optional). Default: 500-m <value> | --maxSimilaritiesPerItem <value>Limit the number of similarities per item to this number (optional). Default: 100Note: Only the Log Likelihood Ratio (LLR) is supported as a similarity measure.**Input text file schema options:**-id <value> | --inDelim <value>Input delimiter character (optional). Default: "[,\t]"-f1 <value> | --filter1 <value>String (or regex) whose presence indicates a datum for the primary item set (optional). Default: no filter, all data is used-f2 <value> | --filter2 <value>String (or regex) whose presence indicates a datum for the secondary item set (optional). If not present no secondary dataset is collected-rc <value> | --rowIDColumn <value>Column number (0 based Int) containing the row ID string (optional). Default: 0-ic <value> | --itemIDColumn <value>Column number (0 based Int) containing the item ID string (optional). Default: 1-fc <value> | --filterColumn <value>Column number (0 based Int) containing the filter string (optional). Default: -1 for no filterUsing all defaults the input is expected of the form: "userID<tab>itemId" or "userID<tab>itemID<tab>any-text..." and all rows will be used**File discovery options:**-r | --recursiveSearched the -i path recursively for files that match --filenamePattern (optional), Default: false-fp <value> | --filenamePattern <value>Regex to match in determining input files (optional). Default: filename in the --input option or "^part-.*" if --input is a directory**Output text file schema options:**-rd <value> | --rowKeyDelim <value>Separates the rowID key from the vector values list (optional). Default: "\t"-cd <value> | --columnIdStrengthDelim <value>Separates column IDs from their values in the vector values list (optional). Default: ":"-td <value> | --elementDelim <value>Separates vector element values in the values list (optional). Default: " "-os | --omitStrengthDo not write the strength to the output files (optional), Default: false.This option is used to output indexable data for creating a search engine recommender.Default delimiters will produce output of the form: "itemID1<tab>itemID2:value2<space>itemID10:value10..."**Spark config options:**-ma <value> | --master <value>Spark Master URL (optional). Default: "local". Note that you can specify the number of cores to get a performance improvement, for example "local[4]"-sem <value> | --sparkExecutorMem <value>Max Java heap available as "executor memory" on each node (optional). Default: 4g-rs <value> | --randomSeed <value>-h | --helpprints this usage text

此选项的优势:更便宜的批量评分版本,同时仍然易于使用和操作。

这个选项的缺点:没有太多的灵活性和复杂性。这将使您的弹性搜索成本得到控制,但不会提高您的推荐的性能,如果这是您的版本 1 实施的一个问题。

使用潜在因素模型改进您的算法选择

在我们决定批量创建我们的推荐之后,我们将模型的训练、评分和服务分离为多个步骤。这也为我们研究更复杂的推荐算法打开了大门,而不仅仅是我们目前使用的基于共现的模型。下一步将是使用矩阵分解的基于潜在因素模型的推荐系统。

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

[OC]

潜在因素模型将允许我们创建(1)使用产品因素相似性的项目-项目模型和(2)项目-用户模型。

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

[OC]

批量潜在因素模型的一个好的解决方案是 Spark 中的 ALS(交替最小二乘法)实现,这是一种用于推荐引擎的矩阵分解技术。它被称为交替最小二乘法,因为该算法分别在改善项目和用户因子之间交替:该算法首先固定用户因子,然后对项目因子运行梯度下降。然后,它切换和固定项目因素,以改善用户因素。ALS 算法具有很强的可扩展性,可以以分布式方式并行运行,并使用 Spark ML 非常高效地处理大型数据集。

你可以在文档中找到一个用 Spark ML 实现 ALS 的例子。我们仍然使用前面讨论过的相同的解决方案架构,Spark ML 提供了为用户项目模型创建建议的方法。

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

[OC]

但是,我们必须编写一些自定义代码来计算一个项目-项目模型的产品因素的相似性。计算产品之间所有对的相似性不适用于大型产品目录。不断增长的组合数量 O(n^2) 很快导致代价过高的洗牌操作和不可行的计算时间。Spark 提供了一个使用位置敏感散列法 ( LSH )的解决方案,这是一个更加有效的识别近似最近邻居的方法。LSH 使用一种特殊的哈希函数来降低数据的维度,同时数据越相似,哈希冲突的可能性就越大。这意味着相似的数据可能会出现在同一个存储桶中,而不会出现在具有不同数据的存储桶中。LSH 是一种概率近似值,它提供了速度和准确性之间的权衡。对于我们的项目-项目推荐模型的项目潜在因素的聚类问题,我们使用 随机投影 作为我们的散列函数,其近似为余弦相似度用于我们的产品向量的分块。

以下代码是一个使用 Spark ML ALS 进行协同过滤和 LSH,根据项目相似性创建项目-项目模型的示例:

import pyspark.sql.functions as F
from pyspark.ml.evaluation import RegressionEvaluator
from pyspark.ml.recommendation import ALS
from pyspark.sql import Row# ALS Example from the Spark Documentationlines = spark.read.text("sample_movielens_ratings.txt").rdd
parts = lines.map(lambda row: row.value.split("::"))
ratingsRDD = parts.map(
    lambda p: Row(
        userId=int(p[0]), movieId=int(p[1]),
        rating=float(p[2]), timestamp=int(p[3])
    )
)ratings = spark.createDataFrame(ratingsRDD)
(training, test) = ratings.randomSplit([0.8, 0.2])

# Build the recommendation model using ALS on the training data
# Note we set cold start strategy to 'drop' to ensure we don't get NaN evaluation metricsals = ALS(
    maxIter=5, regParam=0.01, userCol="userId", itemCol="movieId", 
    ratingCol="rating", coldStartStrategy="drop"
)
model = als.fit(training)# Evaluate the model by computing the RMSE on the test data
predictions = model.transform(test)
evaluator = RegressionEvaluator(
    metricName="rmse", labelCol="rating", predictionCol="prediction"
)
rmse = evaluator.evaluate(predictions)
# Root-mean-square error = 1.7866152217057665**####################################################
# User-Item model predictions using latent factors #
####################################################**# Generate top 10 movie recommendations for each user
userRecs = model.recommendForAllUsers(10)
# Generate top 10 user recommendations for each movie
movieRecs = model.recommendForAllItems(10)
userRecs.show(1, False)
“””
+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|userId|recommendations                                                                                                                                                      |
+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|28    |[[12, 4.987671], [81, 4.968367], [92, 4.862609], [31, 4.0329857], [49, 4.024806], [2, 3.8403687], [82, 3.7117398], [62, 3.4866638], [61, 3.4003847], [24, 3.1223223]]|
+------+-------------------------------------------------------------
“””**#####################################################
# Item-Item Model based on latent factor similarity #
#####################################################**from pyspark.ml.feature import BucketedRandomProjectionLSH
from pyspark.ml.linalg import Vectors, VectorUDTvector_udf = F.udf(lambda l: Vectors.dense(l), VectorUDT())itemFactors = model.itemFactors.withColumn(
    'itemVector', vector_udf(F.col('features'))
)brp = BucketedRandomProjectionLSH(
    inputCol="itemVector", outputCol="hashes", bucketLength=2.0,
    numHashTables=3
)# Hashes of factors match with a probability proportional to their
# cosine similarity
brp_model = brp.fit(itemFactors)recommendations = (
   brp_model
    .approxSimilarityJoin(itemFactors, itemFactors, 2.0,
         distCol="dist")
    .select(
        F.col("datasetA.id").alias("idA"),
        F.col("datasetB.id").alias("idB"),
        F.col("dist")
    )
    .filter('idA != idB')
    .withColumn('recommendation', F.concat_ws('-',
        F.when(F.col('idA') < F.col('idB'),
        F.col('idA')).otherwise(F.col('idB')),
        F.when(F.col('idA') < F.col('idB'),
        F.col('idB')).otherwise(F.col('idA')))
    )
    .select('recommendation', 'dist').distinct()
    .orderBy(F.col('dist'))
)recommendations.show()
“””
+--------------+------------------+
|recommendation|              dist|
+--------------+------------------+
|         15-99|0.6752175108957209|
|         78-86| 0.766118452902565|
|         17-46|1.1002650472525193|
|         15-97|1.1036687784393326|
|         15-78|1.1089519518538236|
“””

完整的代码示例可在此处找到:

[## Spark ALS 项目-项目相似性(1915919 美元)片段

GitLab.com

gitlab.com](https://gitlab.com/snippets/1915919)

此选项的优势:更便宜且可扩展的批处理模型,同时提供用户-项目和项目-项目模型。

这个选项的缺点:更复杂的模型,有更多的超参数来调整 ALS 和 LSH。

为您的数据和模型找到更多应用

迄今为止,你的模型产生了一些建议,但这不一定是使用你的行为数据和潜在因素模型的唯一方式。你的公司可能有一个客户关系管理或营销团队,他们会喜欢一些细分作为他们的目标。行为数据可以成为产品和用户细分的真正资产。

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

[OC]

你可以在我之前关于这个主题的文章中读到关于使用你当前推荐引擎的数据和算法进行细分的内容:

[## 人工智能符合营销细分模型

新的黄金标准:使用机器学习从行为数据中获得用户和产品分类,为一个…

towardsdatascience.com](/data-science-powered-segmentation-models-ae89f9bd405f)

这个选择的好处:你让更多的利益相关者参与进来,并且用你的模式创造更大的商业影响。这降低了企业搁置项目的可能性。

这个选项的缺点:你有更多的涉众参与到他们独特的需求和不断增长的改进压力中。数据科学团队需要能够随着需求的增长而扩展。

取代协同过滤作为您的算法

协同过滤一直是一个强大的推荐算法,因为我们不需要了解我们的产品或用户。一方面,我们仅基于显式或隐式反馈来学习推荐。但另一方面,每个推荐都与特定的产品或用户相关联。这有一些缺点:

  • 冷启动:任何新产品或新用户都需要反馈,我们才能开始推荐。
  • 所有项目完全独立。红苹果和绿苹果在协同过滤中不共享任何反馈或共现信号,即使它们在产品空间中概念上相似。
  • 当产品从目录中删除时,我们也失去了针对该产品的所有信号和指标。

为了克服这些问题,我们必须将我们的建议的信号和指标与能够比产品或用户本身寿命更长的功能联系起来,并在更广泛的类似产品和用户中推广。我们需要积累关于我们产品和用户的功能和知识:

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

[OC]

构建描述产品的特性通常比描述用户更容易:

  • 使用计算机视觉对产品图像进行指纹识别
  • 使用 NLP 主题建模、单词和文档向量嵌入产品描述
  • 地理位置产品的地理区域嵌入(活动、门票、物业列表)
  • 产品元数据,如价格、尺寸、重量、类别、关键词、季节、房产列表的卧室数量等。

我之前发表了一篇博文,讲述了使用搜索嵌入创建地理区域嵌入的一个很好的例子:

[## 位置位置位置

Zoopla.co.uk 大学使用机器学习(Skip-Gram)和一点黑魔法进行地理区域嵌入。

towardsdatascience.com](/location-location-location-ec2cc8a223b1)

在我们创建了广泛的特征来描述产品和潜在用户之后,我们可以使用神经网络来学习我们基于协同过滤的推荐和我们的新产品特征之间的信号。

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

[OC]

我们使用连体神经网络来学习产品或用户特征从项目嵌入空间推荐嵌入空间的映射。项目或用户的推荐嵌入具有比 NN 输入低得多的维度,并且具有通过推荐嵌入空间中的余弦相似性来测量的相似的期望行为。连体神经网络的特点是两个网络的权重相同,并且两个神经网络的梯度下降耦合在一起。在实践中,这是通过使用单个神经网络并依次对两个输入进行评分来实现的:

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

[OC]

我们使用余弦相似性作为我们的连体神经网络模型的输出:

[@staticmethod](http://twitter.com/staticmethod)
def pairwise_cosine_sim(y1, y2):
    """Calculates the pairwise cosine similarity.
    """
    y1_norm = tf.nn.l2_normalize(y1,1)        
    y2_norm = tf.nn.l2_normalize(y2,1)
    return tf.matmul(y1_norm, y2_norm, transpose_b=True)

除此之外,我们的神经网络和其他任何神经网络都没有太大区别。为了训练我们的暹罗神经网络,我们需要定义一个损失函数:对比损失优化一对输入之间的绝对余弦相似性,以最大化正对的余弦相似性,但最小化负对的相似性。

def contrastive_loss(cos_similarity, label, margin=1.0):
    """Contrastive loss function
    """
    distance = 1.0 - cos_similarity
    similarity = label * distance                                           
    dissimilarity = (1 - label) * tf.square(tf.maximum((margin - distance), 0))
    return 0.5 * tf.reduce_mean(dissimilarity + similarity)

裕度(在 0 和 2 之间)可以用作训练应该在多大程度上集中于改善配对的相似性而不是相异度的权重。

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

[OC]

我们还需要用于训练的标记数据。我们可以从版本 1 中使用的 Elasticsearch 集群中获取标签。前景中满足我们质量要求的项目是正对,而其他项目可以充当负对。

连体神经网络的训练循环非常简单:

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

epochs = 10
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
for epoch in range(epochs):
    accuracy = tf.keras.metrics.BinaryAccuracy()
    epoch_loss = tf.keras.metrics.Mean()
    for item_pairs, labels in ds_train:
        with tf.GradientTape() as tape:
            item_similarities = model(np.array(item_pairs[0]), np.array(item_pairs[1]))
            loss = contrastive_loss(item_similarities, tf.reshape(labels, (1,-1)), margin=1.0)
            grad = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(grad, model.trainable_variables))
        epoch_loss.update_state(loss)
        accuracy.update_state(tf.reshape(labels, (1,-1)), item_similarities)

    print(
        "Epoch {:03d}: Loss: {:.3f} Accuraccy: {:.3f}".format(
            epoch,
            epoch_loss.result(),
            accuracy.result()
        )    
    )

最终图显示了来自 Spark 示例电影镜头数据集的相似电影的训练 2D 推荐嵌入空间:

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

[OC]

此选项的优点:不再有冷启动问题!

这个选项的缺点:你需要广泛的有用的项目嵌入作为你的连体神经网络的输入。定义训练标签需要实验:对于您的业务问题,什么定义了一个好的正面或负面项目对?对比损失函数易于实现,但是正负项目对的不平衡可能需要切换到更复杂的损失函数,例如三重损失

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

Jan 是公司数据转型方面的成功思想领袖和顾问,拥有将数据科学大规模应用于商业生产的记录。他最近被 dataIQ 评为英国 100 位最具影响力的数据和分析从业者之一。

在 LinkedIn 上连接:https://www.linkedin.com/in/janteichmann/

阅读其他文章:【https://medium.com/@jan.teichmann】

无监督数据增强的半监督学习研究进展

原文:https://towardsdatascience.com/advancements-in-semi-supervised-learning-with-unsupervised-data-augmentation-fc1fc0be3182?source=collection_archive---------8-----------------------

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

Photo by @bhoogenboom

为什么对人工智能领域很重要?

在这篇文章中,我试图了解半监督学习(SSL)和无监督数据增强(UDA)的进展。首先通过不同的众所周知的机器学习技术。其次,通过阅读最近的一篇博文,以及一篇关于 Google AI 和 UDA 在 SSL 上的文章。

作为一名作家,我解释谷歌大脑成员的文章和谷歌人工智能的博客帖子,可能看起来像一个少年在评论一个职业运动队。如果你和我都是这种情况,我深表歉意,并恳请你的反馈。对我来说,写作是一个学习的过程。

从昨天开始,我表达了花三天时间试图理解三个问题的愿望。

第一天:谷歌如何成为人工智能领域的领跑者?(完成)

第二天:无监督数据增强(UDA)的半监督学习(SSL)取得了哪些进展,为什么它对人工智能领域很重要?

第三天:SSL 中静悄悄的革命是如何改变行业的?

今天是第二天,我将重点介绍 UDA 在 SSL 方面取得的进步,但首先我将开始解释机器学习中的三种主要技术。如果你对这个题目有所了解,你可以跳过第一部分,直接进入第二部分。

什么是无监督学习,监督学习,强化学习?

为了理解“半监督”,让我们首先简要地看一下非监督学习、监督学习强化学习。请注意,这里的大部分信息是从维基百科和其他一些地方编辑的版本,大部分是在媒体上研究数据科学的同行作者。这段文字只是为了给术语一个表面的理解。

无监督学习

无监督学习是一种有组织的 Hebbian 学习,有助于在没有预先存在的标签的情况下,在数据集中找到以前未知的模式。它也被称为自组织,允许模拟给定输入的概率密度。

如果这确实是一种希伯来人的学习,那意味着什么?

Hebbian 学习是最古老的学习算法之一,在很大程度上基于生物系统的动力学。当突触两侧的神经元(输入和输出)具有高度相关的输出时,两个神经元之间的突触得到加强。如果你想阅读更多,我建议你看一看 什么是赫比安学Prafful Mishra 撰写的关于这个话题的文章。

Hebbian 理论是一种神经科学理论,声称突触效能的增加源于突触前细胞对突触后细胞的重复和持续刺激。它试图解释突触可塑性,即学习过程中大脑神经元的适应。此外,如果你愿意,你还可以观看有关赫布三大假设的视频:

Thank you to Veer for sharing this video in the article Hybrid Model for Unsupervised Learning.

这个理论是由唐纳德·赫布在他 1949 年的著作《行为的组织》中提出的。这本书是人工神经网络(ANN)发展的基础的一部分。

在心理学中,它是关于哺乳动物大脑中神经元连接如何加强的假设;这也是一种在人工神经网络中选择权重的技术。算法可以更新现代人工神经网络中神经连接的权重。通过改变神经权重和关联,工程师可以从人工神经网络中获得不同的结果。

在赫比学习的风味中:(1) 无监督,权重通过对刺激的实际反应来加强,(2) 有监督,权重通过期望反应来加强。无监督的 Hebbian 学习(联想)具有权重变得任意大的问题,并且没有减少权重的机制。

退一步讲无监督学习是机器学习的三个主要类别之一,包括监督学习和强化学习。

无监督学习中使用的两种主要方法是:

  1. 主分量
  2. 聚类分析

主成分分析 ( PCA )是一种统计程序,它使用正交变换将一组可能相关的变量(每个变量取不同数值的实体)的观察值转换为一组线性不相关的变量值,称为主成分。

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

PCA of a multivariate Gaussian distribution centered at (1,3) with a standard deviation of 3 in roughly the (0.866, 0.5) direction and of 1 in the orthogonal direction. The vectors shown are the eigenvectors of the covariance matrix scaled by the square root of the corresponding eigenvalue, and shifted so their tails are at the mean.

聚类分析用于无监督学习,对具有共享属性的数据集进行分组或分段,以推断算法关系。聚类分析是机器学习的一个分支,它将尚未标记、分类或归类的数据分组。该分析识别数据中的共性,并基于每个新数据段中此类共性的存在或不存在做出反应。这种方法有助于检测不属于任何一组的异常数据点。

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

The result of a cluster analysis shown as the colouring of the squares into three clusters.

“聚类”的概念无法精确定义,这也是为什么有这么多聚类算法的原因之一。

无监督学习的一个主要应用是在密度估计领域。

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

Demonstration of density estimation using kernel smoothing: The true density is mixture of two Gaussians centered around 0 and 3, shown with solid blue curve. In each frame, 100 samples are generated from the distribution, shown in red. Centered on each sample, a Gaussian kernel is drawn in gray. Averaging the Gaussians yields the density estimate shown in the dashed black curve.

密度估计的一个非常自然的用途是在 非正式调查中对一组给定的数据 的性质。密度估计可以给出诸如数据中的偏斜度多模态等特征的有价值的指示。在某些情况下,他们会得出可能被认为是不言而喻正确的结论,而在其他情况下,他们所做的只是为进一步的分析和/或数据收集指明道路。

(1)偏度概率论与统计学中,偏度是一个实值随机变量的概率分布关于其均值的不对称性的度量。偏斜度值可以是正的或负的,也可以是未定义的。许多模型假设正态分布;即数据关于平均值对称。正态分布的偏斜度为零。但实际上,数据点可能不是完全对称的。因此,对数据集偏斜度的理解表明偏离平均值的偏差是正还是负。

法国数学家 benot Mandelbrot 或许可以解读对偏斜度的一个批评。他认为,现代金融和投资理论主体对正态分布的广泛依赖是任何相关模型的一个严重缺陷。他在一本书中解释了他的观点和替代金融理论:《市场的(错误)行为:风险、破产和回报的分形观》(发表于 2004)。我们当然可以问,这种批评是否可以扩展到人工智能领域的某些部分或某些机器学习技术。

(2)多模态在其最基本的意义上是一种交流和社会符号学理论。多模态从文本、听觉、语言、空间和视觉资源——或模式——的角度描述了用于撰写信息的沟通实践。

对于人工智能领域,多模态可能意味着使用机器学习技术一起解释不同的信号,如文本和图片。

科学出版商 IGI 全球对什么叫做 [进行了概述。什么是多模态?](http://-IGI Global)

模态,或者更明确地说,信息表示的模态,是在某种媒体中表示信息的一种方式[……]多模态允许同时综合使用各种形式的交互[……]多种类型的媒体数据,或者数据项的多个方面。它强调的是存在不止一种类型(方面)的数据。例如,一段数字广播新闻视频有多种形式,包括音频、视频帧、隐藏字幕(文本)等。

在统计学中多模态分布是具有两个或更多模态的连续概率分布。要获得更全面的解释,请查看 Purvanshi Mehta 的文章 多模态深度学习

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

A bivariate, multimodal distribution

Vishal Maini 在他关于无监督学习的文章中解释了无监督学习在人类机器学习中的效用(你可以阅读这篇文章以深入了解):

无监督学习经常被用来对数据进行预处理。通常,这意味着在将它输入到深度神经网络或另一个受监督的学习算法之前,以某种保留意义的方式压缩它,如 PCA 或 SVD。

当然,关于无监督学习的话题还有很多要说的,但是我们将继续讨论有监督学习。

监督学习

监督学习中,一个最佳方案将允许算法正确地为看不见的实例确定类别标签。

两个重要的方面一般说是分类和回归。

分类是识别一个新观察值属于哪一组类别(子群体)的问题。

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

Drawing from Manish Thapliyal article Machine Learning Basics Supervised Learning Theory Part-1

回归分析是一组用于估计变量间关系的统计过程。

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

Picture from Dataaspirant’s article from 2014 on the difference between classification and regression in machine learning.

根据 Stuart J. Russell、Peter Norvig (2010)在人工智能:现代方法: 监督学习中的说法,监督学习是学习一个函数的机器学习任务,该函数基于示例输入-输出对将输入映射到输出。

  1. 从带有训练示例的带标签的训练数据中获取函数。
  2. 每个例子都是一对(输入-输出)输入对象和输出值。
  3. 监督学习算法分析训练数据并产生推断函数。
  4. 推断的函数可用于映射新的示例。

还有比这些更经常传播或共享的步骤。

最佳方案将允许算法正确地确定不可见实例的类别标签。这需要学习算法以一种“合理”的方式从训练数据归纳到看不见的情况。

可能会有一个归纳偏差:学习者用来预测输出的一组假设,给定它没有遇到的输入。尽管大多数学习算法都有一个静态偏差,但一些算法被设计为在获取更多数据时改变其偏差。这并不能避免偏差,因为偏差转换过程本身必然存在偏差。偏见?

一些挑战可能是:

  • 偏差和方差权衡。几个不同但同样好的训练数据集。你应该让它灵活地适应数据吗?如果它太灵活,它可能不同地适合每个训练数据集。
  • 功能复杂度和训练数据量。具有高偏差和低方差的简单“不灵活”学习算法能够从少量数据中学习。高度复杂的函数将只能从非常大量的训练数据中学习,并使用具有低偏差和高方差的“灵活”学习算法。
  • 输入空间的维度。高维空间(100 或 1000)。空间的体积增加太多,数据变得稀疏。例如,计算优化问题中的每个值的组合。如果你想要一个神秘的倾斜,这一点可以被称为维度诅咒
  • 输出值中的噪声。如果期望的输出值经常不正确(由于人为错误或传感器错误),那么学习算法不应该试图找到与训练示例完全匹配的函数。可以通过提前停止和异常检测来减轻噪声(参见无监督学习)。
  • 数据的异质性。与同质性(相似性)相对的在特征或内容上多样的输入。
  • 数据中的冗余。对重复几次的信息给予更大的权重。这可能意味着在一个数据库中有两个不同的字段,或者在多个软件环境或平台中有两个不同的位置。积极的数据冗余可以保护数据并提高一致性
  • 存在相互作用和非线性。线性函数和距离函数决策树或神经网络的问题。如果每个特征对输出都有独立的贡献,那么第一个可能是(线性/距离)如果特征之间有复杂的相互作用,那么第二个(决策/神经)可能是解决方案。

此外,还有一个普遍的对立问题,即过拟合或欠拟合

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

The green line represents an overfitted model and the black line represents a regularised model. While the green line best follows the training data, it is too dependent on that data and it is likely to have a higher error rate on new unseen data, compared to the black line.

统计学中的过度拟合是指“产生的分析过于紧密或精确地对应于一组特定的数据,因此可能无法拟合额外的数据或可靠地预测未来的观察结果”。

当统计模型不能充分捕捉数据的底层结构时,就会出现欠拟合。欠拟合模型是指在正确指定的模型中会出现的一些参数或术语缺失的模型。

**什么是好的契合?**我们可以从一个更有争议的哲学角度来看这个问题。一个社会科学家、政治家和工程师很可能不同意什么是合适的。归根结底,这是关于模型性能的。人、机器等的性能。做一件工作或一项活动。在算法的制作中,当然会涉及到不同的目标。

威尔·科尔森写了一篇名为过度适应与不适应:一个完整的例子的文章,我推荐你去看看,但是我想在这里提一下这篇文章中的一句话:

为了讨论欠拟合和过拟合,我们需要从基础开始:什么是模型?模型只是一个将输入映射到输出的系统。

没有算法可以解决所有问题。在这种情况下,提到搞笑而严肃的没有免费的午餐定理总是很有趣的。在优化和计算复杂性中,这是一个结果,表明对于某些类型的数学问题,找到一个解决方案的计算成本*(计算模型使用的资源)*,平均到类中的所有问题,对于任何解决方法都是相同的。从这个意义上说,没有捷径可走。

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

Cartoon by xkcd

然而,Wolpert 和 Macready 已经证明,在共同进化优化中有免费的午餐。这让我们优雅地进入下一部分。

强化学习

强化学习是与监督学习和非监督学习并列的三种基本机器学习范式之一。为什么会这样呢?

它与监督学习的不同之处在于,不需要呈现标记的输入/输出对,并且不需要明确地校正次优动作。相反,重点是在探索(未知领域)和开发(现有知识)之间找到平衡。

强化学习 ( RL )是机器学习的一个领域,它关注的是软件代理应该如何在一个环境中采取行动,以便最大化一些累积回报的概念。

软件代理 :以代理关系为用户或其他程序服务的计算机程序。

我又参考了 Vishal Maini 的一篇文章,这次是关于 强化学习 *,*他分享了这个模型:

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

The agent observes the environment, takes an action to interact with the environment, and receives positive or negative reward. Diagram from Berkeley’s CS 294: Deep Reinforcement Learning by John Schulman & Pieter Abbeel

然而,该模型也可以以这种方式表示:

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

The typical framing of a Reinforcement Learning (RL) scenario: an agent takes actions in an environment, which is interpreted into a reward and a representation of the state, which are fed back into the agent.

马尔科夫决策过程(MDP) 通常是基本的强化学习经常是如何呈现的另一位作者为走向数据科学 Mohammad Ashraf 在其文章强化学习去神秘化:马尔科夫决策过程(第一部分)中呈现了这个模型:

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

默罕默德在他的文章中很好地介绍了 MDP,我将引用他文章中我认为有用的几行:

马尔可夫属性声明,“给定现在,未来独立于过去。”一旦知道了当前状态,到目前为止遇到的信息的历史可能会被丢弃,并且该状态是一个足够的统计量,它给了我们对未来的相同描述,就好像我们有所有的历史一样[……]一个马尔可夫回报过程或者 MRP 是一个马尔可夫过程,具有价值判断,表明通过我们采样的某个特定序列[……]马尔可夫决策过程累积了多少回报。MDP 是一个有决策的马尔可夫奖励过程,它是一个所有状态都马尔可夫的环境。

他贴出的一个有趣的例子说明了学生马尔可夫决策过程(MDP)。去学习,去睡觉,去酒吧,去 facebook,去辞职——不好回答?这显然是英属 MDP。

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

State-value function in student MDP taken from David Silverman’s lecture at UCL.

如果你是一个喜欢看视频的视觉学习者,你可能想看看这篇关于 Arxiv Insights 的强化学习介绍。

我在这里分享一个他在 6:35 展示的模型:

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

通过反复试验,有一个以最大化长期回报为目标的尝试性任务,代理人在缺乏训练数据的情况下从经验中学习。

前面提到的环境通常被描述为 MDP。这种情况下的许多强化学习算法利用动态编程动态编程技术。

****动态编程指的是通过以递归的方式将复杂的问题分解成更简单的子问题,从而将其简化。如果子问题可以递归地嵌套在更大的问题中,使得动态规划方法是适用的,那么在更大的问题的值和子问题的值之间存在关系。

当一个事物根据它自身或它的类型被定义时,递归就发生了。递归有时在计算机科学、编程、哲学或数学教科书中被幽默地使用,通常是通过给出一个循环定义或自我引用,其中假定的递归步骤不会更接近基本情况,而是导致无限的回归。这类书的词汇表中包含一个笑话条目是很常见的,比如:递归,参见递归

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

强化学习是由于它在许多其他学科中的通用性,包括:博弈论、控制理论、运筹学、信息论、基于模拟的优化、多代理系统、群体智能、统计学和遗传算法。

这些不同的机器学习任务:无监督学习、监督学习和强化学习是不同的,但又是互补的。如果你想了解更多,我推荐你阅读 Vishal Maini 在他的人类机器学习系列中的文章。

半监督学习

半监督学习也被描述过,它是监督和非监督技术的混合。

****半监督学习是一类机器学习任务和技术,也利用未标记数据进行训练——通常是少量标记数据和大量未标记数据。半监督学习介于无监督学习(没有任何标记的训练数据)和监督学习(有完全标记的训练数据)之间。

****半结构化数据是结构化数据的一种形式,它不遵循与关系数据库或其他形式的数据表相关联的数据模型的正式结构,但仍然包含标签或其他标记来分隔语义元素并加强数据内记录和字段的层次结构。

当您没有足够的标记数据来生成准确的模型,并且您没有能力或资源来获取更多数据时,您可以使用半监督技术来增加训练数据的大小。

出于这个原因,半监督学习对于网页分类、语音识别甚至基因测序等用例来说都是双赢的。在所有这些情况下,数据科学家可以访问大量未标记的数据,但实际上为所有数据分配监管信息的过程将是一项无法完成的任务。

半监督分类:标记数据用于帮助识别数据中存在的特定网页类型组以及它们可能是什么。然后,该算法在未标记的数据上进行训练,以定义这些网页类型的边界,甚至可以识别现有人类输入的标签中未指定的新网页类型。

无监督数据扩充

**7 月 10 日在谷歌人工智能
**【无监督数据增强(UDA)】最近博客文章中提出的方法,采用了高度有针对性的数据增强来产生多样和现实的扰动,并且
强制模型相对于这些扰动保持平滑。

  • 使用增强的相似文本或图像的生成示例。用其他相关的例子来充实图片。

  • 他们还提出了一种称为 TSA 的技术,可以有效地防止 UDA 在有更多未标记数据可用时过度拟合监督数据。

  • **对于文本,UDA 与表示学习结合得很好,例如 BERT,

    并且在低数据区非常有效,其中在 IMDb 上仅用 20 个例子就实现了最先进的性能。对于视觉,UDA 在大量基准测试的

    半监督学习设置中减少了超过 30%的错误率。**

  • **最后,UDA 可以有效地利用域外未标记数据

    ,并在有大量监督数据的 ImageNet 上实现改进的性能。在博客中,他们说:**

我们的结果支持最近半监督学习的复兴,表明:(1) SSL 可以匹配甚至优于使用数量级更多标记数据的纯监督学习,(2) SSL 在文本和视觉两个领域都工作得很好,以及(3) SSL 与迁移学习结合得很好,例如,当从 BERT 进行微调时。

他们展示了两张图片来说明他们的模型:

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

An overview of Unsupervised Data Augmentation (UDA). Left: Standard supervised loss is computed when labeled data is available. Right: With unlabeled data, a consistency loss is computed between an example and its augmented version

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

Example augmentation operations for text-based (top) or image-based (bottom) training data.

明天写完更多内容后,我将重温这最后一节。

Arxiv 的在线预印本中有更多内容可供阅读。

这对工业有什么影响?

明天让我检查一下。

这是#500daysofAI 的第 40 天。

希望你喜欢这篇文章,如果有机会记得给我反馈。

什么是#500daysofAI?我正在挑战自己,用#500daysofAI 来写下并思考未来 500 天的人工智能话题。一起学习是最大的快乐,所以如果你觉得一篇文章引起了共鸣,请给我反馈。

ICIAM 2019 深度神经网络可解释性研究进展

原文:https://towardsdatascience.com/advances-on-interpretability-of-deep-neural-nets-at-iciam-2019-1972784fc21d?source=collection_archive---------24-----------------------

关于神经网络可解释性的非常有趣的工作在 ICIAM 会议上提出。

I CIAM 是应用数学界最大的会议**,每四年举办一次。今年它位于西班牙的巴伦西亚,有超过 4000 名参与者,35 摄氏度。在大约一百场讲座同时进行的情况下,有许多关于深度学习主题的有意义的讲座。特别介绍了深层神经网络理论基础方面令人兴奋的工作。因此,在这篇文章中,我想分享一个我觉得特别有趣的例子。**

即使小心对待,深层神经网络也很难掌握。通常,它们被称为“黑盒”。没有提供关于是什么使神经网络收敛到某个预测的信息。但是……那里到底发生了什么?可解释性是对神经网络为什么会达到某种结果的研究。

你们中的许多人可能听说过tensor flow playground,它用简单的例子展示了关于隐藏层的信息。

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

Example of the Tensor Playground!

如果我们想让自治系统为我们做决定,理解 DNN 的解决方案对自治系统的未来至关重要

解释复杂 DNN 模型预测的一般技术是逐层相关性传播(LRP)。****

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

Heat map obtained used the LRP algorithm (Lapuschkin et al. 2016)

考虑一幅你想归类为火车、马或船的图片。LRP 首先检查最后一层中的哪些神经元被激活以获得该解决方案,然后它通过不同层跟踪这些神经元的连接,直到原始像素。令人惊讶的是,神经网络不会检查火车或窗户的形状,但会区分火车,因为它看到了铁轨。网络是作弊吗?不尽然,因为它没有被训练成没有轨道的火车图像,比如玩具火车。

所以,也许我们的数据库不够广泛。这是可解释性分析的可能结果之一。

关于可解释性的不同方法的介绍可以在这里找到

在 ICIAM 深度学习理论进展小型研讨会期间,有一些关于可解释性的演讲,可能最有趣的是来自 Wojciech Samek、Fraunhofer Heinrich Hertz Institute 和 Stephan Waeldchen、柏林工业大学的演讲。

****第一个发言辩论了如何将 LRP 理解为一个深度泰勒分解的预测。关于这些的更多信息和教程可以在他们的 网页 上找到。

研究网络可解释性的方法之一是敏感性分析。为此,梯度的变化被用来分解神经网络,然而,梯度是不可靠的。

敏感性分析研究函数的变化,而不是函数本身的值。

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

Decomposition of the net f(x) ( W. Samek, 2017).

神经网络斜率分解的更好方法是值分解。这样,连续性很容易保持,不像梯度方法。由于神经网络由简单函数组成,深度泰勒分解比简单泰勒分解更合适。因此,可解释性被逐层解释,然后不同的子功能被聚集。然后,LRP 可以被看作是逐层的泰勒分解:

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

Deep Taylor decomposition, where f(x) is the function of relevance. And the Taylor decomposition is done by layers ( W. Samek 2019).

****第二个介绍是关于 率失真方法 ,一个非常不同的方法,他们这个方法的目的是找到一个划分 x∈【0,1]ᵈ(数据)】成子集 s 的相关分量及其互补 Sᶜ.

这样,他们同意固定子集 s 并用随机噪声填充 Sᶜ应该产生相同的分类器预测,同时只有 xₛ的信息,如下图所示。

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

When adding noise to the complementary of S the result of the predictor must be unchanged. ( J. Macdonald et al, 2019).

为此,他们以失真的形式测量分类器预测的变化。我发现这种方法非常有趣,因为它偏离了经典的反向传播或局部线性化方法。然而,在这种方法中发现了一些困难,因为优化是在不同大小的所有可行集合上完成的。寻找相关特征的小集合的计算复杂度,并表明该问题对于 NPᴾᴾ(概率多项式时间)是完全的。因此,通过实现连续的相关分数和集合 s 的某个大小,该问题被放松

正如我所说,神经网络的可解释性对于进一步理解我们的神经网络结果是一个真正有用的新工具。这里有一些的实现,希望能对你自己的结果有所启发。

也许你会在数据集中发现一些意想不到的东西。

[1] S. Waeldchen,J. Macdonald,S. Hauch 和 G. Kutynion,一个用于解释深度神经网络决策的率失真框架 (2019),arXiv:1905.11092

[2] G. Montavon,S. Lapuschkin,A. Binder,W. Samek 和 K.-R. Müller,用深度泰勒分解解释非线性分类决策,(2016),《模式识别杂志》。

推进企业领域的自然语言处理(NLP)

原文:https://towardsdatascience.com/advancing-natural-language-processing-nlp-for-enterprise-domains-1060052294a?source=collection_archive---------17-----------------------

作者:IBM 研究员 Salim Roukos

在公司庞大的文档和知识库中寻找信息来回答用户的问题从来没有想象中那么容易。答案很可能存在,但由于种种原因,它们往往遥不可及。

首先,与 Web 不同,在 Web 上,信息通过一组丰富的链接连接在一起,并经常以多种形式冗余地捕获(使其更容易找到),企业内容通常存储在筒仓中,关键信息的重复要少得多。此外,搜索企业内容的用户通常会问一些复杂的问题,并期望得到比从 Web 搜索引擎得到的答案更详细的答案。这些问题可能包括产品支持、个人账单、适用于客户合同的最新法规、新闻网站上发现的事件的影响等等。最后,企业通常不愿意依赖“黑盒”人工智能,因为它无法解释其建议,可能需要决策者或最终用户可以解释的技术。

自然语言处理(NLP)通过允许用户更自由地表达他们的信息需求,并为日益复杂的问题提供准确的答案,有望帮助在企业内容中找到如此深刻的信息。然而,企业 NLP 系统经常受到许多因素的挑战,包括理解异构的信息孤岛,处理不完整的数据,从少量数据中训练精确的模型,以及在不断添加新内容、产品、术语和其他信息的变化环境中导航。

IBM Research AI 正在沿着三个不同的主题进行探索,以应对这些挑战并改进企业领域的 NLP。第一个目标是推进人工智能,让系统能够从少量数据中学习,利用外部知识,并使用包括神经符号方法在内的技术来处理结合了神经和符号处理的语言。第二个聚焦于信任 AI ,其中提供了关于系统如何达成决策的可解释性。第三种方法涉及扩展 AI,以允许系统的持续适应和更好的监控和测试,以支持企业严格期望下的语言系统部署。

在这篇文章中,我将通过强调我们在 ACL 2019 会议上提交的四篇论文来提供 IBM Research 的企业 NLP 工作的一些细节(我们所有 ACL 论文的完整列表在此处)。前两篇论文涉及语义解析:第一篇使用抽象含义表示(AMR)语言来表示句子的含义,第二篇创建语义解析器,将用户的问题转换为程序来查询知识库。我还将简要探讨我们将不完整的知识库与文本相结合的工作,以提高回答问题的覆盖率。第四篇论文描述了一种系统,该系统使得主题专家能够为可解释的基于规则的系统微调规则。

1。 【抽象意义再现】 :

AMR 是一种语义表示语言,旨在允许相似的句子具有相同的表示,即使它们的措辞不同。我们展示了 AMR 图,它代表了这样一个问题:“如何删除循环日志文件?”其中概念 amr-unknown 代表被请求的内容(在这种情况下,delete-01ofarg 1byarg 0)。

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

在之前的工作中,我们介绍了我们基于栈-LSTM 转换的 AMR 解析器(Ballesteros 和 Al-Onaizan,2017 [1]),其语义准确性,或 **SMATCH,**得分为 65.9%。在这篇论文中,我们描述了几种将 SMATCH 提高到 75.5%的技术,这比早期的 74.4%要好。贡献 1.9%的一种技术是用强化学习来增加训练,以减轻较小的训练数据量。我们使用可能的 AMR 图的采样,希望找到更好的图来学习更好的参数:特别是,我们希望找到最大化预期 SMATCH 奖励的参数。

对于每个句子,我们使用当前的模型参数生成两个图:一个贪婪的最佳图和一个通过从动作空间采样生成的图。梯度近似为(Rennie 等人,2017 年[2])。

贪婪图的匹配作为基线,可以减少梯度估计的方差(Williams,1992 [3])。本文还介绍了在 AMR 2.0 (LDC2017T10)上实现 75.5%的额外功能,其中大部分是新闻内容。我们目前正在探索迁移学习的方法,以将面向新闻的 AMR 解析器扩展到企业内容。

2。 多知识库统一语义解析 :

在许多情况下,用户的问题需要通过查询知识库来回答。我们开发了一种方法,该方法统一了跨多个知识库(KBs)的语义解析,并利用跨查询程序的结构相似性来搜索各种知识库。跨 KBs 的共享缓解了用于构建语义解析器的训练数据的缺乏。我们使用弱监督方法,只有一对用户的问题及其答案,这是通过使用第 k 个 KB 进行训练而获得的。为了克服在所有可能的程序中搜索 KBs 的挑战,我们使用了多策略提取。首先,我们分别为每个领域训练弱监督的解析模型(教师)。第二,我们使用多策略提取将所有的 k 解析器提取到统一的(学生)语义解析器中,学生和 K 教师注意到我们在训练中知道正确的知识库 id,但是在推理过程中不使用该信息。我们在隔夜数据集上进行实验,这是一个具有 7 个 kb 的公共数据集,并且发现与每个教师都单独训练的情况相比,当使用提取的统一解析器(学生)时,性能在准确性上有所提高。

论文提供了关于实验和结果的更多细节。

3。 不完整 KBs 上的问题回答增加了文本 :

大多数知识库是不完整的,但是可以提供有用的知识来与文本语料库融合,以找到在知识库或文档中没有完全回答的问题的答案。这项工作解决了企业中常见的知识库和语料库的异构内容,我们使用了(1)基于图关注的知识库阅读器(SGREADER)和(2)知识感知文本阅读器(KAREADER)的组合。

SGREADER 组件使用图形关注技术从其链接的邻居( )中积累每个子图形实体(e)的知识。图形注意机制被特别设计为考虑两个重要方面:(1)邻居关系是否与问题相关;以及(2)邻居实体是否是问题提到的主题实体。在传播之后,SGREADER 最终为每个实体输出一个矢量化表示,对特定于问题的知识进行编码,这些知识由其链接的邻居来指示。

KAREADER 使用门控机制,通过自关注问题编码器与问题主题实体表示的门控混合来替换问题表示。对于该段落,导出了类似的表示。阅读理解系统使用这些融合的问题和段落表征来得出答案。

论文提供了更多关于实验和结果的细节。

4。【HEIDL】:深度学习的人在回路语言表达 :

企业采用 NLP 的最大挑战之一是从更大更复杂的文本中创建人类可解释的模型的能力。这对于企业来说是必要的,这样才能放心地部署解决方案,更重要的是,利用人类领域的专家来理解和进一步改进 NLP 系统的输出。 HEIDL ,是深度学习的人在回路语言表达式的缩写,是 IBM 创建的一个工具,用于根据精确度和召回率对机器生成的表达式进行排名。

为了评估 HEIDL,IBM Research 和密歇根大学进行了一项研究,对现实世界法律合同中的句子进行分类。数据由 IBM 律师标记,他们梳理了近 150 份合同中的 20,000 个句子,以注释与终止、沟通和支付等关键条款相关的短语。

这些规则是通过深度学习在 IBM 采购合同上学习到的;HEIDL 为人类解释系统正在做什么和改进它提供了高级概念。我们与四位使用 HEIDL 修改规则的数据科学家合作;在 28k 句子的训练集上,所有人都取得了 75%以上的 F 值。此外,当我们在新的非 IBM 合同上进行测试时,HEIDL 系统取得了更好的性能(55%),相比之下,传统的深度学习系统使用 LSTM 网络在相同的 28k 句子上进行训练(44%)。最终,我们的数据科学家可以识别出平均七条规则,在大约 30 分钟内高精度地自动标记近 150 份合同并召回。如果不使用 HEIDL 原型,同样的练习如果手动进行,将需要一周或更长时间。我们计划进行更多的评估,以确认基于 HEIDL 的系统比深度学习系统更强大。

IBM Research AI 和 ACL 2019

IBM Research AI 在 ACL 2019 上的出版物涵盖了我们正在为企业 NLP 领域追求的其他主题;这里列出了。其中包括的四份出版物,带你了解 Project Debater 的幕后技术,该项目于 2019 年 2 月在三藩市与冠军辩手竞争。您也可以在我们的 2 号展位加入我们,我们将展示一些技术演示,展示我们的一些工作。

参考文献

1.米盖尔·巴列斯特罗斯和亚塞尔·奥奈赞。2017.使用 stack-lstms 进行 Amr 解析。《2017 年自然语言处理经验方法会议论文集》,第 1269-1275 页。计算语言学协会。

2.史蒂文·雷尼、艾蒂安·马切雷特、优素福·姆鲁埃、杰雷特·罗斯和瓦伊巴瓦·戈埃尔。2017.图像字幕的自我批判序列训练。IEEE 计算机视觉和模式识别会议论文集,第 7008–7024 页。

3.罗纳德·威廉姆斯。1992.联结主义强化学习的简单统计梯度跟踪算法。机器学习,8(3–4):229–256。

通过 Alexa 奖推进开放域对话系统

原文:https://towardsdatascience.com/advancing-open-domain-dialog-systems-through-alexa-prize-6ad2e484535d?source=collection_archive---------18-----------------------

对话式人工智能的进步因 Alexa 奖而成为可能

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

Photo by Piotr Cichosz on Unsplash

建立一个开放领域的对话系统是最具挑战性的任务之一。几乎所有与开放域对话系统相关的任务都被认为是“人工智能完成的”。换句话说,解决开放域对话系统的问题需要“真正的智能”或“人类智能”。开放领域对话系统需要理解自然语言。缺少预定义的有界解空间和缺少客观的成功矩阵使得响应生成成为非常具有挑战性的建模问题。

为了解决开发这些系统所面临的问题,亚马逊在 2016 年推出了一年一度的竞赛“”Alexa prize。通过这种方式,他们让顶尖的研究人员想出创造性的解决方案。2018 年,比赛的第二次迭代包括提供 CoBot(对话机器人)工具包和各种其他模型,这些模型可以检测敏感内容,评估对话和对话行为检测。

2018 Alexa Prize Finals

介绍

开放领域对话系统需要理解自然语言,以便处理用户查询。由于歧义性和不确定性,开放领域环境下的自然语言理解(NLU)是一个非常困难的问题。为了响应用户的查询,对话系统需要检测他们的意图。开放域对话系统应该理解对话行为、用户话语中的命名实体、检测歧义短语、检测主题、分割句子、检测用户的情感。

“Alexa Prize”的目标是建立能够与人类进行连贯和有吸引力的聊天至少 20 分钟并获得 4 分或更多评分(满分 5 分)的代理。还有许多其他类似的挑战,如“对话系统技术挑战”(DSTC)、“对话式人工智能挑战”(ConvAI),这些都只是基于文本的挑战。

这篇文章概述了 Alexa Prize 团队在构建更好的对话式人工智能方面的进步和新方法。为了进一步理解,用户可以阅读论文“通过 Alexa 奖推进开放域对话系统的艺术状态”。

CoBot(一个机器人开发工具包)

CoBot(一种对话式机器人工具包)的开发是为了最大限度地减少开发人员在基础设施、托管和扩展方面的工作。CoBot 有一些预构建的模型,如主题和对话行为分类器、对话评估器、敏感内容检测。

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

Figure 1: CoBot Architecture Source

CoBot 有助于测试和评估开发人员所做的修改。它提供了强大的日志记录机制,直接存储在 Amazon Cloud Watch 上。它还有一个开发人员友好的 CLI 界面,可以用来模拟对话和转录对话。通过 CoBot,用户可以利用亚马逊的持久存储、数据库和其他服务,如亚马逊 S3、DynamoDB、QuickSight 等,来执行丰富的数据分析和创建可视化。

自动语音识别

开放域对话系统使用语音数据作为输入。糟糕的语音识别系统和无法识别的单词发音会极大地降低这些系统的性能。因此,对于这些系统来说,在将 ASR 错误提供给管道进行下游任务(如 NLU 处理)之前,能够处理 ASR 错误是非常重要的。参与团队使用不同的方法来处理 ASR 错误。在所有方法中,只有一种方法使用了独特的方法,即通过使用上下文知识库来捕获同音字。通过使用这种技术,命名实体的错误率降低了 10%到 15%。

上下文语言模型适应

NLP 中的传统算法使用统计语言模型来解决歧义。使用上下文信息可以进一步提高当前语言模型的性能。这可以通过两种方式实现。第一种是通过向动态插值框架添加上下文信息,第二种是通过将上下文信息并入神经网络。

在第一种方法中,系统基于上下文信息混合不同的统计语言模型。特别地,通过改变我们的基于 n 元语法的语言模型的内插权重,将各种基于 n 元语法的语言模型混合在一起,以更好地适应和识别用户话语。预测这些插值权重以最大化训练数据的对数似然。

第二种方法包括为递归神经网络(RNN)模型添加上下文信息。会话上下文信息被编码到神经语言模型(NLM)中。使用的模型是 LSTM-RNN。Alexa Prize 团队探索了各种方法来整合上下文信息,以处理社交机器人响应和用户话语之间的差异。

语境话题和对话行为模式

为了引导对话的流程,对话行为(如问候、提问、意见、请求等)作为一般意图是有用的。当它与会话的“主题”结合时,它可以帮助自然语言理解。

为了帮助建立更好的开放领域对话系统,Alexa Prize 团队开发了上下文感知主题和对话行为分类模型。去年比赛的 10,000 个对话被标记为 12 个主题和 14 个对话行为。

敏感内容检测分类器

开放域对话设置伴随着最困难的任务之一,对敏感或攻击性内容进行分类。由于文化差异、种族主义、宗教、讽刺、不规范的词汇,这个问题变得更加具有挑战性。

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

Figure 2: Two Stage Semi-Supervision for Sensitive Content Detection Source

大多数团队在公开可用的数据源(如 Reddit 和 Twitter)上训练定制模型。Alexa Prize 团队使用两阶段半监督方法生成了常见的论坛对话(该方法如图 2 所示)。

两阶段半监督方法使用攻击性单词黑名单(这是 800 个攻击性单词的手动精选列表)。阶段 1 包括基于出现在所述黑名单中的攻击性词语的总数对论坛对话进行分类。在阶段 2 中,使用弱监督分类器对高度敏感的评论和不敏感的评论进行采样。这个分类器是在有毒的维基百科评论数据集上训练的。采样数据集用于训练 BiLSTM 分类器。对于单词表示,使用了手套嵌入。

语境对话评估者

开放域对话系统的评估是另一个具有挑战性的问题。Alexa prize 评估开放域对话系统的质量,要求用户根据他们希望与 Alexa 交谈的可能性,在 1 到 5 的范围内给出一个评级。但这些评级并不能评估开放域对话系统的回合级性能。

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

Figure 3: Contextual Conversation Evaluators Source

为了评估开放域对话系统的回合级性能,Alexa prize 团队定义了以下五个指标。

  1. 可理解的:这个指标检查对话系统的响应对于用户的查询是否有意义。
  2. 正题或相关:该指标检查对话系统的回复是否离题。例如,如果用户询问澳大利亚队的一名板球运动员,那么回复应该提到同一队的板球运动员。
  3. 响应不正确:该指标检查响应是否不相关或不适当。
  4. 有趣的:这个指标检查响应是否包含新颖和相关的信息。例如,对话系统提供关于板球运动员的答案,并提供一些附加信息。
  5. 继续对话:该指标检查是否基于对话的当前状态,是否有继续对话的自然方式。

Alexa prize 对话(包含大约 160,000 个话语)根据上述五个指标进行了人工注释。图 3 说明了用于训练上下文对话评估者的模型。该模型使用各种特征,如实体网格、情感和上下文来进行评估。

人工智能的优势和劣势

原文:https://towardsdatascience.com/advantages-and-disadvantages-of-artificial-intelligence-182a5ef6588c?source=collection_archive---------0-----------------------

人工智能是试图在人工智能系统中模拟人类推理的新兴技术之一。约翰·麦卡锡在 1950 年发明了人工智能这个术语。

他说,‘学习的每一个方面或智力的任何其他特征原则上都可以被精确地描述,以至于可以制造一台机器来模拟它。人们将试图发现如何让机器使用语言,形成抽象概念,解决现在留给人类的各种问题,并改进它们自己。

人工智能是计算机程序学习和思考的能力。如果一个程序做一些我们通常认为依赖于人的智能的事情,那么一切都可以被认为是人工智能。

人工智能应用的优势是巨大的,可以彻底改变任何专业领域。让我们看看其中的一些

1)减少人为错误:

短语“人为错误”的诞生是因为人类时不时会犯错误。然而,如果程序设计得当,计算机就不会犯这些错误。使用人工智能,决策是通过应用一套特定的算法从先前收集的信息中做出的。因此减少了误差,并且有可能达到更高精度的准确度。

在使用人工智能的天气预报中,他们已经减少了大多数人为错误。

2)代替人类冒险:

这是人工智能最大的优势之一。我们可以通过开发一个人工智能机器人来克服人类的许多危险限制,而人工智能机器人反过来可以为我们做危险的事情。让它去火星,拆除炸弹,探索海洋的最深处,开采煤和石油,它可以有效地用于任何种类的自然或人为灾害。

例:你听说过乌克兰切尔诺比 l 核电站爆炸事件吗?在那个时候,没有人工智能驱动的机器人可以帮助我们通过在早期阶段控制火势来最小化辐射的影响,因为任何接近核心的人都会在几分钟内死亡。他们最终从直升机上远距离倾倒沙子和硼。

人工智能机器人可以用于干预可能有危险的情况。

3)全天候可用:

除去休息时间,普通人每天工作 4-6 小时。人类生来就是为了有时间放松自己,为新的一天工作做好准备,他们甚至每周休息一次,以保持工作生活和个人生活的完整。但使用人工智能,我们可以让机器 24x7 不间断地工作,它们甚至不会感到无聊,不像人类。

例如:教育机构和帮助热线中心收到了许多可以使用人工智能有效处理的查询和问题。

4)帮助做重复性的工作:

在我们的日常工作中,我们将执行许多重复的工作,如发送感谢信、检查某些文档的错误等等。使用人工智能,我们可以高效地自动化这些平凡的任务,甚至可以为人类移除“无聊的任务,让他们解放出来,变得越来越有创造力。

**示例:**在银行,我们经常会看到为了获得贷款而对文件进行多次验证,这对银行所有者来说是一项重复的任务。使用人工智能认知自动化,所有者可以加快验证文件的过程,客户和所有者都将从中受益。

5)数字辅助:

一些高度先进的组织使用数字助理与用户进行交互,从而节省了对人力资源的需求。许多网站也使用数字助理来提供用户想要的东西。我们可以和他们聊聊我们在找什么。一些聊天机器人的设计方式使得我们很难确定我们是在和聊天机器人还是人类聊天。

**举例:**我们都知道,组织有一个客户支持团队,需要澄清客户的疑惑和疑问。使用人工智能,组织可以建立一个语音机器人或聊天机器人,帮助客户解决所有的问题。我们可以看到许多组织已经开始在他们的网站和移动应用程序中使用它们。

6)更快的决策:

使用人工智能和其他技术,我们可以让机器比人更快地做出决定,更快地执行行动。在做出决定时,人类会从情感和实践两方面分析许多因素,但人工智能驱动的机器按照编程工作,并以更快的方式交付结果。

**举例:**我们都玩过 Windows 里的象棋游戏。由于游戏背后的人工智能,在硬模式下击败 CPU 几乎是不可能的。它会根据背后使用的算法在很短的时间内采取可能的最佳步骤。

7)日常应用:

苹果的 Siri 、Window 的 Cortana 、谷歌的 OK Google 等日常应用在我们的日常生活中频繁使用,无论是搜索位置、自拍、打电话、回复邮件等等。

大约 20 年前,当我们计划去某个地方时,我们会向已经去过那里的人问路。但是现在我们所要做的就是说“好的谷歌维萨卡帕特南在哪里”。它会向你显示维萨卡帕特南在谷歌地图上的位置,以及你和维萨卡帕特南之间的最佳路径。

8)新发明:

人工智能正在推动几乎每个领域的许多发明,这些发明将帮助人类解决大多数复杂的问题。

最近,医生可以使用先进的人工智能技术在早期阶段预测女性的乳腺癌。

因为每个光明的一面都有黑暗的一面。人工智能也有一些缺点。让我们看看其中的一些

1)创作成本高:

由于人工智能每天都在更新,硬件和软件需要随着时间的推移而更新,以满足最新的要求。机器需要修理和维护,这需要大量的费用。它的创造需要巨大的成本,因为它们是非常复杂的机器。

2)让人类变懒:

人工智能正在让人类变得懒惰,它的应用程序自动完成了大部分工作。人类倾向于对这些会给后代带来问题的发明上瘾。

失业:

由于人工智能正在用机器人取代大多数重复性任务和其他工作,人类的干预正在变得越来越少,这将导致就业标准方面的一个主要问题。每个组织都在寻求用人工智能机器人取代最基本的合格人员,人工智能机器人可以更有效地做类似的工作。

4)没有情绪:

毫无疑问,机器在提高工作效率方面要好得多,但它们无法取代组成团队的人际关系。机器无法与人建立联系,而这是团队管理的一个重要特征。

5)缺乏创新思维:

机器只能执行那些它们被设计或编程去做的任务,任何超出这些任务的东西,它们都会崩溃或给出不相关的输出,这可能是一个主要的背景。

概要:

以上是人工智能的一些优缺点。每一项新的发明或突破都将两者兼而有之,但我们人类需要注意这一点,并利用发明的积极方面来创造一个更美好的世界。人工智能具有巨大的潜在优势。对人类来说,关键是确保机器人的崛起不会失控。也有人说,人工智能如果落入坏人之手,会毁灭人类文明。但是,没有一个如此大规模的人工智能应用可以毁灭或奴役人类。

代码的出现:SQL + BigQuery

原文:https://towardsdatascience.com/advent-of-code-sql-bigquery-31e6a04964d4?source=collection_archive---------13-----------------------

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

成千上万的程序员正在用他们最喜欢的编程语言解决即将到来的代码挑战。如果我可以利用这个机会来突出 SQL 和最新的 BigQuery 特性的威力,那会怎么样?

2020 年更新:有雪花

使用 SQL 线程检查我的 2020 代码:

以及 GitHub 回购:

[## FH off/AdventOfCodeSQL

GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码、管理项目和构建…

github.com](https://github.com/fhoffa/AdventOfCodeSQL/)

降临码 是一个降临日历的小编程难题,为各种技能集和技能水平。

如果您可以使用 SQL 和 BigQuery 来编写编译器、交叉路径、递归运行计算和破解密码,会怎么样?#adventofcode2019,开始啦!

问题 1:递归迭代

问题BigQuery 解决方案

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

在 BigQuery 中运行递归函数并不容易——但是现在我们可以做循环和通用脚本。这是我用来解决第二部分问题的主要循环:

LOOP
  IF (SELECT SUM(x) FROM UNNEST(extra) x)<=0 THEN
    LEAVE;
  END IF;  
  SET weight= weight+(SELECT SUM(x) FROM UNNEST(extra) x);
  SET extra = (SELECT ARRAY_AGG(fuel(x)) x FROM UNNEST(extra) x);
END LOOP;

和一个方便的 SQL UDF:

CREATE TEMP FUNCTION fuel(x ANY TYPE) AS (
 GREATEST(0,FLOOR(x/3)-2)
);

我在这里必须解决的最有趣的问题是:我不能有一个cursor来逐行计算每个组件的燃料。所以我必须找出一种并行处理每个 rocket 组件(输入行)的方法——这使得查询方式更加高效。

问题 2:数据作为代码

问题BigQuery 解决方案

可以用 SQL 和 BigQuery 写编译器吗?我们完成图灵了吗?

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

同样,使用脚本LOOP允许我迭代一个输入数组——它定义了从循环中读取时要执行的代码:

LOOP
  IF(input[OFFSET(code_pos)]=99) 
    THEN LEAVE;
  END IF;
  SET input = (SELECT parse(input, code_pos));
  SET code_pos = code_pos+ 4;
END LOOP;

最有趣的部分是我如何使用ARRAY_AGG()CASE按照指示重写每个数组的内容:

SELECT ARRAY_AGG(k) FROM (
SELECT 
CASE n
WHEN x[OFFSET(off+3)] THEN 
  CASE x[OFFSET(off+0)] 
  WHEN 1 THEN x[OFFSET(x[OFFSET(off+1)])]+x[OFFSET(x[OFFSET(off+2)])]
  WHEN 2 THEN x[OFFSET(x[OFFSET(off+1)])]*x[OFFSET(x[OFFSET(off+2)])]
  END
ELSE xx
END k
FROM UNNEST(x) xx WITH OFFSET n
ORDER BY n

然后我不得不面对的最困难的问题是——如何做 99*99 次来找到第二部分的答案?这并不漂亮,但它涉及数组的数组,并在(幸运的)线性空间中进行缓慢的搜索。

警告:搜索 200 个可能的解决方案需要 2 分钟以上。但是由于特定的语句是线性的,你可以跳到正确的结果。

问题 3:我们会在哪里相遇

问题BigQuery 解决方案

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

这是一个有趣的地图遍历问题——对于这个解决方案,我使用了生成 SQL 数组的能力来详细描述每个步骤:

FROM [...], UNNEST(GENERATE_ARRAY(x-move.x, x, IF(move.x>0,1,-1))) arr_x WITH offset n1, UNNEST(GENERATE_ARRAY(y-move.y, y, IF(move.y>0,1,-1))) arr_y WITH OFFSET n2

寻找交叉点的路径之间的连接非常优雅:

USING(arr_x, arr_y)

一个方便的函数解析输入并生成二维运动指令:

CREATE TEMP FUNCTION parse(x ANY TYPE) AS (
 CASE REGEXP_EXTRACT(x, '^(.)')
 WHEN 'D' THEN STRUCT(0 AS x,-parse_n(x) AS y)
 WHEN 'R' THEN (parse_n(x),0)
 WHEN 'U' THEN (0,parse_n(x))
 WHEN 'L' THEN (-parse_n(x),0)
 END
);

我很自豪能够重新分解路径生成代码,使解决方案易于查看:

SELECT ABS(arr_x) + ABS(arr_y) distance, (a.rn + b.rn) wire
FROM (
  SELECT * FROM UNNEST(route('L996,D167,R633,...'))
) a
JOIN (
  SELECT * FROM UNNEST(route('R995,U982,R941,...'))
) b
USING(arr_x, arr_y)
WHERE a.rn>0 AND b.rn>0
ORDER BY wire 
LIMIT 1

问题 4:密码是…

问题BigQuery 解决方案

这里的代码非常短!我希望我编写的手动数组位置更少,但是这样做花费的时间比计算一般情况要少:

SELECT * 
FROM (
  SELECT CAST(FORMAT('%i%i%i%i%i%i',n0, n1, n2, n3, n4, n5) AS INT64) number
  FROM (
    SELECT n0, n1, n2, n3, n4, n5
    FROM UNNEST(GENERATE_ARRAY(1, 5)) n0
    , UNNEST(GENERATE_ARRAY(1, 9)) n1
    , UNNEST(GENERATE_ARRAY(1, 9)) n2
    , UNNEST(GENERATE_ARRAY(1, 9)) n3
    , UNNEST(GENERATE_ARRAY(1, 9)) n4
    , UNNEST(GENERATE_ARRAY(1, 9)) n5
    WHERE n1>=n0
    AND n2>=n1
    AND n3>=n2
    AND n4>=n3
    AND n5>=n4
    AND (
    (n1=n0 AND n1!=n2)
    OR (n2=n1 AND n1!=n0 AND n2!=n3)
    OR (n3=n2 AND n2!=n1 AND n3!=n4)
    OR (n4=n3 AND n3!=n2 AND n4!=n5)
    OR (n5=n4 AND n4!=n3)
    )
  )
)
WHERE number BETWEEN 109165 AND 576723

如你所见,GENERATE_ARRAY()帮助创造了寻找解决方案的空间。

第五天

当我写下这些想法时,问题仍然没有被公布…

嗯……现在是了,但是我要回家了。能不能同时解决?

更新:问题是第 2 天的延续。建造这台“图灵机”在第二天很有趣,但我不想加倍努力。

第六天:图形遍历

问题BigQuery 解决方案

浏览图表并不需要花费太多精力来编写脚本——但是它强调了当一个函数必须经历多次迭代时,BigQuery 可能会很慢。在这种情况下,处理 547 条语句需要大约 20 分钟。提醒一下:BigQuery 在处理万亿字节的数据方面令人难以置信,但不一定能解决一般的计算问题。

LOOP
  SET steps = steps+1
  ;
  CREATE OR REPLACE TEMP TABLE planets AS
  SELECT DISTINCT planet
  FROM (
    SELECT origin planet FROM t1 WHERE dest IN (SELECT planet FROM planets)
    UNION ALL
    SELECT dest planet FROM t1 WHERE origin IN (SELECT planet FROM planets)
  )
  ;
  IF 'SAN' IN (SELECT * FROM planets )
      THEN LEAVE;
  END IF;
END LOOP

现在,如果这个问题不是一次性的,我就不会每次都遍历图,而是预先计算一个更好的结构,用所有路径来立即找到交叉点(因为这是树,不是图)。

最后的想法

我会推荐 SQL 作为通用编程问题工具

不要!

…但对我来说,这是一种尝试 SQL 和 BigQuery 极限的有趣方式。脚本是一个新特性,我还在适应它的语法和局限性。到目前为止,一切顺利。

以代码挑战赛的到来为例!

作为奖励:使用这些技巧来打动你的朋友!

感谢艾捷拉哈默利马诺马克斯本布莱特辛、……早期的鼓励。

(可以代码 763369-9f36786d 加入 BigQuery SQL 排行榜)

代码的来临——你的新节日惯例!

原文:https://towardsdatascience.com/advent-of-code-your-new-holiday-season-routine-159a4bf428c5?source=collection_archive---------36-----------------------

在庆祝节日的时候,强化你解决问题和编码的能力

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

Photo by Mourad Saadi on Unsplash

要旨

伙计,我真的需要温习一下。

我应该检查一下。我看到它越来越多的出现,对我来说精通它将变得很重要。

你最近和自己进行过多少次这样的对话?机会是,你至少有过几次,而且我们大多数人也会欣然承认,我们对此也没做什么。好吧,这里有一个有趣的节日惯例可以帮助你:代码的出现!

事实真相

“代码的来临”是一年一度的系列日常编码挑战,发生在年终假期期间。虽然它的名字暗指基督教传统,但这是一个简单的双关语选择,旨在传达该系列的 25 天性质(来吧,来吧!).从 12 月 1 日到 12 月 25 日,每天都会发布一个新的谜题。这些谜题通常会沿着一个奇妙的故事情节串连起来,让你在接受挑战的时候也能得到娱乐。这是去年的一个例子:

示例拼图(2018 年第一天)

感觉自己已经摔倒了几分钟后,你看着设备的小屏幕。"错误:设备在第一次使用前必须校准。检测到频率漂移。无法维护目标锁。在信息下方,设备显示一系列频率变化(您的谜题输入)。像+6 这样的值意味着当前频率增加 6;像-3 这样的值意味着当前频率降低 3。

例如,如果设备显示+1、-2、+3、+1 的频率变化,那么从零频率开始,将发生以下变化:

电流频率为 0,变化为+1;结果频率 1。电流频率 1,变化为-2;结果频率-1。电流频率-1,变化为+3;结果频率 2。电流频率为 2,变化为+1;结果频率 3。在本例中,结果频率为 3。

以下是其他示例情况:

+1,+1,+1 的结果是 3

+1,+1,-2 产生 0

-1,-2,-3 的结果是-6

从零频率开始,应用所有频率变化后的结果频率是多少?

此时,页面上有一个链接可以让您以文本文件的形式获取完整的输入序列(大约一千个输入)。这就是你解决问题的技巧和软件实现的诀窍之间的结合点。

小心点!大多数人会很高兴地一头扎进读取输入的反刍代码,然后当他们意识到是时候实现核心算法时,他们会低头沉思。首先花点时间确保你完全理解了手头的问题,并且(至少在精神上)在奔向 I/O 代码之前形成算法解决方案。

为什么你应该这样做

您不需要使用任何类型的重要计算硬件来参与这些挑战——请随意将您的云计算思维模式放在一边,让您自己回到您的第一个数据结构和算法努力的单一机器、单一问题思维模式中😉。由埃里克亲自设计的拼图👏的设计使得以蛮力方式解决问题将花费太长时间,但是以更智能的方式解决将在商品硬件上最多 15 秒内解决难题。

你也不需要使用任何超级优化的编程语言。请注意,由于解决难题的正确方法会在几秒钟内给你答案,解决方案的真正区别在于开发时间。因此,用解释语言(Python、R 等)编写的适当方法将优于用编译语言(C、Rust、Go 等)编写的简单方法。我爱这方面。有些人喜欢抱怨什么是最好的,因为你总是可以优化它,让它运行得更快,更接近裸机等等。然而,算法在硬件上的运行速度通常不是终端系统的瓶颈:

与编译器支持的程序优化相反,算法解决方案中更昂贵的因素往往是开发人员解决问题的时间、缺乏并行性或 I/O 拥塞。

你上一次参加一家老牌软件公司的面试,他们强迫你选择一种语言是什么时候?[ ]通常情况下,你会被迫(或者明确地,或者通过一次失败的面试暗示地!)提供模块化、高效且可扩展的解决方案。所有这些在任何图灵完全语言中都是可行的。因此,忘掉本系列的语言战争,把注意力集中在这个问题真正的智力实质上。

事实上,许多人在这里完全摒弃竞争,把代码的出现作为学习一门新语言的机会。就我个人而言,我计划在 Python 中完成我的第一关,然后在 Go 或 Javascript 中跟进(必须保持面向未来的🧐).无论你是在寻找激烈的竞争,一个学习的机会,还是在这个假期建立一个好习惯的机会,考虑在《代码降临》中找到它!

准备好了吗?

从回顾过去几年的一些谜题开始。感受到你更有竞争力的一面了吗?使用代码498713-51f0c909在此加入私人排行榜,看看您与其他参与者的匹配情况。

分享你的观点

你为什么打算或不打算参与此事?如果你不是,什么会改变你的想法?

你有没有屡试不爽的方法来保证长时间完成像这样的日常任务的习惯?

你还想分享什么?

[ ]:我希望你们中没有太多人参加过这样的采访😬。

冒险刮:冒险时间抄本的文本挖掘

原文:https://towardsdatascience.com/adventure-scrape-text-mining-on-adventure-time-transcripts-8a50d09c2b6d?source=collection_archive---------17-----------------------

当代动画倾向于看似为儿童制作,但对成人有深远影响的卡通…因为它们情节的突然发展,复杂的角色情感,以及太真实的笑话。冒险时间就是这样一个让你说“哦,我的球”的节目!

冒险时间是卡通网络上一部长期播放的卡通片,以许多看似不相关的“每周任务”剧集和彩色(我敢说是迷幻)艺术而闻名。前四五季几乎没有什么情节,但最终它对角色的定期轮换有了更一致的情感发展。我非常喜欢节奏的变化,并想知道我是否可以使用数据来跟踪角色的发展。所以,让我们开始数学的东西!

供参考:所有代码都在这个回购中。

注意:下面会有一些剧透…但由于该剧于 2018 年 9 月结束,我假设你有足够的时间赶上!

其他注意事项:这是我的第一个机器学习项目,因此代码不是为了效率而优化的,而是为了清晰或短期效用。

What’s more algebraic than Adventure Time? Data analysis of Adventure Time!

创建数据集

网页抓取

由于《冒险时间》是一部电视剧,我搜索了剧集剧本的抄本。许多收藏有丰富的文本,但没有人物标签,除了组织得非常好的冒险时间粉丝维基的抄本部分

我按照这个指南开发了一个脚本来搜集这些抄本。我从脚本的登陆页面开始,沿着剧集列表往下看,因为它们是按时间顺序排列的(信不信由你,大多数粉丝维基按剧集标题的字母顺序排列脚本)。我是这样做的,并将文本保存到 HTML 文件中:

import requests
import urllib.request
import time
from bs4 import BeautifulSoupurl = ‘[https://adventuretime.fandom.com/wiki/Category_talk:Transcripts'](https://adventuretime.fandom.com/wiki/Category_talk:Transcripts')
response = requests.get(url)soup = BeautifulSoup(response.text, “html.parser”)anchors = [a for a in (td.find(‘a’) for td in soup.findAll(‘td’)) if a]for i in range(0,len(anchors)):
    if anchors[i].has_attr('href'):
        link = anchors[i]['href']
        actual_link = '[https://adventuretime.fandom.com'+link](https://adventuretime.fandom.com'+link) 
        file_name = './transcripts/adventure_time_ep'+str(i)+'.html'
        urllib.request.urlretrieve(actual_link,file_name)
        file = open(file_name,'r')
        new_file = [n.replace('<dl><dd>','') for n in file.readlines() if n.startswith('<dl')]
        file.close()
        new_name = open('./transcripts/adventure_time_ep'+str(i)+'_redacted.html','w')
        for k in range(len(new_file)):
            new_name.write(new_file[k]+'\n')
        new_name.close() 
    time.sleep(1)

虽然这部剧有 283 集,但我只找到了 213 份抄本。其中一些不完整。我预计会有不完整的,混乱的数据,因为所有这些文字记录都是粉丝在志愿者的基础上生成的。

数据清理+数据帧创建

接下来,我必须清理这些数据并为其创建一个数据结构。我选择的结构受到了大卫·罗宾逊在他对《真爱至上》人物网络的分析中的结构的启发:一个熊猫数据框架,其中每一行都是脚本中的一行,我表示剧集编号、行号、演讲者和相关内容。为了进一步分解内容,我把内容分成对话或动作;在绝大多数抄本中,动作用括号[]表示,或者在角色的台词中,或者作为一种舞台指示。下面是一个原始数据的例子,来自这一集:

泡泡糖公主:多棒的一击。谢谢你们再次挽救了局面,孩子们。

芬恩:不客气,公主。她拥抱了他。嗯…[他脸红了,杰克扬起眉毛,觉得很有趣。 ]

泡泡糖公主:我要给你们两个办一个派对。今晚在糖果王国见面!

三人欢呼。“派对时间”标志弹出,气球填满屏幕,切换到下一个场景。芬恩和杰克正穿过 棉花糖森林 糖果城堡 走去。 ]

我把对话和动作分开,不仅仅是因为它们被括号清晰地分开了,我还假设这两者会不同地定义一个角色的个性。这里值得注意的是,在实际的 HTML 文件中,我已经去掉了 HTML 的所有文本格式。

当然,即使有了这些格式化原则,数据也不像我希望的那样干净…

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

The ultimate saying for data cleaning.

下面的代码块演示了我如何将 DataFrame 字段从原始 HTML 文件中分离出来。获取情节和行号很简单,但区分对话和动作可能很有挑战性。一个角色的“台词”可以包含多段对话和动作,因此我创建了一系列条件来捕捉它们。虽然它不是最干净的代码,但它完成了工作。

import requests
import urllib.request
import time
import os.path 
from bs4 import BeautifulSoup
import pandas as pd 
from lxml import html
import numpy as np
import relen_anchors = 280
size = len_anchors*2000
eps = [“” for x in range(size)]
lines = [“” for x in range(size)]
names = [“” for x in range(size)]
dialogue = [“” for x in range(size)]
actions = [“” for x in range(size)]end_of_last_k = 0 
for i in range(len_anchors):
   if os.path.exists(‘./transcripts/adventure_time_ep’+str(i)+’_redacted.html’):
      html = open(‘./transcripts/adventure_time_ep’+str(i)+’_redacted.html’,’r’)
      soup = BeautifulSoup(html, “lxml”)
      for script in soup([“script”, “style”]): *# remove all script and style elements*
         script.extract() 
      text = soup.get_text()
      text_by_line = text.split(‘\n’)
      text_no_breaks = [l for l in text_by_line if len(l) > 0]
      num_lines = len(text_no_breaks)
      line_count = 0
      for k in range(num_lines):
         eps[k + end_of_last_k] = i *#track episode number*
         lines[k + end_of_last_k] = k *#line number in given episode*
         if len(text_no_breaks[k]) > 1: *#sometimes a "line" is just a space...*
            line_count = line_count + 1
            split_up = text_no_breaks[k].split(‘:’,maxsplit=1) *#speaker name separated from main text by colon*
            this_lines_actions = []
            words = []
         if re.match(r’^\W’,text_no_breaks[k]): *#if no colon, it's the narrator/stage directions*
            person = ‘Narrator’
            words.append(text_no_breaks[k])
            this_lines_actions.append(words) 
         elif len(split_up) == 2:
            person = split_up[0] *#text before colon*
         else:
            print(“Error in split!”,i,k,text_no_breaks[k])
         names[line_count + end_of_last_k] = person 
         more_words = []
         if not ‘Narrator’ in person:
            split_by_italics = split_up[1].split(‘[‘)
            if len(split_by_italics) > 1:
               for w in range(len(split_by_italics)): *#len > 1 indicates actions are present*
                  if ‘]’ in split_by_italics[w]: *## the rest of this code catches multiple action and dialogue segments in one line*
                     an_action = split_by_italics[w].split(‘]’) 
                     if len(an_action[0]) > 0:
                        thing = []
                        thing.append(an_action[0])
                        this_lines_actions.append(thing)
                     if len(an_action[1]) > 0:
                        thing = []
                        thing.append(an_action[1])
                        more_words.append(thing)
                  else: 
                     if len(split_by_italics[w]) > 1:
                        this_thing = []
                        this_thing.append(split_by_italics[w])
                        more_words.append(this_thing)
            elif len(split_by_italics) == 1:
               more_words.append(split_by_italics)
         if len(more_words) == 1:
            dialogue[line_count + end_of_last_k] = more_words[0]
         elif len(more_words) > 1:
             no_spaces = []
             for y in range(len(more_words)):
                if len(more_words[y][0]) > 2:
                   no_spaces.append(more_words[y])
             dialogue[line_count + end_of_last_k] = no_spaces
         if len(this_lines_actions) == 1:
            actions[line_count + end_of_last_k] = this_lines_actions[0]
         elif len(this_lines_actions) > 1:
            actions[line_count + end_of_last_k] = this_lines_actions
end_of_last_k = k + end_of_last_k

数据帧编译的其余部分是这里是。当然,清洁工作并没有就此结束…

数据清理,第二部分

《冒险时间》的一个显著特点是里面出现了大量的角色。当然,他们中的绝大多数最多出现几次,但是创作者非常小心地给他们所有人以不同的声音和外观。然而,这个特性也有不好的一面——在创建我的 DataFrame 之后,我发现了大约 1700 个“独特的”字符!

他们是谁?事实上,许多人是“临时演员”——市民、糖果人等等。其他人是出现过一两次的独特个体,像比利或和平大师。当然,有些名字拼错了,长名字的字符用缩写表示(例如,团块公主变成了 LSP 泡泡糖公主成了 PB)。然而,最令人不安的是,我发现舞台指示已经悄悄出现在角色名和冒号之间!

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

不用说,我需要将许多不同的名字组合成它们所代表的一个人,这很快使我决定只集中分析几个重要的人物。下面是我使用的函数:

def combine_names_in_list(list_of_grps,which_name):
    list_of_dfs = [df.loc[df[‘Character’] == x] for x in list_of_grps]
    new_df = pd.concat(list_of_dfs)
    limit_which_name = len(list_of_grps)
    if which_name <= limit_which_name: 
       for i in range(limit_which_name):
          new_df.loc[new_df[‘Character’] == list_of_grps[i], ‘Character’] = list_of_grps[which_name]
    else:
       print(“Improper which_name value!”)
    return new_df

以下是我必须清理的一些例子:

bmo_list = [‘bmo’,’beemo’,’bmo (flashback)’,’bmo (os)’,’bmo (vo)’,’bmo [as bebe]’,’bmo [as lorraine]’,’bmo [as officer davis]’,’bmo [as ronnie, deeper voice]’,’bmo [as ronnie]’,’bmo [flashback]’,’bmo [in its thoughts]’,’bmo [narrating]’,’bmo & bubble’]
bmo_df = combine_names_in_list(bmo_list,0)marceline_list = ['marceline','marc','marcelince','marceline and ghosts','marcy','teenage marceline','young marceline' ]
marceline_df = combine_names_in_list(marceline_list,0)

一些清理工作需要关于演出的知识:

hunson_list = [‘hunson’,’hunson abadeer’,’lord of evil’]
hunson_df = combine_names_in_list(hunson_list,1)

重要的是,我发现芬恩+杰克比剧中的其他角色有更多的台词,所以我认为芬恩+杰克是我的数据框架中他们自己的“角色”。下面是一个结构示例,为了便于查看,各列之间用“||”隔开:

Index || Episode || Line || Character || Dialogue || Action
__________________________________________________________________
434 || 2 || 17 || ice king || what?! , who dares enter the ice kingdom?! || approaches the crater 
436 || 2 || 19 || ice king || you know why i’m here? do you know what ice king means?! 
439 || 2 || 22 || ice king || it means i’m king of ice! this is my domain! and you are violating ice world law — trespassing! 
446 || 2 || 29 || ice king || i don’t care! this is my kingdom. you guys can’t just scoot about on my land willy-nilly. i’ve got rules here. || annoyed 
449 || 2 || 32 || ice king || what?! iam the king! i am the king of c-cool c-co ca… that’s it! rise, monsters of snow, and go beat up finn and jake! || flips out, uses magic to bring out snow monsters

将所有这些迷你数据帧连接成一个大数据帧的代码在这里。终于可以发掘一些数据了!

数据探索,文本挖掘风格

为了逐字分析,我首先按照指南将数据符号化。这里的“标记化”意味着一个字一个字地分离文本数据,创建一个数据帧,对于每个抄本行,该数据帧具有对应于对话和/或动作的每个字的列。我把对话和动作分开符号化了。在我忘记之前,这里是探索性分析代码

有了标记化的数据,我们可以很容易地计算出哪些词在语料库中出现得最频繁。我看了一下给定角色的整体和每集。结果可能不会让你惊讶…

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

Most prevalent words in Princess Bubblegum speech for several episodes.

也就是说,最常见的单词是冠词(例如,“the”、“an”)和代词。由于这些词在言语中占据了很大的空间,它们只在更罕见、更独特的词的上下文中提供意义。我们如何找到这些词,我们如何衡量它们的影响?

文本挖掘中经常使用的一种方法是计算 TF-IDF 统计量。这种统计允许我们对一个文档中的单词相对于同一语料库中的其他文档的唯一性进行加权,从而确定哪些单词最能定义每个文档。在诺瓦克的博客文章之后,我计算了这个统计数据和 TF-IDF 计算所需的其他数据。现在让我们来看看 TF-IDF 是如何定义泡泡糖公主的演讲的!

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

TF-IDF for some Princess Bubblegum speech.

这些数据看起来很不一样。第一个值得注意的特点是第 155 集的两个峰值——因为泡泡糖公主在那一集只说了两个词,这些词有着不相称的重要性。“gah”的权重更大,因为在她说话的其他剧集中,“okay”是一个更常见的词。我们还看到,这两个图的 x 轴显示了非常不同的单词;TF-IDF 几乎没有展示任何填充词。从这些数据来看,这几集的主角是莱蒙霍普(第 153 集和第 154 集)或詹姆斯和詹姆塞夫妇(第 158 集)。通过 Fandom Wiki 检查,这似乎是正确的!因此,对于这个数据集,TF-IDF 可能是了解一集关键特征的好方法,而不一定是角色的情绪或对它的贡献。

因为 TF-IDF 看起来很强大,一些不同的单词应该在多集中出现,我想知道某些单词的重要性如何随着时间的推移而变化(即随着集数的增加),这是否可以代表人物的发展。下面的代码显示了我如何将 TF-IDF 数据作为时间的函数来构建。请注意,我是从包含 TF-IDF 数据的多索引数据帧开始的,其中我按单词和剧集进行索引。

words = tf_idf.index.get_level_values(level=1).unique().tolist() *## get all unique words in character's speech*
get_more = tf_idf.swaplevel(i=0, j=1, axis=0) ## remove hierarchical indexing, level by level
get_more.unstack()
get_more.reset_index(level=1, inplace=True)
get_more.reset_index(level=0, inplace=True) ## word and Episode are both columns now, rather than indices

for word in words:
  collection = get_more.loc[get_more[‘dialogue word’] == word]
  if len(collection) > 1:
   collection.plot(kind=’line’,y=’tf_idf’,x=’Episode’,title=’Word: ‘+word,marker=’.’,xlim=(0,279))
  plt.show()
  plt.close()

泡泡糖公主的一些著名例子如下。我发现有趣的是,她只在节目的最开始使用了“皇家”这个词,而当时她是一个相当古板、控制欲强的君主。

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

“知道”的重要性的演变很有趣,因为她变得更有自我意识,而不是无所不知,她对这个词的使用时好时坏。

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

为了对比这些,我们来看一个非常常见的词“the”,它的 TF-IDF 变化很大,但幅度始终很小:

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

最后一次看泡泡糖公主的数据,我不得不看到她对“玛西琳”的使用是如何随着时间的推移而改变重要性的。我们可以看到《玛瑟琳》的 TF-IDF 在 200 集左右达到峰值。我知道 Fandom Wiki 关于围绕玛瑟琳背景故事的迷你系列的赌注数据非常不完整,所以我知道这不是飙升的原因。然后我想起“恶棍”发生在赌注前不久,虽然这份记录也不完整,但一切都更有意义了。(对于外行人来说:这一事件是泡泡糖公主和玛瑟琳关系的转折点。)

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

在这种背景下,我不得不看看“marcy”数据是什么样子的。

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

事实上,我们看到“marcy”在“Varmints”中成为一个相对重要的术语,并在大约 100 集之后出现,表明他们之间的互动发生了变化。这么少的数据点,我认识到我真的在字里行间,但很高兴在这个简单的统计中看到性格增长的签名!

从这里开始,自然的下一步将是情感分析,或者针对每个角色,或者作为区分剧中角色的一种手段。然而,我只有大约 1000 句台词给泡泡糖公主,可能还有大约 1200 句台词给剧中的两个主要角色,我认为这是一个冒险的尝试。然而,关于 Finn 和 Jake 的数据要多得多,他们每个人大约有 7000 和 5000 行…

infinerator:完全不同的东西

虽然总体上我对机器学习还很陌生,但我已经意识到深度学习仍然是趋势。我对机器学习新闻的细读表明,深度学习越来越多地应用于通常保留给 NLP 的领域。因此,我没有进行情绪分析,而是直接进入了深度学习。

我决定为芬恩制作一个语音生成器…芬恩生成器。(“InFINNerator”是一个三重双关语,所以要记住。)

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

Behold.

除了“对话”,我没有给演讲贴上任何标签;通常,情感分析寻找好的和坏的,并且它需要标记的数据。在对这个数据集进行了所有的初始清理之后,我需要从数据集构造和变更中休息一下。也许有一天我会用近似情绪来标记对话,但目前手工标记这些数据的时间成本太高了。

内嵌器是一个用 PyTorch 编写的字符级递归神经网络(RNN ),运行在 Google Colab 上。我跟随这个伟大的 PyTorch 教程去了解 PyTorch 中 RNNs 的基础知识。我很快发现,在后启示录时代,用来生成名字的简单架构无法为一个热情的人生成语音。

(我不会在这里展示 RNN 的代码,因为它与 RNN 的其他代码非常相似。有兴趣的请看 Colab 笔记本!)

在深入研究 RNN 变更之前,我首先应该说,我必须为这个任务进一步修改我的数据结构。我注意到对话行中有一些 Unicode 字符;我把所有东西都改成了 ASCII。此外,直接从抄本的行是高度可变的长度,这将在数据中产生不必要的复杂性。我打乱了这些行,然后在用一个行尾字符将它们分开后,我将所有的行连接在一起。为了创建序列,我将语料库分成 64 个字符的新行。

我对 RNN 的第一个改进是小批量训练。最初,我一次训练一个热字符,每个梯度步骤在一个 64 字符的行被处理后完成。对于小批量,一个渐变步骤在一个 64 字符的行经过一批行的处理后结束(我使用 32 行的批量)。这导致了一些小的改进。这种单层香草 RNN 产生了很多感叹号的胡言乱语。然而,公平地说,这是第一次尝试,芬恩通常对任何事情都非常兴奋,所以这确实抓住了他外在表现的本质。下面是输出的一个例子:

他回家了,是吗?int n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

所以,我不得不把它提高几个档次。我把香草 RNN 换成了 LSTM 的网络。这个 LSTM 有 1-2 层和一个线性解码器,最后我返回了 LogSoftmax 分布的输出。LSTM 的灵感大致来源于 RNN 这个角色。

我尝试了几种架构:

  • 1 层,hidden_layer_size=256,学习率=4e-4,1e-3
  • 2 层,隐藏层大小=256,学习率=1e-4,4e-4
  • 1 层,hidden_layer_size=512,学习率=1e-4,4e-4,1e-3
  • 1 层,hidden_layer_size=1024,学习率=1e-4,4e-4

不幸的是,这些增强的 LSTM 的性能并不比小批量的香草 RNN 好多少…如果我真的改进了 InFINNerator,我会更新这个帖子!现在,享受甜蜜的芬兰尖叫声吧。

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

You can hear this image, can’t you?

与此同时…我有一些想法,为什么这没有我希望的那样好:

  • Google Colab 偶尔会忘记它正在运行的代码的状态,这可能会导致训练中的不一致
  • 数据集很小,而《冒险时间》是一部主题变化很多的电视剧,所以数据可能太不稳定了。老实说,由于我总共只有大约 300,000 个字符,我预计会超出数据…但似乎更多的训练时间或更大的网络会有所帮助。
  • PyTorch 有些秘密我还没有发现。

如果您对 InFINNerator 或这里的任何其他内容有任何反馈,请告诉我!我在这个项目中学到了很多,关于机器学习、文本挖掘和深度学习,我还有很多要学。感谢阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值