🤗 Huggingface Transformers

Huggingface Transformers 是基于一个开源基于 transformer 模型结构提供的预训练语言库,它支持 Pytorch,Tensorflow2.0,并且支持两个框架的相互转换。框架支持了最新的各种NLP预训练语言模型,使用者可以很快速的进行模型的调用,并且支持模型further pretraining 和 下游任务fine-tuning。 

该库是使用 BERT 等预训练模型的最常用的库,甚至超过了google等开源的源代码。它的设计原则保证了它支持各种不同的预训练模型,并且有统一的合理的规范。使用者可以很方便的进行模型的下载,以及使用。同时,它支持用户自己上传自己的预训练模型到Model Hub中,提供其他用户使用。对于NLP从业者,可以使用这个库,很方便地进行自然语言理解(NLU) 和 自然语言生成(NLG)任务的SOTA模型使用。

特色:

  • 超级 简单快速上手
  • 适合于所有人 – NLP研究员,NLP应用人员,教育工作者
  • NLU/NLG SOTA 模型支持
  • 减少预训练成本,提供了30+预训练模型,100+语言 – 支持Pytorch 与 Tensorflow2.0 转换。
  • 以下为部分整合的预训练语言模型, ref: Transformers Github

🤗 Transformers 提供了数以千计的预训练模型,支持 100 多种语言的文本分类、信息抽取、问答、摘要、翻译、文本生成。它的宗旨让最先进的 NLP 技术人人易用。

🤗 Transformers 提供了便于快速下载和使用的API,让你可以把预训练模型用在给定文本、在你的数据集上微调然后通过 model hub 与社区共享。同时,每个定义的 Python 模块均完全独立,方便修改和快速研究实验。

🤗 Transformers 支持三个最热门的深度学习库: JaxPyTorch and TensorFlow — 并与之无缝整合。你可以直接使用一个框架训练你的模型然后用另一个加载和推理。

在线演示

你可以直接在模型页面上测试大多数 model hub 上的模型。 我们也提供了 私有模型托管、模型版本管理以及推理API

这里是一些例子:

快速上手

我们为快速使用模型提供了 pipeline (流水线)API。流水线聚合了预训练模型和对应的文本预处理。下面是一个快速使用流水线去判断正负面情绪的例子:

>>> from transformers import pipeline

# 使用情绪分析流水线
>>> classifier = pipeline('sentiment-analysis')
>>> classifier('We are very happy to introduce pipeline to the transformers repository.')
[{'label': 'POSITIVE', 'score': 0.9996980428695679}]

第二行代码下载并缓存了流水线使用的预训练模型,而第三行代码则在给定的文本上进行了评估。这里的答案“正面” (positive) 具有 99 的置信度。

许多的 NLP 任务都有开箱即用的预训练流水线。比如说,我们可以轻松的从给定文本中抽取问题答案:

>>> from transformers import pipeline

# 使用问答流水线
>>> question_answerer = pipeline('question-answering')
>>> question_answerer({
...     'question': 'What is the name of the repository ?',
...     'context': 'Pipeline has been included in the huggingface/transformers repository'
... })
{'score': 0.30970096588134766, 'start': 34, 'end': 58, 'answer': 'huggingface/transformers'}

除了给出答案,预训练模型还给出了对应的置信度分数、答案在词符化 (tokenized) 后的文本中开始和结束的位置。你可以从这个教程了解更多流水线API支持的任务。

要在你的任务上下载和使用任意预训练模型也很简单,只需三行代码。这里是 PyTorch 版的示例:

>>> from transformers import AutoTokenizer, AutoModel

>>> tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
>>> model = AutoModel.from_pretrained("bert-base-uncased")

>>> inputs = tokenizer("Hello world!", return_tensors="pt")
>>> outputs = model(**inputs)

这里是等效的 TensorFlow 代码:

>>> from transformers import AutoTokenizer, TFAutoModel

>>> tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
>>> model = TFAutoModel.from_pretrained("bert-base-uncased")

>>> inputs = tokenizer("Hello world!", return_tensors="tf")
>>> outputs = model(**inputs)

词符化器 (tokenizer) 为所有的预训练模型提供了预处理,并可以直接对单个字符串进行调用(比如上面的例子)或对列表 (list) 调用。它会输出一个你可以在下游代码里使用或直接通过 ** 解包表达式传给模型的词典 (dict)。

模型本身是一个常规的 Pytorch nn.Module 或 TensorFlow tf.keras.Model(取决于你的后端),可以常规方式使用。 这个教程解释了如何将这样的模型整合到经典的 PyTorch 或 TensorFlow 训练循环中,或是如何使用我们的 Trainer 训练器)API 来在一个新的数据集上快速微调。

为什么要用 transformers?

  1. 便于使用的先进模型:
    • NLU 和 NLG 上表现优越
    • 对教学和实践友好且低门槛
    • 高级抽象,只需了解三个类
    • 对所有模型统一的API
  2. 更低计算开销,更少的碳排放:
    • 研究人员可以分享亿训练的模型而非次次从头开始训练
    • 工程师可以减少计算用时和生产环境开销
    • 数十种模型架构、两千多个预训练模型、100多种语言支持
  3. 对于模型生命周期的每一个部分都面面俱到:
    • 训练先进的模型,只需 3 行代码
    • 模型在不同深度学习框架间任意转移,随你心意
    • 为训练、评估和生产选择最适合的框架,衔接无缝
  4. 为你的需求轻松定制专属模型和用例:
    • 我们为每种模型架构提供了多个用例来复现原论文结果
    • 模型内部结构保持透明一致
    • 模型文件可单独使用,方便魔改和快速实验

什么情况下我不该用 transformers?

  • 本库并不是模块化的神经网络工具箱。模型文件中的代码特意呈若璞玉,未经额外抽象封装,以便研究人员快速迭代魔改而不致溺于抽象和文件跳转之中。
  • Trainer API 并非兼容任何模型,只为本库之模型优化。若是在寻找适用于通用机器学习的训练循环实现,请另觅他库。
  • 尽管我们已尽力而为,examples 目录中的脚本也仅为用例而已。对于你的特定问题,它们并不一定开箱即用,可能需要改几行代码以适之。

了解更多

章节描述
文档完整的 API 文档和教程
任务总结🤗 Transformers 支持的任务
预处理教程使用 Tokenizer 来为模型准备数据
训练和微调在 PyTorch/TensorFlow 的训练循环或 Trainer API 中使用 🤗 Transformers 提供的模型
快速上手:微调和用例脚本为各种任务提供的用例脚本
模型分享和上传和社区上传和分享你微调的模型
迁移从 pytorch-transformers 或 pytorch-pretrained-bert 迁移到 🤗 Transformers

Transformers model hub

Transformers model hub 提供了不同的预训练语言模型,包含了常见的Robert/BERT/XLNET/以及BART 等,几乎所有的最新模型都可以在上面找到。用户可以很方便地对模型进行调用,只需要一个模型的名字,就可以获取模型文件。

model = AutoModel.from_pretrained(model_name)

设计原则 Design Principles

Transformers 的设计是为了:

  • 研究者可以进行拓展
  • 单个modeling的文件,直接在一个文件中就可以修改模型所需要的所有部分,最小化的模块设计。
  • 算法工程师可以轻松使用 – 可以使用 pipeline 直接调用,获取开箱即用的任务体验,例如情感分析的任务等。可以使用trainers 进行训练,支持fp16,分布式等
  • 工业实践中可以快速部署且鲁棒性良好
  • CPU/GPU/TPU支持,可以进行优化,支持torchscript 静态图,支持ONNX格式

库设计 Library Design

transformers 库包含了机器学习相关的主要三个部分:数据处理process data, 模型应用 apply a model, 和做出预测make predictions。分别对应的如下三个模块:Tokenizer,Transformers,以及 Head。

  • Tokenizers 分词器,支持不同的分词。主要作用是将输入进行分词化后,并转化为相应模型需要的embedding。

Tokenizer 类支持从预训练模型中进行加载或者直接手动配置。这些类存储了 token 到 id 的字典,并且可以对输入进行分词,和decode。huggingface transformers 已经提供了如下图的相关tokenizer 分词器。用户也可以很轻松的对tokenizer 里的特殊字符进行更换,例如CLS/SEP。或者是对Tokenizer模型的字典进行大小修改等。

Tokenizer 提供了很多有用的方法,例如padding,truncating,用户可以很方便的对其进行使用。

Transformer transformers 指的是各种基于transformer结构的预训练语言模型,例如BERT,GPT等。它将输入的sparse的序列,转化为上下文感知的的 contextual embedding。

encoder 模型的计算图通常就是对模型输入进行一系列的 self-attention 操作,然后得到最后的encoder的输出。通常情况下,每个模型都是在一个文件中被定义完成的,这样方便用户进行更改和拓展。

针对不同的模型结构,都采用相同的API,这使得用户可以快速地使用不同的其他模型。transformers 提供 一系列的Auto classes,使得快速进行模型切换非常方便。

model = AutoModel.from_pretrained(model_name)
  • Head 不同于attention的head,这边的 head 指的是下游任务的输出层,它将模型的contextual embedding 转化为特定任务的预测值,包含如下的不同的head:
    • Pretraining Head
      • Casual Language Modeling(普通自回归的语言模型):GPT, GPT-2,CTRL
      • Masked Language Modeling(掩码语言模型):BERT, RoBERTa
      • Permuted Language Modeling(乱序重排语言模型):XLNet
    • Fine-tuning Head
      • Language Modeling:语言模型训练,预测下一个词。主要用于文本生成
      • Sequence Classification:文本分类任务,情感分析任务
      • Question Answering:机器阅读理解任务,QA
      • Token Classification:token级别的分类,主要用于命名实体识别(NER)任务,句法解析Tagging任务
      • Multiple Choice:多选任务,主要是文本选择任务
      • Masked LM:掩码预测,随机mask一个token,预测该 token 是什么词,用于预训练
      • Conditional Generation:条件生成任务,主要用于翻译以及摘要任务。

