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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

基于 TensorFlow 2.0 的 LSTM 多类文本分类

原文:https://towardsdatascience.com/multi-class-text-classification-with-lstm-using-tensorflow-2-0-d88627c10a35?source=collection_archive---------0-----------------------

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

递归神经网络,长短期记忆

NLP 的许多创新是如何将上下文添加到单词向量中。一种常见的方法是使用循环神经网络。以下是递归神经网络的概念:

  • 他们利用连续的信息。
  • 他们有一种记忆,可以捕捉到目前为止已经计算过的内容,也就是说,我上一次讲的内容会影响我接下来要讲的内容。
  • rnn 是文本和语音分析的理想选择。
  • 最常用的 rnn 是 LSTMs。

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

Source: https://colah.github.io/posts/2015-08-Understanding-LSTMs/

以上是递归神经网络的架构。

  • “A”是一层前馈神经网络
  • 如果我们只看右边,它确实循环地通过每个序列的元素。
  • 如果我们打开左边,它看起来会和右边一模一样。

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

Source: https://colah.github.io/posts/2015-08-Understanding-LSTMs

假设我们正在解决一个新闻文章数据集的文档分类问题。

  • 我们输入每个单词,单词在某些方面相互关联。
  • 当我们看到文章中的所有单词时,我们在文章的结尾进行预测。
  • rnn 通过从最后一个输出传递输入,能够保留信息,并能够在最后利用所有信息进行预测。

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

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

  • 这对短句很有效,当我们处理一篇长文章时,会有一个长期依赖的问题。

因此,我们一般不使用普通的 RNNs,而是使用长短期记忆。LSTM 是一种可以解决这种长期依赖问题的 RNNs。

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

在我们的新闻文章文档分类示例中,我们有这种多对一的关系。输入是单词序列,输出是一个单独的类或标签。

现在,我们将使用tensor flow 2.0&Keras解决 LSTM 的 BBC 新闻文档分类问题。数据集可以在这里找到

  • 首先,我们导入库并确保 TensorFlow 是正确的版本。

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

  • 像这样把超参数放在顶部,这样更容易修改和编辑。
  • 当我们到达那里时,我们将解释每个超参数是如何工作的。

hyperparameter.py

  • 定义两个包含文章和标签的列表。同时,我们删除停用词。

articles_labels.py

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

数据中有 2,225 篇新闻文章,我们把它们分成训练集和验证集,根据我们之前设置的参数,80%用于训练,20%用于验证。

train_valid.py

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

Tokenizer 为我们做了所有繁重的工作。在我们的文章中,它是令牌化的,它将需要 5000 个最常见的单词。oov_token就是遇到看不见的词的时候放一个特殊值进去。这意味着我们希望<OOV>用于不在word_index中的单词。fit_on_text将遍历所有文本并创建如下词典:

tokenize.py

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

我们可以看到“”是我们语料库中最常见的标记,其次是“said”,再其次是“mr”等等。

在标记化之后,下一步是将这些标记转换成序列列表。下面是训练数据中已经变成序列的第 11 条。

train_sequences = tokenizer.texts_to_sequences(train_articles)
print(train_sequences[10])

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

Figure 1

当我们为 NLP 训练神经网络时,我们需要序列大小相同,这就是为什么我们使用填充。如果你向上看,我们的max_length是 200,所以我们使用pad_sequences使我们所有的文章长度相同,都是 200。结果,你会看到第一篇文章的长度是 426,变成了 200,第二篇文章的长度是 192,变成了 200,依此类推。

train_padded = pad_sequences(train_sequences, maxlen=max_length, padding=padding_type, truncating=trunc_type)print(len(train_sequences[0]))
print(len(train_padded[0]))

print(len(train_sequences[1]))
print(len(train_padded[1]))

print(len(train_sequences[10]))
print(len(train_padded[10]))

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

另外,还有padding_typetruncating_type,都是post,意思是比如第 11 条,长度是 186,我们填充到 200,我们填充到最后,也就是加了 14 个零。

print(train_padded[10])

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

Figure 2

对于第一篇文章,它的长度是 426,我们将其截断为 200,并且我们在结尾也进行了截断。

然后我们对验证序列做同样的事情。

val_tok.py

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

现在我们来看看标签。因为我们的标签是文本,所以我们将对它们进行标记,在训练时,标签应该是 numpy 数组。因此,我们将把标签列表转换成 numpy 数组,如下所示:

label_tokenizer = Tokenizer()
label_tokenizer.fit_on_texts(labels)

training_label_seq = np.array(label_tokenizer.texts_to_sequences(train_labels))
validation_label_seq = np.array(label_tokenizer.texts_to_sequences(validation_labels))print(training_label_seq[0])
print(training_label_seq[1])
print(training_label_seq[2])
print(training_label_seq.shape)

print(validation_label_seq[0])
print(validation_label_seq[1])
print(validation_label_seq[2])
print(validation_label_seq.shape)

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

在训练深度神经网络之前,我们要探索自己的原始文章和填充后的文章是什么样子的。运行下面的代码,我们浏览第 11 篇文章,我们可以看到一些单词变成了“”,因为它们没有进入前 5000 名。

reverse_word_index = dict([(value, key) **for** (key, value) **in** word_index.items()])

**def** decode_article(text):
    **return** ' '.join([reverse_word_index.get(i, '?') **for** i **in** text])
print(decode_article(train_padded[10]))
print('---')
print(train_articles[10])

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

Figure 3

现在是实施 LSTM 的时候了。

  • 我们构建一个tf.keras.Sequential模型,从嵌入层开始。嵌入层为每个单词存储一个向量。当被调用时,它将单词索引序列转换成向量序列。经过训练,意思相近的单词往往有相似的向量。
  • 双向包装器与 LSTM 层一起使用,它通过 LSTM 层向前和向后传播输入,然后连接输出。这有助于 LSTM 了解长期依赖。然后,我们将它与密集的神经网络相匹配,以进行分类。
  • 我们用relu代替tahn函数,因为它们是很好的替代物。
  • 我们添加一个有 6 个单位的密集层和softmax激活。当我们有多个输出时,softmax将输出层转换成一个概率分布。

lstm_model.py

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

Figure 4

在我们的模型摘要中,我们有我们的嵌入,我们的双向包含 LSTM,后面是两个密集层。双向的输出是 128,因为它是我们在 LSTM 的两倍。我们也可以堆叠 LSTM 层,但我发现结果更糟。

print(set(labels))

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

我们总共有 5 个标签,但是因为我们没有一次性编码标签,我们必须使用sparse_categorical_crossentropy作为损失函数,它似乎认为 0 也是一个可能的标签,而 tokenizer 对象从整数 1 开始标记,而不是整数 0。结果,最后的密集层需要标签 0、1、2、3、4、5 的输出,尽管 0 从未被使用过。

如果希望最后一个密集层为 5,则需要从训练和验证标签中减去 1。我决定让它保持原样。

我决定训练 10 个纪元,你会看到很多纪元。

model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])num_epochs = 10
history = model.fit(train_padded, training_label_seq, epochs=num_epochs, validation_data=(validation_padded, validation_label_seq), verbose=2)

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

Figure 5

def plot_graphs(history, string):
  plt.plot(history.history[string])
  plt.plot(history.history['val_'+string])
  plt.xlabel("Epochs")
  plt.ylabel(string)
  plt.legend([string, 'val_'+string])
  plt.show()

plot_graphs(history, "accuracy")
plot_graphs(history, "loss")

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

Figure 6

我们可能只需要 3 或 4 个纪元。在训练结束时,我们可以看到有一点点过度适应。

在以后的文章中,我们将致力于改进这个模型。

Jupyter 笔记本可以在 Github 上找到。享受余下的周末吧!

参考资料:

