分类目录归档:机器学习

如何在不安装 Transformers 的情况下使用 LLM Tokenizer

在构建 LLM 应用时,想对文本进行分词或者计算长度,却不得不安装了几 GB 的 transformers 和 torch(transformers 依赖 torch),这会导致 Docker 镜像体积剧增。网上对于这个问题提到的很少,但还是有人问,想着还是写下来吧。

其实只要利用 HuggingFace 的 tokenizers 库(Rust 实现),在不依赖 PyTorch 的前提下,就可以复现 AutoTokenizer 的功能(包括 apply_chat_template)。实测下来,在 Qwen 2.5 模型的 tokenizer 下,同样的 1k 长度的 Prompt,就 tokenize 的速度而言,rust 版的 tokenizer 相比于 transformers 中的 AutoTokenizer 可以提速十倍。

以 Qwen2.5 为例的 tokenizers 使用

import json
from tokenizers import Tokenizer
from jinja2 import Template
from pathlib import Path

model_dir = Path("models/Qwen2.5-14B-Instruct/")
tokenizer_json_path = str((model_dir / "tokenizer.json").resolve())
config_json_path = str((model_dir / "tokenizer_config.json").resolve())

tokenizer = Tokenizer.from_file(tokenizer_json_path)

# 加载 Chat Template
# transformers 的 apply_chat_template 实际上就是读取 tokenizer_config.json 里的 chat_template 字段
with open(config_json_path, 'r', encoding='utf-8') as f:
    config = json.load(f)
    chat_template = config.get("chat_template")
    # 获取特殊 token,用于传递给模板上下文
    bos_token = config.get("bos_token", "")
    eos_token = config.get("eos_token", "")

# 准备输入数据
prompt = "Give me a short introduction to large language model."
messages = [
    {"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},
    {"role": "user", "content": prompt}
]

# 手动渲染 Chat Template (替代 tokenizer.apply_chat_template)
# Qwen 的模板通常需要 messages, add_generation_prompt, bos_token, eos_token 等参数
template = Template(chat_template)
text = template.render(
    messages=messages,
    add_generation_prompt=True,
    bos_token=bos_token,
    eos_token=eos_token
)

print("=== Rendered Text ===")
print(text)

prompt = "你好,世界"

encoded = tokenizer.encode(prompt)

# 获取 input_ids 和 attention_mask
input_ids = encoded.ids
attention_mask = encoded.attention_mask

print(input_ids)

print(f"Total tokens: {len(input_ids)}")

给英语人士使用:

How to use LLM tokenizers without the transformers library.

When building LLM applications, if you simply want to tokenize text or calculate token lengths, you are often forced to install several GBs of transformers and torch (since transformers depends on torch). This causes the Docker image size to balloon significantly. There isn’t much discussion about this online, but since people keep asking about it, I thought I’d write it down.

Actually, by utilizing HuggingFace’s tokenizers library (implemented in Rust), you can replicate the functionality of AutoTokenizer (including apply_chat_template) without any dependency on PyTorch. In my tests using the Qwen 2.5 model’s tokenizer, for a prompt of the same 1k length, the Rust-based tokenizer was ten times faster than the AutoTokenizer found in transformers.

Using tokenizers with Qwen 2.5 as an Example

import json
from tokenizers import Tokenizer
from jinja2 import Template
from pathlib import Path

model_dir = Path("models/Qwen2.5-14B-Instruct/")
tokenizer_json_path = str((model_dir / "tokenizer.json").resolve())
config_json_path = str((model_dir / "tokenizer_config.json").resolve())

tokenizer = Tokenizer.from_file(tokenizer_json_path)

# Load Chat Template
# The apply_chat_template method in transformers actually just reads the 
# chat_template field from tokenizer_config.json
with open(config_json_path, 'r', encoding='utf-8') as f:
    config = json.load(f)
    chat_template = config.get("chat_template")
    # Get special tokens to pass to the template context
    bos_token = config.get("bos_token", "")
    eos_token = config.get("eos_token", "")

# Prepare input data
prompt = "Give me a short introduction to large language model."
messages = [
    {"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},
    {"role": "user", "content": prompt}
]

# Manually render Chat Template (replacing tokenizer.apply_chat_template)
# Qwen's template usually requires parameters like messages, add_generation_prompt, bos_token, eos_token, etc.
template = Template(chat_template)
text = template.render(
    messages=messages,
    add_generation_prompt=True,
    bos_token=bos_token,
    eos_token=eos_token
)

print("=== Rendered Text ===")
print(text)

prompt = "你好,世界" # "Hello, World"

encoded = tokenizer.encode(prompt)

# Get input_ids and attention_mask
input_ids =

 encoded.ids
attention_mask = encoded.attention_mask

print(input_ids)

print(f"Total tokens: {len(input_ids)}")

为什么大语言模型(LLM)还不能真正开发软件

Zed 编辑器的博客发的新文章,提出了“心智模型”的说法,可以看看。

Why LLMs Can’t Really Build Software — Zed’s Blog

为什么大语言模型(LLM)还不能真正开发软件

我花了很多时间做的一件事,就是面试软件工程师。这显然是个难题,我也不敢说有什么灵丹妙药;但它确实让我有机会深入思考,那些真正优秀的软件工程师到底是怎么工作的。

软件工程的循环

当你观察一位经验丰富的软件工程师时,你会发现他们总是在重复以下几个步骤:

  • 构建对需求的心智模型(mental model)。
  • 编写代码(希望它能实现需求!)。
  • 构建对代码实际运行情况的心智模型
  • 找出两者之间的差异,然后更新代码(或者调整需求)。

完成这些步骤的方法有很多,但优秀工程师的显著特点在于他们能够构建并维护清晰的心智模型

那么,大语言模型(LLM)呢?

公平地说,大语言模型在编写代码方面确实相当出色。当你指出问题所在时,它们在修改代码方面也表现得相当不错。它们还能做很多真正软件工程师会做的事情:阅读代码、编写和运行测试、添加日志,甚至(大概)使用调试器。

但它们无法做到的是:维护清晰的心智模型

大语言模型会无休止地陷入困惑:它们会想当然地认为自己写的代码是正确的;当测试失败时,它们会不知所措,不知道该修改代码还是修改测试;而当它们感到沮丧时,干脆就把所有东西都删掉,从头再来。

这与我所寻找的优秀工程师特质恰恰相反。

软件工程师在工作过程中会不断测试。当测试失败时,他们可以对照自己的心智模型来决定是修改代码还是修改测试,或者只是收集更多数据再做决定。当他们感到沮丧时,可以通过与人交流来寻求帮助。虽然有时他们也会删除所有代码从头再来,但那是在对问题有了更清晰理解之后。

但很快就会改变,对吗?

随着模型能力越来越强,这种情况会改变吗?也许吧?!但我认为这需要改变模型的构建和优化方式。软件工程需要的模型,不仅仅是能生成代码那么简单。

当一个人遇到问题时,他们能够暂时搁置全部上下文,专注于解决当前问题,然后“弹出”他们的思维堆栈,回到手头的主要任务。他们也能够“放大”视野,关注大局,让细节暂时消失,只在必要时才深入到小块内容中。我们不会仅仅因为要处理更多信息,就不断往自己的“上下文窗口”里塞更多文字,因为那会把我们逼疯。

即使不考虑上下文过多的问题,我们也知道当前的生成式模型存在几个直接影响它们维护清晰心智模型能力的问题:

  • 上下文遗漏:模型不擅长发现被遗漏的上下文信息。
  • 近因偏差:它们在上下文窗口中存在强烈的近因偏差(即更关注最近的信息)。
  • 幻觉:它们经常会“幻觉”出一些本不该存在的细节。

这些问题希望不是无法克服的,目前也正在进行相关工作,试图为模型添加记忆功能,让它们能像我们一样进行类似的“思维技巧”。不幸的是,就目前而言,它们(一旦复杂度超过一定程度)还无法真正理解正在发生什么。

它们无法开发软件,因为它们无法维护两个相似的“心智模型”,找出差异,并判断是应该更新代码还是调整需求。

那么,现在怎么办?

显然,大语言模型对软件工程师来说非常有用。它们可以快速生成代码,并且在综合需求和文档方面表现出色。对于某些任务来说,这已经足够了:需求足够清晰,问题足够简单,它们可以一次性完成整个任务。

话虽如此,对于任何非简单的任务,它们都无法准确地维护足够的上下文,从而迭代出一个可行的解决方案。你,作为软件工程师,仍然需要负责确保需求清晰,并且代码确实实现了它所声称的功能。

在 Zed,我们相信一个人类与智能体(agents)可以协作开发软件的世界。但是,我们坚信(至少目前)你才是驾驶员,而大语言模型只是你触手可及的另一个工具。

MLBiNet:跨句的语义信息提取

MLBiNet: A Cross-Sentence Collective Event Detection Network

zjunlp/DocED: Source code for the ACL 2021 paper "MLBiNet: A Cross-Sentence Collective Event Detection Network ".

跨句子问题的解决关键在于:编码语义信息,在文档级去建模事件的相互依赖关系。具体地说,我们首先设计了一个双向解码器,在解码事件标记向量序列时,模拟一个句子内的事件相互依赖关系。其次,利用信息聚合模块对句子级语义信息和事件标签信息进行聚合。最后,我们将多个双向译码器堆叠起来,并提供跨句信息,形成多层双向标签结构,实现信息在句子间的迭代传播。

Seq2Seq 多层双向网络 捕捉多个不同事件。四个部分:语义编码器、双向解码器、信息聚合模块、堆叠式多元双向标记层

用 attention-RNN 作为主要的架构

a) 独立的编码器模块在融合句子级和文档级语义信息方面具有灵活性;

b) RNN解码器模型的上下文向量和当前状态的学习捕捉:可以捕获序列事件标签相关性,将预测的标签向量作为预测 t 符号的输入