这些模型的head,是在模型文件集中上,包装的另外一个类,它提供了额外的输出层,loss函数等。 这些层的命名规范也很一致,采用的是: XXXForSequenceClassification

其中 XXX 是模型的下游任务(fine-tuning) 或者与训练 pretraining 任务。一些head,例如条件生成(conditional generation),支持额外的功能,像是sampling and beam search。

下图解释了每个head 的输入和输出以及数据集。

下面的代码展示了如何使用 transformers 进行下游的文本分类任务:

from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)

Huggingface Transformer 使用方法(教程)

Transformers提供了数以千计针对于各种任务的预训练模型模型,开发者可以根据自身的需要,选择模型进行训练或微调,也可阅读api文档和源码, 快速开发新模型。

0、Setup

1)安装一个非常轻量级的 Transformers

!pip install transformers

然后

import transformers

2)建议安装开发版本,几乎带有所有用例需要的依赖项

!pip install transformers[sentencepiece]

一、模型简介 Transformer models

1. pipelines 简单的小例子

Transformers 库中最基本的对象是pipeline()函数。它将模型与其必要的预处理和后处理步骤连接起来,使我们能够直接输入任何文本并获得答案

当第一次运行的时候,它会下载预训练模型和分词器(tokenizer)并且缓存下来。

from transformers import pipeline

classifier = pipeline("sentiment-analysis")  # 情感分析
classifier("I've been waiting for a HuggingFace course my whole life.")

# 输出
# [{'label': 'POSITIVE', 'score': 0.9598047137260437}]

也可以传几句话:

classifier(
    ["I've been waiting for a HuggingFace course my whole life.", "I hate this so much!"]
)

# 输出
'''
[{'label': 'POSITIVE', 'score': 0.9598047137260437},
 {'label': 'NEGATIVE', 'score': 0.9994558095932007}]
'''

目前可用的一些pipeline 有:

feature-extraction 特征提取:把一段文字用一个向量来表示
fill-mask 填词:把一段文字的某些部分mask住,然后让模型填空
ner 命名实体识别:识别文字中出现的人名地名的命名实体
question-answering 问答:给定一段文本以及针对它的一个问题,从文本中抽取答案
sentiment-analysis 情感分析:一段文本是正面还是负面的情感倾向
summarization 摘要:根据一段长文本中生成简短的摘要
text-generation文本生成:给定一段文本,让模型补充后面的内容
translation 翻译:把一种语言的文字翻译成另一种语言
zero-shot-classification

这些pipeline的具体例子可见:Transformer models – Hugging Face Course

2. 各种任务的代表模型

二、 使用 Using Transformers

1. Pipeline 背后的流程

Pipeline 背后的流程

在接收文本后,通常有三步:Tokenizer、Model、Post-Processing。

1)Tokenizer

与其他神经网络一样,Transformer 模型不能直接处理原始文本,故使用分词器进行预处理。使用AutoTokenizer类及其from_pretrained()方法。

from transformers import AutoTokenizer

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

若要指定我们想要返回的张量类型(PyTorch、TensorFlow 或普通 NumPy),我们使用return_tensors参数

raw_inputs = [
    "I've been waiting for a HuggingFace course my whole life.",
    "I hate this so much!",
]
inputs = tokenizer(raw_inputs, padding=True, truncation=True, return_tensors="pt")
print(inputs)

PyTorch 张量的结果:

输出本身是一个包含两个键的字典,input_idsattention_mask

{
    'input_ids': tensor([
        [  101,  1045,  1005,  2310,  2042,  3403,  2005,  1037, 17662, 12172, 2607,  2026,  2878,  2166,  1012,   102],
        [  101,  1045,  5223,  2023,  2061,  2172,   999,   102,     0,     0,     0,     0,     0,     0,     0,     0]
    ]), 
    'attention_mask': tensor([
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    ])
}

2)Model

Transformers 提供了一个AutoModel类,它也有一个from_pretrained()方法:

from transformers import AutoModel

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
model = AutoModel.from_pretrained(checkpoint)

如果我们将预处理过的输入提供给我们的模型,我们可以看到:

outputs = model(**inputs)
print(outputs.last_hidden_state.shape)

# 输出 
# torch.Size([2, 16, 768])
preview

Transformers 中有许多不同的架构可用,每一种架构都围绕着处理特定任务而设计,清单:

*Model (retrieve the hidden states)
*ForCausalLM
*ForMaskedLM
*ForMultipleChoice
*ForQuestionAnswering
*ForSequenceClassification
*ForTokenClassification
and others

3)Post-Processing

模型最后一层输出的原始非标准化分数。要转换为概率,它们需要经过一个SoftMax层(所有 Transformers 模型都输出 logits,因为用于训练的损耗函数一般会将最后的激活函数(如SoftMax)与实际损耗函数(如交叉熵)融合 。

import torch

predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
print(predictions)

2. Models

1)创建Transformer

from transformers import BertConfig, BertModel

# Building the config
config = BertConfig()

# Building the model from the config
model = BertModel(config)

2)不同的加载方式

from transformers import BertModel

model = BertModel.from_pretrained("bert-base-cased")

3)保存模型

model.save_pretrained("directory_on_my_computer")

4)使用Transformer model

sequences = ["Hello!", "Cool.", "Nice!"]
encoded_sequences = [
    [101, 7592, 999, 102],
    [101, 4658, 1012, 102],
    [101, 3835, 999, 102],
]

import torch

model_inputs = torch.tensor(encoded_sequences)

3. Tokenizers

1)Loading and saving

from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
tokenizer("Using a Transformer network is simple")

# 输出
'''
{'input_ids': [101, 7993, 170, 11303, 1200, 2443, 1110, 3014, 102],
 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0],
 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}
'''

# 保存
tokenizer.save_pretrained("directory_on_my_computer")

2)Tokenization

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")

sequence = "Using a Transformer network is simple"
tokens = tokenizer.tokenize(sequence)

print(tokens) # 输出 : ['Using', 'a', 'transform', '##er', 'network', 'is', 'simple']

#  从token 到输入 ID
ids = tokenizer.convert_tokens_to_ids(tokens)
print(ids) # 输出:[7993, 170, 11303, 1200, 2443, 1110, 3014]

3) Decoding

decoded_string = tokenizer.decode([7993, 170, 11303, 1200, 2443, 1110, 3014])
print(decoded_string) # 输出:'Using a Transformer network is simple'

4. 处理多个序列 Handling multiple sequences

1) 模型需要一批输入 Models expect a batch of inputs

将数字列表转换为张量并将其发送到模型:

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)

sequence = "I've been waiting for a HuggingFace course my whole life."

tokens = tokenizer.tokenize(sequence)
ids = tokenizer.convert_tokens_to_ids(tokens)

input_ids = torch.tensor([ids])
print("Input IDs:", input_ids)

output = model(input_ids)
print("Logits:", output.logits)

# 输出
'''
Input IDs: [[ 1045,  1005,  2310,  2042,  3403,  2005,  1037, 17662, 12172,  2607, 2026,  2878,  2166,  1012]]
Logits: [[-2.7276,  2.8789]]
'''

2) 填充输入 Padding the inputs

model = AutoModelForSequenceClassification.from_pretrained(checkpoint)

sequence1_ids = [[200, 200, 200]]
sequence2_ids = [[200, 200]]
batched_ids = [
    [200, 200, 200],
    [200, 200, tokenizer.pad_token_id],
]

print(model(torch.tensor(sequence1_ids)).logits)
print(model(torch.tensor(sequence2_ids)).logits)
print(model(torch.tensor(batched_ids)).logits)

# 输出
'''
tensor([[ 1.5694, -1.3895]], grad_fn=<AddmmBackward>)
tensor([[ 0.5803, -0.4125]], grad_fn=<AddmmBackward>)
tensor([[ 1.5694, -1.3895],
        [ 1.3373, -1.2163]], grad_fn=<AddmmBackward>)
'''

5. 总结 Putting it all together

我们已经探索了分词器的工作原理,并研究了分词 tokenizers、转换为输入 ID conversion to input IDs、填充 padding、截断 truncation和注意力掩码 attention masks。Transformers API 可以通过高级函数为我们处理所有这些。

from transformers import AutoTokenizer

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

sequence = "I've been waiting for a HuggingFace course my whole life."

model_inputs = tokenizer(sequence)
# 可以标记单个序列
sequence = "I've been waiting for a HuggingFace course my whole life."
model_inputs = tokenizer(sequence)

# 还可以一次处理多个序列
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]
model_inputs = tokenizer(sequences)
# 可以根据几个目标进行填充
# Will pad the sequences up to the maximum sequence length
model_inputs = tokenizer(sequences, padding="longest")

# Will pad the sequences up to the model max length
# (512 for BERT or DistilBERT)
model_inputs = tokenizer(sequences, padding="max_length")

# Will pad the sequences up to the specified max length
model_inputs = tokenizer(sequences, padding="max_length", max_length=8)
# 还可以截断序列
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

# Will truncate the sequences that are longer than the model max length
# (512 for BERT or DistilBERT)
model_inputs = tokenizer(sequences, truncation=True)

# Will truncate the sequences that are longer than the specified max length
model_inputs = tokenizer(sequences, max_length=8, truncation=True)
# 可以处理到特定框架张量的转换,然后可以将其直接发送到模型。
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

# Returns PyTorch tensors
model_inputs = tokenizer(sequences, padding=True, return_tensors="pt")

# Returns TensorFlow tensors
model_inputs = tokenizer(sequences, padding=True, return_tensors="tf")

# Returns NumPy arrays
model_inputs = tokenizer(sequences, padding=True, return_tensors="np")

Special tokens

分词器在开头添加特殊词[CLS],在结尾添加特殊词[SEP]。

sequence = "I've been waiting for a HuggingFace course my whole life."

model_inputs = tokenizer(sequence)
print(model_inputs["input_ids"])

