Transformers 4.37 中文文档(五)(5)

简介: Transformers 4.37 中文文档(五)

Transformers 4.37 中文文档(五)(4)https://developer.aliyun.com/article/1565244


手动进行深度估计推断

现在您已经看到如何使用深度估计管道,让我们看看如何手动复制相同的结果。

Hugging Face Hub 上的检查点加载模型和相关处理器开始。这里我们将使用与之前相同的检查点:

>>> from transformers import AutoImageProcessor, AutoModelForDepthEstimation
>>> checkpoint = "vinvino02/glpn-nyu"
>>> image_processor = AutoImageProcessor.from_pretrained(checkpoint)
>>> model = AutoModelForDepthEstimation.from_pretrained(checkpoint)

使用image_processor准备模型的图像输入,该处理器将处理必要的图像转换,如调整大小和归一化:

>>> pixel_values = image_processor(image, return_tensors="pt").pixel_values

通过模型传递准备好的输入:

>>> import torch
>>> with torch.no_grad():
...     outputs = model(pixel_values)
...     predicted_depth = outputs.predicted_depth

可视化结果:

>>> import numpy as np
>>> # interpolate to original size
>>> prediction = torch.nn.functional.interpolate(
...     predicted_depth.unsqueeze(1),
...     size=image.size[::-1],
...     mode="bicubic",
...     align_corners=False,
... ).squeeze()
>>> output = prediction.numpy()
>>> formatted = (output * 255 / np.max(output)).astype("uint8")
>>> depth = Image.fromarray(formatted)
>>> depth

图像到图像任务指南

原文链接:huggingface.co/docs/transformers/v4.37.2/en/tasks/image_to_image

图像到图像任务是一个应用程序接收图像并输出另一幅图像的任务。这包括各种子任务,包括图像增强(超分辨率、低光增强、去雨等)、图像修补等。

本指南将向您展示如何:

  • 使用图像到图像管道进行超分辨率任务,
  • 运行相同任务的图像到图像模型,而不使用管道。

请注意,截至本指南发布时,图像到图像管道仅支持超分辨率任务。

让我们开始安装必要的库。

pip install transformers

现在我们可以使用Swin2SR 模型初始化管道。然后,通过调用图像来推断管道。目前,此管道仅支持Swin2SR 模型

from transformers import pipeline
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
pipe = pipeline(task="image-to-image", model="caidas/swin2SR-lightweight-x2-64", device=device)

现在,让我们加载一张图像。

from PIL import Image
import requests
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/cat.jpg"
image = Image.open(requests.get(url, stream=True).raw)
print(image.size)
# (532, 432)

现在我们可以使用管道进行推断。我们将得到一张猫图像的放大版本。

upscaled = pipe(image)
print(upscaled.size)
# (1072, 880)

如果您希望自己进行推断而不使用管道,可以使用 transformers 的Swin2SRForImageSuperResolutionSwin2SRImageProcessor类。我们将使用相同的模型检查点。让我们初始化模型和处理器。

from transformers import Swin2SRForImageSuperResolution, Swin2SRImageProcessor 
model = Swin2SRForImageSuperResolution.from_pretrained("caidas/swin2SR-lightweight-x2-64").to(device)
processor = Swin2SRImageProcessor("caidas/swin2SR-lightweight-x2-64")

pipeline抽象了我们必须自己完成的预处理和后处理步骤,因此让我们对图像进行预处理。我们将图像传递给处理器,然后将像素值移动到 GPU。

pixel_values = processor(image, return_tensors="pt").pixel_values
print(pixel_values.shape)
pixel_values = pixel_values.to(device)

现在我们可以通过将像素值传递给模型来推断图像。

import torch
with torch.no_grad():
  outputs = model(pixel_values)

输出是一个类型为ImageSuperResolutionOutput的对象,看起来像下面这样👇

(loss=None, reconstruction=tensor([[[[0.8270, 0.8269, 0.8275,  ..., 0.7463, 0.7446, 0.7453],
          [0.8287, 0.8278, 0.8283,  ..., 0.7451, 0.7448, 0.7457],
          [0.8280, 0.8273, 0.8269,  ..., 0.7447, 0.7446, 0.7452],
          ...,
          [0.5923, 0.5933, 0.5924,  ..., 0.0697, 0.0695, 0.0706],
          [0.5926, 0.5932, 0.5926,  ..., 0.0673, 0.0687, 0.0705],
          [0.5927, 0.5914, 0.5922,  ..., 0.0664, 0.0694, 0.0718]]]],
       device='cuda:0'), hidden_states=None, attentions=None)

