【Pytorch 第四讲】图像分类的Tricks

2024-03-01 22:36

本文主要是介绍【Pytorch 第四讲】图像分类的Tricks,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 标签平滑

在分类问题中,最后一层一般是全连接层,然后对应标签的one-hot编码,即把对应类别的值编码为1,其他为0。这种编码方式和通过降低交叉熵损失来调整参数的方式结合起来,会有一些问题。这种方式会鼓励模型对不同类别的输出分数差异非常大,或者说,模型过分相信它的判断。但是,对于一个由多人标注的数据集,不同人标注的准则可能不同,每个人的标注也可能会有一些错误。模型对标签的过分相信会导致过拟合。

 标签平滑(Label-smoothing regularization,LSR)是应对该问题的有效方法之一,它的具体思想是降低我们对于标签的信任,例如我们可以将损失的目标值从1稍微降到0.9,或者将从0稍微升到0.1。

总的来说,LSR是一种通过在标签y中加入噪声,实现对模型约束,降低模型过拟合程度的一种正则化方法。

importtorch
importtorch.nn as nnclass LSR(nn.Module):def __init__(self, e=0.1, reduction='mean'):super().__init__()self.log_softmax = nn.LogSoftmax(dim=1)self.e = eself.reduction = reductiondef _one_hot(self, labels, classes, value=1):"""Convert labels to one hot vectorsArgs:labels: torch tensor in format [label1, label2, label3, ...]classes: int, number of classesvalue: label value in one hot vector, default to 1Returns:return one hot format labels in shape [batchsize, classes]"""one_hot = torch.zeros(labels.size(0), classes)#labels and value_added  size must matchlabels = labels.view(labels.size(0),  -1)value_added = torch.Tensor(labels.size(0),  1).fill_(value)value_added = value_added.to(labels.device)one_hot = one_hot.to(labels.device)one_hot.scatter_add_(1, labels, value_added)return one_hotdef _smooth_label(self, target, length, smooth_factor):"""convert targets to one-hot format, and smooth them.Args:target: target in form with [label1, label2, label_batchsize]length: length of one-hot format(number of classes)smooth_factor: smooth factor for label smoothReturns:smoothed labels in one hot format"""one_hot = self._one_hot(target, length, value=1  - smooth_factor)one_hot += smooth_factor / lengthreturn one_hot.to(target.device)

 2. 随即裁减拼接

随机图像裁剪和拼接(Random Image Cropping and Patching)是一种数据增强技术,广泛应用于计算机视觉任务,特别是在深度学习模型的训练过程中。这种技术通过随机地裁剪图像的区域以及对这些区域进行重新排列或拼接,来生成视觉上多样化的训练样本。其目的和作用主要包括以下几点:

1.增加数据多样性

在训练深度学习模型时,数据的多样性是非常重要的。随机图像裁剪和拼接通过创造出视觉上不同的图像样本,有助于增加训练数据的多样性。这种多样性可以帮助模型学习到更加泛化的特征,从而在面对未见过的数据时能够做出更好的预测。

2. 减少过拟合

过拟合是深度学习中常见的问题,发生在模型对训练数据学得太好,以至于失去了泛化能力,对新的、未见过的数据表现不佳。通过随机图像裁剪和拼接,每次训练时输入模型的图像都有所不同,这可以有效减少模型对特定图像细节的依赖,从而减少过拟合的风险。

3. 提高模型鲁棒性

通过随机变化图像的外观(如位置、尺寸和上下文),随机图像裁剪和拼接强迫模型学习到更加鲁棒的特征,这些特征对于图像的具体排列和外观不那么敏感。这样,模型在遇到新的、不同排列或裁剪的图像时,更有可能做出正确的识别和预测。

4. 支持不同尺寸的输入

在某些情况下,模型可能需要处理不同尺寸的输入图像。随机图像裁剪和拼接可以在一定程度上模拟这种情况,训练模型能够更好地处理不同大小的图像,无需对图像进行标准化的预处理步骤。

 代码: 裁减