[## Coursera |顶尖大学的在线课程。免费加入

斯坦福和耶鲁等学校的 1000 多门课程——无需申请。培养数据科学方面的职业技能…

www.coursera.org](https://www.coursera.org/learn/natural-language-processing-tensorflow/home/welcome) [## 纽约州纽约市 2019 年奥莱利地层数据会议

选自 2019 年纽约奥莱利地层数据会议[视频]

learning.oreilly.co](https://learning.oreilly.com/videos/oreilly-strata-data/9781492050681/9781492050681-video327451)

采用 Tensorflow 的多 GPU、多进程

原文:https://towardsdatascience.com/multi-gpu-multi-process-with-tensorflow-ba4cc2fe3ab7?source=collection_archive---------13-----------------------

如何加快你学习算法的速度

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

Tensorflow 是一个实验深度学习算法的巨大工具。但是,要利用深度学习的力量,你需要利用它的计算能力和良好的工程技术。您最终将需要使用多个 GPU,甚至可能是多个进程来达到您的目标。推荐你先看看 TensorFlow 关于 GPU 的官方教程

一个进程,多个 GPU

这是最常见的情况,因为大多数深度学习社区正在进行监督学习,有一个大数据集(图像、文本、声音……)和许多参数。这也是最困难的一点:您需要在多个计算单元上并行化反向传播。

Jonathan Hui 在 2017 年就此贴了一篇的优秀文章,大家可以直接看。这不是本文的重点。

多个进程,多个 GPU

这才是本文真正的看点。如果你正在进行强化学习,或者“奇特”类型的学习,比如遗传算法或水库计算,你可能会注意到拥有多个过程是必不可少的。

实验

我们将尝试以解决贪吃蛇游戏为例。蛇是一串方块,目标是吃格子上的水果。吃一个水果,蛇长增长一,格子上随机出现一个新的水果。蛇(不小心)吃了自己的尾巴就输了。

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

Snake game, the red dot is the fruit

我们将让多个代理同时进行游戏,以加速学习过程。

代理人

我们将使用一个简单的卷积神经网络,但您可以使用任何您想要的模型。例如,我们也可以使用密集神经网络或决策树。

这个博弈不是“动态的”:代理人需要采取的策略只取决于最后一帧。因此,网络被输入最后一帧,在我开发的 python 版本中是一个 10x10 的图像。我使用 100 个 4x4 过滤器,然后是 200 个 3x3 过滤器。我最后展平卷积,添加一个 200 的密集层,最后输出层的长度为 4,用于 4 个可能的动作(上,右,左,下)。

学习

我们就不赘述了,因为这不是这里的重点。例如,您可以使用策略梯度,其中输出层包含每个动作的概率,算法的思想是根据动作导致的分数“提升”动作。推荐你看这篇文章

也可以使用 **Q-learning,**其中输出层包含指定状态(输入帧)下每个动作的平均分数,取这些分数的 argmax 来选择一个动作。我推荐你阅读这篇文章

最后,你还可以使用一种遗传算法,这种算法的思想是在参数(这里是网络的权重)中加入噪声,只保留最好的代理。推荐你看这篇文章

让我们多重处理它

好了,现在我们可以(终于!)说说多重处理。总的来说,这不是一项容易的任务。这里我不谈论多线程,它更简单,但功能也更弱。

多重处理意味着多核。您需要与您想要启动的进程一样多的内核(有时内核可以处理多个“线程”,所以这是您最终关心的数字)。

我们将使用来自 AWS 的实例 p3.8xlarge,提供 32 个 vCores 和 4 个 V100 显卡。AWS 以大约 12 美元/小时的价格租赁它,而这台设备的投资大约为 4.5 万美元,加上运行它所需的能源成本。

因此,我们可以同时运行 32 个不同的代理,每个代理在一个单独的进程中运行。我们将使用 python 中的“多重处理”包。这个包允许我们启动进程并创建与它们通信的管道。这是我们架构的拓扑结构:

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

Graph of multiprocessing

我们有 32 个工作进程和 1 个主进程。工作进程只是玩游戏来收集数据并将其发送给主进程,主进程将根据这些数据进行训练,并将新网络保存在一个文件中。然后,工作人员收到消息以加载新网络,加载它,并再次玩 N 个游戏。因此,我们需要从主流程启动 32 个流程,并在主流程和每个流程之间创建一个管道(即 32 个管道)。我们还需要在主进程中创建线程来异步监听管道。下面是它的代码:

如您所见,我们在开始时创建了流程和管道,然后初始化字典来存储最后的分数和数据批次(键是流程 id)。然后我们创建线程来监听代理并启动它们。通信协议非常简单,只有一个词的消息,像“保存”或“train_with_batchs”。进程间的通信并不容易,因为你只需要传递可序列化的对象,所以基本上是容易解析的数据。例如,您不能直接传递 Tensorflow 会话。最后,我们玩游戏,同时将分数的移动平均值存储在一个文件中。

现在我们来看看 AgentProcess 类,它非常简单:

代理正在创建它的人工智能模型,并使用它来玩游戏。评分方法不是我在这里的重点,但你可以检查它,并调整自己,以获得更好的表现。“数据”是一个三元组(状态、动作、奖励)。相当简单,对吧?

GPU 分配和内存

默认情况下,Tensorflow 会为您的模型选择第一个可用的 GPU,并在设备上为您的进程分配全部内存。我们两个都不要!我们希望我们的工作进程共享一个模型,但分配他们自己的 GPU 集部分供他们自己使用。

共享模型非常困难,因为 Tensorflow 不允许在多个进程之间轻松共享图形或会话。我目前正在深入 Tensorflow,看看有没有可能,提高性能。目前,我得到的唯一解决方案是在每个进程中实例化一个新的 Tensorflow 核心,也就是说在 AgentProcess 类中调用“import tensorflow”。每个流程都有自己的图形和会话。

对于 GPU 分配,我们有 32 个进程,4 个 GPU,每个 16GB 内存。增加每个进程的内存会提高运行模型的进程的速度。但是内存是有限的,所以我们必须手动进行非常严格的优化…训练是由主进程完成的,需要大量内存,所以我为它分配了几乎一整个 GPU。

最终分配是[3,10,10,10](每个 GPU 的进程数,其中第一个也包含主处理器)。要限制内存,您可以使用 per _ process _ GPU _ memory _ fraction 或 gpu_options.allow_growth 手动限制每个进程的比例,这将为您管理内存(不在初始化时分配所有内存,仅在需要时增加内存)。我用的是后者。代码如下:

为了强制进程使用特定的 GPU,我使用了环境变量 CUDA_VISIBLE_DEVICES,它独立于派生工作进程的主进程。

很明显,增加流程的数量可以提高性能,这仅仅是因为处理了更多的批次。

结论

可以使用 Tensorflow 在“相当”强大的机器上进行多重处理和真正的强化学习。记住,机器学习不是如何想象一个算法,主要是如何高效地构建它。

这里是整个 github 回购

使用 BERT、RoBERTa、XLNet、XLM 和 DistilBERT 以及简单变压器进行多标签分类

原文:https://towardsdatascience.com/multi-label-classification-using-bert-roberta-xlnet-xlm-and-distilbert-with-simple-transformers-b3e0cda12ce5?source=collection_archive---------0-----------------------

了解如何使用 Transformer 模型,仅用简单的 Transformer 的 3 行代码来执行多标签分类。

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

Photo by russn_fckr on Unsplash

前言

简单变形金刚库是在优秀的变形金刚库的基础上通过抱脸的方式构建的。你们太不可思议了!

简单变压器现在支持:

还有很多正在筹备中。

介绍

变压器模型和迁移学习方法继续以惊人的速度推动自然语言处理领域向前发展。然而,最先进的性能往往是以大量(复杂)代码为代价的。

Simple Transformers 避免了所有的复杂性,让您开始关注重要的事情,训练和使用 Transformer 模型。绕过所有复杂的设置、样板文件和其他常见的不愉快,在一行中初始化一个模型,在下一行中训练,然后用第三行进行评估。

本指南展示了如何使用简单的变压器来执行多标签分类。在多标签分类中,每个样本可以具有来自给定标签集的任意标签组合*(无、一个、一些或全部)*。

所有的源代码都可以在Github Repo上找到。如果您有任何问题或疑问,这是解决它们的地方。请务必检查一下!

装置

  1. 这里安装 Anaconda 或 Miniconda 包管理器。
  2. 创建新的虚拟环境并安装软件包。
    conda create -n simpletransformers python pandas tqdm
    conda activate simpletransformers
    如果使用 cuda:
    conda install pytorch cudatoolkit=10.0 -c pytorch
    其他:
    conda install pytorch cpuonly -c pytorch
    conda install -c anaconda scipy
    conda install -c anaconda scikit-learn
    pip install transformers
    pip install seqeval
    pip install tensorboardx
  3. 如果您使用 fp16 培训,请安装 Apex。请遵循此处的说明。(从 pip 安装 Apex 给一些人带来了问题。)
  4. 安装简单变压器。
    pip install simpletransformers

多标签分类

为了演示多标签分类,我们将使用 Kaggle 的毒性评论数据集。从上面的链接下载数据集,并将csv文件放在data/目录中。

数据准备

数据集中的评论已经根据下面的标准进行了标注。

  • toxic
  • severe_toxic
  • obscene
  • threat
  • insult
  • identity_hate

数据集包含每个标准的一列,用布尔值 1 或 0 表示注释是否包含相应的毒性。

然而,简单的 Transformers 需要一个包含多热点编码标签列表的列labels,以及一个包含所有文本的列text(废话!).

让我们将df分成训练和评估数据集,这样我们就可以轻松地验证模型。

现在数据集已经可以使用了!

多标签分类模型

这创建了一个MultiLabelClassificationModel,可用于多标签分类任务的训练、评估和预测。第一个参数是 *model_type,*第二个是 model_name ,第三个是数据中标签的个数。

  • model_type可能是['bert', 'xlnet', 'xlm', 'roberta', 'distilbert'].中的一个
  • 关于可用于model_name的预训练模型的完整列表,请参考当前预训练模型

args参数接受一个可选的 Python 字典,其中包含超参数值和配置选项。我强烈推荐在这里查看所有选项。

默认值如下所示。

要加载一个先前保存的模型而不是默认模型,您可以将 model_name 更改为包含已保存模型的目录的路径。

model = MultiLabelClassificationModel('xlnet', 'path_to_model/', num_labels=6)

培养

这将根据训练数据训练模型。您还可以通过将包含相关属性的dict传递给train_model方法来更改超参数。请注意,这些修改将持续甚至在训练完成后。

train_model方法将在每第 n 步创建一个模型的检查点(保存),其中 nself.args['save_steps']。训练完成后,最终模型将保存到self.args['output_dir']

估价

eval_model方法用于对评估数据集进行评估。这个方法有三个返回值。

  • result:以dict的形式给出评估结果。默认情况下,对于多标注分类,仅报告标注等级平均精度(LRAP)。
  • model_outputs:评估数据集中每个项目的模型输出的一个list。如果您需要每个类别的概率,而不是单个预测,这将非常有用。请注意,sigmoid函数已应用于每个输出,以压缩 0 和.之间的值
  • 错误预测:每个错误预测的第InputFeaturelist。文本可以从InputFeature.text_a属性中获得。(*InputFeature*类可以在 *utils.py* 文件中的 回购 )

您还可以包括评估中使用的其他指标。只需将度量函数作为关键字参数传递给eval_model方法。度量函数应该接受两个参数,第一个是真实标签,第二个是预测。这遵循了 sklearn 标准。

确保度量函数与多标签分类兼容。

预测/测试

虽然当我们知道正确的标签并且只需要评估模型的性能时,eval_model是有用的,但是我们很少在现实世界的任务中知道真正的标签(我确信这里面有一些深刻的哲学)。在这种情况下,predict方法就派上了用场。它类似于eval_model方法,除了它不需要真正的标签并返回预测和模型输出。

我们可以在有毒评论数据集中提供的测试数据上进行尝试。

将此提交给 Kaggle 使我获得了 0.98468 的分数,再次证明了自变形金刚和迁移学习出现以来 NLP 取得了多大的进步。请记住,我在这里没有做太多的超参数调优!

结论

伯特及其衍生产品太棒了!我希望简单的变形金刚有助于在使用它们的过程中消除一些障碍。

TensorFlow 2.0 中的多标签图像分类

原文:https://towardsdatascience.com/multi-label-image-classification-in-tensorflow-2-0-7d4cf8a4bc72?source=collection_archive---------1-----------------------

了解如何从海报中预测电影的类型。

你想用 AI 建造令人惊叹的东西吗?你可以学到很多东西。新发布的 TensorFlow 2.0 通过集成更多高级 API,使深度学习开发变得更加容易。如果你已经是一个 ML 从业者,但仍然没有加入 TF 世界,你没有借口了!门票几乎免费。

在这篇博文中,我将描述一些在训练多标签图像分类器时你可能会感兴趣的概念和工具。完整的代码可以在 GitHub 上找到。所以,你可以坐下来动手了!

目录

  • 了解多标签分类
  • TensorFlow 2.0 有什么有趣的地方
  • 数据集(海报中的电影类型)
  • 构建快速输入管道
  • 用 TF 迁移学习。中心
  • 模型训练和评估
  • 导出 Keras 模型

了解多标签分类

近年来,机器学习在解决复杂的预测任务方面取得了巨大的成功,其规模是我们以前无法想象的。开始利用信息技术转变业务的最简单方法是,确定简单的二元分类任务,获取足够数量的历史数据,并训练一个好的分类器,以便在现实世界中很好地进行归纳。总有一些方法可以把一个预测性的商业问题变成一个是/否的问题。客户会流失吗?广告印象会产生点击吗?一次点击会产生转化吗?如果你收集有标签的数据,所有这些二元问题都可以用监督学习来解决。

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

我们还可以设计更复杂的监督学习系统来解决非二进制分类任务:

  • **多类分类:**有两个以上的类,每个观测值属于且仅属于一个类。例如,一家电子商务公司希望根据品牌(三星、华为、苹果、小米、索尼或其他)对智能手机等产品进行分类。
  • **多标签分类:**有两个或两个以上的类别,每个观察值同时属于一个或多个类别。应用的例子是医疗诊断,其中我们需要根据病人的体征和症状给病人开一个或多个治疗处方。
    以此类推,我们可以设计一个用于汽车诊断的多标签分类器。它将所有电子测量、错误、症状、里程作为输入,并预测汽车发生事故时需要更换的零件。

多标签分类在计算机视觉应用中也很常见。我们人类在看一部新电影的海报时,会用本能和印象去猜测它的内容(动作?戏剧?喜剧?等等。).你可能在地铁站遇到过这种情况,你想从墙上的海报中猜出电影的类型。如果我们假设在你的推理过程中,你正在使用海报的颜色信息,饱和度,色调,图像的纹理,演员的身体或面部表情以及任何使流派可识别的形状或设计,那么也许有一种数字方法可以从海报中提取那些重要的模式,并以类似的方式从它们中学习。如何建立一个学习预测电影流派的深度学习模型?让我们来看看你可以在 TensorFlow 2.0 中使用的一些技术!

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

TensorFlow 2.0 有什么有趣的地方

当 TensorFlow 在 2015 年由谷歌首次发布时,它迅速成为世界上最受欢迎的开源机器学习库——“一个全面的工具生态系统,面向希望推动机器学习的最新发展并构建可扩展的 ML 驱动的应用程序的开发者、企业和研究人员。”谷歌宣布在今年 9 月底正式发布 TensorFlow 2.0。新版本增加了主要功能和改进:

  • 默认情况下,Keras 与急切执行完全集成
  • 使用 tf.function 执行更多的 Pythonic 函数,这使得张量流图很好地优化了并行计算
  • 通过 TensorFlow 数据集实现更快的输入管道,以非常高效的方式传递训练和验证数据
  • 使用 TensorFlow 服务TensorFlow LiteTensorFlow.js 在服务器、设备和网络浏览器上实现更强大的生产部署

就个人而言,我喜欢在 TensorFlow 1.x 中构建定制的估算器,因为它们提供了高度的灵活性。所以,我很高兴看到估算器 API 被扩展。我们现在可以通过转换现有的 Keras 模型来创建估计量。

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

TensorFlow 2.0 is now available!

数据集(海报中的电影类型)

这个数据集托管在 Kaggle 上,包含来自 IMDB 网站的电影海报。可以下载一个 csv 文件MovieGenre.csv。它包含每部电影的以下信息:IMDB Id、IMDB 链接、标题、IMDB 分数、类型和下载电影海报的链接。在这个数据集中,每个电影海报可以属于至少一个流派,最多可以分配 3 个标签。海报总数在 40K 左右。

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

需要注意的重要一点是,所有电影类型的数量并不相同。它们中的一些可能非常罕见,这可能对任何 ML 算法都是一个严峻的挑战。您可以决定忽略所有少于 1000 条评论的标签(短片、西部、音乐、体育、黑色电影、新闻、脱口秀、真人秀、游戏节目)。这意味着,由于缺少对这些标签的观察,模型将不会被训练来预测这些标签。

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

构建快速输入管道

如果你熟悉 keras .预处理,你可能知道图像数据迭代器(例如 ImageDataGeneratorDirectoryIterator )。这些迭代器对于多类分类很方便,其中图像目录包含每个类的一个子目录。但是,在多标签分类的情况下,拥有一个遵循这种结构的图像目录是不可能的,因为一个观察可以同时属于多个类。

这就是 tf.data API 占上风的地方。

  • 它更快
  • 它提供了细粒度的控制
  • 它与 TensorFlow 的其余部分集成得很好

首先需要编写一些函数来解析图像文件,并生成一个表示特征的张量和一个表示标签的张量。

  • 在解析功能中,您可以调整图像的大小,以适应模型所期望的输入。
  • 您也可以将像素值缩放到 0 到 1 之间。这是一种常见的做法,有助于加快训练的衔接。如果您将每个像素视为一个特征,您会希望这些特征具有相似的范围,以便梯度不会失去控制,并且您只需要一个全局学习率乘数。
IMG_SIZE = 224 # Specify height and width of image to match the input format of the modelCHANNELS = 3 # Keep RGB color channels to match the input format of the model

要在我们的数据集上训练模型,您希望数据是:

  • 洗得很好
  • 成批的
  • 尽快提供批次。

使用 tf.data.Dataset 抽象可以很容易地添加这些特性。

BATCH_SIZE = 256 # Big enough to measure an F1-scoreAUTOTUNE = tf.data.experimental.AUTOTUNE # Adapt preprocessing and prefetching dynamically to reduce GPU and CPU idle timeSHUFFLE_BUFFER_SIZE = 1024 # Shuffle the training data by a chunck of 1024 observations

AUTOTUNE将使预处理和预取工作负载适应模型训练和批量消费。要预取的元素数量应该等于(或者可能大于)单个训练步骤消耗的批次数量。AUTOTUNE会提示 tf.data 运行时在运行时动态调优值。

现在,您可以创建一个为 TensorFlow 生成训练和验证数据集的函数。

train_ds = create_dataset(X_train, y_train_bin)
val_ds = create_dataset(X_val, y_val_bin)

每个批处理将是一对数组(一个保存特性,另一个保存标签)。特征阵列将具有包含缩放像素的形状(批量大小、IMG 大小、IMG 大小、通道)。标签数组的形状为(BATCH_SIZE,N_LABELS ),其中 N_LABELS 是目标标签的最大数量,每个值表示电影中是否有特定的流派(0 或 1 值)。

用 TF 迁移学习。中心

你可以在一个叫做迁移学习的过程中使用一个预先训练好的模型,而不是从头开始建立和训练一个新的模型。视觉应用的大多数预训练模型都是在 ImageNet 上训练的,ImageNet 是一个大型图像数据库,拥有超过 1400 万张图像,分为 2 万多个类别。迁移学习背后的想法是,由于这些模型是在大型和一般分类任务的背景下训练的,因此可以通过提取和迁移先前学习的有意义的特征来处理更具体的任务。你所需要做的就是获得一个预先训练好的模型,并简单地在其上添加一个新的分类器。新的分类负责人将从头开始接受培训,以便您将目标重新用于多标签分类任务。

TensorFlow 核心团队在分享预训练模型和如何使用tf.keras API 的教程方面做得非常好。
用 hub 转移学习
用 Franç ois Chollet 转移学习

什么是 TensorFlow Hub?

软件开发中的一个基本概念是重用通过库获得的代码。库使开发速度更快,效率更高。对于从事计算机视觉或 NLP 任务的机器学习工程师来说,我们知道从零开始训练复杂的神经网络架构需要多长时间。 TensorFlow Hub 是一个允许发布和重用预制 ML 组件的库。使用 TF。Hub 中,重新训练预训练模型的顶层以识别新数据集中的类变得很简单。TensorFlow Hub 还分发没有顶级分类层的模型。这些可以用来轻松地执行迁移学习。

下载一个无头模型

任何来自 tfhub.dev 的 Tensorflow 2 兼容的图像特征向量 URL 都可能对我们的数据集感兴趣。唯一的条件是确保我们准备的数据集中影像要素的形状与您想要重复使用的模型的预期输入形状相匹配。

首先,让我们准备特征提取器。我们将使用预训练的 MobileNet V2 实例,深度乘数为 1.0,输入大小为 224x224。MobileNet V2 实际上是一个大型的神经网络架构家族,主要用于加速设备上的推理。根据深度乘数(隐藏卷积层中的特征数量)和输入图像的大小,它们有不同的大小。

我们在这里使用的特征提取器接受 shape (224,224,3)的图像,并为每个图像返回一个 1280 长度的向量。

您应该冻结特征提取器图层中的变量,以便训练仅修改新的分类图层。通常,当处理的数据集与训练特征提取器的原始数据集相比非常小时,这是一种很好的做法。

feature_extractor_layer.trainable = False

只有当训练数据集很大并且与原始 ImageNet 数据集非常相似时,才建议微调特征提取器。

附上分类标题

现在,您可以将特征提取层包装在一个tf.keras.Sequential模型中,并在上面添加新的层。

模型摘要如下所示:

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

MobileNet 中的 2.2M 参数被冻结,但在密集层中有 1.3K 可训练参数。你需要在最终的神经元中应用 sigmoid 激活函数,以输出每种流派的概率分数。通过这样做,你依靠多个逻辑回归在同一个模型中同时训练。每个最终神经元将作为一个单独类别的单独的二元分类器,即使所提取的特征对于所有最终神经元是共同的。

当使用此模型生成预测时,您应该期望每个流派有一个独立的概率分数,并且所有概率分数的总和不一定等于 1。这与在多类别分类中使用 softmax 图层不同,在多类别分类中,输出中的概率得分之和等于 1。

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

模型训练和评估

在准备数据集并通过在预训练模型上附加多标签神经网络分类器来构建模型之后,您可以继续进行训练和评估,但首先您需要定义两个主要函数:

  • **一个损失函数:**你需要它来衡量批次上的模型误差(成本)。它必须是可微分的,以便反向传播神经网络中的误差并更新权重。
  • **一个评价函数:**它应该代表你真正关心的最终评价指标。与损失函数不同,它必须更加直观,以便理解模型在现实世界中的表现。

假设你想用宏 F1-score @ threshold 0.5 来评估模型的性能。它是将每个标签的概率阈值固定为 0.5 时获得的所有 F1 得分的平均值。如果所有标签在多标签分类任务中具有相同的重要性,则对所有标签取平均值是非常合理的。我在这里提供了这个度量在 TensorFlow 中的一批观测上的实现。

这个度量是不可微的,因此不能用作损失函数。相反,你可以把它转化成一个可以最小化的可微版本。我们将把结果损失函数称为宏软 F1 损失!

通常,通过使用传统的二元交叉熵来优化模型是很好的,但是宏软 F1 损失带来了非常重要的好处,我决定在一些用例中利用这些好处。如果你有兴趣了解更多细节背后的动机实施这一自定义损失,你可以阅读我的博客文章: “未知的好处使用软-F1 损失在分类系统”

使用宏软 F1 损失训练模型

指定学习率和训练时期数(整个数据集的循环数)。

LR = 1e-5 # Keep it small when transfer learning
EPOCHS = 30

编译模型以配置培训流程。

model.compile(
  optimizer=tf.keras.optimizers.Adam(learning_rate=LR),
  loss=macro_soft_f1,
  metrics=[macro_f1])

现在,您可以传递(要素、标注)的训练数据集来拟合模型,并指示单独的数据集进行验证。将在每个时期后测量验证集的性能。

history = model.fit(train_ds,
  epochs=EPOCHS,
  validation_data=create_dataset(X_val, y_val_bin))

30 个时期后,您可能会观察到验证集的收敛。

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

显示预测

让我们看看当在验证集中的一些已知电影的海报上使用我们的模型时,预测是什么样子的。

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

我们注意到这个模型可以得到“浪漫”的权利。是因为《风流韵事》海报上的红色标题吗?

为《诸神之战》建议新标签的模型怎么样?“科幻”的标签似乎非常准确,与这部电影有关。请记住,在原始数据集中,每个海报最多有 3 个标签。或许,通过使用我们的模型可以推荐更多有用的标签!

导出 Keras 模型

训练和评估模型后,可以将其导出为 TensorFlow 保存的模型以供将来使用。

您可以稍后重新加载 tf.keras 模型,方法是指定包含。pb 文件。

请注意 custom_objects 字典中的“KerasLayer”对象。这就是 TF。用于构建模型的中心模块。

摘要

  • **多标签分类:**当一个观察值的可能标签数大于 1 时,应该依靠多元逻辑回归来解决许多独立的二元分类问题。使用神经网络的好处是你可以在同一个模型中同时解决这么多问题。小批量学习有助于降低训练时的记忆复杂度。
  • TensorFlow 数据 API : tf.data 使构建训练和评估 TensorFlow 模型的快速输入管道成为可能。使用 tf.data.Dataset 抽象,您可以收集观察值作为一对表示图像及其标签的张量分量,并行地对它们进行预处理,并以非常简单和优化的方式进行必要的混洗和批处理。
  • TensorFlow Hub :迁移学习从来没有这么简单。
    TF。Hub 提供来自大型预训练 ML 模型的可重用组件。您可以加载包装为 keras 层的 MobileNet 要素提取器,并在其上附加您自己的完全连接的层。可以冻结预训练模型,只有分类图层的权重会在训练过程中更新。
  • 直接为宏 F1 优化:通过引入宏软 F1 损失,您可以训练模型直接增加您关心的指标:宏 F1 得分@阈值 0.5。在应用这个定制的损失函数时,您可能会发现有趣的好处。我邀请您查看这篇 文章 以了解更多信息。

基于神经网络的多标签图像分类

原文:https://towardsdatascience.com/multi-label-image-classification-with-neural-network-keras-ddc1ab1afede?source=collection_archive---------3-----------------------

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

Image by besthqwallpapers

在本指南中,我们将介绍多标签分类以及我们在实施时可能面临的挑战。在多标签分类中,一个数据样本可以属于多个类别(标签)。其中在多类分类中,一个数据样本只能属于一个类。

例子

  • 根据animal image预测animal类是多类分类的一个例子,其中每种动物只能属于一个类别。
  • movie poster预测movie genre是多标签分类的一个例子,一部电影可以有多种类型。

在转向多标签之前,让我们先了解一下多类分类,因为两者有一些相似之处。

多类分类

在多类别分类中,神经网络的输出节点数与类别数相同。每个输出节点属于某个类,并输出该类的分数。

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

Multi-Class Classification (4 classes)

来自最后一层的分数通过一个 softmax 层。softmax 层将分数转换成概率值。最后,数据被分类到具有最高概率值的相应类别中。下面是 softmax 函数的代码片段。

def softmax(scores): exp = np.exp(scores)
    scores = exp / np.sum(exp)
    return scoressoftmax([5, 7, 4, 6])> [0.0871 0.6439 0.0320  0.2368]

损失函数

  • 我们一般用categorical_crossentropy损失进行多类分类。

目标向量

  • 我们必须向神经网络输入一个one-hot编码向量作为目标。例如,如果数据属于类别 2,我们的目标向量如下。
[0 1 0 0]

我们可以在 Keras 中建立一个用于多类分类的神经网络,如下所示。

Network for Multi-Class Classification

这就是我们如何做一个多类分类。现在让我们跳到多标签分类。

多标签分类

唯一的区别是一个数据样本可以属于多个类。在多标签分类中,我们必须以不同的方式处理一些事情。

激活功能

  • 每门课的最终分数应该是相互独立的。因此,我们不能应用 softmax 激活,因为 softmax 将分数转换为考虑其他分数的概率。
  • 最终得分独立的原因显而易见。如果电影类型是action,那么它不应该影响电影是否也是thriller
  • 我们在最后一层使用 sigmoid 激活函数。Sigmoid 将最终节点的每个分数在 0 到 1 之间转换,而与其他分数无关。
  • 如果某一类的得分超过 0.5,则该数据被归入该类。并且可以有多个独立的得分超过 0.5 的类别。因此,数据可以分为多个类别。以下是 sigmoid 激活的代码片段。
def sigmoid(scores):

    scores = np.negative(scores)
    exp = np.exp(scores)
    scores = 1 / (1 + exp)
    return scoressigmoid([2, -1, .15, 3]))> [0.8807 0.2689 0.5374 0.9525]

损失函数

  • 由于我们使用了一个sigmoid激活函数,我们不得不使用binary_crossentropy损失。

目标向量

  • 这里我们也必须输入一个one-hot编码的向量,但是可能有多个。例如,如果数据属于类别 2 和类别 4,我们的目标向量如下。
[0 1 0 1]

下图说明了多标签分类。

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

Multi-Label Classification (4 classes)

我们可以在 Keras 中为多标签分类建立如下的神经网络。

Network for Multi-Label Classification