事件抽取和一般 RNN 的区别

事件抽取中生成序列长度是已知的,与原始序列一致。

ED任务解码器的词汇表不是单词,而是事件类型的集合

语义编码器

对 word 和 NER type 分别做 embedding,将两个信息拼接起来,每个 token 有了可理解的表征 \mathbf e_t

用 Skip-gram 预训练 word。在训练过程中对NER型嵌入矩阵进行随机初始化和更新。

利用双向LSTM和自注意机制对每个标记的句子级上下文信息进行编码,也就是每次按句子训练。

word embedding + NER type embedding -> e_t

LSTM + self-attn ->h_t^a

对于每个 word:

\mathbf x_t = [\mathbf h_t^a; \mathbf e_t]

相当于是 skip-connection

双向解码器

事件抽取中生成序列长度是已知的,与原始序列一致。用双向编码器,模拟句子间的关系。

前向解码

\begin{gathered}
\overrightarrow{\mathbf{s}}_{t}=f_{\mathrm{fw}}\left(\overrightarrow{\mathbf{y}}_{t-1}, \overrightarrow{\mathbf{s}}_{t-1}, \mathbf{x}_{t}\right) \\
\overrightarrow{\mathbf{y}}_{t}=\tilde{f}\left(W_{y} \overrightarrow{\mathbf{s}}_{t}+b_{y}\right)
\end{gathered}

后向解码

\begin{gathered}
\overleftarrow{\mathrm{s}}_{t}=f_{\mathrm{bw}}\left(\overleftarrow{\mathbf{y}}_{t+1}, \overleftarrow{\mathrm{s}}_{t+1}, \mathrm{x}_{t}\right) \\
\overleftarrow{\mathbf{y}}_{t}=\tilde{f}\left(W_{y} \overleftarrow{\mathrm{s}}_{t}+b_{y}\right)
\end{gathered}

双向解码

双向解码器通过组合 forward 和 backward 解码器立即模拟事件相互依赖性。垂直标记层利用了两个向前的参数和标签注意机制来捕获双向的事件依赖。

信息聚合

对于当前句子,我们关注的信息可以总结为记录哪些实体和令牌触发哪些事件。因此,为了总结信息,我们使用事件标签向量 \mathbf y_t 作为输入,设计与事件标签向量 \mathbf y_t 的LSTM层(图1中所示的信息聚合模型)。

\tilde{\mathbf{I}}_{t}=\overrightarrow{\operatorname{LSTM}}\left(\tilde{\mathbf{I}}_{t-1}, \mathbf{y}_{t}\right)

最后的向量 \tilde{\mathbf I}_{ni} 作为总结向量。

句子级的信息聚合模块架起了跨句信息的桥梁,形式化的信息很容易集成到其他句子的解码过程中,增强了事件相关信息。

多层双向网络

在该模块中,我们将多个双向标记层堆叠机制,以在双向解码器中聚集相邻句子的信息,并在句子中传播信息。由双向解码器层和信息聚合模块录制的信息 (\{\mathbf y_t \}, \mathbf I_i) 已捕获句子中的事件相关信息。但是,跨句子信息尚未互动。对于给定的句子,正如我们在表1中所看到的那样,其相关信息主要存储在邻近的句子中,而遥远的句子很少相关。因此,我们建议在相邻句子中传输总结句子信息 \mathbf I_i

由双向解码器层和信息聚合模块录制的信息 (\{\mathbf y_t \}, \mathbf I_i) 捕获句子中的事件相关信息。但是,跨句子信息尚未获取。

可以通过将输入扩展为\mathbf I_{i-1}\mathbf I_{i+1} 来形成跨句子信息。 k 是层数。

\begin{gathered}
\overrightarrow{\mathbf{s}}_{t}=f_{\mathrm{fw}}\left(\overrightarrow{\mathbf{y}}_{t-1}^{k}, \overrightarrow{\mathbf{s}}_{t-1}, \mathbf{x}_{t}, \mathbf{I}_{i-1}^{k-1}, \mathbf{I}_{i+1}^{k-1}\right) \\
\overleftarrow{\mathbf{s}}_{t}=f_{\mathrm{bw}}\left(\overleftarrow{\mathbf{y}}_{t+1}, \overleftarrow{\mathbf{s}}_{t+1}, \mathbf{x}_{t}, \mathbf{I}_{i-1}^{k-1}, \mathbf{I}_{i+1}^{k-1}\right) \\
\overrightarrow{\mathbf{y}}_{t}^{k}=\tilde{f}\left(W_{y} \overrightarrow{\mathbf{s}}_{t}+b_{y}\right) \\
\overleftarrow{\mathbf{y}}_{t}^{k}=\tilde{f}\left(W_{y} \overleftarrow{\mathbf{s}}_{t}+b_{y}\right) \\
\mathbf{y}_{t}^{k}=\left[\overrightarrow{\mathbf{y}}_{t}^{k} ; \overleftarrow{\mathbf{y}}_{t}^{k}\right]
\end{gathered}

偏差和方差

偏差和方差是训练机器学习模型时需要调整的核心参数。

TL:DR

简单来说是:

误差 error = 方差 variance + 偏差 bias

偏差是通过学习拟合出来模型的期望,与真实规律之间的差距。

方差是模型每一次输出结果与模型输出期望之间的误差,即模型的稳定性。

详解

偏差

比如现在有一些学生的二维数据,身高和体重。这些数据满足 f 分布。f 是一个多项式的函数。

我们用一根直线去拟合数据(最小二乘法),偏差会很大,因为真实的是多项式的,我们的直线预测出的结果可能跟真实情况有出入。

如果我们用多项式函数去拟合数据,偏差就会很小,因为模型变得更加复杂了。

偏差是通过学习拟合出来的结果的期望,与真实规律之间的差距。即:

\mathrm {Bias}(X) = E(\hat{f}(x)) - f(x)

img

方差

若我们用多项式拟合,就会有一个问题:数据是存在噪音的,而噪音更容易影响复杂模型。带噪数据训练的直线模型,和无噪音的数据训练的直线模型是差不多的,很稳定,而在同样的情况下,多项式模型就容易受影响。

img

方差是模型每一次输出结果与模型输出期望之间的误差,即模型的稳定性:

\mathrm {Variance}(X) = E[(\hat f(X) - E[\hat f(X)])^2]

If Bias vs Variance was the act of reading, it could be like Skimming a Text vs Memorizing a Text

如果偏差 vs 方差是阅读的行为,它可能就像略读文本 vs 记忆文本

欠拟合与过拟合

简单的模型一般偏差很高,是欠拟合 (unfitting) 的,为了减少偏差,就要增加模型复杂度,增加参数或减少减少正则化。

复杂的模型一般方差较高,是过拟合的 (overfitting) ,为了降低方差,就要减少复杂度,一般用正则化方法或者换简单模型,还可以增加数据量。

在机器学习中我们要选择恰当的模型复杂度。

参考:

https://www.zhihu.com/question/27068705/answer/1689740820

https://liam.page/2017/03/25/bias-variance-tradeoff/

http://scott.fortmann-roe.com/docs/BiasVariance.html

多输出学习综述(机翻为主

多输出学习的目的是在给定输入的情况下同时预测多个输出。 因为在现实世界中进行决策通常涉及多个复杂因素和标准,所以它是决策中一个重要的学习问题。 近年来,越来越多的研究集中在一次预测多个输出的方法上。根据所研究的特定的多输出学习问题,这种努力以不同的形式发生。 多输出学习的经典案例包括多标签学习,多维学习,多目标回归等。 从我们对该主题的调查中,我们感到惊讶的是,缺乏将多输出学习的不同形式归纳为一个通用框架的研究。 本文通过对多输出学习范式的全面回顾和分析来填补这一空白。 特别是,我们通过从大数据中汲取灵感来表征多输出学习的四个Vs,即体积,速度,多样性和准确性 volume, velocity, variety, and veracity,,以及这四个Vs既受益又给多输出学习带来挑战的方式。 在输出标签的生命周期中,介绍了多输出学习的主要数学定义,并研究了该领域的主要挑战和文献中发现的相应解决方案。 还讨论了几种模型评估指标和流行的数据库。 最后但并非最不重要的一点是,我们从四个V的角度突出了多输出学习的一些新出现的挑战,这是值得进一步研究的潜在研究方向

一 引入

传统的监督学习是最建立和采用的机器学习范例之一。 它为当今的现实世界中的智能系统和应用提供了快速而准确的预测。 传统监督学习的目标是学习将每个给定输入映射到相应的已知输出的函数。 对于预测任务,输出以单个标签的形式出现。 对于回归任务,它是一个值。 传统的监督学习已被证明能够很好地解决这些简单的单输出问题,经典示例是二元分类,例如在电子邮件系统中过滤垃圾邮件,或者是需要根据温度,风速预测机器每日能耗的回归问题。 湿度水平等。

但是,传统的监督学习范式无法很好地满足当今复杂决策制定的不断增长的需求。 结果,迫切需要新的机器学习范例。 在这里,多输出学习已经成为一种解决方案。 目的是在给定单个输入的情况下同时预测多个输出,这意味着有可能解决更复杂的决策问题。与传统的单输出学习相比,多输出学习具有多元性,并且输出可能具有复杂的交互作用, 只能通过结构化推断进行处理。 另外,输出的可能不同的数据类型导致了机器学习问题的各种类别和相应的研究子领域。二元输出值与多标签分类问题[1],[2]有关; 标称输出值与多维分类问题有关[3]; 在标签排名问题中研究了有序输出值[4]; 多目标回归问题考虑了实值输出[5]

所有这些问题加在一起构成了多输出范式,围绕这一领域的文献量也在迅速增长。 已经提出了几项工作,对每个子领域中出现的挑战和学习算法进行了全面的综述。 例如,Zhang和Zhou [1]研究了多标签学习的新兴领域。 Borchaniet等人[5] 总结了多目标回归中日益增加的问题; Vembu 和 Gärtner [4]提出了关于多标签排名的评论。 但是,对于多输出学习的全局情况和输出标签的重要性却很少关注(参见第二节)。此外,尽管每个子领域的问题由于其输出结构的不同而显得很独特(请参阅第III-A节),但它们确实具有共同的特征(请参阅第III-B节),并且会遇到输出标签的特性所带来的共同挑战。 在本文中,我们尝试提供这种观点。

A.多个输出的四个Vs挑战

流行的四个Vs(即体积,速度,多样性和准确性)已被很好地确立为大数据的主要特征。 学者在多输出学习场景中讨论四个V时,通常是指输入数据;然而,这四个V也可以用来描述输出标签,而且这四个V对多输出学习带来了一系列挑战流程,解释如下。

此外,尽管每个子领域的问题由于其输出结构的不同而显得很独特(请参阅第III-A节),但它们确实具有共同的特征(请参阅第III-B节),并且会遇到输出标签的特性所带来的共同挑战。 在本文中,我们尝试提供这样一种观点:

1)数量是指输出标签的爆炸性增长,这给多输出学习带来了许多挑战。 首先,输出标签空间可能会变得非常大,从而导致可伸缩性问题。 其次,标签注释器的负担显着增加,但是,数据集中的注释通常不足以充分训练模型。 反过来,这可能会导致测试期间看不到输出。 第三,卷可能会造成标签不平衡的问题,尤其是如果并非数据集中所有生成的标签都具有足够的数据实例(输入)。