import torch
from torchvision import transforms
from PIL import Image# 定义一个transform,其中包括随机裁剪和随机水平翻转
transform = transforms.Compose([transforms.RandomResizedCrop(size=(224, 224)),  # 随机裁剪到224x224transforms.RandomHorizontalFlip(),  # 随机水平翻转# 可以添加更多的transforms,例如转换到Tensor,标准化等transforms.ToTensor()
])# 打开图像
image = Image.open("path/to/your/image.jpg")# 应用transform
transformed_image = transform(image)# 因为transforms.ToTensor()将PIL图像转换为了Tensor,
# 我们需要使用matplotlib等库来可视化处理后的Tensor图像。
import matplotlib.pyplot as pltplt.imshow(transformed_image.permute(1, 2, 0))
plt.show()

 RICAP 代码:

beta =  0.3  # hyperparameter
for  (images, targets)  in train_loader:# get the image sizeI_x, I_y = images.size()[2:]# draw a boundry position (w, h)w = int(np.round(I_x * np.random.beta(beta, beta)))h = int(np.round(I_y * np.random.beta(beta, beta)))w_ =  [w, I_x - w, w, I_x - w]h_ =  [h, h, I_y - h, I_y - h]# select and crop four imagescropped_images =  {}c_ =  {}W_ =  {}for k in range(4):index = torch.randperm(images.size(0))x_k = np.random.randint(0, I_x - w_[k]  +  1)y_k = np.random.randint(0, I_y - h_[k]  +  1)cropped_images[k]  = images[index][:,  :, x_k:x_k + w_[k], y_k:y_k + h_[k]]c_[k]  = target[index].cuda()W_[k]  = w_[k]  * h_[k]  /  (I_x * I_y)# patch cropped imagespatched_images = torch.cat((torch.cat((cropped_images[0], cropped_images[1]),  2),torch.cat((cropped_images[2], cropped_images[3]),  2)),3)#patched_images = patched_images.cuda()# get outputoutput = model(patched_images)# calculate loss and accuracyloss = sum([W_[k]  * criterion(output, c_[k])  for k in range(4)])acc = sum([W_[k]  * accuracy(output, c_[k])[0]  for k in range(4)])

 3.知识蒸馏

提高几乎所有机器学习算法性能的一种非常简单的方法是在相同的数据上训练许多不同的模型,然后对它们的预测进行平均。但是使用所有的模型集成进行预测是比较麻烦的,并且可能计算量太大而无法部署到大量用户。Knowledge Distillation(知识蒸馏)方法就是应对这种问题的有效方法之一。

在知识蒸馏方法中,我们使用一个教师模型来帮助当前的模型(学生模型)训练。教师模型是一个较高准确率的预训练模型,因此学生模型可以在保持模型复杂度不变的情况下提升准确率。比如,可以使用ResNet-152作为教师模型来帮助学生模型ResNet-50训练。在训练过程中,我们会加一个蒸馏损失来惩罚学生模型和教师模型的输出之间的差异。

给定输入,假定p是真正的概率分布,z和r分别是学生模型和教师模型最后一个全连接层的输出。之前我们会用交叉熵损失l(p,softmax(z))来度量p和z之间的差异,这里的蒸馏损失同样用交叉熵。所以,使用知识蒸馏方法总的损失函数是