tokens = tokenizer.tokenize(sequence)
ids = tokenizer.convert_tokens_to_ids(tokens)
print(ids)

# 输出
'''
[101, 1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012, 102]
[1045, 1005, 2310, 2042, 3403, 2005, 1037, 17662, 12172, 2607, 2026, 2878, 2166, 1012]
'''

print(tokenizer.decode(model_inputs["input_ids"]))
print(tokenizer.decode(ids))

# 输出
'''
"[CLS] i've been waiting for a huggingface course my whole life. [SEP]"
"i've been waiting for a huggingface course my whole life."
'''
# 总结:从分词器到模型
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForSequenceClassification.from_pretrained(checkpoint)
sequences = ["I've been waiting for a HuggingFace course my whole life.", "So have I!"]

tokens = tokenizer(sequences, padding=True, truncation=True, return_tensors="pt")
output = model(**tokens)

Huggingface Transformers库学习笔记(二):使用Transformers(上)(Using Transformers Part 1): https://blog.csdn.net/u011426236/article/details/115460564

SwinIR:图像恢复

cvpr2021: https://arxiv.org/abs/2108.10257

代码:https://github.com/JingyunLiang/SwinIR

本文提出了一个基于Swin Transformer的用于图像恢复的强基线模型SwinIR,在图像超分辨率、去噪等任务上表现SOTA!

图像恢复是一个长期存在的低级视觉问题,旨在从低质量图像(例如,缩小、噪声和压缩图像)中恢复高质量图像.虽然最先进的图像恢复方法基于卷积神经网络,但很少有人尝试使用 Transformer,它们在high-level视觉任务中表现出令人印象深刻的性能。

在本文中,我们提出了一种基于 Swin Transformer 的强大基线模型 SwinIR 用于图像恢复。SwinIR由浅层特征提取、深层特征提取和高质量图像重建三部分组成。特别是,深度特征提取模块由几个残差 Swin Transformer 块 (RSTB) 组成,每个残差块都有几个 Swin Transformer 层和一个残差连接。我们对三个具有代表性的任务进行了实验:图像超分辨率(包括经典、轻量级和真实世界的图像超分辨率)、图像去噪(包括灰度和彩色图像去噪)和 JPEG 压缩伪影减少。实验结果表明,SwinIR 在不同任务上的表现优于最先进的方法高达 0.14 ∼ 0.45dB, 而参数的总数可以减少高达 67%.

网络结构:(感觉其实没啥创新点,就是用了swin block + 残差结构,但效果却挺好)

Shallow and deep feature extraction:3 ×3 convolutional layer

HQ Image Reconstruction:sub-pixel convolution layer or single
convolution layer

消融Ablation Study

实验结果

实验结果表明,SwinIR 在不同任务上的性能优于最先进的方法高达 0.14∼0.45dB,而参数总数最多可减少 67%。

作者多了很多实验:

SR:Classical image SR Lightweight image SR 和Real-world image SR


JPEG compression artifact reduction

Image Denoising

结果:

最新综述丨视频超分辨率研究方法

摘自:极市平台,作者@ Wangsy

https://zhuanlan.zhihu.com/p/342225916

本文是第一个也是唯一一个视频超分方向的综述,回顾了基于深度学习的视频超分技术的研究进展,提出了一种基于深度学习的视频超分分类方法,并总结了SOTA方法在一些公共基准数据集上的性能。

论文地址:https://arxiv.org/abs/2007.12928

看点

近年来,深度学习在很多领域取得了进展,其中包括视频超分辨率任务。本文是第一个也是唯一一个视频超分方向的综述,主要看点如下:

1)回顾了基于深度学习的视频超分技术的研究进展;
2)提出了一种基于深度学习的视频超分分类方法,利用不同处理帧间信息的方式进行分类;
3)总结了SOTA方法在一些公共基准数据集上的性能;
4)分析了视频超分任务的一些前景和挑战;

分类

多篇研究表明,帧间信息的利用对视频超分的性能有很大影响。正确、充分地利用这些信息可以提高超分的最终结果。因此,根据帧间信息的利用方式——是否对齐,将现有方法分为两大类:对齐方法和非对齐方法,如下图所示:

总结

到目前为止,已经有了许多的视频超分算法。下图总结了近年来基于深度学习的视频超分方法的特点。其中MEMC表示运动估计和补偿方法,DC表示可变形卷积方法,3D Conv表示3D卷积方法,RCNN表示循环卷积神经网络方法。

趋势和挑战

尽管基于深度学习的视频超分方法已经取得了很大的进展,但是仍然存在一些挑战。

轻量级超分模型

基于深度学习的视频超分辨率方法虽然具有很高的性能,但由于模型参数庞大,需要大量的计算和存储资源,训练时间长,在实际问题中难以有效部署。随着移动设备在现代生活中的流行,人们期望将模型应用到这些设备上。如何设计和实现一种高性能、轻量级的超分算法,以满足实际应用的需要是一个挑战。

模型的可解释性

深度神经网络通常被认为是黑箱。也就是说,不管模型表现如何,我们也无法知道模型学到了什么真正的信息。在现有的视频超分模型中,卷积神经网络如何恢复低分辨率视频序列还没有一个理论解释。随着对其解释的深入研究,包括视频和图像超分方法在内的超分算法的性能可能会有很大的提高。

大尺度超分辨率

对于视频超分任务,现有的工作主要集中在放大倍数为4的情况下。更具挑战性的尺度(如×8、×16)很少被探索。随着高分辨率(如4K、8K)显示设备的普及,大尺度的超分有待进一步研究。显然,随着尺度的增大,视频序列中未知信息的预测和恢复会变得越来越困难。这可能导致算法的性能下降,削弱模型的鲁棒性。因此,如何开发稳定的深度学习算法来实现更大规模的视频超分辨率仍然是一个重要的问题。

更合理、更恰当的视频降质过程

在现有的研究中,LR视频的退化通常由两种方法得到。一种是使用插值(如双三次插值)直接对HR视频进行下采样。另一种是对HR视频进行高斯模糊,然后对视频序列进行降采样。虽然这两种方法在理论上都有很好的表现,但在实践中却总是表现不佳。真实世界的退化过程是非常复杂的,并且在真实世界的问题中包含了大量的不确定性,模糊和插值对问题的建模是不够的。因此,在构建LR视频时,应该从理论上建立与实际情况相一致的退化模型,以缩小研究与实践之间的差距。 大多数最先进的视频超分辨率方法都是有监督学习。由于降质过程是复杂的和HR/LR对获取是比较难获取的。或许无监督的超分方法可能会称为解决这个问题的一个方法。

更有效的场景变换算法

现有的视频超分方法很少涉及场景变化的视频。实际上,一个视频序列通常有许多不同的场景。在研究这类视频的超分问题时,必须在不改变场景的情况下将其分割成多个片段,并分别进行处理。这可能会导致大量的计算和计算时长。因此,能够处理场景变化的深度学习方法对于实际应用是必要的。

更合理的视频质量评价标准

评价超分辨率结果质量的标准主要有PSNR和SSIM。然而,它们的值并不能反映视频质量对人的感知。也就是说,即使视频的PSNR值很高,视频对人类来说也不一定是舒服的。因此,需要开发出符合人类感知的新的视频评价标准。虽然提出了一些评价标准,但仍需要更多能被广泛接受的标准。

利用帧间信息的更有效方法

视频超分的一个重要特征是利用帧间信息。它的有效利用直接影响着模型的性能。尽管本文提出了许多方法,但仍存在一些不足。例如,三维卷积和非局部模运算量大,光流估计的精度无法保证等。因此,有效利用帧间信息的方法值得进一步研究。

BasicVSR|视频超分算法

视频超分====”钞“能力,没几张显卡真玩不了。

paper: https://arxiv.org/abs/2012.0218

该文是南洋理工&腾讯PCG、CUHK-SenseTime联合实验室、中科院深圳先进技术研究院2020年提出的一种视频超分方案BasicVSR。在多个数据集上、在两种退化方式上,所提BasicVSR与IconVSR均超越已有视频超分方案,特别的,在UDM10数据集上取得了高达0.68dB的性能提升。

Video Super-Resolution on MSU Video Super Resolution Benchmark:

截至2022,该方法仍是sota方法。

正如作者所说,BasicVSR及其扩展IconVSR可以作为未来VSR方法的强大基线!!!

Abstract

​ 由于需要利用额外的时序信息,视频超分往往比图像超分包含更多的模块,这就导致了各式各样的复杂结构。

​ 该文作者对视频超分进行了梳理并重新审查了视频超分的四个基本模块:PropagationAlignmentAggregation以及Upsampling。通过复用现有方案的模块并添加微小改动,作者提出了一种简单方案:BasicVSR,它在推理速度、复原质量方面取得了引人注目的提升。

​ 作者对BasicVSR进行了系统的分析,解释了性能提升的原因所在,同时也讨论了其局限性。在BasicVSR的基础上,作者进一步提出了“信息寄存(information-refile)”与“耦合传播(coupled propagation)”两种机制促进信息集成。所提BasicVSR及其改进IconVSR将视频超分的性能进行了更进一步的提升,可以作为视频超分领域的一个更强的基准。

Introduction

​ 作者对现有各式各样的VSR方案按照各个模块的功能(propagation, alignment, aggregation, upsampling)进行了拆分,相关总结见下表。

  • Propagation:在这里特指信息的流动,比如局部信息,单向信息流动,双向信息流动;
  • Alignment:在这里特指对齐的类型以及有无;
  • Aggregation:在这里指的是对齐特征的集成方式;
  • Upsampling:在这里指的是上采样过程所采用的方案,基本都是Pixel-Shuffle。

​ 在上述四个功能单元中,Propagation和Alignment对性能和效率影响最大。双线传播有助于最大化的进行信息汇集,光流方案有助于进行相邻帧特征对齐。通过简单的上述模块组合所得的BasicVSR即取得了超越SOTA的指标与速度(指标提升0.61dB,推理速度快了24倍)。

