商业机构的网站是什么,乌鲁瓦提建设管理局网站,查询网址域名大全免费,网页设计零基础学习课程(实验性#xff09;计算机视觉教程的量化转移学习
本教程以 Sasank Chilamkurthy 编写的原始 PyTorch 转移学习教程为基础。
转移学习是指利用预训练的模型应用于不同数据集的技术。 使用转移学习的主要方式有两种#xff1a;
作为固定特征提取器的 ConvNet #xff1a;在…(实验性计算机视觉教程的量化转移学习
本教程以 Sasank Chilamkurthy 编写的原始 PyTorch 转移学习教程为基础。
转移学习是指利用预训练的模型应用于不同数据集的技术。 使用转移学习的主要方式有两种
作为固定特征提取器的 ConvNet 在这里您“冻结” 网络中所有参数的权重但最后几层(又称“头部”的权重通常 连接的图层。 将这些最后一层替换为使用随机权重初始化的新层并且仅训练这些层。对 ConvNet 进行微调使用随机训练的网络初始化模型而不是随机初始化然后像往常一样进行训练但使用另一个数据集。 通常如果输出数量不同则在网络中也会更换磁头(或磁头的一部分。 这种方法通常将学习率设置为较小的值。 这样做是因为已经对网络进行了训练并且只需进行较小的更改即可将其“微调”到新的数据集。
您还可以结合以上两种方法首先可以冻结特征提取器并训练头部。 之后您可以解冻特征提取器(或其一部分将学习率设置为较小的值然后继续进行训练。
在本部分中您将使用第一种方法-使用量化模型提取特征。
第 0 部分。先决条件
在深入学习迁移学习之前让我们回顾一下“先决条件”例如安装和数据加载/可视化。
# Imports
import copy
import matplotlib.pyplot as plt
import numpy as np
import os
import timeplt.ion()
安装每夜构建
因为您将使用 PyTorch 的实验部分所以建议安装最新版本的torch和torchvision。 您可以在中找到有关本地安装的最新说明。 例如要在没有 GPU 支持的情况下进行安装
pip install numpy
pip install --pre torch torchvision -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html
# For CUDA support use https://download.pytorch.org/whl/nightly/cu101/torch_nightly.html
载入资料
注意
本部分与原始的迁移学习教程相同。
我们将使用torchvision和torch.utils.data包加载数据。
您今天要解决的问题是从图像中对蚂蚁和蜜蜂进行分类。 该数据集包含约 120 张针对蚂蚁和蜜蜂的训练图像。 每个类别有 75 个验证图像。 可以认为这是一个很小的数据集。 但是由于我们正在使用迁移学习因此我们应该能够很好地概括。
此数据集是 imagenet 的很小子集。
Note
从此处下载数据并将其提取到data目录。
import torch
from torchvision import transforms, datasets# Data augmentation and normalization for training
# Just normalization for validation
data_transforms {train: transforms.Compose([transforms.Resize(224),transforms.RandomCrop(224),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),val: transforms.Compose([transforms.Resize(224),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),
}data_dir data/hymenoptera_data
image_datasets {x: datasets.ImageFolder(os.path.join(data_dir, x),data_transforms[x])for x in [train, val]}
dataloaders {x: torch.utils.data.DataLoader(image_datasets[x], batch_size16,shuffleTrue, num_workers8)for x in [train, val]}
dataset_sizes {x: len(image_datasets[x]) for x in [train, val]}
class_names image_datasets[train].classesdevice torch.device(cuda:0 if torch.cuda.is_available() else cpu)
可视化一些图像
让我们可视化一些训练图像以了解数据扩充。
import torchvisiondef imshow(inp, titleNone, axNone, figsize(5, 5)):Imshow for Tensor.inp inp.numpy().transpose((1, 2, 0))mean np.array([0.485, 0.456, 0.406])std np.array([0.229, 0.224, 0.225])inp std * inp meaninp np.clip(inp, 0, 1)if ax is None:fig, ax plt.subplots(1, figsizefigsize)ax.imshow(inp)ax.set_xticks([])ax.set_yticks([])if title is not None:ax.set_title(title)# Get a batch of training data
inputs, classes next(iter(dataloaders[train]))# Make a grid from batch
out torchvision.utils.make_grid(inputs, nrow4)fig, ax plt.subplots(1, figsize(10, 10))
imshow(out, title[class_names[x] for x in classes], axax)
模型训练的支持功能
以下是模型训练的通用功能。 此功能也
安排学习率保存最佳模型
def train_model(model, criterion, optimizer, scheduler, num_epochs25, devicecpu):Support function for model training.Args:model: Model to be trainedcriterion: Optimization criterion (loss)optimizer: Optimizer to use for trainingscheduler: Instance of torch.optim.lr_schedulernum_epochs: Number of epochsdevice: Device to run the training on. Must be cpu or cudasince time.time()best_model_wts copy.deepcopy(model.state_dict())best_acc 0.0for epoch in range(num_epochs):print(Epoch {}/{}.format(epoch, num_epochs - 1))print(- * 10)# Each epoch has a training and validation phasefor phase in [train, val]:if phase train:model.train() # Set model to training modeelse:model.eval() # Set model to evaluate moderunning_loss 0.0running_corrects 0# Iterate over data.for inputs, labels in dataloaders[phase]:inputs inputs.to(device)labels labels.to(device)# zero the parameter gradientsoptimizer.zero_grad()# forward# track history if only in trainwith torch.set_grad_enabled(phase train):outputs model(inputs)_, preds torch.max(outputs, 1)loss criterion(outputs, labels)# backward optimize only if in training phaseif phase train:loss.backward()optimizer.step()# statisticsrunning_loss loss.item() * inputs.size(0)running_corrects torch.sum(preds labels.data)if phase train:scheduler.step()epoch_loss running_loss / dataset_sizes[phase]epoch_acc running_corrects.double() / dataset_sizes[phase]print({} Loss: {:.4f} Acc: {:.4f}.format(phase, epoch_loss, epoch_acc))# deep copy the modelif phase val and epoch_acc best_acc:best_acc epoch_accbest_model_wts copy.deepcopy(model.state_dict())print()time_elapsed time.time() - sinceprint(Training complete in {:.0f}m {:.0f}s.format(time_elapsed // 60, time_elapsed % 60))print(Best val Acc: {:4f}.format(best_acc))# load best model weightsmodel.load_state_dict(best_model_wts)return model
可视化模型预测的支持功能
通用功能可显示一些图像的预测
def visualize_model(model, rows3, cols3):was_training model.trainingmodel.eval()current_row current_col 0fig, ax plt.subplots(rows, cols, figsize(cols*2, rows*2))with torch.no_grad():for idx, (imgs, lbls) in enumerate(dataloaders[val]):imgs imgs.cpu()lbls lbls.cpu()outputs model(imgs)_, preds torch.max(outputs, 1)for jdx in range(imgs.size()[0]):imshow(imgs.data[jdx], axax[current_row, current_col])ax[current_row, current_col].axis(off)ax[current_row, current_col].set_title(predicted: {}.format(class_names[preds[jdx]]))current_col 1if current_col cols:current_row 1current_col 0if current_row rows:model.train(modewas_training)returnmodel.train(modewas_training)
第 1 部分。训练基于量化特征提取器的自定义分类器
在本部分中您将使用“冻结”量化特征提取器并在其顶部训练自定义分类器头。 与浮点模型不同您不需要为量化模型设置 require_grad False因为它没有可训练的参数。 请参阅文档了解更多详细信息。
加载预训练的模型在本练习中您将使用 ResNet-18 。
import torchvision.models.quantization as models# You will need the number of filters in the fc for future use.
# Here the size of each output sample is set to 2.
# Alternatively, it can be generalized to nn.Linear(num_ftrs, len(class_names)).
model_fe models.resnet18(pretrainedTrue, progressTrue, quantizeTrue)
num_ftrs model_fe.fc.in_features
此时您需要修改预训练模型。 该模型在开始和结束时都有量化/去量化块。 但是由于只使用要素提取器因此反量化层必须在线性层(头部之前移动。 最简单的方法是将模型包装在nn.Sequential模块中。
第一步是在 ResNet 模型中隔离特征提取器。 尽管在本示例中您被责成使用fc以外的所有图层作为特征提取器但实际上您可以根据需要选择任意数量的零件。 如果您也想替换一些卷积层这将很有用。
Note
将特征提取器与量化模型的其余部分分开时必须手动将量化器/去量化器放置在要保持量化的部分的开头和结尾。
下面的函数创建一个带有自定义头部的模型。
from torch import nndef create_combined_model(model_fe):# Step 1\. Isolate the feature extractor.model_fe_features nn.Sequential(model_fe.quant, # Quantize the inputmodel_fe.conv1,model_fe.bn1,model_fe.relu,model_fe.maxpool,model_fe.layer1,model_fe.layer2,model_fe.layer3,model_fe.layer4,model_fe.avgpool,model_fe.dequant, # Dequantize the output)# Step 2\. Create a new headnew_head nn.Sequential(nn.Dropout(p0.5),nn.Linear(num_ftrs, 2),)# Step 3\. Combine, and dont forget the quant stubs.new_model nn.Sequential(model_fe_features,nn.Flatten(1),new_head,)return new_model
警告
当前量化模型只能在 CPU 上运行。 但是可以将模型的未量化部分发送到 GPU。
import torch.optim as optim
new_model create_combined_model(model_fe)
new_model new_model.to(cpu)criterion nn.CrossEntropyLoss()# Note that we are only training the head.
optimizer_ft optim.SGD(new_model.parameters(), lr0.01, momentum0.9)# Decay LR by a factor of 0.1 every 7 epochs
exp_lr_scheduler optim.lr_scheduler.StepLR(optimizer_ft, step_size7, gamma0.1)
训练和评估
此步骤在 CPU 上大约需要 15-25 分钟。 由于量化模型只能在 CPU 上运行因此您不能在 GPU 上运行训练。
new_model train_model(new_model, criterion, optimizer_ft, exp_lr_scheduler,num_epochs25, devicecpu)visualize_model(new_model)
plt.tight_layout()
第 2 部分。微调可量化模型
在这一部分中我们将微调用于迁移学习的特征提取器并对特征提取器进行量化。 请注意在第 1 部分和第 2 部分中特征提取器都是量化的。 不同之处在于在第 1 部分中我们使用了预训练的量化模型。 在这一部分中我们将在对感兴趣的数据集进行微调之后创建一个量化的特征提取器因此这是一种在具有量化优势的同时通过转移学习获得更好的准确性的方法。 请注意在我们的特定示例中训练集非常小(120 张图像因此微调整个模型的好处并不明显。 但是此处显示的过程将提高使用较大数据集进行传递学习的准确性。
预训练特征提取器必须是可量化的。 为确保其可量化请执行以下步骤 使用torch.quantization.fuse_modules熔断(Conv, BN, ReLU)(Conv, BN)和(Conv, ReLU)。将特征提取器与自定义顶端连接。这需要对特征提取器的输出进行反量化。在特征提取器的适当位置插入伪量化模块以模拟训练期间的量化。 对于步骤(1我们使用torchvision/models/quantization中的模型这些模型具有成员方法fuse_model。 此功能将所有convbn和relu模块融合在一起。 对于定制模型这将需要使用模块列表调用torch.quantization.fuse_modules API 进行手动融合。
步骤(2由上一节中使用的create_combined_model功能执行。
步骤(3通过使用torch.quantization.prepare_qat来实现它会插入伪量化模块。
在步骤(4中您可以开始“微调”模型然后将其转换为完全量化的版本(步骤 5。
要将微调模型转换为量化模型可以调用torch.quantization.convert函数(在本例中仅对特征提取器进行量化。
Note
由于随机初始化您的结果可能与本教程中显示的结果不同。
注意 citequantize False/cite model models.resnet18(pretrained Trueprogress Truequantize Falsenum_ftrs model.fc.in_features
步骤 1 model.train(model.fuse_model(步骤 2 model_ft create_combined_model(modelmodel_ft [0] .qconfig torch.quantization.default_qat_qconfig使用默认 QAT 配置步骤 3 model_ft torch.quantization.prepare_qat (model_ftinplace True
优化模型
在当前教程中整个模型都经过了微调。 通常这将导致更高的精度。 但是由于此处使用的训练集很小最终导致我们过度适应了训练集。
步骤 4.微调模型
for param in model_ft.parameters():param.requires_grad Truemodel_ft.to(device) # We can fine-tune on GPU if availablecriterion nn.CrossEntropyLoss()# Note that we are training everything, so the learning rate is lower
# Notice the smaller learning rate
optimizer_ft optim.SGD(model_ft.parameters(), lr1e-3, momentum0.9, weight_decay0.1)# Decay LR by a factor of 0.3 every several epochs
exp_lr_scheduler optim.lr_scheduler.StepLR(optimizer_ft, step_size5, gamma0.3)model_ft_tuned train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler,num_epochs25, devicedevice)
步骤 5.转换为量化模型
from torch.quantization import convert
model_ft_tuned.cpu()model_quantized_and_trained convert(model_ft_tuned, inplaceFalse)
让我们看看量化模型在几张图像上的表现
visualize_model(model_quantized_and_trained)plt.ioff()
plt.tight_layout()
plt.show()