我们需要获取reconstruction并对其进行后处理以进行可视化。让我们看看它是什么样子的。

outputs.reconstruction.data.shape
# torch.Size([1, 3, 880, 1072])

我们需要挤压输出并去掉轴 0,裁剪值,然后将其转换为 numpy 浮点数。然后我们将排列轴以获得形状[1072, 880],最后将输出带回范围[0, 255]。

import numpy as np
# squeeze, take to CPU and clip the values
output = outputs.reconstruction.data.squeeze().cpu().clamp_(0, 1).numpy()
# rearrange the axes
output = np.moveaxis(output, source=0, destination=-1)
# bring values back to pixel values range
output = (output * 255.0).round().astype(np.uint8)
Image.fromarray(output)

计算机视觉知识蒸馏

原始文本:huggingface.co/docs/transformers/v4.37.2/en/tasks/knowledge_distillation_for_image_classification

知识蒸馏是一种技术,用于将知识从一个更大、更复杂的模型(教师)转移到一个更小、更简单的模型(学生)。为了从一个模型中提取知识到另一个模型,我们采用一个在特定任务上(本例中为图像分类)训练过的预训练教师模型,并随机初始化一个学生模型用于图像分类训练。接下来,我们训练学生模型以最小化其输出与教师输出之间的差异,从而使其模仿行为。这最初是由  Hinton 等人在神经网络中提取知识 中首次引入的。在这个指南中,我们将进行特定任务的知识蒸馏。我们将使用 beans 数据集

这个指南演示了如何使用 🤗 Transformers 的 Trainer API 将一个 fine-tuned ViT 模型(教师模型)蒸馏到一个 MobileNet(学生模型)。

让我们安装进行蒸馏和评估过程所需的库。

pip install transformers datasets accelerate tensorboard evaluate --upgrade

在这个例子中,我们使用 merve/beans-vit-224 模型作为教师模型。这是一个基于 google/vit-base-patch16-224-in21k 在 beans 数据集上微调的图像分类模型。我们将将这个模型蒸馏到一个随机初始化的 MobileNetV2。

我们现在将加载数据集。

from datasets import load_dataset
dataset = load_dataset("beans")

我们可以从任一模型中使用图像处理器,因为在这种情况下它们返回相同分辨率的相同输出。我们将使用 datasetmap() 方法将预处理应用于数据集的每个拆分。

from transformers import AutoImageProcessor
teacher_processor = AutoImageProcessor.from_pretrained("merve/beans-vit-224")
def process(examples):
    processed_inputs = teacher_processor(examples["image"])
    return processed_inputs
processed_datasets = dataset.map(process, batched=True)

基本上,我们希望学生模型(随机初始化的 MobileNet)模仿教师模型(微调的视觉变换器)。为了实现这一点,我们首先从教师和学生中获取 logits 输出。然后,我们将它们中的每一个除以控制每个软目标重要性的参数 temperature。一个称为 lambda 的参数权衡了蒸馏损失的重要性。在这个例子中,我们将使用 temperature=5lambda=0.5。我们将使用  Kullback-Leibler 散度损失来计算学生和教师之间的差异。给定两个数据 P 和 Q,KL 散度解释了我们需要多少额外信息来用 Q  表示 P。如果两者相同,它们的 KL 散度为零,因为不需要其他信息来解释 P。因此,在知识蒸馏的背景下,KL 散度是有用的。

from transformers import TrainingArguments, Trainer
import torch
import torch.nn as nn
import torch.nn.functional as F
class ImageDistilTrainer(Trainer):
    def __init__(self, teacher_model=None, student_model=None, temperature=None, lambda_param=None,  *args, **kwargs):
        super().__init__(model=student_model, *args, **kwargs)
        self.teacher = teacher_model
        self.student = student_model
        self.loss_function = nn.KLDivLoss(reduction="batchmean")
        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        self.teacher.to(device)
        self.teacher.eval()
        self.temperature = temperature
        self.lambda_param = lambda_param
    def compute_loss(self, student, inputs, return_outputs=False):
        student_output = self.student(**inputs)
        with torch.no_grad():
          teacher_output = self.teacher(**inputs)
        # Compute soft targets for teacher and student
        soft_teacher = F.softmax(teacher_output.logits / self.temperature, dim=-1)
        soft_student = F.log_softmax(student_output.logits / self.temperature, dim=-1)
        # Compute the loss
        distillation_loss = self.loss_function(soft_student, soft_teacher) * (self.temperature ** 2)
        # Compute the true label loss
        student_target_loss = student_output.loss
        # Calculate final loss
        loss = (1. - self.lambda_param) * student_target_loss + self.lambda_param * distillation_loss
        return (loss, student_output) if return_outputs else loss