!pip install torch torchvision
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision.models as models# 定义学生模型
class StudentModel(nn.Module):def __init__(self):super(StudentModel, self).__init__()self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)self.pool = nn.MaxPool2d(2, 2)self.fc1 = nn.Linear(64 * 56 * 56, 128)self.fc2 = nn.Linear(128, 10)  # 假设是10分类任务def forward(self, x):x = F.relu(self.conv1(x))x = self.pool(F.relu(self.conv2(x)))x = torch.flatten(x, 1)x = F.relu(self.fc1(x))x = self.fc2(x)return x# 使用预训练的ResNet作为教师模型
teacher_model = models.resnet18(pretrained=True)# 初始化学生模型
student_model = StudentModel()def distillation_loss(y_student, y_teacher, T):"""计算蒸馏损失:param y_student: 学生模型的输出:param y_teacher: 教师模型的输出:param T: 温度参数:return: 蒸馏损失"""loss = F.kl_div(F.log_softmax(y_student / T, dim=1),F.softmax(y_teacher / T, dim=1),reduction='batchmean') * (T * T)return lossimport torch.optim as optim# 定义优化器和损失函数
optimizer = optim.SGD(student_model.parameters(), lr=0.001, momentum=0.9)
criterion = nn.CrossEntropyLoss()# 假设我们有一个数据加载器
# trainloader = ...# 训练学生模型
for epoch in range(10):  # 遍历数据集多次for inputs, labels in trainloader:optimizer.zero_grad()# 获取教师模型和学生模型的输出with torch.no_grad():outputs_teacher = teacher_model(inputs)outputs_student = student_model(inputs)# 计算蒸馏损失和分类损失loss_distillation = distillation_loss(outputs_student, outputs_teacher, T=20)loss_classification = criterion(outputs_student, labels)# 总损失是蒸馏损失和分类损失的加

 4. Cutout

Cutout是一种新的正则化方法。原理是在训练时随机把图片的一部分减掉,这样能提高模型的鲁棒性。它的来源是计算机视觉任务中经常遇到的物体遮挡问题。通过cutout生成一些类似被遮挡的物体,不仅可以让模型在遇到遮挡问题时表现更好,还能让模型在做决定时更多地考虑环境(context)。