2)速度是指获取标签的速度有多快,其中包括概念漂移现象[6]。 速度会因输出分布的变化而带来挑战,目标输出会以无法预料的方式随时间变化。

3)多样性是指输出标签的异质性。 输出标签是从多个来源收集的,具有不同结构的各种数据格式。 特别是,具有复杂结构的输出标签可能会在多输出学习中带来多个挑战,例如找到一种对输出依赖关系进行建模的合适方法,或者如何设计多元损失函数,或者如何设计有效的算法。

4)准确性是指输出标签质量的差异。 诸如噪声,缺失值,异常或数据不完整之类的问题都是准确性的特征。

B.这项调查的目的和组织

本文的目的是使用四个V作为本研究领域当前和未来挑战的框架,对多输出学习范式进行全面概述。 多输出学习已吸引了许多机器学习学科的极大关注,例如词性(POS)序列标签,语言翻译和自然语言处理,计算机视觉中的运动跟踪和光学字符识别以及文档分类和排名。 信息检索。 我们希望本次调查能够全面了解多输出学习,并总结多个社区正在解决的不同问题。 最终,我们希望促进多输出学习的进一步发展,并激发研究人员追求有价值的和需要的未来研究方向。

本调查的其余部分结构如下。

第二部分说明了输出标签的生命周期,以帮助理解四个V所带来的挑战。

第三部分提供了无数输出结构的概述以及在多输出学习中解决的常见子问题的定义。 本节还包括有关评估模型时使用的通用指标和可公开获得的数据的一些简短详细信息。 第四节介绍了四个V及其相应的代表性作品在多输出学习中所面临的挑战。

第五节总结了调查。

二 输出标签的生命周期

输出标签在多输出学习任务中起着重要作用,因为模型执行任务的能力在很大程度上取决于这些标签的质量。 图1描述了标签生命周期的三个阶段:注释,表示和评估。 接下来是对每个阶段的简要概述,以及可能会损害多输出学习系统的有效性的潜在问题。

A.如何标记数据

标签标注需要人类在语义上标注一条数据,并且是训练多输出学习模型的关键步骤。 数据可以直接使用其基本注释,也可以添加标签; 可以将它们汇总到集合中以进行进一步分析。 根据应用程序和任务的不同,标签注释有多种类型。 例如,用于图像分类任务的图像应使用标签或关键字标记,而分段任务将要求图像中的每个对象都使用蒙版进行定位。 字幕任务将要求图像带有一些文本描述,等等。

通常,无论有无注释要求,从头开始创建大型的注释数据集都是耗时且费力的工作。 有多种获取标记数据的方法。 社交媒体为研究人员提供了一个平台,供他们搜索带标签的数据集,例如Facebook和Flickr,这些数据集允许用户发布带有标签的图片和评论。 诸如WordNet和Wikipedia之类的开源集合也可以成为标记数据集的有用来源。

除了直接获取带有标签的数据集外,诸如Amazon Mechanical Turk之类的众包平台还可以帮助研究人员通过招募在线工作者来征集未标签数据集的标签。 注释类型取决于建模任务,并且由于众包的效率,该方法已迅速成为获取标记数据集的流行方法。

ImageNet [7]是通过众包平台标记的流行数据集。 它的图像数据库被组织成WordNet层次结构,并已用于帮助研究人员解决一系列领域中的问题。 还开发了许多注释工具来注释不同类型的数据。 LabelMe [8]是一个基于Web的工具,它为用户提供了一种方便的方式来标记图像中的每个对象并纠正其他用户注释的标签。 BRAT [9]也是基于Web的,但是是专门为自然语言处理任务(例如,命名实体识别和POS标记)而设计的。 TURKSENT [10]是一种注释工具,可支持社交媒体帖子中的情感分析。

B.标签代表形式

对于不同的任务,有许多不同类型的标签注释,例如标签,标题和掩码,并且每种类型的注释都可以具有几种表示形式,这些表示形式通常被表示为矢量。 例如,最常见的是二进制矢量,其大小等于标签的词汇量大小。 带注释的样本(例如,带有标签的样本)的值分配为1,其余的样本的值分配为0。但是,二进制矢量对于更复杂的多输出任务不是最佳的,因为这些表示不能保留所有有用的信息。 诸如语义或固有结构之类的细节将丢失。 为了解决这个问题,已经开发了替代的表示方法。

例如,标签的实值向量[11]使用实值指示带注释的标签的强度和程度。 标签属性之间关联的二进制矢量已用于传达标签的特征。 分层标签嵌入向量[12]捕获标签中的结构信息。 语义词向量(例如Word2Vec [13])可用于表示标签和文本描述的语义和/或上下文。 在实际的多输出应用程序中,关键是选择最适合给定任务的标签表示形式。

C.标签评估和挑战

标签评估是确保标签和标签表示质量的重要步骤。 因此,标签评估在多输出任务的执行中起着关键作用。 可以使用不同的模型来评估标签质量,具体选择哪种标签取决于任务。 通常,可以从三个不同方面评估标签:

1)注释是否具有良好的质量(步骤A); 2)选择的标签表示是否很好地代表了标签(步骤B); 3)提供的标签集是否充分覆盖了数据集(标签集)。 评估后,通常需要人类专家来探索任何潜在的问题,并在需要时提供反馈以改进标签的不同方面。

1)标签注释的问题:上述注释方法,例如众包,注释工具和社交媒体,可以帮助研究人员有效地收集注释数据。 但是,在没有专家的情况下,这些注释方法极有可能导致所谓的“噪音标签”问题,其中包括缺少注释和不正确的注释。产生噪声标签的原因多种多样,例如,使用缺少所需领域知识的众包工作者,社交媒体用户的图像或帖子中包含不相关的标签,或标题中的文字含糊不清。

2)标签表示的问题:输出标签也可能具有内部结构,通常,此结构信息对于手头的多输出学习任务的执行至关重要。 基于标签的信息检索[14]和图像标题[15]是结构至关重要的两个示例。 但是,将这些信息作为标签包含在表示中并非易事,因为数据通常很多,并且需要领域知识来定义其结构。 此外,输出标签空间可能包含歧义。 例如,传统上在自然语言处理任务中使用词袋(BOW)作为标签空间的表示形式,但是BOW包含词义模糊性,因为两个不同的词可能具有相同的含义,而一个词可能指的是 多种含义。

3)标签集的问题:构建用于数据注释的标签集需要具有领域知识的人类专家。 另外,通常是由于数据快速增长或某些标签的发生率较低,提供的标签集没有足够的数据标签。 因此,在测试数据中可能会出现看不见的标签,从而导致 open-set[16],zero-shot[17]或概念漂移[18]问题。

三 多输出学习

与传统的单输出学习相反,多输出学习可以同时预测多个输出。 输出可以是各种类型和结构,可以解决的问题是多种多样的。 表I总结了使用多输出学习的子字段及其对应的输出类型,结构和应用程序。在本节中,我们首先介绍了多输出学习问题中的一些输出结构。 接下来提供各个子字段共有的不同问题定义,以及在输出空间上放置的不同约束。 我们还将讨论这些问题的一些特殊情况,并简要概述一些针对多输出学习的评估指标。 本节以对几种常用数据集的分析为基础,对输出维度的演变进行了一些总结。

A.无数的产出结构