什么是光流法?光流是一种用于描述图像运动的技术。它通常应用于它们之间具有小时间步长的一系列图像,例如视频帧。光流计算图像中点的速度,并估计点可能在下一个图像序列中的位置。

光流是由物体或照相机的运动引起的两个连续帧之间图像物体的视运动的模式。它是2D向量场,其中每个向量都是位移向量,表示点从第一帧到第二帧的运动。考虑下面的图片,它显示了一个球连续5帧运动。箭头显示其位移向量。光流在以下领域具有许多应用: – 运动的结构 – 视频压缩 – 视频稳定…光流基于以下几个假设进行工作: 1. 在连续的帧之间,对象的像素强度不变。 2. 相邻像素具有相似的运动。

光流

​ 在BasicVSR的基础上,作者提出了如下两种新颖的扩展得到了IconVSR。

  • 信息寄存,它采用了额外的模块提取从稀疏选择帧(比如关键帧)中提取特征,然后插入到主网络用于特征改善。
  • 耦合传播,它促进了前向与反向传播分支中的信息交换。

​ 这两个模块不仅可以降低误差累积问题,同时可以获取更完整的时序信息以生成更高质量的特征,进而得到更好的重建结果。得益于上述两种设计,IconVSR以0.31dB指标提升超过了BasicVSR。

Method

 上图给出了BasicVSR的架构示意图。在这里我们先对BasicVSR转给你所涉及到的几个功能性模块进行一些简单的介绍。

Propagation

Propagation 是VSR中最具影响力的模块,它特指信息的利用方式。现有的传播机制可以分为一下三大类:

  • Local Propagation: 滑动窗口的方法(比如RBPN,TGA,EDVR)采用局部窗口内的多帧LR图像作为输入并进行中间帧的重建。这种设计方式约束了信息范围,进而影响了模型的性能。下图给出了不同信息范围下的模型性能对比,可以看到:(1)全局信息的利用具有更佳性能;(2) 片段的两端性能差异非常大,说明了长序列累积信息(即全局信息)的重要性。

Unidirectional: 已有单向传播方案(比如RLSP、RSDN、RRN、FRVSR)采用了从第一帧到最后一帧的单向传播的方式,这种方式导致了不同帧接受的信息是不平衡的,比如第一帧只会从自身接受信息,而最后一帧则可以接受整个序列的信息。下图给出了单向传播与双向传播的性能差异对比。可以看到:(1)在早期,单向传播方案的PSNR指标严重低于双向传播方案;(2)整体来看,单向传播方案的指标要比双向传播的方案低0.5dB。

Bidirectional:上述两种信息传播方案的弊端可以通过双向传播方案解决。BasicVSR采用了经典的双向传播机制,给定输入图像及其近邻帧,相应的特征传播分别描述为和

Alignment

​ 空间对齐在VSR中起着非常重要的作用,它负责将高度相关的的图像/特征进行对齐并送入到后续的集成模块。主流VSR方案可以分别以下三大类:

  • Without Alignment: 现有的递归方案(比如RLSP、BRCN、RSDN、RRN)通常不进行对齐,非对齐的特征直接进行集成导致了次优的性能。作者在实验中发现:不添加对齐会导致1.19dB的指标下降,也就是说对齐是非常有必要
  • Image Alignment:早期的TOFlow采用光流在图像层面进行对齐,已有研究表明:相比图像层面对齐,特征层面的对齐可以取得显著的性能提升
  • Feature Alignment: 作者采用了类似TOFlow的光流方案,并用于特征对齐,对齐后的特征融入到后的残差模块中。这里采用的特征对齐可以描述如下:

Aggregation and Upsampling

​ BasicVSR采用了非常基本的模块(残差模块以及PixelShuffle)用于特征集成与上采样,假设中间特征表示,这里的特征集成与上采样模块描述如下:

​ 总而言之,BasicVSR采用了双向传播机制、特征层面的光流对齐、concate进行特征集成,pixelshuffle进行上采样。

IconVSR

​ 以BasicVSR作为骨干,作者引入了两种新颖的单元以消除传播过程中的误差累积促进时序信息集成。

  • Information-Refil: 不精确的对齐会导致误差累积问题,尤其是该文所采用的长期传播方案。为消除上述问题,作者提出了信息寄存机制,见下图。

​ 它采用了额外的特征提取器提取关键帧与近邻帧的特征,所提取的特征将于对齐特征通过卷积进行融合。

Coupled Propagation: 在双向传播中,特征经由相反的方向进行独立处理。作者对此添加了耦合传播机制,使得两者产生关联

Experiments

​ 训练数据:REDS和Vimeo90K;测试数据:REDS4、REDSval4、Vid4、UDM10、Vimeo90K-T。数据退化方式BI和BD。

​ SpyNet用于光流估计,EDVR-M用于特征提取,Adam优化器,Cosine学习率机制,特征提取与光流部分的学习率为,其他部分的学习率为。总计训练300K,特征提取与光流的权值在前5000次冻结。Batch=8,LR的大小为,Cb损失。

​ 下表给出了所提方案与其他视频超分方案在不同退化方式、不同测试集上的指标、推理速度以及参数量的对比。

​ 从上表可以看到:

  • BasicVSR以全面优势超过了现有视频超分方案,在UDM10数据集上,以0.61dB超过了RSDN且具有相当的参数量、更快的速度;
  • IconVSR可以进一步提升BasicVSR的指标高达0.31dB

Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network

论文标题:Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network

github: https://github.com/leftthomas/ESPCN

2016年的文章。在此之前使用CNN进行SR的方法都是将LR图像先用一个single filter(通常是bicubic)upscale至HR的尺寸,再进行reconstruction的。所有SR的操作都再HR空间进行。  而本文提出在LR空间进行特征提取。并引入sub-pixel convolution layer用于学习一组upscaling filter,用这些针对特征图训练得到的更复杂的filter代替手工bicubic filter。可以降低计算成本,实现实时SR。直接将LR图像输入一个l层的CNN中,之后通过一层sub-pixel卷积层upscaleLR特征图生成对应的HR图像。

这篇论文提出了一种亚像素卷积的方法来对图像进行超分辨率重建,速度特别快。虽然论文里面称提出的方法为亚像素卷积(sub-pixel convolution),但是实际上并不涉及到卷积运算,是一种高效、快速、无参的像素重排列的上采样方式。由于很快,直接用在视频超分中也可以做到实时。其在Tensorflow中的实现称为depthtospace ,在Pytorch中的实现为PixelShuffle

这种上采样的方式很多时候都成为了上采样的首选,经常用在图像重建领域,如后续有在降噪领域中的FFDNet

论文的主要创新点为:

1. 只在模型末端进行上采样,可以使得在低分辨率空间保留更多的纹理区域,在视频超分中也可以做到实时。
2.模块末端直接使用亚像素卷积的方式来进行上采样,相比于显示的将LR插值到HR,这种上采样方式可以学习到更好、更为复杂的方式,可以获得更好的重建效果。

可以看到,相比于其他的一些超分算法,这里实际上只改动了最后的上采样方式。在模型倒数第二层学习对应的通道数( r2c )的卷积,其中c为最终的通道数,如输出是RGB图,则c为3,如输出是灰度图或者Y通道的图,则c为1;r为需要进行的上采样倍数,为正整数倍,不同的上采样倍数只需要调整这一层卷积的通道数即可。

由于带计算的操作都是在低分辨率空间中进行的,所以速度相对会快很多。

这里给出的示例为r=3,c=1,即单通道图的3倍上采样图。结合超像素的思想来看,以第一张特征图进行的3×3宫格的像素重排列,行优先地按顺序将不同深度的特征依次重排列到宫格上。

这里给出的示例图是简单场景,像素重排列的方式为:

从公式可以看出,对于多通道的图,以通道数作为一个整体,即将特征图通道数中连续的c个通道作为一个整体,再然后进行像素重排列,得到多通道的上采样图。

论文的核心创新点就在于这里的像素重排列的方式。

整体的效果上来说,也是非常的惊人。从模型的角度上而言,其主干模型可以采样其他SOTA的主干结构。由于上采样的差异,可以学习到更好、更复杂的上采样方式,所以最终的重建效果是要稍好于SOTA的模型的。并且由于上采样特别高效,速度非常的快。从PSNR的角度来看,ESPCN比TNRD(TNRD发表于TPAMI2015,是DnCNN的前身)稍好,但是速度却相差一个数量级左右。

结论

这篇论文提出了一种亚像素卷积层,在低分辨率空间中可以学习到更好、更复杂的上采样方式,对于不同的重建倍数,只需要对应地更改低分辨率空间中的卷积通道数,非常灵活。其最终的重建PSNR效果也是SOTA,速度上具有很巨大的优势,视频超分也能做到实时。这种上采样方式也广泛地应用于其他的重建领域中。

mmediting 中文文档

MMEditing: 多任务图像视频编辑工具箱

这是一个图像和视频编辑的工具箱,它目前包含了常见的编辑任务,比如图像修复,图像抠图,超分辨率和生成模型。在编辑图像或者视频的时候,我们往往是需要组合使用以上任务的,因此将它们整理到一个统一的框架下,方便大家使用。

基于 PyTorch 的图像&视频编辑开源工具箱, 提供修复/抠图/超分辨率/生成等任务最先进的算法。

github: https://github.com/open-mmlab/mmediting

中文文档: https://mmediting.readthedocs.io/zh_CN/latest/

目前 MMEditing 支持下列任务:

主分支代码目前支持 PyTorch 1.5 以上的版本。

MMEditing 的优势:

1. 统一的框架:我们设计了先进的框架来统一最常见的图像修复,图像抠图,超分辨率和生成模型这几个任务。用户可以在一个框架中方便地调用不同的算法和模型。

2. 灵活的模块化设计:用户能够基于这套框架灵活地增加新的功能和算法。

3. 丰富的模型和文档:下图中展示了我们支持的算法数目,要知道其中有不少算法是首次有完整的复现哦~我们也完善了文档(文档覆盖率高达90%以上)和入门材料,方便用户上手。