这些都是我们必须为多标签分类做出的重要改变。现在,让我们来探讨一下在多标签分类中可能面临的挑战。

多标签分类中的数据不平衡

多标签分类的主要挑战是数据不平衡。我们不能像在多类分类中那样简单地使用抽样技术。

数据不平衡是机器学习中众所周知的问题。其中数据集中的一些类比其他类更频繁,神经网络只是学习预测频繁的类。

例如,如果数据集包含 100 幅猫和 900 幅狗的图像。如果我们根据这些数据训练神经网络,它每次都会学习预测狗。在这种情况下,我们可以使用采样技术轻松平衡数据。

  • 通过移除一些狗的例子(下采样)
  • 通过使用图像增强或任何其他方法创建更多的 cat 示例(上采样)。

然而,当我们有多标签数据时,这个问题就变得很现实。让我们看看下面的电影类型数据集(40K 样本),其中我们必须从一部电影poster中预测电影genre。一部电影可以属于多个类型。总共有 16 种类型的体裁。

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

Movie Genre Count

缩减采样挑战

  • 在这个数据中,标签dramacomedy出现的频率非常高。但是我们不能简单地丢弃带有多数标签的数据样本,因为这些数据样本也可能与其他标签相关联。丢弃这些样本也会导致其他标签的丢失。

上采样挑战

  • 如果我们用少数类产生相似的例子,那么将会有多个具有相似模式的标签。这将增加过度拟合的机会。

即使我们有一个理想的电影类型数据集(40K 样本),其中所有类型在数量上是相等的。每部电影平均有两种类型。那么每个流派会出现(40000*2)/16 = 5000 次左右。我们仍然有一个不平衡的数据集,因为网络只看到每个流派的 12.5%的时间。在这种情况下,网络只是学习预测根本没有流派。

为了更好地理解,下面是一步一步的计算。

Total samples => 40000Total genre => 16Avg genre in one sample => 2Occurance of one genre in all samples => (40000*2)/16 => 5000Percentage of one genre per sample => 5000/40000 => 0.125 => 12.5%

为了解决多标签分类中的数据不平衡问题,已经做了大量的研究。以下是几篇关于多标签分类和数据不平衡的论文。

在我的下一篇博客中,我将会从海报项目中做电影类型预测 。即多标签分类项目。在此之前,请保持联系,并准备好您的 GPU。

更多来自作者