对复杂的决策任务的需求不断增长,导致产生了新的产出,其中一些具有复杂的结构。 随着社交媒体,社交网络和各种在线服务的普及,研究人员可以存储并收集各种各样的输出标签。 输出标签可以是任何东西; 它们可以是文本,图像,音频或视频,也可以是多媒体的组合。 例如,给定一个长文档作为输入,输出可能是文本格式输入的摘要。 给定一些文本片段,输出可能是图像,其内容由输入文本描述。 类似地,可以在给定不同类型的输入的情况下生成音频,例如音乐和视频。 除了不同的输出类型外,还有许多不同的可能的输出结构。 在这里,我们使用示例给出了几种典型的输出结构,其中以图像作为输入

1)独立向量:独立向量是具有单独维度(特征)的向量,其中每个维度代表一个特定的标签,而该标签不一定依赖于其他标签。 二进制矢量可用于将给定的数据表示为标签,属性,BOW,可视包,哈希码等。 实值向量提供了加权维,其中实值表示输入数据相对于相应标签的强度。 应用包括使用二进制矢量[19]-[21]对文本,图像或视频进行注释或分类,以及使用实值矢量[23]进行需求或能量预测。 如图2(1)所示,可以使用独立的矢量表示图像的标签,其中所有标签“人”,“晚餐”,“餐桌”和“酒”的权重均相等。

2)分布:与独立向量不同,分布可提供有关特定维度将与特定数据样本相关联的概率的信息。 在图2(2)中,权重最大的标签是“人物”,是图像的主要内容,而“晚餐”和“桌子”具有相似的分布。 分配输出的应用包括头部姿势估计[25],面部年龄估计[26]和文本挖掘[27]。

3) 排名:输出也可能采用排名的形式。其中显示了标签从最重要到最不重要的顺序。 分布学习模型的结果可以转换为排名,但是排名模型不仅限于分布学习模型。 文本分类[28],问题解答[29]和视觉对象识别[30]是经常使用排名的应用程序。

4)文本:文本可以是关键字,句子,段落甚至文档的形式。 图2(4)举例说明了作为图像标题输出的文本的示例-“人们在吃晚饭。” 文本输出的其他应用是文档摘要[45]和段落生成[46]。

5)序列:序列输出是指从标签集中选择的一系列元素。 根据输入以及前一元素的预测输出来预测每个元素。 输出序列通常对应于输入序列。 例如,在语音识别中,我们期望输出是与给定语音音频信号相对应的文本序列[47]。 在语言翻译中,我们期望输出是转换成目标语言的句子[32]。 在图2(5)所示的示例中,输入是图像标题,即文本,并且输出是序列中每个单词的POS标签。

6)树:树输出本质上是层次结构形式的输出。 输出(通常是标签)具有内部结构,其中每个输出都有一个标签,该标签属于或连接到树中的祖先。 例如,在语法分析[35]中,如图2(6)所示,输入语句的每个输出都是POS标签,而整个输出则是一个分析树。 “人”被标记为名词N,但根据树,它也是名词短语NP。

7)图像:图像是一种特殊的输出形式,由多个像素值组成,其中每个像素根据输入及其周围的像素进行预测。 图2(7)显示了超分辨率构造[37],它是一种常见的应用,其中图像是常见的输出。 超分辨率构造是指从低分辨率图像构造高分辨率图像。 其他图像输出应用程序包括从文本到图像的合成[48](从自然语言描述生成图像)和人脸生成[49]。

8)边界框:边界框作为输出,通常用于查找图像中出现的一个或多个对象的确切位置。 这是物体识别和物体检测中的常见任务[30]。 在图2(8)中,每个脸都由边界框定位,以便可以识别每个人。

9)链接:作为输出的链接通常表示网络中两个节点之间的关联[36]。 图2(9)给出了一个任务,该任务用于预测给定一个分区社交网络(边缘代表用户之间的友谊)时,当前两个未链接的用户将来是否会成为朋友。

10)图形:图形通常用于建模之间的关系。 它们由一组节点和边组成,其中一个节点代表一个对象,一个边指示两个对象之间的关系。 例如,场景图[50]通常作为描述图像内容[34]的一种方式输出。 图2(10)显示,给定输入图像,输出是图形定义,其中节点是图像中出现的对象,即“人”,“晚餐”,“桌子”和“酒”,以及 边缘是这些对象之间的关系。 场景图作为任务的表示非常有用,例如图像生成[51]和视觉问答[52]。

11)其他输出:除了这几种类型之外,还有许多其他类型的输出结构。 例如,轮廓和多边形输出类似于边界框,可以用作对象定位的标签。 在信息检索中,输出可以是类似于给定查询的数据对象的列表类型。 在图像分割中,输出通常是不同对象的分割蒙版。 在信号处理中,输出可能是语音或音乐的音频。 另外,某些实际应用程序可能需要与多个任务相关的更复杂的输出结构。 例如,可能需要同时识别和定位对象,例如在同显性中,即发现多个图像的共同显着性[53],同时在给定多个图像的同时对相似对象进行分段[54],或者检测 在对象编码中[55]识别多个图像中的对象。

B.多输出问题定义

多输出学习将每个输入(实例)映射到多个输出。 假定X = Rd是d维输入空间,而Y = Rm是m维输出标签空间。 多输出学习多输出学习将每个输入(实例)映射到多个输出。 假定X = Rd是d维输入空间,而Y = Rm是m维输出标签空间。 多输出学习的目的是从训练集 $D = {(x_i,y_i) | 1≤i≤n }$ 中学习函数 $f:X→Y$。 对于每个训练示例$(xi,yi)$,xi∈X是d维特征向量,yi∈Y是与xi相关联的对应输出。 多输出学习的一般定义如下:根据输入输出对的训练样本找到一个函数F:X×Y→R,其中F(x,y)是一个兼容性函数,用于评估 输入x和输出y是。 然后,在测试状态下给定未知实例x的情况下,预测输出为兼容性最大的实例≤i≤n}$ 中学习函数f:X→Y。 对于每个训练示例(xi,yi),xi∈X是d维特征向量,yi∈Y是与xi相关联的对应输出。 多输出学习的一般定义如下:根据输入输出对的训练样本找到一个函数F:X×Y→R,其中F(x,y)是一个兼容性函数,用于评估 输入x和输出y是。 然后,在测试状态下给定未知实例x的情况下,预测输出为兼容性最大的实例

该定义为多输出学习问题提供了一个通用框架。 尽管不同的多输出学习子字段的输出结构各不相同,但是可以在给定输出标签空间Y某些约束的情况下在此框架内定义它们。我们选择了几个流行的子字段,并在第III-B1-III节中介绍了它们的输出空间的约束。 -B9。 请注意,多输出学习不限于这些特定方案; 它们仅是示例。

1)多标签学习:多标签学习的任务是学习一个函数f(·),该函数为看不见的实例预测正确的标签集[1]。 在此任务中,每个实例都与一组类标签/标签关联,并由稀疏的二进制标签向量表示。 值+1表示实例已标记,而1表示未标记。 因此,yi∈Y = {-1,+ 1} m。 给定一个看不见的实例x∈X,学习的多标签分类函数f(·)输出f(x)∈Y,其中输出向量中值为+1的标签用作x的预测标签。

2)多目标回归:多目标回归的目的是针对一个实例同时预测多个实值输出变量[5],[57]。 在此,与每个实例相关联的多个标签区域,由实值向量表示,其中的值表示实例与标签的对应程度。 因此,我们有yi∈Y= Rm的约束。 给定一个看不见的实例x∈X,学习的多目标回归函数f(·)预测实值向量f(x)∈Y作为输出

3)标签分布学习:标签分布学习确定每个标签在多标签学习问题中的相对重要性[58]。 这与多标签学习相反,后者只是学习预测一组标签。但是,如图2所示,标签分布学习的思想是预测多个标签,该标签的度值表示每个标签对实例的描述程度。

4)标签排名:标签排名的目标是将实例映射到一组预定义标签的有限集合上的总顺序。

5)序列比对学习:序列比对学习旨在识别两个或多个序列之间的关系区域。 此任务中的输出是输入实例的多个标签序列。 输出向量具有约束yi∈Y= {0,1,…,c} m,其中c表示标签的总数。 在序列比对学习中,可能会因输入而异。 给定一个看不见的instancex∈X,则学习的序列比对函数f(·)outputsf(x)∈Y,其中输出向量中的所有预测标记均形成预测序列forx

6)网络分析:网络分析探索了网络结构中对象与实体之间的关系和相互作用,而链接预测是该子域中的常见任务。 设G =(V,E)表示网络图,以节点集表示对象,以E为边缘集表示对象之间的关系。 两个节点之间是否存在连接。 输出向量yi∈Y= {-1,+ 1}是一个二进制向量,其值表示在任意一对节点之间是否存在边e =(u,v)u,v∈V edge/∈E。 不会出现在当前图形G中,并且每个维度都表示一对当前未连接的节点。

7)数据生成:数据生成是多输出学习的子字段,旨在创建并输出一定分布的结构化数据。 深度生成模型通常用于生成数据,该数据可以是文本,图像或音频的形式。 问题中的多个输出标签将成为词汇表中的不同单词,像素值,音频音调等。 以图像生成为例。 输出向量具有约束yi∈Y= {0,1,…,255} mw×mh×3,其中mwandm是图像的宽度和高度。 给定一个看不见的instancex∈X,通常是随机噪声或带有某些约束的嵌入矢量,则学习的基于GAN的网络f(·)outputsf(x)∈Y,其中输出矢量中的所有预测像素值均形成生成的图像 福克斯。

8)语义检索:语义检索是指在某些给定信息中查找含义。 在这里,我们考虑在每个输入实例都具有可用于帮助检索的语义标签的环境中进行语义检索[59]。 因此,每个实例表示都包括语义标签,即outputyi∈Y= Rm。 给定一个看不见的实例x∈X作为查询,学习的检索函数f(·)预测实值向量f(x)∈Y作为中间输出结果。 然后,可以使用中间输出向量,通过使用基于距离的适当检索方法来从数据库中检索相似数据实例的列表。