我们现在将登录到 Hugging Face Hub,这样我们就可以通过 Trainer 将我们的模型推送到 Hugging Face Hub。

from huggingface_hub import notebook_login
notebook_login()

让我们设置 TrainingArguments、教师模型和学生模型。

from transformers import AutoModelForImageClassification, MobileNetV2Config, MobileNetV2ForImageClassification
training_args = TrainingArguments(
    output_dir="my-awesome-model",
    num_train_epochs=30,
    fp16=True,
    logging_dir=f"{repo_name}/logs",
    logging_strategy="epoch",
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
    metric_for_best_model="accuracy",
    report_to="tensorboard",
    push_to_hub=True,
    hub_strategy="every_save",
    hub_model_id=repo_name,
    )
num_labels = len(processed_datasets["train"].features["labels"].names)
# initialize models
teacher_model = AutoModelForImageClassification.from_pretrained(
    "merve/beans-vit-224",
    num_labels=num_labels,
    ignore_mismatched_sizes=True
)
# training MobileNetV2 from scratch
student_config = MobileNetV2Config()
student_config.num_labels = num_labels
student_model = MobileNetV2ForImageClassification(student_config)

我们可以使用 compute_metrics 函数在测试集上评估我们的模型。这个函数将在训练过程中用于计算我们模型的 准确率f1

import evaluate
import numpy as np
accuracy = evaluate.load("accuracy")
def compute_metrics(eval_pred):
    predictions, labels = eval_pred
    acc = accuracy.compute(references=labels, predictions=np.argmax(predictions, axis=1))
    return {"accuracy": acc["accuracy"]}

让我们使用我们定义的训练参数初始化 Trainer。我们还将初始化我们的数据收集器。

from transformers import DefaultDataCollator
data_collator = DefaultDataCollator()
trainer = ImageDistilTrainer(
    student_model=student_model,
    teacher_model=teacher_model,
    training_args=training_args,
    train_dataset=processed_datasets["train"],
    eval_dataset=processed_datasets["validation"],
    data_collator=data_collator,
    tokenizer=teacher_processor,
    compute_metrics=compute_metrics,
    temperature=5,
    lambda_param=0.5
)

我们现在可以训练我们的模型。

trainer.train()

我们可以在测试集上评估模型。

trainer.evaluate(processed_datasets["test"])

在测试集上,我们的模型达到了 72%的准确率。为了对蒸馏效率进行合理性检查,我们还使用相同的超参数从头开始在豆类数据集上训练  MobileNet,并观察到测试集上的  63%准确率。我们邀请读者尝试不同的预训练教师模型、学生架构、蒸馏参数,并报告他们的发现。蒸馏模型的训练日志和检查点可以在此存储库中找到,从头开始训练的 MobileNetV2 可以在此存储库中找到。


Transformers 4.37 中文文档(五)(6)https://developer.aliyun.com/article/1565246

相关文章
|
4月前
|
数据可视化 自动驾驶 机器人
Transformers 4.37 中文文档(五)(4)
Transformers 4.37 中文文档(五)
42 0
|
4月前
|
存储 缓存 Shell
Transformers 4.37 中文文档(一)(3)
Transformers 4.37 中文文档(一)
287 1
Transformers 4.37 中文文档(一)(3)
|
4月前
|
PyTorch TensorFlow 调度
Transformers 4.37 中文文档(二)(5)
Transformers 4.37 中文文档(二)
69 5
|
4月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(一百)(6)
Transformers 4.37 中文文档(一百)
33 1
|
4月前
|
自然语言处理 安全 PyTorch
Transformers 4.37 中文文档(一)(4)
Transformers 4.37 中文文档(一)
54 1
|
4月前
|
编解码 缓存 算法
Transformers 4.37 中文文档(一百)(2)
Transformers 4.37 中文文档(一百)
43 1
|
4月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(一百)(5)
Transformers 4.37 中文文档(一百)
29 1
|
4月前
|
PyTorch TensorFlow 调度
Transformers 4.37 中文文档(四)(2)
Transformers 4.37 中文文档(四)
53 1
|
4月前
|
存储 自然语言处理 测试技术
Transformers 4.37 中文文档(八)(1)
Transformers 4.37 中文文档(八)
28 2
|
4月前
|
并行计算 PyTorch 算法框架/工具
Transformers 4.37 中文文档(八)(5)
Transformers 4.37 中文文档(八)
153 2