[## 理解自我监督学习,并举例说明

迈向艾将军的一步?

shiva-verma.medium.com](https://shiva-verma.medium.com/understanding-self-supervised-learning-with-examples-d6c92768fafb)

基于深度学习的多标签土地覆盖分类

原文:https://towardsdatascience.com/multi-label-land-cover-classification-with-deep-learning-d39ce2944a3d?source=collection_archive---------15-----------------------

使用深度神经网络进行多标签土地覆盖分类的分步指南

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

Multi-label Land Cover Classification — Source

与单标签分类相比,对多标签土地覆盖分类的探索较少。相比之下,多标签分类更现实,因为我们总是在每个图像中找到多个土地覆盖。然而,通过深度学习应用和卷积神经网络,我们可以解决多标签分类的挑战。

在本教程中,我们使用重新设计的多标签 UC Merced 数据集和 17 个土地覆盖类。加州大学 Merced 土地利用数据集最初是作为最早的计算机视觉卫星数据集之一推出的。UC Merced 数据集被认为是卫星图像数据集的 MNIST。原始数据集由 21 类单标签分类组成。

在下一节中,我们将获取数据并研究数据集中的类和类不平衡。接下来,我们使用深度神经网络训练我们的模型,最后,我们使用外部图像测试我们的模型以进行推断。

获取数据

我们可以从以下网址使用 WGET 软件包直接访问 Jupyter 笔记本/Google Colab 中的数据。

!wget [https://www.dropbox.com/s/u83ae1efaah2w9o/UCMercedLanduse.zip](https://www.dropbox.com/s/u83ae1efaah2w9o/UCMercedLanduse.zip)!unzip UCMercedLanduse.zip

一旦我们获得数据并解压缩,我们就准备好探索它了。让我们从标签开始。我们阅读熊猫的标签。

df = pd.read_csv(“UCMerced/multilabels.txt”, sep=”\t”)df.head()

这是前五行的标签。正如您所看到的,数据是一个热编码格式。每个图像有 17 个标签,其中“0”表示该标签在特定图像中不存在,而“1”表示该标签在图像中存在。我们总共有 2100 张图片。

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

UC Merced Multi-labels DataFrame

在我们继续使用神经网络和深度学习对任务进行分类之前,我们可以看看数据集中类的分布。检查数据集的分布是检查数据集中数据不平衡的重要步骤。我们首先创建一个新的数据框来存储类及其计数。

# Create Class count dataframe
class_count = pd.DataFrame(df.sum(axis=0)).reset_index()
class_count.columns = [“class”, “Count”]
class_count.drop(class_count.index[0], inplace=True)# Visualize class distribution as Barchartfig, ax= plt.subplots(figsize=(12,10))
sns.barplot(y="class", x="Count",  data=class_count, ax=ax);

以下可视化显示了数据集中的类别不平衡。我们有超过 1200 个图像的路面类,而飞机类有 100 个图像。

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

Class Distribution — UC Merced Multi-label dataset

在下一节中,我们开始用 Fastai 库训练数据集。Fastai 是一个用户友好的库,构建在 Pytorch 之上,提供了许多易于使用的功能。

培养

我们需要为训练准备数据。我们的数据标签是一个热点编码格式,我认为这将是一个挑战。幸运的是,浏览了一下 Fastai 论坛,我发现 Fastai 中有一个本机函数,可以使用一键编码格式处理多标签。当我们给数据集加标签时,我们需要传递列名,还需要指明数据是多类别数据集。

path = Path(“UCMerced”)data_src = (ImageList.from_df(df=df, path=path, folder=’images’,    suffix=”.tif”)
      .split_by_rand_pct(0.2)
      .label_from_df(cols=list(class_count[‘class’]),  label_cls=MultiCategoryList, one_hot=True))

一旦我们创建了数据源,我们就可以通过 Fastai 中的 data bunch API 来传递它。我们还执行一些数据扩充。

tfms = get_transforms(flip_vert=True, max_lighting=0.1, max_zoom=1.05, max_warp=0.)data = (data_src.transform(tfms, size=256).databunch().normalize(imagenet_stats))data.show_batch(4)

这里有一些随机图像,它们的标签用 Fastai 可视化。

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

Random images and labels — UC Merced dataset

接下来,我们创建一个学习器,在那里我们传递我们创建的数据串、模型的选择(在本例中,我们使用 resnet34)和指标(accuracy_thresh 和 F Score)。

f_score = partial(fbeta, thresh=0.45)learn = cnn_learner(data, models.resnet34, metrics=[accuracy_thresh, f_score], callback_fns=[CSVLogger,ShowGraph, SaveModelCallback])

我们也可以通过 Fastai 中的 lr_find 作图,得到适合训练数据集的学习率。

learn.lr_find()learn.recorder.plot()

现在,我们可以开始用数据训练我们的模型。我们使用 fit_one_cycle 函数,这是一个强大的函数,使用一个循环技术结合了最先进的技术。

learn.fit_one_cycle(5, 1e-2)

一旦训练开始,Fastai 就显示与每个时期的训练和验证损失和时间一起提供的度量

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

Training

我们的最终历元记录了 95.53 的准确度阈值和 90.84 的 F 分数,这对于仅仅五个历元来说是相当准确的。我们可以进一步训练,提高我们的指标。为此,我们可以冻结一些层,并从头开始训练其他层。

learn.freeze()
lr = 1e-3learn.fit_one_cycle(5, slice(lr))

我们最终的模型得分是 91.39 F 分,相比之前的训练有了一点点的提升。我们可以通过使用更多的纪元或增加深度神经网络的架构来进行更多的训练。你可以尝试一下,看看是否有助于改进模型。在下一节中,我们将使用外部图像作为模型的推论。

不同数据集的预测

为了测试该模型,我们从外部来源预测几幅图像,并观察该模型的表现。

!wget [https://www.dropbox.com/s/6tt0t61uq2w1n3s/test.zip](https://www.dropbox.com/s/6tt0t61uq2w1n3s/test.zip)!unzip test.zipimg = open_image(“/content/test/roundabout_086.jpg”)img

测试数据集中的第一幅图像如下所示。

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

让我们看看这个模型预测了什么:

MultiCategory bare-soil;buildings;cars;grass;pavement

嗯,这就是模型产生的结果,我认为从我们在训练数据集中使用的类来看,它是准确的。我们的预测已经预测了图像中存在的大多数类(至少从我的眼睛中可以看到)。

让我们用另一个图像来测试。

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

这个模型预测

MultiCategory airplane;cars;pavement

飞机和人行道,是的,但是我没看见任何汽车。

结论

在本教程中,我们使用深度神经网络训练了一个多标签类别分类模型。我们还用其他图像对模型进行了推论。

本教程的代码和 Google Colab 笔记本可以在这个 Github 资源库中找到。

[## shaka som/多标签-土地覆盖-深度学习

与单标签分类相比,对多标签土地覆盖分类的探索较少。相比之下…

github.com](https://github.com/shakasom/multilabel-landcover-deeplearning)

你可以通过这个链接直接访问 Google Colab 笔记本

[## shaka som/多标签-土地覆盖-深度学习

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

github.com](https://github.com/shakasom/multilabel-landcover-deeplearning/blob/master/Multi_label_Land_Cover_Classification.ipynb)

多标签文本分类

原文:https://towardsdatascience.com/multi-label-text-classification-5c505fdedca8?source=collection_archive---------2-----------------------

根据描述给电影分配标签

介绍

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

Unsplash

要了解各种分类类型,我们来考虑上图。

┌──────────────┬────────────────────┬──────────────────────┐
│ Is it a hen? │    Which label?    │    Which labels?     │
├──────────────┼────────────────────┼──────────────────────┤
│ **Yes**/No       │ harmony/**hen**/nature │ **harmony, hen, nature** │
│ **BINARY**       │ **MULTICLASS**         │ **MULTI-LABEL **         │
└──────────────┴────────────────────┴──────────────────────┘

二元分类的情况下,我们只问一个是/否类型的问题。如果有多个可能的答案,并且只能选择一个,那么就是多类分类。在我们的例子中,我们不能只选择一个标签,我认为所有的标签都与照片匹配。多标签分类的目标是为单个实例分配一组相关的标签。然而,大多数广为人知的算法都是针对单标签分类问题而设计的。本文描述了 scikit-multilearn 库中可用的四种多标签分类方法,并介绍了样本分析。

多标签分类方法

  1. 问题转化方法将多标签问题分成一个或多个常规的单标签问题。
  2. 问题自适应方法将单标签算法一般化,直接处理多标签数据。
  3. 集成方法结合了前两种方法的优点

在接下来的部分中,我将描述下图所示的方法。

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

Fig. 1 Multi-label classification methods

二元相关性

在二元相关性的情况下,单标签二元分类器的集合在原始数据集上被独立地训练,以预测每个类的成员资格,如图 2 所示。

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

Fig. 2 Binary Relevance example

┌─────────────────────┬─────────────────────────────────────────┐
│     **Advantages  **    │              **Disadvantages **             │
├─────────────────────┼─────────────────────────────────────────┤
│ - linear complexity │ - ignoring correlation between labels   │
│ - simplicity        │   by treating each label independently  │
└─────────────────────┴─────────────────────────────────────────┘

标签电源集

这种方法将标签的每个组合映射到单个标签中,并训练单个标签分类器(图 3)。

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

Fig. 3 Label Powerset example

┌────────────────┬───────────────────────────────────┐
│   **Advantages **  │           **Disadvantages **          │
├────────────────┼───────────────────────────────────┤
│ - taking label │ - high computational complexity   │
│   correlations │ - can lead to imbalanced dataset  │
│   into account │  with multiple classes associated │
│                │  with few examples                │
└────────────────┴───────────────────────────────────┘

MLkNN

对于测试集中的每个实例,识别其在训练集中的 K 个最近邻。对于 Y 中的每个类 Y,属于 Y 的相邻实例的数量用于计算测试实例属于或不属于 Y 的后验概率。基于这些概率中哪个更大,我们决定是否将类 Y 分配给测试实例。

为了更好地理解,假设下面的样本是在测试实例 X = 1 的训练集中找到的邻居。

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

现在,我们必须为测试实例 X = 1 计算每个类别的先验和后验概率

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

f1 和 f2 获得了最大值。因此,我们将测试实例分配给这两个类。

┌─────────────────────────┬───────────────────────────────────────┐
│       **Advantages **       │            ** Disadvantages **            │
├─────────────────────────┼───────────────────────────────────────┤
│ - better accuracy than  │ - with the binary relevance strategy, │
│   the previous methods  │   the ratio estimation                │
│ - correlations between  │   may not be accurate                 │
│   labels are considered │ - data distributions for some labels  │
│                         │   are imbalanced                      │
└─────────────────────────┴───────────────────────────────────────┘

分类器链

分类器链模型像二进制相关方法一样学习分类器。然而,所有的分类器都是连锁的。

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

Fig. 4 Classifier Chain rule

  1. 首先,所有的特征(X1,X2,…,Xm)被用来预测 y1。
  2. 然后,所有的特征(X1,X2,…,Xm,y1)被用来预测 y2
  3. 最后,应用(X1,X2,…,Xm,y1,y2)来预测 y3

标签的预测顺序对结果有很大的影响。

┌────────────────────────────┬──────────────────────────┐
│         **Advantages **        │      **Disadvantages **      │
├────────────────────────────┼──────────────────────────┤
│ - label correlation taken  │ - accuracy heavily       │
│   into consideration       │   depends on the order   │
│ - acceptable computational │ - for n labels there     │
│   complexity               │   are n! possible orders │
└────────────────────────────┴──────────────────────────┘

资料组

我们将为我们的项目使用 CMU 电影摘要语料库开放数据集。你可以直接从这个 链接 下载数据集。

该数据集包含多个文件,但我们只需要其中的两个:

  • **movie . Metadata . tsv:**81,741 部电影的元数据,从 2012 年 11 月 4 日的 Freebase 转储中提取。该文件中提供了电影类型标签
  • plot_summaries.txt: 从 2012 年 11 月 2 日的英文维基百科转储中提取的 42,306 部电影的情节摘要。每一行都包含维基百科电影 ID(索引到 movie.metadata.tsv )和情节摘要

代码示例

我们将创建一个表格,包含分配给电影的多种类型和描述。基于这样的描述,我们将尝试给每部电影分配合适的类型。

让我们从导入必要的库开始。对于上述方法,我们将使用 skmultilearn 模块。

现在是时候清理文本中的特殊符号了,去掉停用词,打上戳记,并将类型变量放入单独的二进制列中。

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

当数据准备好了,我们可以把它分成训练集和测试集,并转换成一个 TF-IDF 特征矩阵。我们将根据语料库中的词频(由于计算的复杂性)对其中的前 10000 个进行排序。请注意,最大长度为 3 的 N 元文法在这里被认为是潜在的特征。由于 n_gram_rangemax_features 在精度上是必不可少的参数,推荐大家自己玩:)

让我们应用上述模型并比较结果。为了选择我们将测量的最佳模型:

  1. 准确性 —准确性是最常见的衡量标准。然而,这在很大程度上是由我们在这种情况下以及在大多数商业案例中所拥有的大量真正的负面因素造成的。
  2. F1 分数 —如果我们需要在精确度和召回率之间寻求平衡,并且存在不均匀的类别分布(大量实际否定),F1 分数可能是一个更好的衡量标准
  3. 汉明损失 —被错误预测的标签的比例。在不平衡数据集的情况下带来额外的信息。

准确度= 0.004,F1 得分= 0.222,汉明损失= 0.033

准确度= 0.090,F1 得分= 0.261,汉明损失= 0.009

准确度= 0.052,F1 得分= 0.235,汉明损失= 0.01

如您所见,由于数据集严重失衡,所有情况下的准确性都非常低。标签 Powerset 模型获得了最好的结果。然而,我们仍然要应用分类器链。我将在这里预测每个类的概率赋值,然后用阈值参数玩一会儿(默认情况下它等于 0.5 )。上面说了如何区分 0/1 标签赋值。你会发现它的价值对于型号的选择是至关重要的。

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

该图显示最佳阈值约为 0.2。这是 F1 分数接近最大值 0.43、准确度增加且汉明损失低的点。

结论

总之,描述了流行的多标记分类方法,并在实际例子中进行了比较。分类器链方法通过修改最小阈值获得了最好的结果,基于此我们在二分类问题中指定 1。在未来的工作中,标签的顺序可能会被打乱和测试,这是一个耗时的过程。

在下一篇文章中,我将使用深度学习方法解决相同的问题。这是自然语言处理中发展最快和最重要的子领域,可以获得最好的结果。

感谢阅读!

基于 XLNet 的多标签文本分类

原文:https://towardsdatascience.com/multi-label-text-classification-with-xlnet-b5f5755302df?source=collection_archive---------3-----------------------

使用 XLNet 实现最先进的多标签和多类别文本分类

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

Photo by Christopher Gower on Unsplash

在 2019 年 6 月 19 日发表时,XLNet 在 18 项任务上取得了最先进的结果,包括文本分类、问答、自然语言推理、情感分析和文档排名。

它甚至在 20 个任务上超过了 BERT!

由卡耐基梅隆大学和谷歌大脑开发的 XLNet 是一个基于排列的自回归语言模型。

我们不会过多地探究模型的内部工作原理,因为有很多很好的资源可以用于这个目的。相反,本文将集中讨论 XLNet 在多标签和多类文本分类问题上的应用。

介绍

让我们快速回顾一下。在多类分类问题中,有多个类,但是任何给定的文本样本将被分配一个类。

另一方面,在多标签文本分类问题中,一个文本样本可以被分配给多个类别。

我们将使用由 HuggingFace 开发的变形金刚库。Transformers 库提供了许多先进语言模型的易用实现:BERT、XLNet、GPT-2、RoBERTa、CTRL 等。

此外,我还想对 Kaushal Trivedi 表示感谢,他在 BERT 上关于多标签分类的惊人的教程是这里代码的基础。

我们将应对 Kaggle 的毒性评论分类挑战,我们需要预测在线评论的六种可能的评论毒性类别的概率。

快速说明一下,XLNet 有一个基础版本和一个大版本:

  • XLNet 库:12 层,768 个隐藏单元,12 个注意头,110M 参数。
  • XLNet Large: 24 层,768 个隐藏单元,16 个注意头,340M 参数

我们将在 Google Colab 上训练我们的模型,Google Colab 免费提供 16 GB 的特斯拉 P100!

由于特斯拉 P100 的 GPU 内存限制,我们将使用 XLNet 基础为我们的任务。

我们不会从头开始训练模型,而是对预训练的模型进行微调。这个概念被称为迁移学习。

没有别的事了,我们开始吧!

密码

点击此处获取本文附带的 Colab 笔记本。

首先,让我们安装必要的库,实际上只是变压器。

接下来,我们导入必要的库。

检查 GPU 是否可用。

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

将你的 google drive 安装到你的 Colab 笔记本上。

对于我们的例子,我们将在 google drive 中创建一个Data文件夹,并将数据集放在那里。

读取.csv文件。

让我们来看看数据集。

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

Train dataset

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

Test dataset

让我们做一些快速 EDA。分析标签的分布,我们注意到标签是不平衡的。

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

Distribution of labels in the training data

在将一段文本输入模型之前,必须将文本标记成适当的子词。为此,我们可以使用 HuggingFace 的XLNetTokenizer

理论上,基于 XLNet 的模型能够处理多达 512 个子字的序列。然而,为了减少训练时间,也考虑到有限的 GPU 内存,我们将选择一个较小的序列大小。

我们可以分析评论的子词数量的分布。

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

Distribution of the number of sub-word tokens in the training data

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

Distribution of the number of sub-word tokens in the testing data

由于大多数评论的子词少于 250 个,我们可以将所有评论截断或填充到 250 个子词。

将输入文本序列转换成适当的数字标记 id。

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

Example of the processed tokenized inputs

接下来,我们将创建注意屏蔽,它指示模型在适当的令牌上执行注意。目的是防止我们的模型对填充标记进行关注。

将标记化的数字输入和注意屏蔽附加到数据帧。

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

Train dataframe

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

Test dataframe

出于交叉验证的目的,我们将执行培训和验证分割。

创建特征、遮罩和标签数组,并将其转换为火炬张量。

接下来,为训练集和验证集创建Dataloaders。我们将使用 32 的批量大小。

如果 Colab 为您的运行时分配 12 GB Tesla K80,您可能会考虑将批处理大小减少到 16,以避免耗尽 GPU 内存。

让我们定义我们的 XLNet 分类模型。

由于输入序列有 250 个记号,XLNet 将产生 250 个输出向量,每个向量的维数为 768。我们将对输出向量进行平均汇集,并生成一个维数为 768 的向量。该向量将成为全连接层的输入,该层将预测 6 个注释毒性标签。

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

Mean pooling the output vectors into a single vector

您肯定可以探索其他方法来汇集输出,比如将输出连接成一个大的向量,或者甚至使用 XLNet 最后几个隐藏层的输出。

接下来,我们初始化优化器。我们将使用AdamW优化器。如果需要,您还可以设置学习率计划。

我们现在将定义训练函数。在训练期间,该函数将在达到最低验证损失时保存模型。

在特斯拉 P100 上,一次训练大约需要 1 小时 30 分钟。

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

在我们的模型被训练之后,我们可以为 153,164 个测试示例生成预测。

如果我们试图一次性预测所有测试示例的标签,我们的 GPU 很可能会耗尽内存。对此的解决方案是为每 32 个测试实例生成预测,并将它们连接在一起。

当然,32 的批量大小可以根据 GPU 内存的多少而改变。

将结果提交给 Kaggle,经过一个时期的微调训练,我们获得了 0.98182 的公共分数和 0.98323 的私有分数。不算太寒酸!

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

请注意,我们没有执行任何参数调整或功能工程。

如果您想要预测的硬标签而不是软概率,只需将软概率四舍五入到最接近的整数(0 或 1)。

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

就是这样!Colab 笔记本的链接可以在这里找到。

感谢您阅读这篇文章!如果你有任何想法或反馈,请在下面留下评论或给我发电子邮件到 leexinjie@gmail.com。我很想收到你的来信!

使用 FastAI 和 PyTorch 的多层感知器

原文:https://towardsdatascience.com/multi-layer-perceptron-usingfastai-and-pytorch-9e401dd288b8?source=collection_archive---------17-----------------------

使用 FastAI 和 Pytorch 对多层感知器的温和介绍。

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

Multi-Layer Perceptron network. Image credit=http://pubs.sciepub.com/ajmm/3/3/1/figure/2s

在这篇博客中,我将向您展示如何使用 FastAI v1 和 Pytorch 构建一个神经网络(多层感知器),并成功训练它识别图像中的数字。 Pytorch 是脸书发布的一个非常流行的深度学习框架, FastAI v1 是一个库,它使用现代最佳实践简化了训练快速准确的神经网络。它基于在 fast.ai 进行的深度学习最佳实践的研究,包括对视觉、文本、表格和 collab(协作过滤)模型的“开箱即用”支持。如果你正在寻找源代码,请前往 GitHub 上的 fastai repo 。这个笔记本将指导用这个库建立一个神经网络。如果你想了解什么是多层感知器,你可以看看我的以前的博客,在那里我使用 numpy 从头构建了一个多层感知器,以及另一个博客,在那里我使用 TensorFlow 构建了相同的模型。正如你所注意到的,编写这款笔记本所需的代码量比以前的笔记本少得多,这都要归功于 fastai 库,它让我们能够将更多的精力放在解决问题上,而不是编写代码。这个博客也可以在我的 Github 上作为 Jupyter 笔记本使用。

样板命令

标准做法是用下面三行开始笔记本;它们确保您对库所做的任何编辑都会自动重新加载到此处,并且显示的任何图表或图像都会显示在此笔记本中。

%reload_ext autoreload
%autoreload 2
%matplotlib inline

导入快速人工智能库

让我们导入 fastai 库,并将 batch_size 参数定义为 128。通常,图像数据库非常庞大,因此我们需要使用批处理将这些图像送入 GPU,批处理大小 128 意味着我们将一次送入 128 幅图像,以更新我们深度学习模型的参数。如果由于 GPU RAM 较小而导致内存不足,可以将批处理大小减少到 64 或 32。

**from** **fastai.vision** **import** *
bs=128

下载数据集

我们将从从 fastai 数据集页面下载 MNIST 手写数据集开始。MNIST 是小型(28x28)手写灰度数字的标准数据集,开发于 20 世纪 90 年代,用于测试当时最复杂的模型;今天,经常被用作介绍深度学习的基本“hello world”。这个 fast.ai datasets 版本使用标准的 PNG 格式,而不是原来的特殊二进制格式,这样你就可以在大多数库中使用常规的数据管道;如果您想像原始通道一样只使用一个输入通道,只需从通道轴中选取一个切片。

path = untar_data(URLs.MNIST);
path

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

通过运行上面的命令,数据被下载并存储在上面显示的路径中。让我们看看数据目录是如何设置的,因为我们必须从这些目录导入数据。让我们从查看路径目录开始,我们可以在下面看到我们的数据已经有了培训和测试文件夹。

path.ls()

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

让我们看看培训文件夹。数据在不同的文件夹中按数字 1 到 9 分割。

(path/'training').ls()

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

在每个数字文件夹中,我们都有图像。

(path/'training/0').ls()[1:5]

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

导入数据

现在我们已经了解了我们的数据目录是如何建立的;我们将使用 FastAI amazing 数据块 API 导入数据,使用 FastAI 图像转换函数进行数据扩充。让我们从定义我们想要做什么样的转换开始。

ds_tfms = get_transforms(do_flip=**False**, flip_vert=**False**, max_rotate= 15,max_zoom=1.1, max_lighting=0.2, max_warp=0.2)

get_transforms 函数中,我们可以定义所有我们想要做的转换。FastAI 使数据扩充变得非常容易,因为所有的转换都可以在一个函数中传递,并且使用了非常快速的实现。让我们看看函数中给出的每个参数。

  • do_flip=False,flip_vert=False :我们不想在垂直和水平方向翻转数字,因为这对于数字数据来说不是一个好主意。
  • max_rotate= 15 :在顺时针和逆时针最大旋转 15 度的同时,随机旋转图像
  • max_zoom=1.1 :将图像放大/缩小原始图像的 10%
  • max_lighting=0.2 :将应用由 max_lighting 控制的随机闪电和对比度变化
  • max_warp=0.2 :以概率 p_affine 应用大小在-max_warp 和+max_warp 之间的随机对称变形,在这种情况下默认为 0.75。

既然我们已经定义了我们想要在输入图像上做什么样的转换,那么让我们开始定义 FastAI 称之为 data batches 或 databunch。图像数据集规模庞大,因此我们从不希望将整个数据集导入内存,相反,我们定义了一个 databunch,它将允许我们加载批量数据并即时进行所需的转换。

data = (ImageItemList.from_folder(path, convert_mode='L')
        .split_by_folder(train='training', valid='testing')
        .label_from_folder()
        .transform(tfms=ds_tfms, size=28)
        .databunch(bs=bs))

杰瑞米·霍华德称上述步骤为标签工程,因为大部分时间和精力都花在正确导入数据上。FastAI 的数据块 API 使用类似 API 的 R ggplots *【图形语法】*来定义我们想要如何导入我们的数据变得非常容易,在这里你可以不断地链接不同的函数,直到你准备好你的数据束。让我们了解一下上面的代码在做什么-

  • image item list . from _ folder(path,convert_mode=‘L’) —根据扩展名中带有后缀的文件名在路径中创建项目列表。Convert_mode='L '帮助我们定义要导入的图像是灰度/单通道图像,默认为“RGB ”,这意味着 3 通道图像。FastAI 使用 PIL 库,所以 convert 实际上是一个 PIL 功能
  • split _ by _ folder(train = ’ training ',valid=‘testing’): 此函数通知 databunch,我们在路径目录的’ training ‘和’ testing '子文件夹中有训练和测试数据
  • label_from_folder() —此函数通知 databunch 从文件夹名称中提取数字标签
  • transform(tfms=ds_tfms,size=28) —该函数通知 databunch 将 ds_tfms 变量中定义的变换应用于每幅图像
  • databunch(bs=bs) —此函数将此 databunch 转换为 FastAI 的 ImageDataBunch 类,批量大小在 bs 变量中定义,即本例中为 128。

现在我们已经定义了我们的数据,让我们看一看我们的数据。如下图所示,您可以看到数字是使用 show_batch 函数导入并可视化的,注意这些图像应用了我们定义的转换。

print(data.classes) *## Prints class labels*
print(data.c) *## Prints number of classes*
data.show_batch(rows=3, figsize=(10,6), hide_axis=**False**) *## Show sample data*

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

用 Pytorch 定义多层感知器

现在我们已经定义了我们的数据集群。让我们用 Pytorch 来定义我们的多层感知器模型。对于完全连接的层,我们使用 nn。线性函数,为了应用非线性,我们使用 ReLU 变换。在 Pytorch 中,我们只需要定义前进函数,而后退函数是使用自动签名自动定义的。如果您是 Pytorch 的新手,他们会提供优秀的文档和教程。我建议你通过 PYTORCH 完成这个深度学习:60 分钟闪电战教程,它将涵盖理解下面发生的事情所需的所有基础知识。

**class** **Mnist_NN**(nn.Module):
    **def** __init__(self):
        super().__init__()
        self.lin1 = nn.Linear(784, 512, bias=**True**) 
        self.lin2 = nn.Linear(512, 256, bias=**True**)
        self.lin3 = nn.Linear(256, 10, bias=**True**)

    **def** forward(self, xb):
        x = xb.view(-1,784) 
        x = F.relu(self.lin1(x))
        x = F.relu(self.lin2(x))
        **return** self.lin3(x)

训练模型

现在我们已经定义了我们的模型,我们需要训练它。我们可以使用 FastAI 的学习器功能,它可以更容易地利用优化方法中的现代增强功能和许多其他巧妙的技巧,如 Leslie Smith 的论文中强调的单周期风格训练,以实现更快的收敛。让我们定义一下我们的学习者类别-

*## Defining the learner*
mlp_learner = Learner(data=data, model=Mnist_NN(), loss_func=nn.CrossEntropyLoss(),metrics=accuracy)

让我们通过上面的论证来理解发生了什么

  • data=data —传递我们的 Databunch 函数
  • model=Mnist_NN() —传递我们定义的 MLP 模型 Mnist_NN
  • 损失函数=nn。CrossEntropyLoss() —定义损失函数进行优化,在本例中,我们使用交叉熵损失
  • metrics=accuracy —这只是为了培训时的打印目的,此论点与培训无关

Learner class 提供了一个很棒的功能,可以在训练你的深度学习模型的时候,找到理想的学习速率作为起点。让我们试着找到理想的学习速度。

*## Finidng Ideal learning late*
mlp_learner.lr_find()
mlp_learner.recorder.plot()

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

理想情况下,我们希望找到斜率最大的点。在这种情况下,指针是 1e-2。因此,我们将从 1e-2 开始作为我们的学习速率,并使用 fit_one_cycle 函数进行五个时期,该函数使用了 Leslie Smith 的论文中强调的单周期风格训练方法,以实现更快的收敛。此外,FastAI 在训练时显示’ tqdm 风格的进度条,在训练结束时,它开始显示表格,该表格显示我们在验证数据上定义的损失函数和度量的进度。

mlp_learner.fit_one_cycle(5,1e-2)

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

让我们通过降低学习率来进一步降低学习率,并对模型进行更多的训练。

mlp_learner.fit_one_cycle(5,1e-3)

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

mlp_learner.recorder.plot_losses()

正如我们所看到的,仅仅通过使用简单的多层感知器,我们就达到了 98.6%的准确率。

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

结论

Fast.ai 是由杰瑞米·霍华德和他的团队提出的一个很好的倡议,我相信 fastai library 可以通过让构建深度学习模型变得超级简单来真正实现将深度学习民主化的动机。

我希望你喜欢阅读,并随时使用我的代码来尝试它为您的目的。此外,如果对代码或博客有任何反馈,请随时联系 aayushmnit@gmail.com 的 LinkedIn 或给我发电子邮件。

使用 Rasa 和自定义标记器的多语言聊天机器人

原文:https://towardsdatascience.com/multi-lingual-chatbot-using-rasa-and-custom-tokenizer-7aeb2346e36b?source=collection_archive---------11-----------------------

使用您自己的多语言聊天机器人自定义标记器来增强 Rasa NLU 管道的提示和技巧。

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

Photo by Alex Knight on Unsplash

在之前的教程中,我已经介绍了为意图分类和命名实体识别创建你自己的 Rasa NLU 服务器的基本指南。在本文中,我们将查看向 Rasa NLU 管道添加自定义标记器的必要步骤。本文由 5 个部分组成:

  1. 设置
  2. 标记器
  3. 注册表文件
  4. 培训和测试
  5. 结论

1.设置

默认情况下,Rasa 框架为我们提供了四个内置的标记器:

  • 空白符号化器
  • 街霸分词器(中文)
  • Mitie Tokenizer
  • 空间记号化器

内置标记器

如果您在中文语言上测试它,您可以简单地将 config.yml 文件中的标记器名称更改为以下内容,就可以开始了。

language: zh
pipeline:
  - name: "JiebaTokenizer"
  - name: "RegexFeaturizer"
  - name: "CRFEntityExtractor"
  - name: "EntitySynonymMapper"
  - name: "CountVectorsFeaturizer"
  - name: "CountVectorsFeaturizer"
    analyzer: "char_wb"
    min_ngram: 1
    max_ngram: 4
  - name: "EmbeddingIntentClassifier"

如果您注意到 CountVectorsFeaturizer 有两个实例,请不要惊慌。根据官方网站:

管道使用了*CountVectorsFeaturizer*的两个实例。第一种基于单词来特征化文本。第二种方法基于字符 n 元语法来描述文本,保留单词边界。根据经验,我们发现第二个特征更加强大,但是我们决定保留第一个特征,使特征更加健壮。

自定义标记器

对于其他语言,我们需要修改一些东西。您可以在任何分词器上测试它,但我将使用一个名为 SudachiPy 的日本分词器。我在之前的文章中也提到过这个 python 模块。请随意查看。使用 Rasa NLU 服务器的必要模块设置虚拟环境。完成后,转到下面的链接并根据给出的说明安装 SudaichiPy。然后,修改 config.yml 文件。

language: ja
pipeline:
  - name: "JapaneseTokenizer"
  - name: "RegexFeaturizer"
  - name: "CRFEntityExtractor"
  - name: "EntitySynonymMapper"
  - name: "CountVectorsFeaturizer"
  - name: "CountVectorsFeaturizer"
    analyzer: "char_wb"
    min_ngram: 1
    max_ngram: 4
  - name: "EmbeddingIntentClassifier"

我只修改了记号赋予器的名字和语言。你可以给它起任何你喜欢的名字,但是你必须保持它的一致性。稍后我们将修改其他文件。确保使用相同的名称。您需要通过运行以下代码来测试它:

您应该能够看到以下结果:

['国家', '公務', '員']

2.标记器

我们需要创建一个标记器 python 文件。转到虚拟环境的目录,找到以下目录:

Lib/site-packages/rasa/nlu/tokenizer/

您应该能够看到以下文件(不包括 japanese_tokenizer.py)

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

创建一个新的 py 文件,并根据自己的喜好命名(我将其命名为 japanese_tokenizer.py)。从版本 1.6.0 开始,tokenizer 的结构发生了一些变化。从 1.7.0 开始,进行了以下更改:

  • 添加了 ConveRT 标记器
  • 从所有记号赋予器中移除选项use_cls_token。令牌化者现在默认添加 CLS 令牌。
  • 从特征者中移除选项return_sequence。默认情况下,特征返回序列。CLS 表征的特征向量包含完整话语的特征。
  • Tokenizer类中实现了标记化器的trainprocess。子类只需要实现tokenize

相应地修改文件。打开它并添加以下代码:

Rasa 1.6.0 之前

import re
from typing import Any, Dict, List, Textfrom rasa.nlu.components import Component          
from rasa.nlu.config import RasaNLUModelConfig
from rasa.nlu.tokenizers import Token, Tokenizer
from rasa.nlu.training_data import Message, TrainingData

Rasa 1.6.0 之后

import re
from typing import Any, Dict, List, Textfrom rasa.nlu.config import RasaNLUModelConfig
from rasa.nlu.tokenizers.tokenizer import Token, Tokenizer
from rasa.nlu.training_data import Message, TrainingData
from rasa.nlu.constants import (
    INTENT_ATTRIBUTE,
    TEXT_ATTRIBUTE,
    TOKENS_NAMES,
    MESSAGE_ATTRIBUTES,
)

Rasa 1.7.0 之后

import re
from typing import Any, Dict, List, Textfrom rasa.nlu.tokenizers.tokenizer import Token, Tokenizer
from rasa.nlu.training_data import Messagefrom rasa.nlu.constants import TOKENS_NAMES, MESSAGE_ATTRIBUTES

除了 regex 之外,所有的导入都很重要。让我们继续创建主类(JapaneseTokenizer)。

Rasa 1.6.0 之前

class JapaneseTokenizer(Tokenizer, Component):

Rasa 1.6.0 和 1.7.0 之后

class SudachiTokenizer(Tokenizer):

在这个类中,您将需要以下类:

  • init
  • 火车
  • 标记化

您实际上可以复制任何现有的文件,并根据您的需要修改它。标记化应该基于您拥有的语言和模块。需要注意的一点是,您需要返回一个令牌列表。token 类由标记化单词和单词偏移量组成。请参考 JiebaTokenizer.py 和 WhiteSpaceTokenizer.py 以获得更多关于结构 Tokenizer 类的信息。

我的最终代码如下所示:

Rasa 1.6.0 之前

Rasa 1.6.0 之后

Rasa 1.7.0 之后

3.注册表文件

下一步是修改所有的配置文件。每次升级或降级 rasa 版本时,您都必须这样做。转到虚拟环境的目录,找到以下目录:

Lib/site-packages/rasa/nlu/

您应该有以下文件夹和文件

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

打开 registry.py 文件并开始编辑内容。在导入区域,添加以下代码:

from rasa.nlu.tokenizers.japanese_tokenizer import JapaneseTokenizer
  • Japanese _ tokenizer:py 文件的名称。
  • JapaneseTokenizer :类的名称。您必须确保该名称与 config.yml 和 component_classes 中使用的名称完全相同。

在同一个 registry.py 文件中,找到 component_classes 列表并向其中添加 JapaneseTokenizer(根据您自己的类名修改它)。

component_classes = [
    # utils
    SpacyNLP,
    MitieNLP,
    # tokenizers
    JapaneseTokenizer,
    MitieTokenizer,
    SpacyTokenizer,
    WhitespaceTokenizer,
    JiebaTokenizer,
...

保存文件,我们现在准备测试它。

4.培训和测试

在虚拟环境中打开一个终端,并将其指向 config.yml 文件的基目录(我们在第一节中修改过的那个目录)。确保您有一个包含培训数据的数据文件夹。运行以下代码:

rasa train nlu

培训可能需要一些时间,这取决于您的意向数量。您应该能够看到以下输出:

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

一旦完成,你应该在模型文件夹中有一个 tar.gz 文件。运行以下命令进行测试(相应地修改模型的名称):

rasa shell -m models/nlu-20190924-144445.tar.gz

它将在终端内部运行交互式 shell 模式。你可以输入你的句子来测试结果。

5.结论

让我们回顾一下为 Rasa NLU 设置日语分词器的基本步骤。首先,我们需要修改 config.yml 文件并安装 SudachiPy 模块。

然后,我们创建了一个 japanese_tokenizer.py 文件,其中包含初始化、训练和标记化所需的代码。

我们继续修改 registry.py 文件,将导入代码和 JapaneseTokenizer 引用添加到 component_class 列表中。

最后,我们通过 rasa 提供的交互式 shell 模式对模型进行训练和测试。

希望你喜欢这篇文章,下次再见!

参考

  1. https://towards data science . com/a-初学者指南-rasa-nlu-for-intent-class ification-and-named-entity-recognition-a4f 0f 76 B2 a96
  2. https://towards data science . com/Suda chipy-a-Japanese-morphological-analyzer-in-python-5 f1 F8 fc 0 c 807
  3. https://gist . github . com/wfng 92/831 b 47 df 29 de 687 c8ea 3264 FFB 9134 ee
  4. https://github.com/WorksApplications/SudachiPy
  5. https://rasa.com/docs/rasa/nlu/choosing-a-pipeline/

文本分类语言模型中的多任务学习

原文:https://towardsdatascience.com/multi-task-learning-in-language-model-for-text-classification-c3acc1fedd89?source=collection_archive---------20-----------------------

用于文本分类的通用语言模型微调

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

Photo by Jeremy Thomas on Unsplash

Howard 和 Ruder 提出了一种新的方法,通过使用预训练嵌入、LM 微调和分类微调来实现任何 NLP 任务的鲁棒迁移学习。具有相同超参数但不同下降的样本 3 层 LSTM 架构展示了用于 6 个下游 NLPS 任务的超越和稳健的模型。他们将其命名为通用语言模型微调(ULMFiT)。

本故事将讨论关于文本分类的通用语言模型微调 (Howard 和 Ruder,2018),并将涵盖以下内容:

  • 体系结构
  • 实验
  • 履行

体系结构

如前所述,ULMFiT 有 3 个阶段。第一阶段是使用通用领域数据来建立 LM 预训练模型。第二阶段是对目标数据集 LM 进行微调,第三阶段是对目标数据集分类进行微调。语言模型(LM)是平均随机梯度下降权重下降长短期记忆(AWD-LSTM)。它不使用变压器,而是使用具有各种调谐压差超参数的常规 LSTM。

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

Flow of ULMFiT (Howard and Ruder, 2018)

通用域 LM 预训练

这是一个不受领域限制的问题,因此我们可以利用任何数据来训练模型。换句话说,数据量可能非常非常大。例如,它可以使用维基百科或 reddit 内容的全部内容。这样做的目的是获取一般特征来处理不同类型的下游问题。大量的实验表明迁移学习对自然语言处理有显著的改善。

目标任务 LM 微调

有一个通用的向量,它可能不会直接在特定的问题上表现很好,因为它太一般了。所以微调是必须的动作。首先,模型将通过语言模型(LM)问题进行微调。理论上,它比一般领域的 LM 训练收敛得更快,因为它只需要学习目标任务的单源特性。使用了一些技巧来提高 ULMFiT 的性能。他们是discriminative fine-tuningslanted triangular learning rates。D

区别性微调 提出对不同层使用不同的学习速率。从实验中,Howard 和 Ruder 发现只选择最后一层的学习速率。最后 2 层的学习率是最后一层/ 2.6,并且使用相同的公式来设置较低层的学习率。

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

Stochastic Gradient Descent (SGD). η is learning rate while ∇θJ(θ) is the gradient of objective function. (Howard and Ruder, 2018)

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

SGD with discriminate fine-tuning. η l is learning rate of l-th layer. (Howard and Ruder, 2018)

【斜三角形学习率(STLR) 是另一种使用动态学习率的方法,它在开始时线性增加,然后线性衰减,从而形成一个三角形。

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

STLR Formula. T is number of training iteration. cut_frac is the fraction of increasing learning rate. cut is the iteration switching from increasing to decreasing. p is the fraction of the number of iterations which increase or decreased. (Howard and Ruder, 2018)

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

Slanted triangular learning rate schedule used for ULMFiT (Howard and Ruder, 2018)

目标任务分类器微调

该分类器层中的参数是从零开始学习的。由于强信号可以存在于任何地方,但不限于序列中的最后一个字,Howard 和 Ruder 建议通过最大轮询和平均轮询来连接所有层。

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

Concatenate layers. hT is the hidden state at the last time step. (Howard and Ruder, 2018)

除了将最后一个隐藏状态与最大池和平均轮询连接起来,在这个阶段还应用了一些技巧来提高性能。招数有gradual unfreezingBPTT for Text Classification (BPT3C)bidirectional language mode

逐步解冻 是在第一个历元中冻结除最后一层以外的所有层,只微调最后一层。在下一个时期,最后冻结层将被解冻,并微调所有未冻结层。在未来时代,越来越多的地层将被解冻。

***用于文本分类的 BPTT(BPT3C)***如果输入序列很大,启用梯度传播。一个大的输入序列(假设是一个文档)将被分成固定长度的批。每一批的初始隐藏状态是前一批的最终状态。如前所述,最大池和平均轮询被跟踪和反向传播。

双向语言模型 利用正向和反向 LM 从输入中学习特征。

实验

从 IMDb,TREC-6 和 AG 数据集,你可以注意到,如果目标数据集很小,它获得了很大的好处。

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

Validation errors for IMDb, TREC-6, and AG (Howard and Ruder, 2018)

霍华德和鲁德提出了许多提高性能的技巧。下图展示了技巧组合的结果。

  • 完整:微调完整模型
  • discr:应用区别性微调。
  • 最后:仅微调最后一层
  • 解冻链:文本分类的 BPTT
  • Freez:逐渐解冻
  • stlr:倾斜三角形学习率
  • cos:积极的余弦退火计划

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

Comparison result among different tracks. (Howard and Ruder, 2018)

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

IMDb Comparison Result (Howard and Ruder, 2018)

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

AG, DBpedia, Yelp-bi and Yelp-full Comparison Result (Howard and Ruder, 2018)

履行

fast.ai 提供了一个来自 github 的样本代码。

拿走

  • 本文提出了几种新颖的微调技术。
  • 展示了自然语言处理中迁移学习的能力。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。你可以在 LinkedIn和我联系,或者在 Medium 或 Github 上关注我。

参考

J.霍华德和史路德。文本分类通用语言模型微调。2018

基于 Keras 的命运大序多任务学习

原文:https://towardsdatascience.com/multi-task-learning-on-fate-grand-order-with-keras-261c5e8d3fb8?source=collection_archive---------10-----------------------

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

Gender: Female, Region: Europe, Fighting Style: Melee, Alignment: LE, Main Colors: [‘Black’, ‘Blue’, ‘Purple’]. Model saw a number of other images of this character in training, but all were of a significantly different style to this.

标准的图像分类任务遵循二元分类(猫对狗)或者可能多类分类(猫对狗对人)的趋势,但是许多真实世界的任务,如理解图像或文本,通常需要不止一个有用的标签。出于这种更有用的需要,我认为许多任务在本质上可以被框定为多标签,本质上就是单个样本在输出数组中有几个正确的标签。

在之前的一篇文章中,我使用了一些小 CNN 来为鞋子生成元数据标签。在那篇文章中,我有关于材料、图案、颜色等等的变量。我的第一步是制作一个大型多标签模型,一次性预测所有值。我发现这在那种情况下行不通,因为对于有限的数据集来说,特征向量是多么稀疏。所以我依靠创造一系列更小的多标签模型。在我写完那篇文章后,有人在评论区问我为什么不使用多任务模型来完成那项工作(这是一个非常好的问题!)

据我目前的理解,多任务模型是指单个模型优化解决一系列通常相关的问题。从机械上来说,这是通过将来自模型管道的某个核心部分的输出馈送到一系列输出头来完成的,这些输出头的损耗可以被评分和组合,通常通过相加,然后网络可以根据总损耗来调整其权重。

总的想法是,通过学习相关的任务,网络将共享上下文,并学习更好地执行这些任务,而不是独自承担每个单独的任务。吴恩达在他的深度学习课程中从高层次讲述了这一点,围绕建立自动驾驶汽车的多任务模型。

这篇文章中的所有图片都是测试图片,在它们的描述中有网络生成的标签。

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

Gender: Female, Region: Asia, Fighting Style: Melee, Alignment: TN, Main Colors: [‘White’, ‘Blue’, ‘Green’]. This one in interesting because I encoded teal as blue and green in the target array so it did well.

构建数据集和数据结构化

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

Gender: Female, Region: Europe, Fighting Style: Melee, Alignment: LG, Main Colors: [‘Silver’, ‘Gold’, ‘Blue’]. This is more similar to the style of the first image that appeared in the training set. It looks like the first artist photoshopped this basic image to make that wallpaper.

在进入模型的细节之前,第一步是为手头的问题构建一个数据集。在这种情况下,我决定围绕命运大订单游戏和系列建立一个壁纸/艺术的图像数据集(当时这只是一个有趣的想法)。我过去在这个游戏上写过一些帖子,在那里我构建了一些基于神经网络的机器人来玩这个游戏。在这篇文章中,我并不特别关心游戏机制,我只是去建立了一个由 400 张图片组成的数据集,这些图片可能包含 40 个不同的角色,并用 26 个不同的标签标注了不同的主题。这包括角色的性别,他们来自的地区,战斗风格,图像的主要颜色,以及角色排列(合法的好,真正的中立,混乱的邪恶,等等。如果你不知道角色的排列,并想阅读更多,请点击这里。我的目标只是建立一系列的分类变量,我认为包括一些更难的变量,如字符对齐,将是对更典型的标签如基于颜色的标签的有趣补充。

给它贴标签相当费时,占用了周五晚上的大部分时间。简化过程的是,由于大多数数据不会根据给定的角色(性别、地区、排列、战斗风格)而改变,我能够在单独的 csv 中为它们填写配置文件,并将它们合并到图像的颜色符号中,这节省了大量时间。最终的结果是一些不同的分类变量,当我把它们全部取出时,产生了 26 个不同的类。

模型结构和训练

现在开始建模。从技术上来说,我可以采用与之前类似的方法,但这不会成为一篇有趣的文章。因此,我将数据集分为 5 个“任务”(性别、地区、战斗风格、排列和颜色),每个任务都将成为模型中的一个头部,在这里进行预测、记录损失、对所有任务求和,然后模型会相应地调整其权重。

为了找出潜在的模型架构,我的一般出发点是看看我是否可以使用预先训练的网络作为特征提取器,然后将输出传递给 5 个不同的任务输出头。在对架构结构进行了一些实验后,我发现使用 VGG19 网络作为固定的特征提取器,并在模型头部之前将其输出特征传递给几个密集的计算层是非常成功的。这是一个很好的发现,因为它大大减少了需要优化的参数数量,因为我能够保持 VGG19 权重不变。

我在下面贴了一份模型代码的副本,并将浏览它的一部分。第 3 行用 imagenet 权重初始化 VGG19 网络,然后我遍历并冻结所有层。在第 9 行,我构建了模型输入,这是一个普通的 VGG 风格的 224x224 像素彩色图像,在第 10 行被输入到 VGG19 模型中。接下来,我创建了一些大小为 256 的密集层。我对这些的想法是,因为我离开了冻结的 VGG19 网络,这些层将做繁重的工作来学习和共享不同任务的上下文。一旦构建了这个密集的计算模块,我就开始将该模块的输出(变量 x)输入到标记为 y1、y2、y3、y4、y5 的每个“头”中。现在,我将每个头部创建为一个由 128 个节点组成的密集层,然后是一个由 64 个节点组成的层。最后,所有这些头的顶部都有一个最终输出层,其中节点的数量就是类的数量。对于性别、地域、战斗风格和排列,这些层都有 softmax 激活,我后来给它们提供了交叉熵损失。对于最终的彩色输出头,它是一个 sigmoid 激活,并提供有一个二进制交叉熵损失函数。

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

Multi-task model structure, function takes in a list of 5 losses, 5 metrics, and a level for dropout to initialize the network.

我在 Nvidia 1080 GPU 上运行了 50 个纪元和几分钟的网络。我也开始学习率相当高,但增加了一个功能,以削减学习率的一半,每 5 个时代,所以接近运行结束时,学习率低得多,权重将被调整得更加缓慢。

结果

这个模型结构是在相当小的数据集上训练的,该数据集有 26 个类和 400 个数据点。我认为,由于数据的稀疏性,它的性能对于直接的多标签模型来说很难处理,但是由于上下文确实在不同的头部之间共享,所以该模型能够在所有 5 个不同的任务中表现良好。

不同任务的损失如下所示,它显示了不同的任务对于模型来说具有不同的处理难度。性别和颜色之类的事情对模型来说相对容易,这两项任务的准确率分别为 59%和 63%。这可能是一种近乎随机的猜测,因为女性角色的性别比例失调。最困难的任务是排列,其中有 9 个职业倾向于合法的好,因为许多典型的“英雄”类型的角色被归类为有合法的好类型排列。对于这一类,模型开始时非常接近随机猜测的 18.75%

我加入了字符对齐任务,因为我认为这对模型来说很难学习。我认为这是常见的多任务问题,有某些任务会比其他任务更难。因此,我认为这将是一个很好的基准,来衡量网络如何很好地利用来自不同任务的上下文

val_gender_acc: 0.5938
val_region_acc: 0.4688
val_fighting_style_acc: 0.4062
val_alignment_acc: 0.1875
val_color_acc: 0.6328

在考虑这些更困难的任务时,我在考虑如何提高这些任务的模型性能。这花了我一点时间,但我意识到我可以使用相同的技术来排除网络故障,并将它们应用到那些困难的任务中。这很酷,因为这意味着即使您将所有这些问题合并到一个模型中,您仍然可以依靠您在标准模型开发中熟悉的故障排除技术。

当我让网络训练 50 个历元时,它在第 26 个历元时达到其最低的验证集损失,因此这就是被保存的模型。所有类别都得到了改进,但我很高兴看到字符对齐的验证准确率从最初的 18.75%上升到了 71.88%。我确实认为,我可以通过专门向该体系结构的这一分支添加额外的节点来提高性能,但我现在将把它作为未来的测试。

val_gender_acc: 0.9062
val_region_acc: 0.8438
val_fighting_style_acc: 0.8125
val_alignment_acc: 0.7188
val_color_acc: 0.7812

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

Gender: Male, Region: Middle East, Fighting Style: Ranged, Alignment: LG, Main Colors: [‘Gold’, ‘Blue’, ‘White’]. Model was never exposed to this character in training and does a good job overall. His alignment is not Lawful Good though, he’s pretty evil.

结束语

我提到的一件事是,网络能够共享不同任务的背景,在我的研究中,我看到的一个领域是颜色和排列似乎彼此有很高的相关性。对于大多数壁纸/扇面艺术,我训练的具有邪恶排列的人物比那些具有良好排列的人物有更暗的图像。因此,对于本帖中的第一个图像,角色有一个合法的好对齐,但被模型标记为合法的邪恶。

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

Gender: Female, Region: Europe, Fighting Style: Melee, Alignment: LE, Main Colors: [‘Black’, ‘Blue’, ‘Purple’].

一个更典型的深色图片和一个邪恶的角色在下面的测试图片中。这个角色有一个混乱邪恶的排列,并且经常有深色的艺术品。因此网络正确地推断出测试图像具有邪恶的特征。

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

Gender: Female, Region: Europe, Alignment: CE, Main Colors: [‘Black’, ‘Purple’, ‘Red’]

当第一个图像中的字符以该字符的更正常的配色方案显示时,模型正确地将它们识别为合法商品。虽然我认为分别在对齐和颜色任务上训练的两个网络可以学习这些功能,但并行学习这些任务意味着网络可以直接从不同的任务中学习。

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

Gender: Male, Region: Europe, Fighting Style: Melee, Alignment: LG, Main Colors: [‘Gold’, ‘Silver’, ‘Blue’]. I like this particular artist wlop and did not give any examples of this style in the training set. With this image the gender is incorrect, but the other characteristics are good.

除了上下文共享的好处之外,多任务网络的结构意味着我可以按照特定任务的难度来调整它,就像我调整传统网络一样。这产生了几个世界中最好的。该网络可以在不同的任务之间共享权重和上下文,同时一次性优化所有任务。这意味着减少网络的重复工作(也减少了我的重复工作,因为我必须运行和维护它们)。然后,我可以像调整标准网络一样调整它们,这意味着如果有困难,我可以用我熟悉的方式解决。在一个高层次上,我使用的策略是增加计算能力(节点和层)直到它过拟合,然后用正则化和丢弃来打击网络,以帮助它做出更一般化的预测,并帮助提高验证集性能。

总的来说,这对我来说是一个很好的练习,因为能够建立这种类型的网络架构是有用的,因为它有助于解决需要为给定的数据点生成多个标签的常见现实问题,并且这种解决方案比一群网络更容易维护。

我目前正在研究多任务学习的 Pytorch 实现,所以当我有时间修改它并可能制作一个新的数据集时,我希望能就此发表一篇文章,因为同一数据集上的两篇文章可能有用,也可能没用…除此之外,结合 RNNs 和 CNN 的多任务模型可能会很好。像对齐这样的类别的一个问题是,我很难仅基于图像来解决它,但我知道不同角色的知识/背景,这非常有帮助。由于额外的基于文本的上下文,添加用于特征提取的 RNN 可能是提高模型性能的好方法。这种文本+图像的方法也是我认为有很多现实应用的方法,因为大多数数据点都有这些类型的数据(猫图片+博客帖子,服装图片+描述,物品图像+评论)。

请随意查看 github repo 的这篇文章 ,我在那里用过的两个 jupyter 笔记本都在。

多视角图像分类

原文:https://towardsdatascience.com/multi-view-image-classification-427c69720f30?source=collection_archive---------5-----------------------

从逻辑回归到多视图卷积神经网络

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

Vintage Car Design. Credit © Publicdomainphotos | Link

介绍

不久前,我参加了戴姆勒-奔驰主办的机器学习黑客马拉松。我们面临的问题相当有趣,并不常见。所以我决定写一篇关于它的文章,以防我的方法可以帮助其他面临类似任务的人。

在本文的第一章,我将尝试展示我的成功方法,向您展示我的思考过程,证明一些设计选择的合理性,并阐述一些有趣的概念。另一方面,第二章将致力于一个更复杂的基于神经网络的解决方案,它天生适合于这类问题。在页面的底部,你可以找到我的 Github 库的链接,我在那里分享了支持本文信息的代码。

我们要解决的问题是根据 2D 视觉信息,将汽车插头的 3D 模型分为五类。解决这一任务非常有价值,尤其是在汽车制造装配过程的自主规划的背景下。

该问题最有趣的方面是每个汽车插头有 8 个图像,其中 6 个对应于物体的正交投影(即不同的视图:顶视图、底视图、前视图、后视图、左视图和右视图),而另外 2 个是随机的等轴投影。下面的图 1 显示了一个正交投影的例子。

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

Figure 1 : Orthographic Projections.

挑战

在这场比赛中有三个主要的挑战,得分取决于识别这些障碍并正确解决它们。第一个,可能是最明显的一个,是类不平衡的情况,其中两个类在数据集中比其他三个类更不常见。考虑到这一点很重要,因为竞赛中使用的性能指标是一个极不均匀的加权准确度,它考虑了类别的分布(即,稀有类别对于正确分类相对更重要,有时是 80 倍)。第二个挑战是,我们有五个小时的时间来编写所有代码,不能访问云或任何其他加速计算的方式(除非我们的个人笔记本电脑配备了 Nvidia GPUs,但大多数都没有)。最后,对每个物体进行分类的多幅图像的可用性提出了一个问题,即如何将从所有 8 幅图像中收集的视觉信息结合起来,以便做出充分知情的预测。这最后一个挑战是这篇文章背后的主要动机。

对于类不平衡的问题,重采样技术不是一个好的选择。事实上,下采样实际上是不可能的,因为我们总共只有 833 个汽车插头(总共 833x8 = 6664 个图像),并且稀有类的样本数量非常少。此外,使用数据扩充,虽然在技术上是可能的,但对我来说似乎不是一个好主意,因为产生图像视图的正交投影是一种具有严格规则集的工程制图。因此,应用任何类型的几何变换都会产生不属于原始数据分布的图像:使用这些图像进行训练基本上就像推动模型学习如何预测它永远不会面对的图像,从而不必要地增加了问题的复杂性。同样值得注意的是,颜色在我们的图像中没有任何意义。为了更好地理解这一点,下面的图 2 提供了一个汽车插头的不同原始图像的例子。

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

Figure 2 : Different views of a Car Plug (code name anonymized)

我决定解决班级不平衡问题的方法是通过成本敏感学习,这基本上意味着通过引入一组权重来修改机器学习算法的成本函数,以便为“重要”班级中发生的错误分配更重的惩罚。这种变化有助于引导模型训练以潜在的犯更多“更便宜”的错误为代价,减少那些代价高昂的错误。为了进一步说明这一点,假设我们有 50 个数据点,49 个属于 A 类,1 个属于 b 类。为了简单起见,我们还假设 0–1 损失(0 表示正确预测,1 表示不正确预测)而不是普遍的交叉熵损失。在正常情况下,所有类别的权重都是 1,模型将尝试学习如何正确预测大多数数据点,而不考虑它们的类别。但是,如果我们假设对 B 类样本的错误分类承担了 A 类样本的 x100 的成本,并且我们修改了成本函数以考虑这一点,那么模型将最终选择正确地对 B 类的一个数据点进行分类,即使这意味着对所有其他 49 个数据点的预测失败,因为这是使总成本最小化的设置:491 + 0100= 49。相反,如果我们在 B 类数据点中犯了一个错误,并且我们得到了所有其他 A 类样本,则成本将是:490 + 1100 = 100,这仍然远远高于前一种情况。在实践中使用成本敏感学习就像将一个权重字典传递给算法构造器(至少那些支持它的构造器)一样简单。

由于时间限制和缺乏合适的计算资源,我决定远离任何基于神经网络的方法,原因很简单,因为在 CPU 上正确配置和训练需要太多时间。相反,我选择了更传统的计算机视觉解决方案,将流行的手工设计的特征提取器与经典的机器学习算法结合起来。伙计们,这是一个关于逻辑回归如何赢得计算机视觉黑客马拉松第一名的故事。

首先,我们将介绍我在黑客马拉松中使用的方法。然后,我们将提出一个基于神经网络架构的潜在更好的替代方案,它可以固有地处理多视图问题。在竞赛期间,我也想到了第二个解决方案,但是我知道,由于时间和资源的限制,我无法实现它。不过后来我试了一下,果然提供了比较好的效果。

图像处理

正如我们在图 2 中看到的,在将这些图像或它们的矢量表示提供给任何机器学习算法之前,我们需要处理几个问题。首先,我们需要去掉右侧和顶部不必要的视觉效果(搜索栏、菜单等)。).第二,我们需要去除背景中的灰色阴影,这将通过降低数据中的噪声水平来显著加快训练速度。

事实证明,我们可以使用一个简单的过程来做这两件事:我们首先使用 Canny 边缘检测器来检测边缘,然后我们应用两个连续的形态学操作:膨胀来使边缘变大,并连接边缘检测后断开的部分,然后我们使用腐蚀来使边缘变薄恢复正常(膨胀后的腐蚀通常被称为闭合,并用于填充比这些操作的内核尺寸更小的孔洞)。之后,只需找到所有轮廓并保留最大的轮廓,该轮廓将与中间的汽车插头相对应。这样,我们也丢弃了边界周围所有多余的工件。下面的图 3 显示了这个过程前后汽车插头的图像。

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

Figure 3 : Preprocessing of images : Canny edge detection followed by two morphological operations (Dilation and Erosion), followed by a contour detection to isolate the object in the middle.

此时,我们可能会想,既然颜色没有任何有意义的价值,我们不妨将这些图像转换成灰度。在基于经典机器学习算法的第一种方法中,我们将做到这一点。但是对于下面的基于神经网络的一个,我们保留 3 个通道,因为我们将利用迁移学习。

方法 1:特征提取和机器学习

在深度学习时代之前,研究人员曾经手工制作特征提取器来表征图像。但是我们所说的特征提取器到底是什么意思呢?本质上,它是一个提取图像或其一部分的数字表示的函数,并且被设计来捕捉它的一些区别特征。假设我们有一个 RGB 图像,每个颜色通道由三个 2D 矩阵组成,值在 0 到 255 之间。我们可以将每个矩阵量化为 4 个区间(0–63,64–127,128–191,192–255),每个区间包含相关范围内的像素值。通过这种方式,我们可以用 4 个数值(x_1,x_2,x_3,x_4)的向量来表示 2D 矩阵,其中每个 x_k 是矩阵中落在面元号 k 内的值的数量。我们可以对 RGB 图像的 3 个通道重复这一过程,并且在连接之后,我们将以表示该图像的大小为 12 (4 个面元* 3 个通道)的向量结束。我们刚刚创建了一个简单的特征提取器来捕获图像的颜色信息。虽然本质上很简单,但实际上你可以在颜色是最能提供信息的因素的任务中使用这种技术。图 4 显示了这个特征提取器的运行情况。请注意,在特征向量中,每个图像的主色的较高的面元是如何被更好地区分的。这种表现明确地抓住了三个图像之间的差异。

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

Figure 4 : Example of a color feature extractor.

多年来,学术界提出了各种手动设计的用于不同目的的特征提取器。几个重要的是 HOG(梯度方向直方图),SIFT(尺度不变特征变换),SURF(加速鲁棒特征),LBP(局部二进制模式)等。这些提取器的设计过程的主要焦点是确保对图像的某些属性的鲁棒性:比例、照明、部分遮挡、旋转、失真等。这些方法是传统计算机视觉的核心支柱,一直持续到深度学习的出现,在深度学习中,它们基本上被神经网络所取代,神经网络可以学习自己的特征提取机制,与他们需要以端到端的方式解决的任务相关。不出所料,这有助于他们取得优异的总体成绩。

好了,聊够了!那么我们如何使用这些特征提取器来解决我们的问题呢?首先,我们将讨论它们传统上是如何被用来解决标准图像分类问题的,然后我们将介绍我是如何将这一过程应用于多视图任务的。

大多数特征提取器首先检测图像中感兴趣的关键点,然后为每个关键点产生矢量描述。描述符通常是固定大小的数字向量。

来自所有图像的描述符被收集,然后被聚类以得出一组原型(即质心),这些原型充当“视觉单词的词汇表”。然后,我们执行图像量化:我们在每个图像中找到视觉单词,并创建计数特征向量,类似于我们在文本分类任务中通常遇到的单词袋方法中所做的。该过程的步骤详述如下:

  1. 在将所有“训练”图像(每个图像可能有许多特征)转换成灰度之后,从所有“训练”图像中提取所有特征,转换成形状为 FxM 的矩阵,其中 F 是找到的特征的数量,M 是特征提取器的维数(通常为 64 或 128)。
  2. 使用聚类算法(例如 K-means)对 FxM 矩阵进行聚类,其中 K(聚类数)将表示我们在整个数据集中找到的视觉单词的词汇表。每个簇都是一个视觉单词。
  3. 对于每幅图像,提取所有特征,预测它们的聚类,并计算每个聚类下有多少特征。换句话说,我们统计词汇表(也称为码本)的每个视觉单词在图像中的出现次数。结果是表示图像的大小为(1,K)的特征向量。应用于数据集中的所有图像,我们最终得到形状(N,K)的矩阵,其中 N 是图像的数量,K 是词汇的大小(即聚类的数量)。换句话说,一个矩阵,其中行代表我们的图像(数据点),列代表属性或特征。该矩阵的每个单元表示在行图像中找到的属于列聚类的特征的数量。
  4. 对该矩阵使用任何经典的机器学习算法进行分类:逻辑回归、SVM、随机森林、MLP 等。也就是说,在这种情况下应该避免使用基于树的方法,因为这个问题很可能是线性的,就像大多数文本分类任务中的情况一样。

因为一张图胜过千言万语,所以让我们通过一个简单的流程图来进一步解释这个过程。请注意步骤 1 后在灰度图像上检测到的关键点(彩色圆圈)。

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

Figure 5 : Flow diagram of the process of converting a set of images into a feature matrix where each row is an image and each column is an attribute or feature.

有了这些知识,我们就可以想出一种方法来使这种方法适应我们的多视图分类问题。我们需要引入的变化实际上非常简单,发生在步骤 3:我们将从所有 8 幅图像中提取特征,然后将它们转化为代表汽车插头的单一特征向量,而不是从图像中提取特征并将其转化为一袋单词特征向量。如果我们将相同的方法应用于多视图文本分类任务(其中由多个文本组成的概念需要被分类),这将相当于组合在与给定概念相关的所有文本中找到的单词,然后构建单词出现特征向量。图 6 显示了这个过程。

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

Figure 6 : Combining features extracted from all 8 view images into a single feature vector for the Car Plug.

好了,现在让我们谈谈一些实际问题。我的大多数决定都是为了优化时间和性能。就特征提取器而言,SIFT 是一个非常可靠的选择,但我实际上使用了 SURF,它基本上是 SIFT 的一个更快的版本,具有相对相似的性能。对于 SURF 特性的维度,我选择 64 而不是 128,主要是为了加速任何进一步的训练。我希望 128 能提供稍微好一点的性能。得到的矩阵具有大小为 64 的大约 800K 个特征。选择 K-means 中的聚类数 K 是下一个重要的决定。这是因为 K 代表将构成最终特征矩阵的列的视觉单词的数量。通常在这种情况下,值越高越好,但是收益递减法则适用,超过某个点后,边际改进将不值得复杂性增加。在我的例子中,我选择 K=200,但是高达 800 的值是标准的,应该进行试验。在这一点上,我只是创建了大小为 833x200(汽车插头数量 x 集群数量)的最终特征矩阵。图 7 显示了特征向量的两个例子和每个插头的一个随机选择的图像视图。

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

Figure 7 : Two examples of key-point detection on a single view and the final feature vector of the associated Car Plug.

在训练了一个逻辑回归模型后,我得到了平均 87%的加权准确率(未加权的准确率很容易在 90–95%的范围内)。这是一个相当不错的分数,但我们能做得更好吗?我们绝对可以试试!

方法 2:多视图卷积神经网络

本节将专门介绍一种用于处理多视图问题的定制神经网络架构。如果我们退后一步,花一秒钟来思考这个问题,我们将如何使用神经网络来将我们的输入映射到它们的类别?嗯,在一个标准的图像分类问题中,我们会选择一个流行的 CNN 架构(ResNet,Inception,VGG 等)的基础。)作为特征提取器,然后在其上添加一个分类器块,由一个或多个稠密层组成,作为迁移学习的一种形式。如果我们试图在我们的多视图图像任务中使用类似的原理,我们可以想象多次创建网络的基础块(特征提取器),每个图像视图一个。这样,我们使用迁移学习分别从所有 8 幅图像中提取特征。然而,我们仍然会遇到与之前相同的问题:我们没有在开始时组合来自图像的信息,而是推迟了此事,现在我们必须组合来自多组特征地图(即代表由基本 CNN 产生的每个视图的特征地图)的信息。处理这个问题的一个方法是将这些特征地图堆叠在一起。例如,如果每个视图的特征图具有 KxKxC 的形状,我们可以将它们中的 8 个沿着通道的维度堆叠成一大组 KxKx8C 形状的特征图。图 8 展示了这个过程。

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

Figure 8 : Combining views’ features maps by stacking them across the channel dimension.

无论我们如何选择堆栈,这种方法的问题在于它假设图像视图是有序的,而实际上并不存在。如果我们首先堆叠俯视图的特征图,最后堆叠仰视图的特征图,那么我们应该对每个汽车插头做同样的事情。然而,没有参考指定什么是汽车插头的顶部,什么是底部,我们可以认为任何观点是任何一方。或者说,如果我们拿两个汽车插头,第一个插头的一个视图,没有办法在第二个汽车插头中找到“等价”的视图。因此,应该避免任何基于顺序的假设。

我们还有第二种选择,即寻找一种将来自多个值的信息组合成一个值的操作。事实证明,在 CNN 中有一个这样的功能,我们称之为池化。我们可以在视图的维度上使用某种形式的池,将 8 组特征图组合成一个相同的形状,从而组合来自所有图像视图的信息。这一切都很好,但到目前为止这只是一个理论上的想法,有任何证据表明这实际上可以工作吗?在文本分类中可以找到一个这样的证明,例如,我们通过取所有嵌入的平均值,将文本中每个单词的单词嵌入组合成单个嵌入。我们正在尝试为我们的图像视图做一些类似的事情。但也许,更好的证明是找到一篇尝试这种方法的论文,并提供支持它的实验结果。快速谷歌搜索会发现有一篇这样的论文(虽然不是唯一的),它被方便地称为:用于 3D 形状识别的多视图卷积神经网络。图 9 显示了论文中提出的架构,这几乎正是我们上面解释的。

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

Figure 9 : Each object view is fed to the same CNN1 base, then we apply a pooling operation across the view dimension. The pooled view is then fed into a second CNN2 before being classified. The authors use the second CNN in order to learn a compact representation for the 3D shape, which they use for both classification and retrieval. For a simple classification, we can do away with it [1].

我在 PyTorch 中实现了这个 MVCNN 架构,并为 CNN1 使用了一个 ResNet34 Base 。在一个平均视图池层之后,我在上面添加了一个块,由一系列密集层和去除正则化组成,我称之为分类器块。为了训练,我最初固定了基本的 CNN1,并且只训练了分类器块:这在迁移学习中通常被称为特征提取。然后,我解冻整个网络中的所有权值,把学习率降到一个很低的值,对整个 MVCNN 进行端到端的训练:这在迁移学习中被称为微调**。最终,我的加权准确率达到了 98%……非常令人印象深刻,是吧?实际上没有那么多。除了怪异的性能指标和类别不平衡,高分应该是意料之中的,因为这项任务对机器学习来说可能不是很有挑战性。**

是的,是的,我知道你可能只是为了密码而来,我很乐意效劳!你会在这个 github repo 里找到你需要的一切:代码。笔记本评论很好,但遗憾的是,我不能分享数据。如果您热衷于试验这里提出的技术,并且您没有合适的数据集,可以考虑使用多视图图像分类的基准: ModelNet40 。如果您对第一种方法更感兴趣,任何普通的影像分类数据集都可以。

这就是我的乡亲,我希望你学到了一两件事。如果你喜欢这些内容,不要犹豫回来,我很快会推出更多的文章。

直到那时,再见~

参考

[1]苏,杭,等.用于三维形状识别的多视角卷积神经网络."IEEE 计算机视觉国际会议论文集。2015.

基于单词包和单词序列的多类分类

原文:https://towardsdatascience.com/multiclass-classification-with-word-bags-and-word-sequences-4fffd4d62e0c?source=collection_archive---------12-----------------------

使用 tf-idf 向量的 SVM 在分类 20 个新闻组文本语料库的质量和性能上超过了 LSTM。

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

文档是一个特定的单词序列。但并不是所有的单词序列都是文档。将两者的区别传授给算法是一项艰巨的任务。在文本分析中考虑单词序列通常计算量很大。LSTM 等深度学习方法允许我们将文档建模为一串单词,最近他们确实在 NLP 任务中取得了一些成功。

另一方面,当我们撕碎文件并按单词制作袋子时,我们最终得到这些单词的权重/数量的向量。从文档到这个向量的映射可以是多对一的,因为所有可能的单词序列都产生相同的向量。所以对原始文件含义的破译(更不用说复活它了!),从这个向量是不可能的。然而,这种用几十年的旧词汇来建模文档的方法一直是 NLP 任务的主要支柱。

当单词的顺序对于确定文档的类别很重要时,单词串方法将胜过单词包。我们已经用的合成文档证明了这一点,在那里,LSTM 打败了单词袋方法(使用 tf-idf 向量的朴素贝叶斯方法)进行分类。但是对于针对二元情感分类的电影评论的真实文本语料库,我们已经表明 LSTM 和 SVM(具有 tf-idf 向量)在质量上是可比的,即使前者花费的时间长得多。

这篇文章的目的是进一步评估“袋子和绳子”在多种情况下的区别。我们将使用从 scikit-learn api 获得的 20 个新闻组文本语料库。我们还将看看使用单词嵌入的影响——包括预先训练的和定制的。我们在这里浏览一些代码片段,但是完整的代码可以从 github 下载。[late expage]

1.对 20 个新闻语料库进行标记

这个语料库由 20 个新闻组的帖子组成,因此它们都有很好的标签。有超过 18000 个帖子差不多均匀地分布在 20 个主题上。在下面的代码片段中,我们获取这些帖子,清理并标记它们,为分类做准备。

  • 第 7–9 行。符号化。删除所有标点符号和 NLTK 停用词。确保所有单词/标记都以字母开头。并且只保留长度在 3 到 15 个字符之间的单词。
  • 第 13 行:使用 scikit-learn api 来获取帖子,但要确保删除关于给定帖子属于什么主题的“泄露”线索。
  • 第 22 行:记下每个文档中的字数有助于我们稍后为 LSTM 选择合理的序列长度。nTokens 上的百分位数统计显示,超过 92%的文档都少于 200 个单词。

2.单词嵌入

单词嵌入很短(长度 p 比词汇的大小短得多 nWords )单词的数字向量表示。它们允许我们将单词空间的维度从语料库词汇的长度(这里大约 107,000)减少到更短的长度,比如这里使用的 300。下载预先训练好的 fasttext 单词向量,通过 Gensim 离线生成电影语料库的自定义 fasttext。在这两种情况下,一旦拿到手,它们就被简单地从磁盘上读取。

  • 第 6–7 行:我们在 json 文件中有定制的 Gensim 生成的单词向量,其结构为{word:vector,…}所以我们干脆把它当字典来读
  • 第 8–21 行:在预训练向量的情况下,我们读取下载的文件,并进行一些错误检查。
  • 第 25–27 行:准备 nWords x 300 嵌入矩阵,其中每一行代表对应单词的 300 长数值向量。

最终结果是一个矩阵,其中每行代表一个单词的 300 长的向量。字/行按照 word_index 字典— {word:index} 中的整数索引排序。在 Keras 的情况下,单词是根据它们的频率排序的。在 tf-idf 矢量器的情况下,一个单词根据它在词汇表中的字母顺序得到它的索引。只是记账,没什么复杂的。

3.打包行李和序列

LSTM 使用单词序列作为输入,而传统的分类器使用单词包,如 tf-idf 向量。手里有了每个文档作为令牌列表,我们就可以做好准备。

3.1 SVM 的 Tf-Idf 矢量

我们使用 scikit-learn Tf-Idf 矢量器从令牌构建词汇表(下面第 6 行的 word_index dict 变量)和文档向量(第 7 行)。

Xencoded 是一个稀疏的 nDocs x nWords 矩阵。当使用单词嵌入时,我们通过乘以我们在第 2 节中计算的嵌入矩阵,将其转换为密集的 nDocs x 300 矩阵。然后对这些较短的 300 长的密集载体进行分类。

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

3.2 的序列

Keras 中的 text 处理器将每个文档转换成一个整数序列/字符串,其中的整数值表示相同处理生成的 {word:index} 字典中的实际单词。索引值从 1 开始,跳过为填充保留的 0。我们使用 200 长的序列,因为令牌上的统计数据显示,超过 92%的文档少于 200 个单词。在下面代码的第 7 行中,少于 200 个单词的文档用索引值 0 进行“post”填充,该值被嵌入层忽略(在第 4 节的嵌入层定义中设置了 mask_zero=True )。

4.模型

LSTM 通过 Keras 实现,而 SVM 通过 scikit-learn 实现。两者都使用相同的训练/测试分割,因此比较是公平的。整个语料库的百分之二十(即 3660 个文档)被留出用于测试,同时对剩余的 14636 个文档进行训练。

4.1 LSTM

在本系列的早期文章中,我们使用最简单的 LSTM 模型,有一个嵌入层,一个 LSTM 层和输出层。当使用外部单词嵌入时,嵌入层将不被训练,即,权重将是我们在部分 2 中从磁盘读取的。

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

Figure 1. A simple LSTM model for multiclass classification

图 1 中的嵌入层将特征的数量从 107196(语料库中唯一单词的数量)减少到 300。LSTM 图层输出一个 150 长的矢量,该矢量将被输入到输出图层进行分类。模型本身的定义非常简单。

  • 第 3–7 行:仅当不使用外部单词嵌入时,才训练嵌入层。
  • 第 9 行:下降域有助于防止过度拟合

训练是通过提前停止来完成的,以防止在下面代码的第 5 行过度训练。最终输出图层生成一个与标注数量一样长的矢量,该矢量的 argmax 就是预测的分类标注。

4.2 SVM

SVM 的模型要简单得多,因为需要决定的活动部件和参数要少得多。当然,这总是一件好事。

5.模拟

混淆矩阵和获得的 F1 分数是我们感兴趣的。有了来自任一方法的预测标签,我们使用 scikit-learn API 来计算它们。

虽然我们以不同的顺序浏览了一些片段,但是运行 lstm 的 lstm-20news.py 和运行 svm 的 svm-20news.py 的完整代码在 github 上。正如在早期文章中指出的,各种随机种子被初始化以获得可重复性。模拟是在下面的 shell 脚本的帮助下进行的,该脚本循环遍历我们正在考虑的变化。

5.1 LSTM

嵌入层应该有助于

107196 * 300 权重参数+ 300 偏差参数= 32159100 参数

这与下面第 11 行中带有外部单词嵌入的 LSTM 运行的不可训练参数的数量相匹配。

Layer (type)                 Output Shape              Param #   
=================================================================
embedding_1 (Embedding)      (None, 200, 300)          32159100  
_________________________________________________________________
lstm_1 (LSTM)                (None, 150)               270600    
_________________________________________________________________
dense_1 (Dense)              (None, 20)                3020      
=================================================================
Total params: 32,432,720
Trainable params: 273,620
Non-trainable params: 32,159,100
_________________________________________________________________
None
Train on 14636 samples, validate on 3660 samples
Epoch 1/50
 - 224s - loss: 2.5373 - acc: 0.1837 - val_loss: 2.1770 - val_acc: 0.2757
Epoch 2/50
 - 223s - loss: 2.1440 - acc: 0.2913 - val_loss: 2.0411 - val_acc: 0.3437
Epoch 3/50
...
...
Epoch 35/50
 - 223s - loss: 0.5122 - acc: 0.8351 - val_loss: 0.9211 - val_acc: 0.7295
Epoch 00035: early stopping
...
...
micro avg     0.7295    0.7295    0.7295      3660
macro avg     0.7209    0.7167    0.7137      3660
weighted avg  0.7300    0.7295    0.7255      3660

Time Taken: 7859.074368476868

运行超过 2 小时,由于提前停止标准而停止,并获得 0.73 的 F1 分数。图 2 显示了收敛速度,大约 20 个历元左右,一个好的位变平。

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

Figure 2 Convergence of LSTM model with fastext word-embeddings.

5.2 SVM

SVM 的运动部件少得多,完成速度也快得多。对于 fasttext 嵌入,它使用 18296 x 300 的密集矩阵(下面的第 7 行),并获得 0.68 的 F1 分数。

X, labels #classes classes 18296 (18296,) 20 ['alt.atheism', 'comp.graphics', 'comp.os.ms-windows.misc', 'comp.sys.ibm.pc.hardware', 'comp.sys.mac.hardwa
re', 'comp.windows.x', 'misc.forsale', 'rec.autos', 'rec.motorcycles', 'rec.sport.baseball', 'rec.sport.hockey', 'sci.crypt', 'sci.electronics', 'sci.med
', 'sci.space', 'soc.religion.christian', 'talk.politics.guns', 'talk.politics.mideast', 'talk.politics.misc', 'talk.religion.misc']
Vocab sparse-Xencoded 107196 (18296, 107196)
# Bad Word Vectors: 1
Dense-Xencoded (18296, 300)
...
...
               micro avg     0.6899    0.6899    0.6899      3660
               macro avg     0.6757    0.6766    0.6722      3660
            weighted avg     0.6835    0.6899    0.6839      3660

Time Taken: 140.8366870880127

6.结果

我们手头的结果不仅比较了用于多类分类的 bag 和序列,还比较了使用预训练和定制单词嵌入的影响。图 3 显示了在所有情况下获得的 F1 分数和所用的时间。具有直接 tf-idf 矢量的 SVM 在质量和性能方面做得最好。预先训练的单词嵌入帮助 LSTM 提高了 F1 分数。预计 LSTM 的运行时间会更长,这与我们在本系列的前几篇文章中看到的一致。

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

Figure 3. Quality and performance comparison of bags vs strings for 20-news classification. SVM is clearly the leader in quality and performance. Word-embeddings seem to help LSTM achieve better ressults.

下面的图 4 比较了两种方法获得的最佳混淆矩阵。

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

Figure 4. The diagonal dominance is observed in either case. Interestingly both approaches seem to be confused between more or less the same pairs of classes.

7.结论

那么,我们该如何理解这个由三部分组成的系列文章的结果呢?对于一个以序列为主的合成文本语料库,单词串轻而易举地击败了单词包。对于二进制分类任务,的分数是偶数。在这项多类分类任务中,天平已经向单词包倾斜。鉴于深度学习方法有如此多的旋钮,人们永远无法确定所获得的结果是否不能通过调整一些旋钮来改善(请告诉我是哪些……单位/层/批次/细胞/……以及当你在做的时候改善了多少……)。因此,这里有一些松散的评估,无论他们的价值。

  • 对于一个真实的文本语料库来说,单词包是很难被击败的——尤其是在运行时间非常短的情况下
  • 单词包向量并没有真正受益于单词嵌入的使用。我们在早期的文章中已经看到了这一点,比如单词嵌入和文档向量:第 2 部分。分类
  • 单词嵌入可以提高基于单词串的方法的结果质量。

数据科学中的多重共线性

原文:https://towardsdatascience.com/multicollinearity-in-data-science-c5f6c0fe6edf?source=collection_archive---------7-----------------------

它是什么,为什么它是一个问题?

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

Multicollinearity

最近在一次关于人工智能的会议上,讨论中出现了统计学的话题。统计方法是一个很好的工具,可以量化您的测试,并检查自变量(您可以控制和改变的变量——想想图表中的 X 轴项)之间的显著影响,以及它如何影响因变量(因自变量的改变而改变的变量——图表中的 y 轴项)。

例如,y=2x 将意味着 X(我们的自变量)的每一个变化,y 将改变 2(因变量的变化)。当一个自变量对应一个因变量时,这就很简单了。然而,当我们的数据集中有多个变量时,问题就变得有点复杂了——这些变量被称为会影响我们的目标变量(我们试图使用线性回归来预测的变量)的特征。

当每个功能变得相互“依赖”时,情况就变得更加复杂了。另一种说法是,当我们改变一个自变量,并期望因变量发生变化时,我们看到另一个自变量也发生了变化。这两个独立变量现在是相互依赖的,或者说是相互共线的。添加更多彼此共线的要素,我们得到多重共线性。

回归模型中的自变量相关时,多重共线性出现。

多重共线性主要有两种类型。第一个是结构性的(自变量 x 是平方的),这只是一个副产品,因为更多的时候你会使用现有的自变量来创建它,你将能够跟踪它。想象一下,当我们有了一个数据集,我们决定使用 log 来缩放所有要素或对它们进行归一化。这就是结构性多重共线性的一个例子。第二个,在我看来更危险的是,是数据多重共线性。这已经嵌入在你的数据框架(熊猫数据框架)的特征集中,并且很难观察到。

这会导致什么问题?它会降低我们的总体系数和 p 值(称为显著性值),并导致不可预测的方差。这将导致过度拟合,其中模型可能在已知的训练集上做得很好,但在未知的测试集上将失败。由于这会导致较高的标准误差和较低的统计显著性值,多重共线性使得难以确定某个特征对目标变量的重要性。如果显著性值较低,我们将无法拒绝空值,这将导致假设检验的第二类错误。

在讨论中,我被问到的下一个问题与你的问题相同。我们如何注意到它们?嗯,我发现最好的方法是互相测试每个独立的特性。如果你有有限的功能可以使用,这是很棒的,不需要太多的工作,这就是我为我的一个涉及线性基本模型的项目所做的。但是当你有数百个或者更多的特征时,就困难多了。在这一点上,它也成为一个维度问题(称为维度的诅咒)。此时最好是使用 PCA(主成分分析)来减少你的特征。

另一种检测方法是看系数得分。

如果您可以确定哪些变量受到多重共线性和相关性强度的影响,那么您就可以确定是否需要修复它了。幸运的是,有一个非常简单的测试来评估您的回归模型中的多重共线性。方差膨胀因子 (VIF)确定独立变量之间的相关性以及相关性的强度。

使用方差膨胀因子 VIF,我们可以确定两个独立变量是否共线。测量时,如果两个特征的 VIF 为 1,则它们彼此不共线(即这两个特征之间没有相关性)。然而,随着数字的增加,它们之间的相关性就越高。如果 VIF 返回一个大于 5 的数,那么这两个特征应该使用 PCA 减少到一个。

还有另一个最终的统计工具,它对于分析要素之间的差异非常有用。ANOVA 代表方差分析。一般来说,变量之间的方差越大,它们相关的可能性就越小。但也许这将是未来讨论的主题。我将在下面链接我的讨论来源,其中也包含一个很好的例子,你可以尝试一下。

[## 回归分析中的多重共线性:问题、检测和解决方案

当回归模型中的独立变量相关时,会出现多重共线性。这种相关性是一个问题…

statisticsbyjim.com](https://statisticsbyjim.com/regression/multicollinearity-in-regression-analysis/)

多语言机器学习

原文:https://towardsdatascience.com/multilingual-machine-learning-972de4248218?source=collection_archive---------25-----------------------

利用专利数据探索 BLEU 评分

介绍

Does your machine learn in Chinese? I don’t speak Mandarin or Cantonese so Google Translate gets all the credit — good or bad — for translating the preceding sentence into “您的機器學習中文嗎?” But how might a researcher quickly evaluate the quality of machine translations? This question encapsulates the basic challenge that gives rise to the BLEU metric. BLEU, which stands for bilingual language understudy, is a default measure of machine translation quality and is also sometimes applied to cross-lingual natural language processing (NLP) tasks. The metric is well-established in the machine translation space but some analysts question the algorithm’s applicability to a wider set of tasks beyond the measure’s original objectives. This article takes an initial dive into the lessons, implementations, and limits of BLEU using examples drawn from multilingual patent documents.

BLEU 的基础知识

IBM 的研究人员在 2002 年开发了 BLEU 算法,作为一种参考基准人工翻译来评估机器翻译质量的有效方法。如果你对该算法的创建背景和目标感兴趣,由开发人员 Papineni 及其同事撰写的原始论文是一个不错的起点。BLEU 是“候选”机器翻译和一个或多个“参考”人工翻译之间匹配单词序列的调整后的精度度量。BLEU 计算机器翻译中与人工翻译中的 n-grams 匹配的长度为 n 的单词序列的“n-grams”,除以机器翻译中 n-grams 的总数。该度量被调整,因为它将匹配计数削减到人工翻译中 n 元语法出现的最大数量,并且还惩罚在单词长度上偏离参考翻译的机器翻译。

得到的 BLEU 分数是一个介于 0 和 1 之间的数字,其中 0 表示候选文本和参考文本之间的 n 元语法匹配为零,1 可能等于与参考文本之一完全相似的机器翻译。在实践中,通过相应 n-gram 计算的几何平均值,测量计数在多个单词序列长度上匹配 n-gram(四单词序列)、tri-gram(三单词序列)、n-gram(两单词序列)和 n-gram(一单词序列)。该算法设计用于句子语料库级别的比较,在句子的基本单元计算 n-gram 匹配,然后组合成语料库级别的分数。为了澄清术语,本文中使用的术语“文档”是指句子的语料库。如果你对理解算法的其他资源感兴趣,你可以查看 deeplearning.ai 上讨论算法细节的视频教程,或者 machinelearningmastery.com 上探索 NLTK 实现的书面教程。为了探索度量的实际用例,我接下来使用中文专利的翻译来应用 BLEU。

BLEU 在专利文本中的应用

获取翻译

根据管理专利的全球组织 WIPO(世界知识产权组织)最近的一份报告,机器学习领域越来越多的专利是用中文撰写和提交的。要在这个多语言空间探索 BLEU 的基础,你可以首先从电子商务公司阿里巴巴将其扩展到全球覆盖的一项 NLP 创新的中国国内专利开始。中文专利的标题如下所示。关于示例专利的其他细节,

**original_title_cn** = "机器处理及文本纠错方法和装置、计算设备以及存储介质"

WIPO 的数据查询工具提供了英文中文两种语言版本,你可以在浏览器中查看。

人类专家经常翻译出质量相当的译文,但在选词和结构上有所不同。因此,BLEU 接受单个或多个人工翻译作为比较的参考。为了更直接地探索参考译文的产生,我通过基于网络的人工翻译平台 Gengo 从两个不同的人工译者那里获得了中文专利的两个汉英翻译。接下来,您可以从两个来源获得“候选”机器翻译

**reference_human1_summary** = "The invention discloses a machine processing and text error correction method and device, a computing device, and a storage medium, specifically comprising corrected and rewritten text pairs of incorrect text and corresponding correct text. The corrected and rewritten text pairs serving as a training corpus to train the machine processing model, thereby preparing a machine processing model suitable for text error correction. Through extraction of corrected and rewritten text pairs from a log, the machine processing model can be trained and thus made fit for text correction by inputting the first text into the machine processing model to get the second text, that is the error correction result text. In addition, the language model or the common lexicon can be used to determine whether the first text needs to be corrected. The training corpus extracted from a log can be used to train the language model, or the common lexicon can be sorted by segmenting and counting text in the log. This is how to easily implement text error correction."**reference_human2_summary = "**This invention makes public a machine processing and text error correction method and hardware, computing equipment and storage medium, and specifically pairs error text with the corresponding corrected and modified correct text. It uses this text pair as training material for the machine processing model, and from there prepares the machine processing model that is applied to the text correction. It can train the machine processing model using a diary or daily journal and make it suitable for text correction. The first text version is inputted into the machine processing model to get the second text version, which is the corrected text. Additionally, it can also use a stored language model or common vocabulary bank to determine if the first text version needs correction. It can use the practice language material gathered from the diary or daily journal to train the language model, and it can also initialize the common vocabulary bank through the segmentation and analysis of the diary or daily journal text. Through all this, text correction is conveniently implemented."

单独的机器学习算法,谷歌翻译和世界知识产权组织(WIPO),如下图所示。

**candidate_google_summary** = "The invention discloses a machine processing and text error correction method and device, a computing device and a storage medium, and particularly comprises an error correction rewriting pair of an error text and a corresponding correct text, and an error correction rewriting pair as a training corpus, and a machine processing model. Training is performed, thereby preparing a machine processing model suitable for text correction. The machine processing model can be trained to mine the error correction by mining the error correction rewrite pair from the log. The first text is input into the machine processing model to obtain a second text, that is, an error correction result text. In addition, you can use the language model or common lexicon to determine whether the first text needs to be corrected. The language model can be trained using the training corpus extracted from the log, or the common lexicon can be organized by segmenting and counting the text in the log. Thereby, text correction is facilitated."**candidate_wipo_summary** = "The present invention discloses a machine processing and text correction method and device, computing equipment and a storage medium. Specifically comprising corrected and rewritten text pairs of incorrect text and corresponding correct text, the corrected and rewritten text pairs serving as a training corpus for training a machine processing model, and in this way developing a machine processing model for use in text correction. Through extraction of corrected and rewritten text pairs from a log, the machine processing model can be trained and thus made fit for text correction by inputting a first text into the machine processing model to obtain a second text i.e. a corrected text result. Moreover, a language model or a lexicon of commonly used words can be used to assess whether text needs correction. The training corpus extracted from the log can be used to train the language model and also, through text segmentation and statistical analysis of text in the log compile a lexicon of commonly used words. Thus, text correction can be made easier and more convenient."

计算 BLEU 分数

BLEU 有多种实现和扩展,比如流行的 sacreBLEU 包等等。本示例首先使用自然语言工具包(NLTK)中的 bleu_score 模块计算分数,该工具包基于 Papineni 等人的原始实现。corpus_bleu函数接受表示为单个单词标记的引用和候选翻译,您可以通过标准的 NLP 预处理步骤创建这些单词标记。对于包含多个句子的文档,最初的 BLEU 实现逐句计算 n-gram 匹配,然后对所有候选句子的裁剪 n-gram 计数求和,最后除以文档中候选 n-gram 的数量。正如 NLTK 文档所述:BLEU 度量“计算微观平均精度(即在除法之前对每个假设参考对的分子和分母求和)。”默认情况下,corpus_bleu计算等权重 n 元语法分数的几何平均值,包括四元语法、三元语法、二元语法和一元语法。

两个机器翻译示例的 BLEU 分数计算结果是什么?结果表明,Google 和 WIPO 的翻译与 Gengo 上人工翻译的参考译文具有相似的质量。Google Translate 的第一候选译文得分为 0.53,WIPO 得分为 0.54,如下图所示。

# calculate BLEU score of Google translation
bleu_google = round(corpus_bleu(refs_list_6, can_google_summary[:]),         
                    2)# calculate BLEU score of WIPO translation
bleu_wipo = round(corpus_bleu(refs_list_5, can_wipo_summary[:]), 2)print(f"Google Translate BLEU score: {bleu_google}")
print(f"WIPO BLEU score: {bleu_wipo}")

记住这个 BLEU 应用的实际例子,有助于建立该算法对机器翻译和自然语言处理任务的应用的潜在范围。

蓝色界限

研究者普遍认为 BLEU 有利于机器翻译系统的评估。然而,一些研究人员警告说,BLEU 可能不适合机器翻译的某些方面或更广泛的 NLP 任务。一个关键的批评是,BLEU 分数可能不一定与人类翻译中的重大质量差异相关联。正如 Callison-Burch 和他的同事在一篇被大量引用的论文中所指出的:“有些情况下,BLEU 的改进不足以反映翻译质量的真正提高,而在其他情况下,没有必要改进 BLEU 来实现翻译质量的显著提高。”这些作者还提出,BLEU 可能不适合于比较利用不同技术的机器翻译系统,检测 BLEU 没有建模的翻译方面,或者评估测试语料库中不常见的改进。

对 BLEU 进行文献综述的研究人员在最近的一篇论文中指出,BLEU 与人类的相关性可能会随着被评估系统的细节、所使用的特定语料库文本以及用于人类评估的确切协议而变化。作者,Reiter 和他的同事建议,BLEU 应该通过真实世界的人类评估来评估,如 A/B 测试,以确定 BLEU 与真实世界的有效性可靠相关的环境。基于文献综述的结果,这些作者警告说,研究人员应该将 BLEU 作为系统级机器翻译的诊断方法,而不是作为测量系统输出的评估技术。随着文献表明对该测量的效用和缺点的普遍认可,一些研究人员,例如最近一篇论文的作者,专注于增加 BLEU 分数报告的清晰度。这将包括,例如,让研究人员包括预处理方案和其他标准化惯例,用于报告 BLEU 评分的实施和评分细节。这些论文中提出的观点在专利领域和不同的用例中应用和解释 BLEU 分数时需要谨慎。

结论

这篇文章概述了 BLEU 分数的目标、例子和限制。要在 Jupyter 笔记本中运行本文附带的完整 Python 代码,您可以前往 Github 资源库进行多语言机器学习。关于我对这个领域的兴趣的更多背景,请查看我在 lee-mackey.com的网站。随着机器学习领域的专利文档继续变得越来越多语言化,特别是来自中文专利的专利文档,本文中提出的观点有望帮助您在将该算法应用于您的特定用例时,将考虑事项浮出水面并融入上下文。如果您在 NLP 工作流中跨语言工作,了解 BLEU 的这些细节将有助于选择是否、何时以及如何在您的项目中使用该指标。

自然语言处理中的多语言句子模型

原文:https://towardsdatascience.com/multilingual-sentence-models-in-nlp-476f1f246d2f?source=collection_archive---------15-----------------------

两种主要的多语言句子嵌入模型综述

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

Photo by Dmitry Ratushny on Unsplash

为什么选择多语言模型

多语言模型是一种可以理解不同语言的机器学习模型。一个例子是对一段文本是否是有害评论进行分类。使用常规的机器学习模型,我们将能够只检测英语的有害评论,而不能检测西班牙语的有害评论。但是,如果我们使用多语言模型,我们将能够检测英语、西班牙语和其他多种语言的有毒评论。

那么多语言模型是如何工作的呢?一种常见的方法是将任何传入的语言转换成空间中的语言不可知向量,其中相同输入的所有语言将指向相同的区域。也就是说,任何具有相同意义的短语都会映射到潜在空间的相同区域。

今天有几种多语种嵌入可用,它们允许你用向量交换任何单词。主要的两个是脸书的激光嵌入(Llanguage-AgnosticSEntenceRpresentations)和谷歌的多语言使用嵌入(UuniversalSentenceEncoder)。激光嵌入涵盖 93 种主要语言,而使用仅涵盖 16 种语言。让我们更深入地了解一下激光。

什么是激光

LASER 的工作原理是将任何输入句子交换(嵌入)到 1024 维空间的向量中。每个句子得到一个这样的向量,

句子的激光矢量表示对于输入语言和 NLP 任务都是通用的。这是一个例子—

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

Courtesy of Facebook

左边是一些激光嵌入的句子。右边是嵌入德语的句子。如你所见,具有相同含义的向量位置非常接近。

这允许我们使用激光作为我们的 NLP 模型下游的输入特征,用于我们的特定任务,而不用担心输入语言。也许像激光输出嵌入的逻辑回归一样简单,突然我们有了一个语言无关的分类器,可以在任何语言上工作。

最棒的是脸书公开与世界分享代码和模型。让我们看看如何设置和运行这个令人敬畏的多语言嵌入模型。

在服务器上设置激光器

这里是 Github 转激光。我们将通过运行以下代码在我们的机器上的 docker 中安装 LASER,以下 bash 命令也支持 docker 监听端口 8050 —

#!/bin/bash
git clone [https://github.com/facebookresearch/LASER](https://github.com/facebookresearch/LASER)
cd LASER
docker build --tag=laser docker
docker run -p 8050:80 -it laser python app.py

在样本文本上尝试激光嵌入

现在我们准备用火做饭。在 python 终端中,定义以下函数,用激光嵌入句子—

#!/bin/python
import requests
import numpy as np
def get_vect(query_in, lang = 'en', address = '127.0.0.1:8050'):
    url = "http://" + address + "/vectorize"
    params = {"q": query_in, "lang": lang}
    resp = requests.get(url=url, params=params).json()
    return resp["embedding"]

让我们用各种语言定义几个句子。定义下面的字典—

input_dict = {
    "en":"Machine learning isn't as hard as people think.",
    "de":"Maschinelles Lernen ist nicht so schwer wie die Leute denken.",
    "fr":"L'apprentissage automatique n'est pas aussi difficile qu'on le pense.",
    "it":"L'apprendimento automatico non è così difficile come la gente pensa.",
    "es":"El aprendizaje automático no es tan difícil como la gente piensa.",
    "ru":"Машинное обучение не так сложно, как думают люди.",
    "ar":"التعلم الآلي ليس صعبا كما يظن الناس.",
    "pt":"O aprendizado de máquina não é tão difícil quanto as pessoas pensam.",
}

现在,让我们将我们定义的字典发送给运行激光嵌入服务的 docker

embedded_dict = {}
for key in input_dict:
    embedded_dict[key] = np.array(get_vect(input_dict[key], lang = key))

这是我们嵌入的样子——

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

而每个嵌入是 1024 维向量。不过,有一点需要注意,LASER service 会对给定段落中的句子进行平均嵌入。因此发送 5 段文本将产生 5 个向量,每个向量 1024 dim。每个句子内部的向量都是估算的,然而,他们选择的设计平均了这些向量——

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

如果你注意到了,我们发给 LASER 的句子是“机器学习没有人们想象的那么难。”八种不同的语言。让我们验证相同意义的向量在同一个向量空间中的说法。为此,我们将使用两个向量的余弦相似度,相似度为 1 意味着向量是相同的

from sklearn.metrics.pairwise import cosine_similarity
cos_lib = cosine_similarity(embedded_dict['it'], embedded_dict['es'])

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

事实上,将意大利语句子与西班牙语句子进行比较,相似度达到 99%以上,这表明这些向量指向我们 1024 维空间中的同一个区域。

结论

正如我们所见,在大多数情况下,相同的句子有几乎相同的向量表示。这意味着即使例子中的语言不同,它们背后的含义是相同的,激光嵌入系统可以将这一点传送给计算机。

激光嵌入允许我们抽象出文档的语言,并直接使用向量来完成所需的任务,例如文档分类或有毒语言检测。

多元线性回归-初学者指南

原文:https://towardsdatascience.com/multiple-linear-regression-beginners-guide-5b602d716aa3?source=collection_archive---------9-----------------------

用 Python 为初学者从头开始制作多元线性回归模型

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

在本文中,我将重点介绍如何为初学者用 python 从头开始制作一个多元线性回归模型。我们将使用正规方程方法来使这个受监督的机器学习模型工作。线性回归在哪里使用,它如何帮助我们?

线性回归用于预测价格、天气、股票价格、商品质量、销售额等。**这是一个模型,用于找出自变量(用于进行预测)和因变量(要预测的值)**这两个因素之间的相关性。一个好的多元线性回归模型背后的关键是一个小的成本函数,我将在本文后面解释什么是成本函数。

我们将使用美国住房数据集。在给定平均面积收入、平均面积房龄、平均面积房间数、平均面积房间数、平均面积卧室数和面积人口等特征的情况下,我们将使用该数据集来预测房屋的价格。让我们理解这个简单算法背后的数学原理,并编写代码!

进行预测的主要等式是:

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

Equation of Hypothesis

这里 h(X)是得到预测值的假设或函数。θ0 是截距,θ1、θ2、θ3、θ4 和θ5 是独立特征 x1、x2、x3、x4 和 x5 的系数。按照惯例,我们将指定 x0 = 1。系数是独立因素和非独立因素之间的关系,决定了独立因素对非独立因素的影响。我们将使用上述方程的矩阵形式,我将在后面展示。

#Importing the libraries and the reading the data into a Pandas DataFrameimport numpy as np
import pandas as pd
df = pd.read_csv('USA_Housing.csv')
df.drop('Address',axis = 1,inplace = True)
df.head()

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

我已经删除了 address feature 列,只对这个模型使用连续的数值。数据集总共有 5000 条记录和 6 个特征列。现在,为了将我们的数据分割成训练和测试,我们将首先将其从 pandas.core.frame.DataFrame 转换成 numpy.ndarray,然后使用切片来分割它。

#Converting from pandas.core.frame.DataFrame to numpy.ndarray
df_to_array = df.values#Taking a look at our array
df_to_array

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

This is how the array looks for me

完成转换后,使用 numpy.random.shuffle 函数打乱数据,使其在切片前随机。对于拆分,我将使用 80%的数据(本例中为 3750 条记录)作为训练集,其余 20%(本例中为 1250 条记录)作为测试集。

#Shuffle the data and the slice it to split
np.random.shuffle(df_to_array)
train, test = df_to_array[:3750,:], df_to_array[3750:,:]
train

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

This is how the training set looks for me

test

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

This is how the testing set looks for me

既然分割已经完成,我们需要进一步将我们的训练集和测试集分割为自变量和因变量。如您所见,数组的最后一列是价格,我们将再次对数组进行切片,将除最后一列之外的所有功能列分配给 X 训练和 X 测试,并将最后一列功能列分配给 y 训练和 y 测试,因为我们必须预测价格。

#Diving split data into X and y for machine learning where X will be for independent variables and y for dependent
X_train = train[:,:-1]
X_test = test[:,:-1]
y_train = train[:,-1]
y_test = test[:,-1]

在本文的开始,我告诉过你我们将按照惯例指定 x0 = 1,所以我们将附加一个 1 的数组作为 X 训练和 X 测试矩阵的第一个特征列。x 矩阵也称为设计矩阵。

#For training set
x_bias = np.ones((3750,1))
X_train = np.append(x_bias,X_train,axis=1)#For testing set
x_bias = np.ones((1250,1))
X_test = np.append(x_bias,X_test,axis=1)

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

This is how the new X train array looks for me

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

This is how the new X test array looks for me

如果你们还记得,我告诉过你们系数θ1,θ2,θ3,θ4 和θ5,以及截距θ0。我们现在将使用法线方程来找到θ向量,这将帮助我们确定六个值。

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

The Normal Equation

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

This is how the θ vector will look in our case

在正规方程中,X 是维数为 3750 x 6 或(3750,6)的 X 训练矩阵(数组),y 是维数为 3750 x 1 或(3750,6)的 y 训练向量(数组)。合成的θ矢量的维数将为 6 x 1 或(6)。

为了计算θ矢量,我们将把正规方程分解成两部分,分别计算,一旦完成,我们将把它合并,得到总和。

#Solving the transpose and inverse
x_transpose = np.transpose(X_train)
x_transpose_dot_x = x_transpose.dot(X_train)
var1 = np.linalg.inv(x_transpose_dot_x)
var1

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

A matrix of dimension 6 x 6

var1 是等式的第一部分,即:

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

#X transpose dot y vector
var2 = x_transpose.dot(y_train)
var2

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

A vector of dimension 6 x 1

var2 是等式的第二部分,即:

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

现在这两部分已经计算出来了,我们可以把它们结合起来得到θ矢量。

#Solving the full equation and getting our intercept andcoefficients
theta = var1.dot(var2)
theta

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

既然我们已经找到了截距和系数的值,我们将最终使用矩阵形式的假设方程(我之前已经展示过了)进行预测:

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

这里显示的 y 向量实际上是预测值的向量,我们将使用它来确定我们的模型表现如何。

predicted_values = np.dot(X_test,theta)
predicted_values

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

How the array/vector of predicted values of shape 1250 x 1 or (1250,) looks for me

成本函数

现在,为了评估我们的模型表现如何,我们将使用均方差或成本函数进行评估。误差越小,性能越好。

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

Cost Function

我刚才展示的公式是我们将在测试数据和预测值中使用和实现的公式。J(θ)中的θ是我们计算的θ向量,y 是预测值,y 是实际值,两者都在索引 I 处,其中 I 是从 I 到 n(测试样本大小=1250)。

#Now to calculate the mean squared error
Mean_Squared_Error = sum((predicted_values-y_test)**2)/1250
print(Mean_Squared_Error)

我们的均方误差是 10124760115.910074,非常好!我之所以声称它很好,是因为平方值的范围在 7286180743.499536 和 6122911662474.643 之间,比误差本身大得多,从而帮助我们做出更准确的预测。

R 平方得分

对于线性回归,一个高度推荐的度量模型性能的指标是 R 平方得分。它帮助我们了解数据与拟合回归线的接近程度。R 平方分数的范围是从 0 到 1,其中 1 是可能的最佳分数,但很难达到。R 平方的公式为:

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

Formula for R-squared score

这里 y 是预测值,y 是实际的 y 测试值,y 条是 y 测试的平均值,n 是测试集的样本大小,在我们的例子中是 1250 条记录。

 R2_score = 1 - sum((predicted_values-y_test)**2)/sum((y_test-mean)**2)print(R2_score)

我们取得了 0.9223931240402982 的 R 平方分数,这确实很好。这意味着该模型能够解释平均值周围 92.23%的可变性,考虑到我们具有低均方误差和高 R 平方得分的因素,我们可以说我们的模型表现得非常好。

我希望你发现它内容丰富!如果你有任何问题或者我做错了什么,请联系我!您可以通过以下方式与我联系:

电子邮件:arnav@oberoi.co.in

领英:https://www.linkedin.com/in/arnavoberoi/

要获得这些代码和数据集,请访问我的 github 库:【https://github.com/arnavobero1/LinearRegression-fromScratch

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值