9)时间序列预测:时间序列预测的目标是根据先前的观察预测序列中的未来值[60]。 输入是一段时间内的一系列数据向量,输出是futuretimestamp的数据向量。 表示时间索引。 attimetis的输出向量表示为asyti∈Y= Rm。 因此,在一段时间tt = 0tot = Tareyi =(y0i,…,yti,… yTi)内的输出。 给定先前观察到的值,学习的时间序列函数输出预测的连续未来值。

C.多输出学习的特殊案例

1)多类别分类:如果将输出类别表示为整数编码或单热向量,则可以将多类别分类归类为传统的单输出学习范例.

2)细粒度分类:细粒度分类是一个挑战 多分类任务,其中类别可能仅具有细微的视觉差异[61]。 尽管细分类的输出与多分类具有相同的向量表示,但是向量具有不同的内部结构。 同样,在其标签层次结构中,具有相同父代的标签往往比具有不同父代的标签更紧密相关。

3)多任务学习:多任务学习(MTL)的目的是通过同时学习多个相关任务来提高通用性能的子领域[62],[63]。 问题中的每个任务输出一个标签或一个值。 可以将其视为多输出学习范例的一部分,因为学习多个任务类似于学习多个输出。 MTL利用任务之间的关联性来提高学习模型的性能。 MTL和多输出学习之间的主要区别在于,在MTL中,可能在不同的训练集或功能上训练不同的任务,而在多输出学习中,输出变量通常共享相同的训练数据或功能。

D.模型评价指标

在本节中,我们介绍用于评估具有测试数据集的多输出学习模型的常规评估指标。 设T = {(xi,yi)|1≤i≤N}为测试数据集,f(·)为多输出学习模型,ˆyi = f(xi)为测试示例xi的预测输出off(·) 。 另外,letYiandˆYide分别表示对应于yi和ˆyi的标签集。I是一个指标函数,其中I(g)= 1 if g is true,否则为0

1)基于分类的度量标准:基于分类的度量标准针对多标签分类,语义检索,图像标注和标签排名等分类问题评估多输出学习的性能。 离散值。 常规分类指标分为三类:基于示例,基于标签和基于排名

a)基于示例的指标:基于示例的指标[64]针对每个数据实例评估多输出学习模型的性能。首先独立评估在每一个测试实例性能。所有个体结果的平均值用于反映模型的整体性能。 多输出分类任务的评估与二进制分类(单输出)任务在相同的机制下工作:二进制分类的经典度量可以扩展为评估多输出分类模型[1]。 常用的指标是精确匹配率,准确性,准确性,召回率,F1得分和汉明损失

b)基于标签的指标:基于标签的指标评估每个输出标签的性能。 这些度量汇总了所有标签的贡献,以得出对模型的平均评估。 有两种获取基于标签的度量的技术:宏平均和微观平均。 基于宏平均的方法可独立计算每个标签的指标,然后对所有具有相等权重的标签进行平均。 相比之下,基于微平均的方法对每个数据样本的权重相同。 TP1,FP1,TN1和FN1分别表示每个标签的真阳性,真阴性,假阳性和假阴性的数目。 设为特定标签的二进制评估指标(准确性,准确性,召回率或F1分)。 因此,宏观方法和微观方法定义如下

c)基于排名的指标:基于排名的指标根据输出标签的排序评估性能。

One-error 是排名最高的标签不在真实标签集中的次数。 这种方法仅考虑模型的最自信的预测标签。 所有数据实例的平均One-error错误计算为

Ranking loss 排名损失标签对错误排序的平均比例

平均精度(AP)是在真实标签集中排在特定标签上方的标签的比例,是所有真实标签的平均值。值越大,模型的性能越好。 所有测试数据实例的平均AP定义如下。。。

讨论:前面列出的度量标准是那些常用于基于分类的多输出学习问题的度量标准,但是度量标准的选择根据每个应用程序的不同考虑而有所不同。 以图像注释为例。 如果任务的目的是正确注释每个图像,则基于示例的度量标准是评估性能的最佳选择。 但是,如果目标是基于关键词的图像检索,则最好使用宏平均度量[64]。此外,某些度量更适合于多输出学习问题的特殊情况。 例如,对于不平衡的学习任务,某些基于分类的指标(例如误差,准确性和F1分数)的几何平均值[65]更令人信服,可用于评估。最小灵敏度[66]可以帮助确定阻碍学习的类别 我们将不详细讨论这些指标,因为它们不是本文的重点

2)基于回归的度量标准:毫无疑问,基于回归的度量标准可评估具有回归问题(例如对象定位或图像生成)的多输出学习性能。 输出通常是实数值。 常用的基于回归的度量标准是平均绝对误差(MAE),均方误差(MSE),平均相关系数(ACC)和联合交集(IoU)。 这些度量的详细信息可以在补充材料中找到。

3)新指标:数据生成是多点学习的一个新兴子领域,它使用生成模型输出具有一定分布的结构化数据。 根据当前任务的具体情况,通常从两个方面评估模型的性能:

1)生成的数据是否实际上遵循所需的实际数据分布,以及 2)生成的样本的质量。 经常使用诸如平均对数似然[67],覆盖率[68],最大平均差异(MMD)[69]和几何得分[70]之类的指标来评估分布的准确性。 量化生成数据质量的度量标准仍然具有挑战性。常用的是初始分数(IS)[71],modescore(MS)[72],Fréchet初始距离(FID)[73]和内核初始距离(KID)[74] ]。 精度,召回率和F1分数也用于GAN中,以量化模型中的过拟合程度[75]。

E.多输出学习数据集

用于测试多输出学习问题的大多数数据集已经构建或广受欢迎,因为它们反映并因此测试了需要克服的挑战。 我们根据四个V中反映的挑战介绍了这些数据集。 表II列出了数据集,包括它们的多输出特征

大规模数据集,即可用于测试量的数据集非常大。 他们相应的统计数据的庞大性说明了迫切需要克服这一特定V所带来的挑战。4。许多专注于输出分布变化(例如概念漂移/速度)的研究都依赖于合成流。 实验中的数据或静态数据库。 我们还包括一些较流行的真实世界和/或动态数据库,用于试验这些任务。 如表所示,数据集来自不同的应用领域,表明了这一挑战的重要性

旨在测试复杂的多输出学习问题的数据集包含不同输出结构的混合。 例如,表中列出的图像数据集包括对象的标签和边框。 这些数据集可用于测试各种数据。

最后,我们来确定一下准确性。 许多详细说明嘈杂标签的工作都是通过从一个干净的数据集开始评估其方法,然后将其添加到人工噪声中。 这有助于研究人员控制和测试不同级别的噪声。 我们还列出了一些流行的现实世界数据集,其中注释中存在一些未知水平的错误

四 多输出学习和代表性工作的挑战

对复杂的预测输出的迫切需求以及输出标签的爆炸性增长对多输出学习提出了若干挑战,并暴露了迄今为止存在的许多学习模型的不足之处。 在本节中,我们将讨论这些挑战中的每一个,并回顾一些代表性的作品,说明它们如何应对这些新兴现象。 此外,考虑到人工神经网络(ANN)的成功,我们还展示了几个使用ANN进行每次挑战的多输出学习的最新示例。

A. Volume – Extreme Output Dimensions 体积-极端输出维度

大规模数据集在实际应用中无处不在。 如果满足以下三个条件之一,则将数据集定义为大规模:它具有大量数据实例,输入要素空间具有高维或输出空间具有高维。 许多研究试图解决由大量数据实例(例如,[212]中的实例选择方法)或具有高维特征空间(例如,[213]中的特征选择方法)引起的可伸缩性问题。 但是,与高产出维度相关的问题却很少受到关注。

例如,考虑一下,如果可以从具有不同标签的标签集中选择三维输出向量的每个维度的标签,那么输出结果的数量就是c^m。 因此,这些超高输出尺寸/标签导致极大的输出空间,进而导致高计算成本。 因此,设计能够应对巨大且持续增长的产出的多产出学习模型至关重要。

对当前有关超高输出维度的最新研究的分析显示了一些有趣的见解。 我们的分析基于多种学科研究中使用的数据集,例如机器学习,计算机视觉,自然语言处理,信息检索和数据挖掘。 我们特别关注了三个顶级期刊和三个顶级国际会议上的文章:IEEE交易论电池分析和机器智能(TPAMI),IEEE交易论神经网络和学习系统(TNNLS),机器学习研究杂志(JMLR),国际机器学习会议(ICML), 神经信息处理系统会议(NIPS)和知识发现与数据挖掘会议(KDD)。 图3和4总结了我们的评论。 从图3和图4可以明显看出,被研究算法的输出维数随着时间的推移持续增加。 此外,针对所有选定标题的有关此问题的最新文章现在处理的输出尺寸超过一百万,在某些情况下,输出量接近数十亿。 此外,发布时间更短的会议的统计数据表明,输出维度的增长速度有多快。 通过此分析,我们得出结论,输出维数的爆炸式增长正在推动多输出学习算法的许多发展。

我们回顾的研究倾向于分为两类:定性和定量方法。 定性方法通常包含生成模型,而定量模型通常包含判别模型。这两种模型之间的主要区别在于,生成模型专注于学习输入x和标签y联合概率P(x,y),而判别模型集中在后验P(y | x)上。 请注意,在生成模型中,P(x,y)可用于生成一些数据x,在这种情况下,在这种情况下,将生成的输出与x一起使用。