4. 高效的实现:MMEditing所有的训练包括 GAN 的对抗训练都是基于高效的分布式训练框架部署的,对于一些基础的操作单元,我们也相应地进行了优化。

主要特性

  • 模块化设计MMEditing 将编辑框架分解为不同的组件,并且可以通过组合不同的模块轻松地构建自定义的编辑器模型。
  • 支持多种编辑任务MMEditing 支持修复抠图超分辨率生成等多种主流编辑任务。
  • SOTAMMEditing 提供修复/抠图/超分辨率/生成等任务最先进的算法。

需要注意的是 MMSR 已作为 MMEditing 的一部分并入本仓库。 MMEditing 缜密地设计新的框架并将其精心实现,希望能够为您带来更好的体验。

安装

MMEditing 依赖 PyTorch 和 MMCV,以下是安装的简要步骤。

步骤 1. 依照官方教程安装PyTorch

步骤 2. 使用 MIM 安装 MMCV

pip3 install openmim
mim install mmcv-full

步骤 3. 从源码安装 MMEditing

git clone https://github.com/open-mmlab/mmediting.git
cd mmediting
pip3 install -e .

模型库

支持的算法:图像修复

图像抠图

图像超分辨率

视频超分辨率

图像生成

视频插帧

请参考模型库了解详情。

Super-Resolution 超分辨率

超分辨率(简称超分),是将低分辨率图像放大到高分辨率图像,如下图,一只小狒狒经过 SR网络后,可以得到放大,变成一只“大”狒狒。

随着深度学习的兴起,早在2014年,香港中文大学多媒体实验室就提出了首个使用卷积神经网络解决超分辨率的模型——SRCNN。作为图像超分辨率工作,SRCNN 对后续计算机视觉的底层算法研究产生了重要影响。后续,各种各样的网络结构如雨后春笋般地冒了出来,比如VDSR,EDSR,SRResNet 等等; 还有追求视觉效果的 SRGAN, ESRGAN。

MMEditing把一些基本的超分算法,比如 SRCNN,EDSR,SResNet,SRGAN还有视频的 EDVR 算法都包括进去。之前 OpenMMLab 中的 MMSR 也有类似的功能,相比之下,MMEditing 使用了更好的框架设计,用上了 MMCV 和 MMDetection 在发展过程中的经验积淀。整个 MM 系列都采用了类似的框架,只要掌握了一种,就能够轻而易举地掌握其他任务的代码库。

Inpainting修复

Inpainting(图像修复)是图像编辑领域里面一项基础的任务,其主要目标是修复图像中的受损(污染)区域。如下图中,左边是原图,中间是受损区域示意图,你可以去除图像中的不想要的人物,或者是图像中杂乱的不规则的受损区域。然后经过 Inpainting 修复算法就得到最右边的图啦。

Inpainting 作为一项基础任务,现如今已经被广泛的应用到各种各样的场景,比如面部修复,背景填充以及视频编辑中。

之前传统的 Patch-Matching 算法可以通过图中已知区域的纹理来快速填补当前受损区域。随着深度学习的发展,越来越多的工作利用深度神经网络实现更好的图像修复效果。深度图像修复领域中,有许多经典的开创性的工作像 Global&Local、Partial Conv 以及 DeepFill 系列,他们作为深度图像修复的经典模型被广泛地应用到后来的研究工作当中。可是这些方法都没有官方的 PyTorch 实现,为了方便大家更好的研究和深入了解这些模型,我们在 MMEditing 中集成了这些算法的训练和测试功能。同时,我们对其中一些重要的模块进行了代码上的优化,以使其更加符合 PyTorch 的风格,甚至是更快的 GPU 计算,从而能够有更好的训练速度。

Matting抠像

抠像(Matting)问题是一个在计算机视觉研究领域有重要价值的研究课题,其在工业界也有非常重要的应用。

抠像是将前景从图片或者视频中与背景分离开来的问题,比如下图中,输入是左图,一位超级可爱的小姐姐在秀丽的风景前中,我们希望得到右边的小姐姐的抠像结果(b)。它和 segmentation分割的不同之处在于,matting 需要得到更精准的边缘(如头发)以及与背景的组合系数。

为了降低求解的难度,一种最常见的方式是引入用户输入的 trimap(如下图),来对图片进行简单的三分类。其中,图中的黑色为背景,白色为前景,灰色为未知区域。给定 trimap 后,我们只需要求解未知区域的抠图结果,这大大降低了求解的难度。

在 MMEditing 中,我们首次完整复现了 DIM(Deep Image Matting)在原论文中的性能。除此之外,MMEditing 还包含当前开源 Matting 模型中性能最好的 GCA Matting 模型,以及速度最快的 IndexNet Matting。

Generation生成模型

Generation,中文含义为“生成”。所谓生成,不同于其他图像编辑的任务,旨在创造新的图像。我们试图通过深度学习的方式,让神经网络成为创造者,产生新的信息。生成任务一般分为两种,非条件(unconditional)和条件(conditional)的生成。所谓非条件生成,主要是从潜在空间(latent space)中的噪声(noise)往图像域(image domain)进行转换,并试图近似相关边缘概率分布,产生逼真的图像;所谓条件生成,主要是从一个图像域映射到潜在空间,并进一步转换到另一个图像域。目前的MMEditing主要支持后者,即从一个图像域映射到另一个图像域,如分割的mask转换到真实图像、马转换到斑马等。后者的条件生成也更加符合目前图像编辑的主题。

而目前 MMEditing 支持的条件图像生成,又可以分为两种不同的设定。其中一种生成模型的训练数据中,包含成对的训练数据,被称为“成对图像到图像转换(paired image-to-image translation)”。这种设定一般生成任务的难度比较低,但对数据本身的要求比较高,生成效果一般比较良好。最经典的成对图像到图像转换的方法,名为 pix2pix。 它也是图像到图像转换领域开山鼻祖的文章,因此我们在这个版本中首先考虑对它进行实现,获得了与作者官方实现一致的结果。

另一种生成模型的训练数据中,仅包含非成对的训练数据,被称为“非成对图像到图像转换(unpaired image-to-image translation)”。这种设定一般对数据要求较低,很容易构建两个明确的图像域,但生成难度较大,生成效果会略微降低。提出非成对图像到图像转换问题,并首先给出解决方案(cycle-consistency)的方法,名为 CycleGAN。CycleGAN 作为最经典的非成对图像到图像转换的生成方法,我们在这个版本中同样首先考虑对它进行实现和效果对齐。

生成(Generation)任务通常比较困难,但向人们展示出了惊人的效果和广阔的研究前景。在未来 MMEditing 代码库的版本中,我们会考虑加入更多不同的生成设定,以及多种生成方法,让我们的代码库更加全面、丰富、强大。

AlphaFold2蛋白质结构预测

摘自 机器学习算法工程师

科学界已知的几乎所有蛋白质结构,都在这里了。蛋白质是生命的基础构件,它们由氨基酸链组成,折叠成不同的复杂形状。蛋白质的功能通常由其 3D 结构决定。如果我们了解蛋白质的折叠方式,就可以开始探索它们是如何工作的,并尝试改变它们的功能。尽管 DNA 提供了制造氨基酸链的指令,但预测它们如何相互作用以形成蛋白质的 3D 结构是一个巨大的挑战。
一年前,DeepMind 发布了 AlphaFold2,以原子水平的准确度预测了 2/3 的蛋白质结构,并与 EMBL-EBI 共同发布了开放可搜索的蛋白质结构数据库 AlphaFold DB,与世界共同分享这一技术。
7 月 28 日,DeepMind 宣布 AlphaFold DB 已从 100 万个结构扩展到超过 2 亿个结构,扩大超过 200 倍,这一进展将极大地提升人们对于生物学的理解。
几乎涵盖所有已知蛋白质
「你可以认为它基本涵盖了所有蛋白质结构。包括植物、细菌、动物和许多其他生物的预测结构,这为 AlphaFold 开辟了巨大的新机会,可以对环保、粮食安全和被忽视疾病等重要问题产生影响,」DeepMind 创始人、首席执行官杰米斯 · 哈萨比斯在介绍 AlphaFold DB 这次扩展时说道。

这一更新包括植物、细菌、动物和其他生物的蛋白质预测结构。

这一更新意味着蛋白质数据库 UniProt 都将带有蛋白质预测结构(UniProt 是一个全面的,高质量的,免费使用的蛋白质序列与功能信息数据库,它还包含了大量来自研究文献的关于蛋白的生物学功能信息)。研究者可以通过 Google Cloud Public Datasets 批量下载,让世界各地的科学家更容易访问 AlphaFold。
斯克里普斯转化研究所创始人 Eric Topol 表示:「AlphaFold 是生命科学领域独一无二的重大进步,展示了 AI 的力量。过去确定蛋白质的 3D 结构需要数月或数年,现在只需几秒钟。AlphaFold 已经加速并实现了大规模发现,包括破解核孔复合体的结构。新的蛋白质结构不断增加,几乎照亮了整个蛋白质宇宙,我们可以期待每天都有更多的生物谜团被解开。」
AlphaFold 的影响
自发布至今,AlphaFold 已产生令人难以置信的影响。它是 DeepMind 构建的最复杂的人工智能系统,需要多项关键创新,并已应用到多种下游任务中。
AlphaFold2 可以在原子精度上准确地预测蛋白质的结构,它不仅为生物学中 50 年来的重大挑战提供了解决方案,也证明了:人工智能可以极大地加速科学发现,进而推动人类进步,这一点意义重大。
DeepMind 已经开源了 AlphaFold 的代码,并在《自然》杂志上发表了两篇深度论文,引用量已超过 4000。此外,DeepMind 还与 EMBL-EBI 合作设计了一种帮助生物学家使用 AlphaFold 的工具,并共同发布了 AlphaFold DB。
在发布 AlphaFold 之前,DeepMind 征求了 30 多名生物学研究专家的意见,使得他们以最大化潜在利益和最小化潜在风险的方式与世界分享 AlphaFold 。