import torch
import numpy as npclass  Cutout(object):"""Randomly mask out one or more patches from an image.Args:n_holes (int): Number of patches to cut out of each image.length (int): The length (in pixels) of each square patch."""def __init__(self, n_holes, length):self.n_holes = n_holesself.length = lengthdef __call__(self, img):"""Args:img (Tensor): Tensor image of size (C, H, W).Returns:Tensor: Image with n_holes of dimension length x length cut out of it."""h = img.size(1)w = img.size(2)mask = np.ones((h, w), np.float32)for n in range(self.n_holes):y = np.random.randint(h)x = np.random.randint(w)y1 = np.clip(y - self.length //  2,  0, h)y2 = np.clip(y + self.length //  2,  0, h)x1 = np.clip(x - self.length //  2,  0, w)x2 = np.clip(x + self.length //  2,  0, w)mask[y1: y2, x1: x2]  =  0.mask = torch.from_numpy(mask)mask = mask.expand_as(img)img = img * maskreturn img

 5. mixup training

Mixup training 是一种数据增强技术,用于提高深度学习模型的泛化能力和性能。这种技术最初由Hongyi Zhang, Moustapha Cisse, Yann N. Dauphin, David Lopez-Paz 在论文 "mixup: Beyond Empirical Risk Minimization" 中提出。Mixup 通过在图像和标签级别进行线性插值,生成新的训练样本,从而增加训练数据的多样性。

其中,λ是从Beta(α, α)随机采样的数,在[0,1]之间。在训练过程中,仅使用(xhat, yhat)。Mixup方法主要增强了训练样本之间的线性表达,增强网络的泛化能力,不过mixup方法需要较长的时间才能收敛得比较好。

实现1:

for  (images, labels)  in train_loader:l = np.random.beta(mixup_alpha, mixup_alpha)index = torch.randperm(images.size(0))images_a, images_b = images, images[index]labels_a, labels_b = labels, labels[index]mixed_images = l * images_a +  (1  - l)  * images_boutputs = model(mixed_images)loss = l * criterion(outputs, labels_a)  +  (1  - l)  * criterion(outputs, labels_b)acc = l * accuracy(outputs, labels_a)[0]  +  (1  - l)  * accuracy(outputs, labels_b)[0]

实现2:

for i,(images,target) in enumerate(train_loader):# 1.input outputimages = images.cuda(non_blocking=True)target = torch.from_numpy(np.array(target)).float().cuda(non_blocking=True)# 2.mixupalpha=config.alphalam = np.random.beta(alpha,alpha)#randperm返回1~images.size(0)的一个随机排列index = torch.randperm(images.size(0)).cuda()inputs = lam*images + (1-lam)*images[index,:]targets_a, targets_b = target, target[index]outputs = model(inputs)loss = lam * criterion(outputs, targets_a) + (1 - lam) * criterion(outputs, targets_b)# 3.backwardoptimizer.zero_grad()   # reset gradientloss.backward()

 6. AdaBound

AdaBound 是一种优化算法,旨在结合 Adam 优化器的快速收敛性和 SGD 优化器在训练后期的稳定性。AdaBound 通过动态调整每一步的学习率,使其在训练过程中逐渐从 Adam 转变为 SGD。这种方法的关键在于,它为每个参数设置了动态的学习率边界,以确保学习率不会过高或过低。AdaBound 最初由 Luo 等人在论文 "Adaptive Gradient Methods with Dynamic Bound of Learning Rate" 中提出。

1. AdaBound 与 AdamW 和 SGD 的区别

  • AdaBound:结合了 Adam 和 SGD 的优点,通过动态调整学习率边界来模仿 SGD 的学习率调度,旨在克服 Adam 在训练后期可能出现的性能下降问题。
  • AdamW:是 Adam 的一个变种,引入了权重衰减(L2 正则化)作为优化的一部分,而不是作为损失函数的一部分,以解决 Adam 优化器在正则化时可能出现的问题。
  • SGD:随机梯度下降,是最基本的优化算法,通常配合动量(Momentum)和学习率调度器使用,以加快收敛速度并提高模型的最终性能。

2. 安装adabound

pip install adabound

3. 使用adabound

optimizer = adabound.AdaBound(model.parameters(), lr=1e-3, final_lr=0.1)

7. AutoAugment

AutoAugment 是一种自动化的数据增强技术,主要应用于深度学习和机器学习领域,特别是在图像识别和处理任务中。其核心目标是自动发现最优的数据增强策略,从而提高模型的性能和泛化能力。数据增强是指在不改变原始数据标签的情况下,通过各种方法扩充训练数据集的技术,如旋转、翻转、缩放图像等,来提升模型对新未见数据的适应性和鲁棒性。

 AutoAugment 通过搜索最优的数据增强策略来实现自动化增强。它利用强化学习,特别是一种称为控制器的模型,来预测给定任务的最佳增强策略。这个控制器通过尝试不同的增强操作(如图像的色彩平衡调整、剪裁、旋转等)并观察它们对模型性能的影响,来学习哪些操作可以提高模型的准确率

  • 提高模型准确性:通过增加数据多样性,减少过拟合,使模型在未见过的数据上表现更好。
  • 减少手工调参需求:自动化寻找最佳数据增强策略,减轻了人工选择和调整数据增强方法的负担。
  • 增强模型泛化能力:更广泛的数据表示有助于模型在多种条件下保持性能,尤其是在现实世界的应用中。
"""AutoAugment data augmentation method based on`"AutoAugment: Learning Augmentation Strategies 
from Data" <https://arxiv.org/pdf/1805.09501.pdf>`_.If the image is torch Tensor, 
it should be of type torch.uint8, and it is expectedto have [..., 1 or 3, H, W] shape,where ... means an arbitrary number of leading dimensions.If img is PIL Image, it is expected to be in mode "L" or "RGB".Args:policy (AutoAugmentPolicy): Desired policy enum defined by:class:`torchvision.transforms.autoaugment.AutoAugmentPolicy`. Default is ``AutoAugmentPolicy.IMAGENET``.interpolation (InterpolationMode): Desired interpolation enum defined by:class:`torchvision.transforms.InterpolationMode`. Default is ``InterpolationMode.NEAREST``.If input is Tensor, only ``InterpolationMode.NEAREST``, ``InterpolationMode.BILINEAR`` are supported.fill (sequence or number, optional): Pixel fill value for the area outside the transformed

 

import torch
import torchvision
from torchvision import datasets, transforms
from torchvision.transforms import AutoAugment, AutoAugmentPolicy# 定义数据预处理和增强
#AutoAugmentPolicy 可以根据你的需求选择不同的策略(如 CIFAR10、SVHN 策略等)
transform = transforms.Compose([transforms.Resize((32, 32)),  # 调整图像大小AutoAugment(policy=AutoAugmentPolicy.IMAGENET),  # 应用 AutoAugment,这里以 ImageNet 策略为例transforms.ToTensor(),  # 将图像转换为 PyTorch 张量transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # 归一化
])# 加载数据集(以 CIFAR10 为例)
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)# 创建数据加载器
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)# 下面可以定义和训练你的模型...

这篇关于【Pytorch 第四讲】图像分类的Tricks的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/764055

相关文章

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

Verybot之OpenCV应用一:安装与图像采集测试

在Verybot上安装OpenCV是很简单的,只需要执行:         sudo apt-get update         sudo apt-get install libopencv-dev         sudo apt-get install python-opencv         下面就对安装好的OpenCV进行一下测试,编写一个通过USB摄像头采

用Pytho解决分类问题_DBSCAN聚类算法模板

一:DBSCAN聚类算法的介绍 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,DBSCAN算法的核心思想是将具有足够高密度的区域划分为簇,并能够在具有噪声的空间数据库中发现任意形状的簇。 DBSCAN算法的主要特点包括: 1. 基于密度的聚类:DBSCAN算法通过识别被低密

项目实战系列三: 家居购项目 第四部分

购物车 🌳购物车🍆显示购物车🍆更改商品数量🍆清空购物车&&删除商品 🌳生成订单 🌳购物车 需求分析 1.会员登陆后, 可以添加家居到购物车 2.完成购物车的设计和实现 3.每添加一个家居,购物车的数量+1, 并显示 程序框架图 1.新建src/com/zzw/furns/entity/CartItem.java, CartItem-家居项模型 /***

PMP–一、二、三模–分类–14.敏捷–技巧–看板面板与燃尽图燃起图

文章目录 技巧一模14.敏捷--方法--看板(类似卡片)1、 [单选] 根据项目的特点,项目经理建议选择一种敏捷方法,该方法限制团队成员在任何给定时间执行的任务数。此方法还允许团队提高工作过程中问题和瓶颈的可见性。项目经理建议采用以下哪种方法? 易错14.敏捷--精益、敏捷、看板(类似卡片)--敏捷、精益和看板方法共同的重点在于交付价值、尊重人、减少浪费、透明化、适应变更以及持续改善等方面。

【python计算机视觉编程——7.图像搜索】

python计算机视觉编程——7.图像搜索 7.图像搜索7.1 基于内容的图像检索(CBIR)从文本挖掘中获取灵感——矢量空间模型(BOW表示模型)7.2 视觉单词**思想****特征提取**: 创建词汇7.3 图像索引7.3.1 建立数据库7.3.2 添加图像 7.4 在数据库中搜索图像7.4.1 利用索引获取获选图像7.4.2 用一幅图像进行查询7.4.3 确定对比基准并绘制结果 7.

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法(KNN)8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特征8.4.3 多类支持向量机8.4.4 提取单元格并识别字符8.4.5 图像校正

Nn criterions don’t compute the gradient w.r.t. targets error「pytorch」 (debug笔记)

Nn criterions don’t compute the gradient w.r.t. targets error「pytorch」 ##一、 缘由及解决方法 把这个pytorch-ddpg|github搬到jupyter notebook上运行时,出现错误Nn criterions don’t compute the gradient w.r.t. targets error。注:我用

PMP–一、二、三模–分类–14.敏捷–技巧–原型MVP

文章目录 技巧一模14.敏捷--原型法--项目生命周期--迭代型生命周期,通过连续的原型或概念验证来改进产品或成果。每个新的原型都能带来新的干系人新的反馈和团队见解。题目中明确提到需要反馈,因此原型法比较好用。23、 [单选] 一个敏捷团队的任务是开发一款机器人。项目经理希望确保在机器人被实际建造之前,团队能够收到关于需求的早期反馈并相应地调整设计。项目经理应该使用以下哪一项来实现这个目标?