1)定性方法/生成模型:图像合成[48],[214]的目的是从图像的文本图像描述中合成新图像。 一些开创性的研究人员已经使用GAN合成图像,其中GAN的图像分布为多个输出[67]。 但是,在现实生活中,GAN只能生成低分辨率图像。 但是,自从首次尝试这种方法以来,在扩大GAN尺寸以生成具有合理输出的高分辨率图像方面已经取得了进展。 例如,Reedet等[48]提出了一种GAN架构,该架构在给出文字描述的情况下生成视觉上合理的64×64像素图像。 在后续研究中,他们提出了GAWWN [214],它通过利用附加注释将合成的图像缩放到128×128分辨率。 随后,提出了StackGAN [215],它能够从文本描述中生成256×256分辨率的逼真的图像。HDGAN [216]是图像合成的最新技术。 512×512像素的端到端时尚。 不可避免地,未来的分辨率会进一步提高

MaskGAN [217]使用GAN生成文本(即有意义的单词序列)。 标签集大小与词汇量大小一致。 输出维数是生成的单词序列的长度,从技术上讲,该长度可以不受限制。 但是,MaskGAN仅处理句子级文本生成。 文档和书籍级别的文本生成仍然具有挑战性。

2)定量方法/判别模型:类似实例和特征选择方法可以减少输入实例的数量,进而减少输入维数,因此设计类似地降低输出维数的模型是很自然的。 嵌入方法可通过将原始空间投影到较低维度的空间上来压缩空间,并保留预期的信息,例如标签相关性和邻域结构。 可以采用流行的方法,例如随机投影或规范相关分析投影[218]-[221],以减小输出标签空间的尺寸。 结果,可以在压缩的输出标签空间上执行这些建模任务,然后将预测的压缩标签投影回原始的高维标签空间。 Mineiro和Karampatziakis [222]提出了一种针对超大输出空间的新型随机嵌入方法。 AnnexML [169]是用于图的另一种新颖的嵌入方法,可捕获嵌入空间中的图结构。 嵌入是由标记向量的k个最近邻(kNN)构成的,并且预测是通过近似最近邻搜索方法有效进行的。 两种用于处理极端输出尺寸的流行ANN方法是fastText学习树[223]和XML-CNN [224]。 FastText学习树[223]共同学习数据表示和树结构,并从中学习,然后将树结构用于有效的分层预测。XML-CNN是基于CNN的模型,该模型合并了dynamicmax-pooling方案以捕获来自输入文档区域的细粒度特征。 隐藏的瓶颈层用于减小模型大小。

B. Variety – Complex Structures 多样化复杂结构

随着标签数量的增加,迫切需要了解标签的固有结构。 复杂的输出结构可能导致多输出学习中的多个挑战。 例如,在标签之间通常存在强相关性和复杂依赖性。 因此,在多输出学习中,对标签表示中的输出依赖关系进行适当建模是至关重要的,但并非不重要。 此外,设计一个多元损失函数并提出一种有效的算法来缓解复杂结构所造成的高复杂性也具有挑战性.

1)适当的输出依存关系建模:多输出学习的最简单方法是将学习问题分解为最小依赖的单输出 一个代表性的方法是二进制相关性(BR)[225],它独立地为输出空间中的所有标签学习二进制分类器。 给定一个看不见的实例,BR预测通过预测每个二元分类器,然后汇总预测的标签来输出标签。 但是,这样的独立模型没有考虑输出之间的依赖关系。 可以将一组预测的输出标签分配给测试实例,即使这些标签从不共同出现在训练集中。 因此,至关重要的是对输出依赖关系进行适当建模,以获得多输出任务的更好性能。

已经提出了许多经典的学习方法来对具有相互依赖性的多个输出进行建模。 这些包括标签幂集(LP)[226],分类器链(CC)[227],[228],结构化支持向量机(SSVM)[56],条件随机字段(CRF)[229]等。 LP通过将输出空间中标签的每个不同组合视为一个标签来对输出依赖性进行建模,这将问题转化为学习多个单标签分类器之一。 要训练的单标签分类器的数量是标签组合的数量,它随标签数量的增加而指数增长。 因此,当使用大量输出标签进行训练时,LP具有计算成本高的缺点。 随机k标签集[230]是LP分类器的集合,它是LP的一种变体,它通过在标签的不同随机子集上训练每个LP分类器来减轻计算复杂性问题。

CC通过考虑输出相关性来改善BR。 它通过修改后的特征空间将来自BR的所有二进制分类器链接到一条链中。 给定第j个标签,实例xi会增加第一个,第二个,…,(j-1)个标签,即(xi,l1,l2,…,lj-1),作为训练第j个分类器的输入 给定一个看不见的实例,CC使用第一个分类器预测输出,然后使用来自第一个分类器的预测作为第二个分类器的输入来扩充实例,以预测下一个输出。 CC从第一个分类器到最后一个分类器以此方式处理值,从而保留了输出相关性。 但是,不同顺序的链导致不同的结果。 提出了CC的整体ECC [227]来解决这个问题。 它在一组随机排序链上训练分类器并取平均结果。概率CC(PCC)[231]通过估计输出标签的联合分布来捕获输出相关性,从而提供了CC的概率解释。 CCMC [114]是一种CC模型,它考虑了标签困难的顺序,以减少由歧义标签引起的性能下降。 这是一种易于学习的范例,它可以识别简单标签和硬标签,并使用对简单标签的预测来帮助解决较难的标签。

SSVM利用大幅度 profit 的想法来处理多个相互依存的输出。 兼容性函数定义为F(x,y)= wT(x,y),其中权重向量和:X×Y→Rqis联合特征映射输入和输出对。 SSVM的目标是找到分类器hw(x)=argmaxy∈Yw,φ(x,y):

除了学习输出之间的相关性的经典模型外,一些最新的多输出学习模型还基于ANN。 例如,基于卷积神经网络的模型通常集中在分层多标签[233]或排名[234]上。 递归神经网络(RNN)模型通常集中于序列到序列学习[235]和时间序列预测[236]

生成型深度神经网络用于生成输出数据,例如图像,文本和音频[67]。

2)多元损失函数:定义了各种损失函数以计算真实情况和预测输出之间的差异。 给定相同的数据集,不同的损失函数会表现出不同的误差,它们会极大地影响模型的性能。0/ 1损失是分类中常用的标准损失函数[237]

通常,0/1丢失是指训练样本分类错误的数量。 但是,它非常严格,并且没有考虑标签依赖性。因此,它不适用于大量输出或结构复杂的输出。 另外,它是非凸且不可微的,因此很难使用标准凸优化方法来最小化损失。 实际上,通常使用替代损失,它是任务损失的凸上限。 然而,当推广单一输出方法来处理多个输出时,多输出学习中的代理损失通常会失去一致性[238]。多输出学习子字段上的多项工作研究了不同代理函数的一致性,并表明它们在某些充分条件下是一致的。 [239],[240]。然而,这仍然是多输出学习的一个挑战性方面。需要进一步探索不同问题的理论一致性。

在下文中,我们描述了四种常见的替代损失:铰链损失,负对数损失 ,感知器损耗和softmax margin损耗。铰链损耗是使用最广泛的代理损耗之一,通常用于结构化SVM中[241]。 它推动正确输出的得分大于预测的得分

根据输出结构和任务,边距(y,y)具有不同的定义。 例如,对于序列学习或具有相等权重的输出,可以简单地将(y,y)定义为汉明损失∑mj = 1I(y(j)= y(j))。 对于具有分层输出结构的分类学分类,可以将(y,y)定义为树状图之间的树距离[19]。 Forranking(y,y)可以定义为与最优值相比的Rankingy的平均AP [242]。 在语法分析中,(y,y)定义为标记跨度的数量,其中yandy不一致[35]。 不可分解的损失,例如F1度量,AP或IOU,也可以定义为余量。

负对数损失是CRF中常用的方法[229]。 请注意,最小化负对数丢失与最大化数据的对数概率相同

感知器损失通常用于结构化感知器任务中[243],与铰链损失相同但没有余量

Softmax-margin损失是多输出学习模型(例如SSVM [244]和CRF)中最流行的损失函数之一

平方损失是一种流行且方便的损失函数,通常会对基本事实和预测之间的差异进行惩罚。 它通常用于传统的单输出学习中,并且可以通过对所有输出的平方差求和来轻松扩展到多输出学习。

在多输出学习中,通常先将其与连续值输出或连续中间结果一起使用,然后再将其转换为离散值输出。

3)高效的算法:复杂的输出结构显着增加了算法建立模型的负担。大型输出,复杂的输出依存关系和/或复杂的损失函数都可能成为问题。 因此,专门提出了几种算法来有效地解决这些挑战。 许多人利用经典的机器学习模型来加速算法并减轻复杂性的负担。 四种使用最广泛的经典模型基于kNN,决策树,k均值和散列

1)基于kNN的方法是简单而强大的机器学习模型。 根据与欧氏距离有关的测试实例向量的最接近关系来进行预测。 LMMO-kNN [246]是一个基于SSVM的模型,涉及相对于标签数量的指数数量的约束。该模型强加了来自相邻示例的标签矢量实例化的NN约束,以显着减少训练时间并进行快速预测。

2)决策树- 基于方法[247],[248]的方法从训练数据中学习带有树状输出标签空间的树。 他们递归地划分节点,直到每个叶子都包含少量标签。 每个新颖的数据点都沿树向下传递,直到到达叶为止。

3)基于k均值的方法,如SLEEC [79],使用k均值聚类对训练数据进行聚类。 SLEEC学习每个群集的独立嵌入,并单独对其群集中的新实例执行分类。 这显着减少了预测时间。