迄今为止,来自 190 个国家 / 地区的超过 500000 名研究人员访问了 AlphaFold DB,查看了超过 200 万个结构。一些免费提供的蛋白质结构也已集成到其他公共数据集中,例如 Ensembl、UniProt 和 OpenTargets,被数百万用户访问。

在与其他机构合作时,DeepMind 优先考虑那些最具积极社会效益的应用,重点关注那些资金不足或被忽视的计划。
拼凑核孔复合体
在最新一期《科学》杂志特刊上,几个研究团队描述了 AlphaFold 帮助拼凑核孔复合体——生物学中最具挑战性的难题之一。这个巨大的结构由数百个蛋白质部分组成,控制着进出细胞核的一切。

人们通过使用现有的实验方法揭示它的轮廓,结合 AlphaFold 预测完成和解释其中不清楚的区域,最终揭示了它的微妙结构。《科学》将其称为实验结构生物学的胜利,这种新研究方式现在正成为实验室的常规做法,开启了新的科学研究道路。
结构搜索工具
Foldseek、Dali 等结构搜索工具允许用户非常快速地搜索与给定蛋白质相似的结构。这将是为实际有用的蛋白质(例如分解塑料的蛋白质)挖掘大型序列数据集的第一步,它可以提供有关蛋白质功能的线索。
对人类健康的影响
AlphaFold 已经对人类健康产生了重大而直接的影响。与欧洲人类遗传学会的合作证明 AlphaFold 对于解开罕见遗传疾病的原因至关重要。此外,AlphaFold 还通过更好地了解新发现的可能成为药物靶点的蛋白质,帮助科学家更快地找到与其结合的潜在药物来加速药物发现。
参考内容:https://www.science.org/doi/10.1126/science.add2210https://www.theverge.com/2022/7/28/23280743/deepmind-alphafold-protein-database-alphabethttps://www.deepmind.com/blog/alphafold-reveals-the-structure-of-the-protein-universehttps://www.nature.com/articles/d41586-022-02083-2

YOLOv7-Pose 基于YOLOv7的关键点模型

目前人体姿态估计总体分为Top-down和Bottom-up两种,与目标检测不同,无论是基于热力图或是基于检测器处理的关键点检测算法,都较为依赖计算资源,推理耗时略长,今年出现了以YOLO为基线的关键点检测器。玩过目标检测的童鞋都知道YOLO以及各种变种目前算是工业落地较多的一类检测器,其简单的设计思想,长期活跃的社区生态,使其始终占据着较高的话题度。

【演变】

在ECCV 2022和CVPRW 2022会议上,YoLo-Pose和KaPao(下称为yolo-like-pose)都基于流行的YOLO目标检测框架提出一种新颖的无热力图的方法,类似于很久以前谷歌使用回归计算关键点的思想,yolo-like-pose一不使用检测器进行二阶处理,二部使用热力图拼接,虽然是一种暴力回归关键点的检测算法,但在处理速度上具有一定优势。

kapao

去年11月,滑铁卢大学率先提出了 KaPao:Rethinking Keypoint Representations: Modeling Keypoints and Poses as Objects for Multi-Person Human Pose Estimation,基于YOLOv5进行关键点检测,该文章目前已被ECCV 2022接收,该算法所取得的性能如下:

paper:https://arxiv.org/abs/2111.08557

code:https://github.com/wmcnally/kapao

yolov5-pose

今年4月,yolo-pose也挂在了arvix,在论文中,通过调研发现 HeatMap 的方式普遍使用L1 Loss。然而,L1损失并不一定适合获得最佳的OKS。且由于HeatMap是概率图,因此在基于纯HeatMap的方法中不可能使用OKS作为loss,只有当回归到关键点位置时,OKS才能被用作损失函数。因此,yolo-pose使用oks loss作为关键点的损失

相关代码在https://github.com/TexasInstruments/edgeai-yolov5/blob/yolo-pose/utils/loss.py也可见到:

 if self.kpt_label:
                    #Direct kpt prediction
                    pkpt_x = ps[:, 6::3] * 2. – 0.5
                    pkpt_y = ps[:, 7::3] * 2. – 0.5
                    pkpt_score = ps[:, 8::3]
                    #mask
                    kpt_mask = (tkpt[i][:, 0::2] != 0)
                    lkptv += self.BCEcls(pkpt_score, kpt_mask.float()) 
                    #l2 distance based loss
                    #lkpt += (((pkpt-tkpt[i])*kpt_mask)**2).mean()  #Try to make this loss based on distance instead of ordinary difference
                    #oks based loss
                    d = (pkpt_x-tkpt[i][:,0::2])**2 + (pkpt_y-tkpt[i][:,1::2])**2
                    s = torch.prod(tbox[i][:,-2:], dim=1, keepdim=True)
                    kpt_loss_factor = (torch.sum(kpt_mask != 0) + torch.sum(kpt_mask == 0))/torch.sum(kpt_mask != 0)
                    lkpt += kpt_loss_factor*((1 – torch.exp(-d/(s*(4*sigmas**2)+1e-9)))*kpt_mask).mean()

yolov7-pose

上个星期,YOLOv7的作者也放出了关于人体关键点检测的模型,该模型基于YOLOv7-w6

目前作者提供了.pt文件和推理测试的脚本,有兴趣的童靴可以去看看,本文的重点更偏向于对yolov7-pose.pt进行onnx文件的抽取和推理。

【yolov7-pose + onnxruntime】

首先下载好官方的预训练模型,使用提供的脚本进行推理:

% weigths = torch.load('weights/yolov7-w6-pose.pt')
% image = cv2.imread('sample/pose.jpeg')
!python pose.py 

一、yolov7-w6 VS yolov7-w6-pose

首先看下yolov7-w6使用的检测头

二、修改export脚本

如果直接使用export脚本进行onnx的抽取一定报错,在上一节我们已经看到pose.pt模型使用的检测头为IKeypoint,那么脚本需要进行相应更改:在export.py的这个位置插入:

 # 原代码:
    for k, m in model.named_modules():
        m._non_persistent_buffers_set = set()  # pytorch 1.6.0 compatibility
        if isinstance(m, models.common.Conv):  # assign export-friendly activations
            if isinstance(m.act, nn.Hardswish):
                m.act = Hardswish()
            elif isinstance(m.act, nn.SiLU):
                m.act = SiLU()
     model.model[-1].export = not opt.grid  # set Detect() layer grid export
                
    # 修改代码:
    for k, m in model.named_modules():
        m._non_persistent_buffers_set = set()  # pytorch 1.6.0 compatibility
        if isinstance(m, models.common.Conv):  # assign export-friendly activations
            if isinstance(m.act, nn.Hardswish):
                m.act = Hardswish()
            elif isinstance(m.act, nn.SiLU):
                m.act = SiLU()
        elif isinstance(m, models.yolo.IKeypoint):
            m.forward = m.forward_keypoint  # assign forward (optional)
            # 此处切换检测头
    model.model[-1].export = not opt.grid  # set Detect() layer grid export

forward_keypoint在原始的yolov7 repo源码中有,作者已经封装好,但估计是还没打算开放使用。

使用以下命令进行抽取:python export.py –weights ‘weights/yolov7-w6-pose.pt’ –img-size 960 –simplify True

三、onnxruntime推理

onnxruntime推理代码:

import onnxruntime
import matplotlib.pyplot as plt
import torch
import cv2
from torchvision import transforms
import numpy as np
from utils.datasets import letterbox
from utils.general import non_max_suppression_kpt
from utils.plots import output_to_keypoint, plot_skeleton_kpts

device = torch.device("cpu")

image = cv2.imread('sample/pose.jpeg')
image = letterbox(image, 960, stride=64, auto=True)[0]
image_ = image.copy()
image = transforms.ToTensor()(image)
image = torch.tensor(np.array([image.numpy()]))

print(image.shape)
sess = onnxruntime.InferenceSession('weights/yolov7-w6-pose.onnx')
out = sess.run(['output'], {'images': image.numpy()})[0]
out = torch.from_numpy(out)

output = non_max_suppression_kpt(out, 0.25, 0.65, nc=1, nkpt=17, kpt_label=True)
output = output_to_keypoint(output)
nimg = image[0].permute(1, 2, 0) * 255
nimg = nimg.cpu().numpy().astype(np.uint8)
nimg = cv2.cvtColor(nimg, cv2.COLOR_RGB2BGR)
for idx in range(output.shape[0]):
    plot_skeleton_kpts(nimg, output[idx, 7:].T, 3)

# matplotlib inline
plt.figure(figsize=(8, 8))
plt.axis('off')
plt.imshow(nimg)
plt.show()
plt.savefig("tmp")

推理效果几乎无损,但耗时会缩短一倍左右,另外有几个点:

  • image = letterbox(image, 960, stride=64, auto=True)[0] 中stride指的是最大步长,yolov7-w6和yolov5s下采样多了一步,导致在8,16,32的基础上多了64的下采样步长
  • output = non_max_suppression_kpt(out, 0.25, 0.65, nc=1, nkpt=17, kpt_label=True) ,nc 和 kpt_label 等信息在netron打印模型文件时可以看到
  • 所得到的onnx相比原半精度模型大了将近三倍,后续排查原因
  • yolov7-w6-pose极度吃显存,推理一张960×960的图像,需要2-4G的显存,训练更难以想象

ParseNet: Looking Wider to See Better

论文地址: https://arxiv.org/abs/1506.04579

代码: https://github.com/weiliu89/caffe

U形的编解码结构奠定了深度学习语义分割的基础,随着基线模型的表现越来越好,深度学习语义分割关注的焦点开始由原先的编解码架构下上采样如何更好的恢复图像像素转变为如何更加有效的利用图像上下文信息和提取多尺度特征。因而催生出语义分割的第二个主流的结构设计:多尺度结构。接下来的几篇论文解读将对重在关注图像上下文信息和多尺度特征的结构设计网络进行梳理,包括ParseNet、PSPNet、以空洞卷积为核心的Deeplab系列、HRNet以及其他代表性的多尺度设计。

