传统的用于执行分类任务的深度学习模型,往往是解决的单分类任务,即为一幅图像只预测一个标签,但现实世界中往往一幅图像中通常是含有多个标签的 。Pytorch中分类任务常用的损失函数CrossEntropyLoss也是处理单标签数据的,无法实现多标签数据端到端的训练。在工作或日常实验中,我们经常会遇到一幅图像中含有多个标签的问题,我们需要怎样来处理呢?下面给出两个解决方案:1、即一幅图像包含几个标签就使这幅图像在一个epoch训练中出现多少次,但每次参与训练时该图像对应的标签是不同的,这种方法是最简单的;2、使用Pytorch的BCELoss,该损失函数支持一幅图像对应多个标签的输入,输入的标签为一组0和1组成的向量。
许多小伙伴咨询如何计算模型的准确率,前段时间一直在忙别的项目,趁着五一假期,将计算模型准确率的方法补全了。补充了两种模型性能计算的方法:1、calculate_acuracy_mode_one(model_pred, labels)函数:需要人为的设定一个阈值,当模型的预测结果(经过sigmoid函数处理的模型输出结果可以视为预测结果为这一类的概率)大于这个阈值则视为图像中含有这一类物体;2、calculate_acuracy_mode_two(model_pred, labels)函数:需要人为的设定每幅图像中含有多少类物体(即:矬子里面拔大个,选择预测概率最大的预测结果作为预测结果),实验中大家可以根据自己的需求选取不同的模型性能计算方式。
首先需要为你的数据集生成一个txt文件,用来存储图像的名称与标签,图像中包含该标签则为1,否则为0。如下所示:
废话不多说,直接上代码:
from PIL import Image
from torch.utils.data import Dataset, DataLoader
import torch
import torch.nn as nn
from torch.optim import lr_scheduler
from torchvision import datasets, models, transforms
import time
import os
# 是否使用gpu运算
use_gpu = torch.cuda.is_available()
# 定义数据的处理方式
data_transforms = {
'train': transforms.Compose([
# 将图像进行缩放,缩放为256*256
transforms.Resize(256),
# 在256*256的图像上随机裁剪出227*227大小的图像用于训练
transforms.RandomResizedCrop(227),
# 图像用于翻转
transforms.RandomHorizontalFlip(),
# 转换成tensor向量
transforms.ToTensor(),
# 对图像进行归一化操作
# [0.485, 0.456, 0.406],RGB通道的均值与标准差
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
# 测试集需要中心裁剪,甚至不裁剪,直接缩放为224*224for,不需要翻转
'val': transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(227),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.22