4)哈希方法(例如cohashing [249],[250]和DBPC [251])通过在输入或中间嵌入空间上使用哈希来减少预测时间。cohashing 学习了一个嵌入空间保留输入和输出之间的语义相似性结构。 然后为学习的嵌入生成紧凑的二进制表示,以提高预测效率。 DBPC在学习神经网络的潜在潜在非线性结构的同时,共同学习了一个深潜的Hamming空间和二进制原型,所学习的Hamming空间和二进制原型极大地降低了预测复杂度并降低了存储/存储成本。

C. Volume – Extreme Class Imbalances 数量极端的标签失衡

实际的多输出应用程序很少为所有标签/类提供具有相同数量训练实例的数据。 一类中的一个实例过多而另一类中的实例意味着数据不平衡,这在许多应用程序中很常见。 因此,从此类数据中学到的传统模型倾向于更偏爱多数类。 例如,在生成人脸时,经过训练的模型往往会生成名人的脸,因为名人的图片比其他人多得多。 尽管在二元分类的背景下已经广泛研究了班级失衡问题,但是这个问题仍然在多输出学习中仍然是一个挑战,特别是在极端失衡的情况下。

关于多输出学习的许多研究要么创建了平衡数据集,要么忽略了平衡数据带来的问题。 平衡类分布的自然方法是对数据集重新采样。 有两种主要的重采样技术:欠采样和过采样[252]。 贴合底下的方法缩小了多数类的大小。 NearMiss 方法族[253]是该类别的代表作品。 诸如SMOTE及其变体[254]之类的过采样方法对少数类采用过采样技术来处理不平衡的类学习问题。 但是,所有这些重采样方法主要是针对单输出学习问题而设计的。 还有其他技术可以使用ANN处理多输出学习任务中的类失衡问题,

例如Donget等人[255]。 然后,硬样本挖掘策略通过发现稀疏抽样的少数群体的边界,将多数群体的主导效应最小化。 [256]和[257]中的两种方法都利用对抗训练通过使用权重加权技术来减轻失衡,从而多数类倾向于产生与少数类相似的影响。

D. Volume – Unseen Outputs 数量-看不见的输出

传统的多输出学习假设测试中的输出集与训练中的输出集相同,即测试实例的输出标签在训练中已经出现。 但是,在实际应用程序中可能并非如此。 例如,无法使用基于现有动物的学习分类器来检测新出现的生物物种。 同样,如果训练视频集中没有出现带有相同标签的此类动作或事件,则无法在实时视频中识别这些动作或事件,粗略的动物分类器也无法提供所检测到的动物种类的详细信息,例如 伊萨 拉布拉多犬 或牧羊犬

根据学习任务的复杂性,标签注释通常非常昂贵。 此外,数字标签的巨大增长不仅由于计算效率低而导致高维输出空间,而且由于在测试过程中看不见输出标签,使得有监督的学习任务面临挑战

1)零射多标签分类:多标签分类是一个典型的多输出学习问题。 根据应用程序的不同,多标签分类问题可以具有各种输入,例如文本,图像和视频。 每个输入实例的输出通常是二进制标签向量,指示与输入关联的标签。 多标签分类问题学习从输入到输出的映射。 但是,随着标签空间的增加,通常会在测试期间找到看不见的输出标签,而在训练集中却没有出现这样的标签。 为了研究这种情况,在[17]和[260]中首先提出了零射多类分类问题,并且大多数利用了预定义的语义信息,例如属性[11]和单词表示[13]。 然后将此技术扩展到零击多标签分类,以将多个看不见的标签分配给一个实例。 类似地,零射多标签学习利用对可见标签和不可见标签的知识,并对输入要素,标签表示和标签之间的关系进行建模。 例如,Gaureet等人[259]利用可见和不可见标签的共现统计,并使用生成模型共同对标签矩阵和共现矩阵进行建模。 Rios和Kavuluru [260]和Leeet等[261] 将标签关系的知识图与神经网络合并

2)零射动作本地化:类似于零射分类问题,在没有任何培训视频示例的情况下将视频中的人为动作本地化是一项艰巨的任务。 受零射图像分类的启发,对零镜头动作分类的许多研究都基于对行为到属性的映射的先验知识,从分离动作中预测了看不见的动作[262]-[264]。 这样的映射通常是预定义的,可见的和看不见的动作通过属性的描述链接在一起。 因此,它们可以被用来概括未定义的动作,但是不能定位动作。最近,提出了一些工作来克服这个问题。 贾内特等人[265] 在不使用任何视频数据或动作注释的情况下提出Objects2action。 它利用了可从开源集合(如WordNet和Ima-geNet)获得的大量对象注释,图像和文本描述。 Mettes和Snoek [266]随后通过考虑参与者与对象之间的关系来增强了Objects2action。

3)开放式识别:传统的多输出学习问题(包括零镜头多输出学习)在封闭的假设下运行,即在训练时间通过训练样本或由于它们而知道所有测试类别的情况 在语义标签空间中预定义。 但是,Scheireret等人[16] 提出了一种称为开放集识别的概念,用于描述在测试中出现未知类的情况。 开放集识别代表了一种对集机器,可以对已知类别以及未知类别进行分类。 在以后的研究中[267],[268],他们通过建立一个紧凑的消融概率模型,将该思想扩展到多类环境中。 Bendaleand Boult [269]通过提出一个新的模型层来估计输入为未知类的可能性,从而将ANN进行了开放集识别。

图5示出了在多输出学习中不同水平的看不见的输出之间的关系。 开放式识别是所有问题中最普遍的问题。 few-shot 和 zero-shot学习针对不同的多输出学习问题进行了研究,例如多标签学习和事件定位。然而,开放集识别仅在与多类分类相结合的情况下进行研究。 在多输出学习的背景下,其他问题仍待探讨

E. Veracity – Noisy Output Labels 准确性-嘈杂的输出标签

出于各种原因,几乎所有的标签注释方法都会导致一定数量的噪音。 关联性可能很弱,文本可能模棱两可,并且众包的工作人员可能不是领域专家,因此标签可能不正确[270]。因此,通常有必要处理嘈杂的输出,例如丢失,损坏,不正确和/或部分输出 标签,在现实世界中的任务中。

1)缺少标签:通常,人类注释者会使用突出的标签来注释图像或文档,但会丢失一些尽管如此强调的标签。 另外,图像中的所有对象可能无法定位,因为存在太多对象或对象太小。 Instagram等社交媒体允许用户标记上传的图像。 但是,标签可能与任何内容有关:事件的类型,人员的心情和天气。 另外,没有用户可能标记图像的每个对象或每个方面。 直接使用这样的标记数据集的区域多输出学习模型不能保证给定任务的执行。 因此,在实际应用中必须处理缺少的标签。

在早期研究中,缺失的标签通过将它们视为阴性标签来处理[271]-[273]。 然后,基于完全标记的数据集执行建模任务。 但是,这种方法会给学习问题带来不希望的偏差。 因此,现在使用更广泛的方法是通过矩阵完成[186],[192],[274]来缺失值插补。 这些方法中的大多数基于低排名假设,并且最近基于标签相关性,从而提高了学习成绩[275],[276]

2)标签不正确:高维输出空间中的许多标签都没有提供信息或完全错误[277]。 这在雇用非专家工作者的众包平台注释中尤其常见。 来自社交媒体网络的标记数据集通常也没有什么用处。 处理不正确标签的基本方法是简单地除去那些样品[278],[279]。 也就是说,通常很难检测出样品的标签错误。 因此,设计从嘈杂的数据集学习的多输出学习算法具有很大的现实意义。

现有的处理噪声标签的多输出学习方法通常分为两类。 第一组基于建立稳健的损失函数[280] – [282],该函数会修改损失函数中的标签以减轻噪声的影响。第二组建模潜在标签,并学习从潜在标签到嘈杂标签的过渡[283]。 – [285]。

部分标签:部分标签[286]-[288]是标签不正确的一种特殊情况,其中每个训练实例都与一组候选标签相关联,但其中只有一个是正确的。这是实际应用中的常见问题。 例如,一张照片可能包含许多带有标题的面孔,其中列出了照片中的人物,但名称与该面孔不匹配。 已经开发了许多用于学习部分标签的方法,以从候选集[289],[290]中恢复真实标签。 但是,大多数情况是基于每个实例仅具有一个基本事实的假设,而不同的标签注释方法可能永远都适用。 在众包平台上使用多个工作程序来注释数据集时,通常从所有工作程序的注释的并集集合中收集最终注释,其中每个实例可能与多个相关标签和不相关标签相关联。 因此,Xie和Huang [291]开发了一种新的学习框架,即部分多标签学习(PML),它通过利用数据结构信息来优化置信度加权秩损失,从而放松了这一假设。 图6总结了带有嘈杂输出标签的所有场景,包括多标签学习,缺少标签,不正确的标签,部分标签学习和PML。

F. Velocity—Changes in Output Distribution 速度-输出分布的变化

许多现实世界的应用程序必须处理数据流,其中数据连续不断地到达,并且可能无休止地到达。 在这些情况下,输出分布会随时间变化或发生概念漂移。 流数据在监视[98],驾驶员路线预测[95],需求预测[97]和许多其他应用中很常见。 以监视视频中的视觉跟踪[292]为例,其中视频流可能无穷无尽。 随着视频不断生成连续的帧,数据流以很高的速度进入。 目标是检测。因此,学习模型必须在有限的内存下工作时适应可能的概念漂移。