自从全卷积网络(Fully Convolutional Networks, FCN)和UNet提出以来,主流的改进思路是围绕着编解码结构来进行的。但又一些改进在当时看来却不是那么“主流”,其中有一些是针对如何提升网络的全局信息提取能力来进行改进的。FCN提出之后,一些学者认为FCN忽略了图像作为整张图的全局信息,因而在一些应用场景下不能有效利用图像的语义上下文信息。图像全局信息除了增加对图像的整体理解之外,还有助于模型对局部图像块的判断,此前一种主流的方法是将概率图模型融入到CNN训练中,用于捕捉图像像素的上下文信息,比如说给模型加条件随机场(Conditional Random Field,CRF),但这种方式会使得模型难以训练并且变得低效。

针对如何高效利用图像的全局信息问题,相关研究在FCN结构的基础上提出了ParseNet,一种高效的端到端的语义分割网络,旨在利用全局信息来指导局部信息判断,并且引入太多的额外计算开销。提出ParseNet的论文为ParseNet: Looking Wider to See Better,发表于2015年,是在FCN基础上基于上下文视角的一个改进设计。在语义分割中,上下文信息对于提升模型表现非常关键,在仅有局部信息情况下,像素的分类判断有时候会变得模棱两可。尽管理论上深层卷积层的会有非常大的感受野,但在实际中有效感受野却小很多,不足以捕捉图像的全局信息。ParseNet通过全局平均池化的方法在FCN基础上直接获取上下文信息,图1为ParseNet的上下文提取模块,具体地,使用全局平均池化对上下文特征图进行池化后得到全局特征,然后对全局特征进行L2规范化处理,再对规范化后的特征图反池化后与局部特征图进行融合,这样的一个简单结构对于语义分割质量的提升的巨大的。如图2所示,ParseNet能够关注到图像中的全局信息,保证图像分割的完整性。

关于全局特征与局部特征的融合,ParseNet给出两种融合方式:早期融合(early fusion)和晚期融合(late fusion)。早期融合就是图6-1中所展现的融合方式,对全局特征反池化后直接与局部特征进行融合,然后在进行像素分类。而晚期融合则是把全局特征和局部特征分别进行像素分类后再进行某种融合,比如说进行加权。但无论是早期融合还是晚期融合,如果选取的归一化方式合适,其效果是差不多的。

下图是ParseNet在VOC 2012数据集上的分割效果,可以看到,ParseNet的分割能够明显关注到图像全局信息。

补充:反卷积(Deconvolution)、上采样(UNSampling)与上池化(UnPooling)

图(a)表示UnPooling的过程,特点是在Maxpooling的时候保留最大值的位置信息,之后在unPooling阶段使用该信息扩充Feature Map,除最大值位置以外,其余补0。

与之相对的是图(b),两者的区别在于UnSampling阶段没有使用MaxPooling时的位置信息,而是直接将内容复制来扩充Feature Map。从图中即可看到两者结果的不同。

图(c)为反卷积的过程,反卷积是卷积的逆过程,又称作转置卷积。最大的区别在于反卷积过程是有参数要进行学习的(类似卷积过程),理论是反卷积可以实现UnPooling和unSampling,只要卷积核的参数设置的合理。

2、FCN 全卷积网络 Fully Convolutional Networks

FCN对图像进行像素级的分类,从而解决了语义级别的图像分割(semantic segmentation)问题。与经典的CNN在卷积层之后使用全连接层得到固定长度的特征向量进行分类(全联接层+softmax输出)不同,FCN可以接受任意尺寸的输入图像,采用反卷积层对最后一个卷积层的feature map进行上采样, 使它恢复到输入图像相同的尺寸,从而可以对每个像素都产生了一个预测, 同时保留了原始输入图像中的空间信息, 最后在上采样的特征图上进行逐像素分类。

简单的来说,FCN与CNN的区别在把于CNN最后的全连接层换成卷积层,输出的是一张已经Label好的图片。

YOLOv7来临:论文详读和解析+训练自己数据集

2022年7月,YOLOv7来临,

论文链接:https://arxiv.org/abs/2207.02696

代码链接:https://github.com/WongKinYiu/yolov7

文章摘自https://mp.weixin.qq.com/s/5qK1FIU7qp0Sv3IE49-t_w

在v7论文挂出不到半天的时间,YOLOv3和YOLOv4的官网上均挂上了YOLOv7的链接和说明,由此看来大佬们都比较认可这款检测器。

官方版的YOLOv7相同体量下比YOLOv5精度更高,速度快120%(FPS),比 YOLOX 快180%(FPS),比 Dual-Swin-T 快1200%(FPS),比 ConvNext 快550%(FPS),比 SWIN-L快500%(FPS)。在5FPS到160FPS的范围内,无论是速度或是精度,YOLOv7都超过了目前已知的检测器,并且在GPU V100上进行测试, 精度为56.8% AP的模型可达到30 FPS(batch=1)以上的检测速率,与此同时,这是目前唯一一款在如此高精度下仍能超过30FPS的检测器。另外,YOLOv7所获得的成果不止于此,例如:

  • YOLOv7-e6 (55.9% AP, 56 FPS V100 b=1) by +500% FPS faster than SWIN-L Cascade R-CNN (53.9% AP, 9.2 FPS A100 b=1)
  • YOLOv7-e6 (55.9% AP, 56 FPS V100 b=1) by +550% FPS faster than ConvNeXt-RCNN (55.2% AP, 8.6 FPS A100 b=1)
  • YOLOv7-w6 (54.6% AP, 84 FPS V100 b=1) by +120% FPS faster than YOLOv5-X6-v6.1 (55.0% AP, 38 FPS V100 b=1)
  • YOLOv7-w6 (54.6% AP, 84 FPS V100 b=1) by +1200% FPS faster than Dual-Swin-RCNN (53.6% AP, 6.5 FPS V100 b=1)
  • YOLOv7 (51.2% AP, 161 FPS V100 b=1) by +180% FPS faster than YOLOX-X (51.1% AP, 58 FPS V100 b=1)

本文做出的贡献如下:

  1. 设计了几种可训练的bag-of-freebies,使实时检测器可以在不提高推理成本的情况下大大提高检测精度;
  2. 对于目标检测的发展,作者发现了两个新的问题,即模块重参化如何高效替代原始模块,以及动态标签分配策略如何处理好不同输出层的分配。因此在本文中提出了方法进行解决。
  3. 作者为实时探测器提出了“扩展”和“复合缩放”(extend” and “compound scaling”)方法,可以更加高效地利用参数和计算量,同时,作者提出的方法可以有效地减少实时探测器50%的参数,并且具备更快的推理速度和更高的检测精度。(这个其实和YOLOv5或者Scale YOLOv4的baseline使用不同规格分化成几种模型类似,既可以是width和depth的缩放,也可以是module的缩放)

2.1 实时检测器

目前最先进的实时探测器主要基于YOLO和FCOS,如果需要研发更先进的实时检测器,通常需要具备以下特征:

  • (1)更快和更高效的网络架构;
  • (2)更有效的特征积分方法;
  • (3)更准确的检测方法;
  • (4)更鲁棒的损失函数;
  • (5)更有效的标签分配方法;
  • (6)更有效的训练方式。

2.2 模型重参化

模型重参化策略在推理阶段将多个模块合并为一个计算模块,可以看作是一种集成技术(model ensemble,其实笔者觉得更像是一种基于feature的distillation),可以将其分为模块级集成和模型级集成两类。对于模型级重新参数化有两种常见的操作:

  • 一种是用不同的训练数据训练多个相同的模型,然后对多个训练模型的权重进行平均。
  • 一种是对不同迭代次数下模型权重进行加权平均。

模块重参化是近年来一个比较流行的研究课题。这种方法在训练过程中将一个整体模块分割为多个相同或不同的模块分支,但在推理过程中将多个分支模块集成到一个完全等价的模块中。然而,并不是所有提出的重参化模块都可以完美地应用于不同的架构。考虑到这一点,作者开发了新的重参数化模块,并为各种架构设计了相关的应用程序策略。下图是作者使用重参化实现构建的多个module,按照分组数不同进行排列,为什么作者会选择32的分组数,应该搞过部署的佬们会清楚一些,模块参考:https://github.com/WongKinYiu/yolov7/blob/main/models/common.py~

2.3 模型缩放

模型缩放通过扩大或缩小baseline,使其适用于不同的计算设备。模型缩放方法通常包括不同的缩放因子,如:

  • input size(输入图像大小)
  • depth(层数)
  • width(通道数)
  • stage(特征金字塔数量)

从而在网络的参数量、计算量、推理速度和精度方面实现很好的权衡。网络架构搜索(NAS)也是目前常用的模型缩放方法之一

三、模型设计架构

3.1 高效的聚合网络

在大多数关于设计高效网络的论文中,主要考虑的因素是参数量、计算量和计算密度。但从内存访存的角度出发出发,还可以分析输入/输出信道比、架构的分支数和元素级操作对网络推理速度的影响(shufflenet论文提出)。在执行模型缩放时还需考虑激活函数,即更多地考虑卷积层输出张量中的元素数量。

图2(b)中CSPVoVNet是VoVNet的一个变体。除了考虑上述几个设计问题外,CSPVoVNet的体系结构还分析了梯度路径,使不同层能够学习更多样化的特征。上面描述的梯度分析方法还能使推理速度更快、模型更准确(看下图!其实和Resnext有点像,但比它复杂一些)。

  • 图2(c)中的ELAN出于以下设计考虑——“如何设计一个高效的网络?”得出结论是:通过控制最短最长梯度路径,更深的网络可以有效地进行学习并更好地收敛。
  • 因此,在本文中,作者提出了基于ELAN的扩展版本E-ELAN,其主要架构如图2(d)所示。在大规模ELAN中,无论梯度路径长度和计算模块数量如何,都达到了稳定的状态。但如果更多计算模块被无限地堆叠,这种稳定状态可能会被破坏,参数利用率也会降低。本文提出的E-ELAN采用expand、shuffle、merge cardinality结构,实现在不破坏原始梯度路径的情况下,提高网络的学习能力。

