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 的Swin2SRForImageSuperResolution
和Swin2SRImageProcessor
类。我们将使用相同的模型检查点。让我们初始化模型和处理器。
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")
我们可以从任一模型中使用图像处理器,因为在这种情况下它们返回相同分辨率的相同输出。我们将使用 dataset
的 map()
方法将预处理应用于数据集的每个拆分。
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=5
和 lambda=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