现有的多输出学习方法通过在每次数据流到达时更新学习系统来对输出分布的变化进行建模。 更新方法可能是基于集成的[293]-[297]或基于ANN的方法[292],[298]。 处理概念漂移的其他策略包括假设对过去的数据有渐弱的影响[296]; 维护预测性能测量的变化检测器,并相应地重新校准模型[295],[299]; 使用随机梯度下降来更新网络并使用ANN来容纳新的数据流[292]。 值得注意的是,kNN是处理多输出问题的最经典的框架之一,但是由于效率低下的问题,它无法成功地适应输出分布变化的挑战。许多在线哈希和基于在线量化的方法[300], 提出[301]来提高kNN的效率,同时适应变化的输出分布。

G. 其他挑战

可以将上述两个挑战中的任意一个组合起来,以构成更为复杂的挑战。 例如,嘈杂的标签和看不见的输出可以组合在一起,形成开放式嘈杂的标签问题[302]。 另外,嘈杂标签和极端输出尺寸的组合也值得研究和进一步探索[206]。 输出分布的变化与嘈杂的标签一起会导致缺少值的在线时间序列预测问题[303],而分布的变化与动态标签集(看不见的输出)结合会导致带有增量标签的开放世界识别问题[304]。 在极端类别不平衡的情况下改变输出分布会产生一个普遍的问题,即同时具有概念漂移和类别不平衡的流数据[18],[305]。 而且,在实际应用中,复杂的输出结构与不断变化的输出分布的组合也很常见[306]

H.公开挑战

1)输出标签的解释:表示输出标签的方法有很多,每种方法都从特定的角度表示标签信息。 以标签标签为输出,例如,二进制属性输出嵌入表示输入所涉及的属性。 分层标签输出嵌入传达了输入的层次结构。语义词输出嵌入反映了输出之间的语义关系。可以看到,每个展品

一定程度的人类可解释性。 因此,一种新兴的标签嵌入方法是从多个角度和丰富的上下文中合并不同的标签信息,以增强可解释性[307]。 这是一项具有挑战性的工作,因为很难以人类容易理解和理解的方式对输出之间的相互依赖性进行适当建模。 例如,预期半人马的图像将用诸如马和人之类的语义标签来描述。 此外,该图像有望被描述为具有诸如头部,手臂和尾部之类的属性,因此,对具有丰富标签解释的输入和输出之间的关系进行适当建模是一个开放的挑战,应在未来的研究中加以探索

2) 产出异质性:随着对复杂决策制定的需求增加,对具有更复杂结构的产出的需求也随之增加。 回到监视工具的例子,传统方法中的人员重新识别通常包括两个步骤:人员检测,如果输入了该人员,则对其进行重新识别。 这些步骤本质上是两个单独的任务,如果要提高性能,则需要一起学习。 最近有几位研究人员尝试了这一艰巨的挑战,即建立一个可以同时学习具有不同输出的多个任务的模型。Mousavianet等人[308]。 联合进行了人员识别和识别,而Van Ranstet等人[309]通过深度估计解决了图像分割问题。 但是,需要更多的探索和调查来克服这一挑战。 例如,一个值得做的工作就是回答这个问题:我们是否可以同时学习社交网络中新用户的表示以及他们与现有用户的潜在链接?

五 结论

在过去的十年中,多输出学习引起了极大的关注。 本文对使用四个Vs作为框架的多输出学习的研究进行了全面回顾。 我们从输出标签的生命周期开始探索多输出学习范式的特征。 我们强调与学习过程的每个步骤相关的问题。 此外,我们提供了输出类型,结构,选定问题的定义,通用模型评估指标以及实验中使用的流行数据存储库的概述,并在全文中引用了代表性的著作。 本文最后讨论了四个V所带来的挑战以及一些值得进一步研究的未来研究方向

线性模型识别手写数字

mnist-3.0.1

MNIST 数据集 (Mixed National Institute of Standards and Technology database) 是美国国家标准与技术研究院收集整理的大型手写数字数据库,包含60,000个示例的训练集以及10,000个示例的测试集。

获取数据

http://yann.lecun.com/exdb/mnist/

    memory = joblib.Memory('./view')
    fetch_openml_cached = memory.cache(fetch_openml)
    mnist_dataset = fetch_openml_cached('mnist_784', as_frame=True)
    mnist_dataset = pd.DataFrame(data=np.c_[mnist_dataset['data'], mnist_dataset['target']],
                                 columns=mnist_dataset['feature_names'] + ['target'])
    return mnist_dataset

打包为函数 load_mnist

查看分析

pd.info()

pd.describe()项的含义和相应的单个方法

  • count:元素数
  • unique:具有唯一(唯一)值的元素数
  • top: 最频繁值(mode)
  • freq:频率(出现次数)
  • mean: 算术平均值
  • std: 标准差
  • min:最小值
  • max: 最大值
  • 50%: 中位数(median)
  • 25%, : 1/4 分位数, 3/4 分位数75%
    print(mnist_dataset)
    mnist_dataset.info()

    print(mnist_dataset.columns)
    print(mnist_dataset.describe())

数据预处理

自己定义查看 numpy 数据

def view_data(X, line_num=10):
    print("\nview_data\nshape:{0}, dim: {1}, dtype: {2}".format(X.shape, X.ndim, X.dtype))
    print(X[:line_num])

包装函数

    X, y = mnist_matrix[:, 0:-1], mnist_matrix[:, -1]
    view_data(X, 1)
    view_data(y)

转换为合适的数据结构

    mnist_matrix = np.array(mnist_matrix, dtype=float)

查看数据、可视化

    digit = np.array(X[20], dtype=int)
    digit = digit.reshape(28, 28)
    plt.imshow(digit, cmap="binary")
    plt.show()

    plt.hist(y)
    plt.hist(y[:60000])
    plt.show()

归一化

    X = mnist_matrix[:, 0:-1] / 255
    y = np.array(mnist_matrix[:, -1], dtype=int)
    view_data(X, 1)
    view_data(y)

划分数据集

    train_threshold = 60000
    N = y.shape[0]
    X = np.hstack((np.ones((N, 1)), X))

    X_training = X[:train_threshold, :]
    y_training = y[:train_threshold]

    X_test = X[train_threshold:, :]
    y_test = y[train_threshold:]

训练

获取维度、进一步处理训练集、初始化模型、误差函数

批量损失函数是这样的:

\mathrm{Lost}\left(h_{\theta}(x), y\right)=\left\{\begin{array}{ll}
-\log \left(h_{\theta}(x)\right) & y=1 \\
-\log \left(1-h_{\theta}(x)\right) & y=0
\end{array}\right.

合并为这个式子:

\mathrm{Lost}\left(h_{\theta}(x), y\right)=-y \log \left(h_{\theta}(x)\right)-(1-y) \log \left(1-h_{\theta}(x)\right)

模型

def sigmoid(x):
    return 1.0 / (1.0 + np.exp(-x))

def hypothesis(W, X):
    return sigmoid(X @ W)

def logistic_regression(X, y, aim_digit):
    N, dim = X.shape[0], X.shape[1]
    W = np.zeros(dim, dtype=np.float32)

    tmp = aim_digit * np.ones(N, dtype=np.int32)
    y_new = np.array((y == tmp), dtype=np.int32)
    # view_data(y)

    error_func(W, X, y_new)
    result = optimize.minimize(fun=error_func, x0=W, args=(X, y), jac=gradient,  method='Newton-CG')
    return result.x

测试、评价模型

试一下

    count = 5
    X_sample = X_test[:count, :]
    for i in range(count):
        digit = np.array(X_sample[i, 1:] * 255, dtype=int)
        digit = digit.reshape(28, 28)
        plt.imshow(digit, cmap="binary")
        plt.show()
    y_hat = predict(W, X_sample)
    print(y_hat == 1)

评价指标

准确率(accuracy)计算公式为:

A C C=\frac{T P+T N}{T P+T N+F P+F N}

精确率是针对我们预测结果而言的,它表示的是预测为正的样本中有多少是真正的正样本。你认为的正样本,有多少猜对了(猜的精确性如何)。那么预测为正就有两种可能了,一种就是把正类预测为正类(TP),另一种就是把负类预测为正类(FP),也就是

P=\frac{TP}{TP+FP}

召回率表示的是样本中的正例有多少被预测正确了。或者说正样本有多少被找出来了(召回了多少)。那也有两种可能,一种是把原来的正类预测成正类(TP),另一种就是把原来的正类预测为负类(FN)。

R=\frac{TP}{TP+FN}

在信息检索领域,精确率和召回率又被称为查准率和查全率,

查准率=检索出的相关信息量 / 检索出的信息总量 \\
查全率=检索出的相关信息量 / 系统中的相关信息总量

F-Measure 是 Precision 和 Recall 加权调和平均。F1 度量为

F = \frac{2\times P\times R}{P+R}
def get_accuracy(W, X_test, y_test, aim_digit):
    N = y_test.shape[0]
    y_test = y_test == aim_digit
    y_hat = hypothesis(W, X_test) > 0.5
    view_data(y_test)
    view_data(y_hat)

    tmp = np.array(y_test == y_hat, dtype=np.int32)
    view_data(tmp)
    return np.mean(tmp) * 100

建立多分类器

利用 sigmoid 函数输出各个不同类型数字的概率,取最高概率,就得到了一个预测数字。有兴趣可以实现一下。

scikit-learn

from sklearn.linear_model import LogisticRegression
logisticRegr = LogisticRegression(solver="newton-cg")
logisticRegr.fit(X_training, y_training)
y_hat = logisticRegr.predict(X_test)
score = logisticRegr.score(X_test, y_test)
print(score)