在体系结构方面,E-ELAN只改变了计算模块中的结构,而过渡层的结构则完全不变。作者的策略是利用分组卷积来扩展计算模块的通道和基数,将相同的group parameter和channel multiplier用于计算每一层中的所有模块。然后,将每个模块计算出的特征图根据设置的分组数打乱成G组,最后将它们连接在一起。此时,每一组特征图中的通道数将与原始体系结构中的通道数相同。最后,作者添加了G组特征来merge cardinality。除了维护原始的ELAN设计架构外,E-ELAN还可以指导不同的分组模块来学习更多样化的特性。(难以置信,要是在CPU上运行,分分钟可能爆)

3.2 基于连接的模型的模型缩放

缩放这个就不说了,和YOLOv5、Scale YOLOv4、YOLOX类似。要不就depth and width,要不就module scale,可参考scale yolov4的P4、P5、P5结构。

四、可训练的赠品礼包(bag-of-freebies)

4.1 卷积重参化

尽管RepConv在VGG上取得了优异的性能,但将它直接应用于ResNet和DenseNet或其他网络架构时,它的精度会显着降低。作者使用梯度传播路径来分析不同的重参化模块应该和哪些网络搭配使用。通过分析RepConv与不同架构的组合以及产生的性能,作者发现RepConv中的identity破坏了ResNet中的残差结构和DenseNet中的跨层连接,这为不同的特征图提供了梯度的多样性(题外话,之前在YOLOv5 Lite上做过此类实验,结果也是如此,因此v5Lite-g的模型也是砍掉了identity,但分析不出原因,作者也没给出具体的分析方案,此处蹲坑)。

基于上述原因,作者使用没有identity连接的RepConv结构。图4显示了作者在PlainNet和ResNet中使用的“计划型重参化卷积”的一个示例。

4.2 辅助训练模块

深度监督是一种常用于训练深度网络的技术,其主要概念是在网络的中间层增加额外的辅助头,以及以辅助损失为指导的浅层网络权重。即使对于像ResNet和DenseNet这样收敛效果好的网络结构,深度监督仍然可以显着提高模型在许多任务上的性能(这个和Nanodet Plus相似,按笔者理解可以当成是深层局部网络的ensemble,最后将辅助头和检测头的权重做融合)。图5(a)和(b)分别显示了“没有”和“有”深度监督的目标检测器架构,在本文中,作者将负责最终的输出头称为引导头,将用于辅助训练的头称为辅助头。

接下来讨论标签分配的问题。在过去,在深度网络的训练中,标签分配通常直接指的是ground truth,并根据给定的规则生成hard label(未经过softmax)。然而近年来,以目标检测为例,研究者经常利用网络预测的质量分布来结合ground truth,使用一些计算和优化方法来生成可靠的软标签(soft label)。例如,YOLO使用bounding box预测和ground truth的IoU作为软标签。

在本文中,作者将网络预测结果与ground truth一起考虑后再分配软标签的机制称为“标签分配器”。无论辅助头或引导头,都需要对目标进行深度监督。那么,‘’如何为辅助头和引导头合理分配软标签?”,这是作者需要考虑的问题。目前最常用的方法如图5(c)所示,即将辅助头和引导头分离,然后利用它们各自的预测结果和ground truth执行标签分配。

本文提出的方法是一种新的标签分配方法,通过引导头的预测来引导辅助头以及自身。换句话说,首先使用引导头的prediction作为指导,生成从粗到细的层次标签,分别用于辅助头和引导头的学习,具体可看图5(d)和(e)。

Lead head guided label assigner: 引导头引导“标签分配器”预测结果和ground truth进行计算,并通过优化(在utils/loss.py的SigmoidBin()函数中,传送门:https://github.com/WongKinYiu/yolov7/blob/main/utils/loss.py 生成软标签。这组软标签将作为辅助头和引导头的目标来训练模型。(之前写过一篇博客,【浅谈计算机视觉中的知识蒸馏】]https://zhuanlan.zhihu.com/p/497067556)详细讲过soft label的好处)这样做的目的是使引导头具有较强的学习能力,由此产生的软标签更能代表源数据与目标之间的分布差异和相关性。此外,作者还可以将这种学习看作是一种广义上的余量学习。通过让较浅的辅助头直接学习引导头已经学习到的信息,引导头能更加专注于尚未学习到的残余信息。

Coarse-to-fine lead head guided label assigner: Coarse-to-fine引导头使用到了自身的prediction和ground truth来生成软标签,引导标签进行分配。然而,在这个过程中,作者生成了两组不同的软标签,即粗标签和细标签,其中细标签与引导头在标签分配器上生成的软标签相同,粗标签是通过降低正样本分配的约束,允许更多的网格作为正目标(可以看下FastestDet的label assigner,不单单只把gt中心点所在的网格当成候选目标,还把附近的三个也算进行去,增加正样本候选框的数量)。原因是一个辅助头的学习能力并不需要强大的引导头,为了避免丢失信息,作者将专注于优化样本召回的辅助头。对于引导头的输出,可以从查准率中过滤出高精度值的结果作为最终输出。然而,值得注意的是,如果粗标签的附加权重接近细标签的附加权重,则可能会在最终预测时产生错误的先验结果。

4.3 其他可训练的bag-of-freebies

  1. Batch normalization:目的是在推理阶段将批归一化的均值和方差整合到卷积层的偏差和权重中。
  2. YOLOR中的隐式知识结合卷积特征映射和乘法方式:YOLOR中的隐式知识可以在推理阶段将计算值简化为向量。这个向量可以与前一层或后一层卷积层的偏差和权重相结合。
  3. EMA Model:EMA 是一种在mean teacher中使用的技术,作者使用 EMA 模型作为最终的推理模型。

五、实验

5.1 实验环境

作者为边缘GPU、普通GPU和云GPU设计了三种模型,分别被称为YOLOv7-Tiny、YOLOv7和YOLOv7-W6。同时,还使用基本模型针对不同的服务需求进行缩放,并得到不同大小的模型。对于YOLOv7,可进行颈部缩放(module scale),并使用所提出的复合缩放方法对整个模型的深度和宽度进行缩放(depth and width scale),此方式获得了YOLOv7-X。对于YOLOv7-W6,使用提出的缩放方法得到了YOLOv7-E6和YOLOv7-D6。此外,在YOLOv7-E6使用了提出的E-ELAN,从而完成了YOLOv7-E6E。由于YOLOv7-tincy是一个面向边缘GPU架构的模型,因此它将使用ReLU作为激活函数。作为对于其他模型,使用SiLU作为激活函数。

选择当前先进的检测器YOLOR作为基线。在相同设置下,表1显示了本文提出的YOLOv7模型和其他模型的对比。从结果中可以看出:

  • 与YOLOv4相比,YOLOv7的参数减少了75%,计算量减少了36%,AP提高了1.5%。
  • 与最先进的YOLOR-CSP相比,YOLOv7的参数少了43% ,计算量少了15%,AP高了0.4%。
  • 在小模型的性能中,与YOLOv4-tiny相比,YOLOv7-Tiny减少了39%的参数量和49%的计算量,但保持相同的AP。
  • 在云GPU模型上,YOLOv7模型仍然具有更高的AP,同时减少了19%的参数量和33%的计算量。

5.3 与sota算法的比较

本文将所提出的方法与通用GPU上或边缘GPU上最先进的的目标检测器进行了比较

  • 比较YOLOv7-Tiny-SiLU和YOLOv5-N(v6.1),YOLOv7-Tiny-SiLU在速度上快127帧,准确率提高10.7%。
  • YOLOv7在帧率为161帧时有51.4%的AP,而相同AP的PP-YOLOE-L只有78帧,且参数l少41%。
  • YOLOv7-X在114FPS时,比YOLOv5-L(v6.1)99FPS的推理速度更快,同时可以提高3.9%的AP。
  • YOLOv7-X与YOLOv5-X(v6.1)相比,YOLOv7-X的推理速度要快31fps。此外,在参数量和计算量方面,YOLOv7-X比YOLOv5-X(v6.1)减少了22%的参数和8%的计算量,但AP提高了2.2%。
  • 使用输入分辨率1280,YOLOv7与YOLOR进行比较,YOLOv7-W6的推理速度比YOLOR-P6快8FPS,检测率也提高了1%的AP。
  • 至于YOLOv7-E6和YOLOv5-X6(v6.1)比较时,前者的AP增益比后者高0.9%,但参数减少45%,计算量减少63%,推理速度提高了47%。
  • YOLOv7-D6的推理速度与YOLOR-E6接近,但AP提高了0.8%。
  • YOLOv7-E6E的推理速度与YOLOR-D6接近,但AP提高了0.3%。

六、结论

本文提出了一种新的实时检测器。在研究过程中,本文发现了重参化模块的替换问题和动态标签的分配问题。为了解决这一问题,提出了一种可训练的bag-of-freebies策略来提高目标检测的精度。基于此,本文开发的YOLOv7系列目标检测模型获得了最先进的结果。

训练自己数据:

数据集准备:准备coco类型数据 ,新建MyDataCoco.yaml

# COCO 2017 dataset http://cocodataset.org

# download command/URL (optional)
# download: bash ./scripts/get_coco.sh

# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train:yolov7/data/train.txt  # 118287 images
val:yolov7/data/val.txt  # 5000 images
test:yolov7/data/test.txt  # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794

# number of classes
nc: 10

# class names
names: ['lighthouse',
'sailboat',
'buoy',
'railbar',
'cargoship',
'navalvessels',
'passengership',
'dock',
'submarine',
'fishingboat' ]

 results: