深度集成学习不均衡样本图像分类

用五个不同的网络,然后对分类概率进行平均,得到分类结果。基本上分类精度可以提升10%

1.导入基本库

import torch
import copy
import torch.nn as nn
import torchvision.models as models
from torchvision import datasets
from torchvision import transforms
from tqdm import tqdm
from torch.utils.data import DataLoader
from torch.utils.data import random_split
from transformers import AutoModelForImageClassification,AutoConfig

2.数据集准备

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 数据预处理
transform = transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),  
])train_dataset = datasets.ImageFolder(root='./aug_datasets1', transform=transform)
dataset_size  = len(train_dataset)train_size = int(0.8 * dataset_size)
val_size = dataset_size - train_sizetrain_dataset, val_dataset = random_split(train_dataset, [train_size, val_size])train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)
val_dataloader = DataLoader(val_dataset, batch_size=32, shuffle=False)

3.定义不同模型与对应的训练策略

模型1 ResNet

class ResNet(nn.Module):def __init__(self, num_classes=21,train=True):super(ResNet, self).__init__()if(train):self.resnet = models.resnet50(weights=torchvision.models.ResNet50_Weights.IMAGENET1K_V1)else:self.resnet = models.resnet50(weights=None)in_features = self.resnet.fc.in_featuresself.resnet.fc = nn.Sequential(nn.Linear(in_features, 512),nn.ReLU(inplace=True),nn.Dropout(0.5),nn.Linear(512, num_classes))self.resnet.to(device)def forward(self, x):return self.resnet(x)# 训练策略def startTrain(self, train_loader, val_loader):criterion = nn.CrossEntropyLoss()optimizer = torch.optim.AdamW(self.parameters(), lr=1e-4, weight_decay=1e-4)scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=50)Best_Acc = 0.0print("Training ResNet.....")for epoch in range(10):  # 训练 10 个 epochself.train()train_loss = 0for batch in tqdm(train_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)optimizer.zero_grad()# 处理图像并将其传递给模型logits = self(images)# 计算损失并进行反向传播loss = criterion(logits, labels)loss.backward()optimizer.step()train_loss += loss.item()print(f"Epoch {epoch+1}/{10}, Train Loss: {train_loss/len(train_loader)}")scheduler.step()self.eval()val_loss = 0correct = 0total = 0with torch.no_grad():for batch in tqdm(val_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)# 处理图像并传递给模型logits = self(images)# 计算损失loss = criterion(logits, labels)val_loss += loss.item()# 计算准确率_, predicted = torch.max(logits, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f"Validation Loss: {val_loss/len(val_loader)}")print(f"Accuracy: {100 * correct / total}%")if(100 * correct / total > Best_Acc):Best_Acc = 100 * correct / totaltorch.save(self.state_dict(), './saved/resnet/model_weights_{}.pth'.format(Best_Acc))

模型2 EfficientNet

class EfficientNet(nn.Module):def __init__(self, num_classes=21,train=True):super(EfficientNet, self).__init__()if(train):self.effnet = models.efficientnet_b2(weights=torchvision.models.EfficientNet_B2_Weights.IMAGENET1K_V1)else:self.effnet = models.efficientnet_b2(weights=None)in_features = self.effnet.classifier[1].in_featuresself.effnet.classifier = nn.Sequential(nn.Linear(in_features, 512),nn.ReLU(inplace=True),nn.Dropout(0.5),nn.Linear(512, num_classes))self.effnet.to(device)def forward(self, x):return self.effnet(x)# 训练策略def startTrain(self, train_loader, val_loader):# 焦点损失,gamma参数增强对少数类的关注criterion = nn.CrossEntropyLoss()optimizer = torch.optim.AdamW(self.parameters(), lr=1e-4, weight_decay=1e-4)scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=5)Best_Acc = 0.0print("Training EfficientNet.....")for epoch in range(10):  # 训练 10 个 epochself.train()train_loss = 0for batch in tqdm(train_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)optimizer.zero_grad()# 处理图像并将其传递给模型logits = self(images)# 计算损失并进行反向传播loss = criterion(logits, labels)loss.backward()optimizer.step()train_loss += loss.item()print(f"Epoch {epoch+1}/{10}, Train Loss: {train_loss/len(train_loader)}")scheduler.step(train_loss/len(train_loader))self.eval()val_loss = 0correct = 0total = 0with torch.no_grad():for batch in tqdm(val_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)# 处理图像并传递给模型logits = self(images)# 计算损失loss = criterion(logits, labels)val_loss += loss.item()# 计算准确率_, predicted = torch.max(logits, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f"Validation Loss: {val_loss/len(val_loader)}")print(f"Accuracy: {100 * correct / total}%")if(100 * correct / total > Best_Acc):Best_Acc = 100 * correct / totaltorch.save(self.state_dict(), './saved/efficientnet/model_weights_{}.pth'.format(Best_Acc))    

模型3 DenseNet

class DenseNet(nn.Module):def __init__(self, num_classes=21, train=True):super(DenseNet, self).__init__()self.num_classes = num_classesif(train):self.densenet = models.densenet121(weights=torchvision.models.DenseNet121_Weights.IMAGENET1K_V1)else:self.densenet = models.densenet121(weights=None) in_features = self.densenet.classifier.in_featuresself.densenet.classifier = nn.Sequential(nn.BatchNorm1d(in_features),nn.Linear(in_features, 512),nn.ReLU(inplace=True),nn.Dropout(0.5),nn.Linear(512, num_classes))self.densenet.to(device)def forward(self, x):return self.densenet(x)# 训练策略def startTrain(self, train_loader, val_loader):criterion = nn.CrossEntropyLoss()optimizer = torch.optim.Adam(self.parameters(), lr=1e-4)scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=50)Best_Acc = 0.0print("Training DenseNet.....")for epoch in range(10):  # 训练 10 个 epochself.train()train_loss = 0for batch in tqdm(train_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)optimizer.zero_grad()# 处理图像并将其传递给模型logits = self(images)# 计算损失并进行反向传播loss = criterion(logits, labels)loss.backward()optimizer.step()train_loss += loss.item()print(f"Epoch {epoch+1}/{10}, Train Loss: {train_loss/len(train_loader)}")scheduler.step()self.eval()val_loss = 0correct = 0total = 0with torch.no_grad():for batch in tqdm(val_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)# 处理图像并传递给模型logits = self(images)# 计算损失loss = criterion(logits, labels)val_loss += loss.item()# 计算准确率_, predicted = torch.max(logits, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f"Validation Loss: {val_loss/len(val_loader)}")print(f"Accuracy: {100 * correct / total}%")if(100 * correct / total > Best_Acc):Best_Acc = 100 * correct / totaltorch.save(self.state_dict(), './saved/densenet/model_weights_{}.pth'.format(Best_Acc))        

 模型4 ResNeXt

class ResNeXt(nn.Module):def __init__(self, num_classes=21,train=True):super(ResNeXt, self).__init__()if(train):self.resnext50 = models.resnext50_32x4d(weights=torchvision.models.ResNeXt50_32X4D_Weights.IMAGENET1K_V1)else:self.resnext50 = models.resnext50_32x4d(weights=None)in_features = self.resnext50.fc.in_featuresself.resnext50.fc = nn.Sequential(nn.BatchNorm1d(in_features),nn.Linear(in_features, 512),nn.ReLU(inplace=True),nn.Dropout(0.5),nn.Linear(512, num_classes))self.resnext50.to(device)self.to(device)def forward(self, x):return self.resnext50(x)def startTrain(self, train_loader, val_loader):optimizer = torch.optim.AdamW(self.parameters(), lr=1e-4)scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=5e-4, epochs=30, steps_per_epoch=len(train_loader))        criterion = nn.CrossEntropyLoss()Best_Acc = 0.0print("Training ResNeXt.....")for epoch in range(10):  # 训练 10 个 epochself.train()train_loss = 0for batch in tqdm(train_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)optimizer.zero_grad()# 处理图像并将其传递给模型logits = self(images)# 计算损失并进行反向传播loss = criterion(logits, labels)loss.backward()optimizer.step()train_loss += loss.item()print(f"Epoch {epoch+1}/{10}, Train Loss: {train_loss/len(train_loader)}")scheduler.step(train_loss/len(train_loader))self.eval()val_loss = 0correct = 0total = 0with torch.no_grad():for batch in tqdm(val_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)# 处理图像并传递给模型logits = self(images)# 计算损失loss = criterion(logits, labels)val_loss += loss.item()# 计算准确率_, predicted = torch.max(logits, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f"Validation Loss: {val_loss/len(val_loader)}")print(f"Accuracy: {100 * correct / total}%")if(100 * correct / total > Best_Acc):Best_Acc = 100 * correct / totaltorch.save(self.state_dict(), './saved/se-resnext/model_weights_{}.pth'.format(Best_Acc))           

模型5 SwinTransformer

class SwinTransformer(nn.Module):def __init__(self, num_classes=21,train=True):super(SwinTransformer, self).__init__()if(train):self.vit = AutoModelForImageClassification.from_pretrained('./swinv2-tiny-patch4-window16-256/models--microsoft--swinv2-tiny-patch4-window16-256/snapshots/f4d3075206f2ad5eda586c30d6b4d0500f312421/')   #这个地方怎么写加载模型self.vit.classifier = nn.Sequential(nn.Dropout(0.5),nn.Linear(self.vit.classifier.in_features, num_classes))# 冻结Swin Transformer模型中的所有层for param in self.vit.parameters():param.requires_grad = False        # 只解冻最后两个Transformer块和分类头for param in self.vit.swinv2.encoder.layers[-4:].parameters():  # 假设你想解冻最后两层param.requires_grad = Truefor param in self.vit.classifier.parameters():param.requires_grad = Trueelse:# 先加载 config,然后手动修改 num_labelsconfig = AutoConfig.from_pretrained('./saved/swin-transformer/')config.num_labels = 21self.vit = AutoModelForImageClassification.from_pretrained('./saved/swin-transformer/',config=config)   self.vit.to(device)def forward(self, x):return self.vit(x)# 训练策略def startTrain(self, train_loader, val_loader):# 使用标签平滑处理,考虑到类别是连续尺度criterion = nn.CrossEntropyLoss()# 两阶段训练策略# 阶段1: 只训练解冻的层num_epochs_stage1 = 10num_epochs_stage2 = 10optimizer_stage1 = torch.optim.AdamW([p for p in self.parameters() if p.requires_grad], lr=1e-3)scheduler_stage1 = torch.optim.lr_scheduler.OneCycleLR(optimizer_stage1, max_lr=1e-3, epochs=num_epochs_stage1, steps_per_epoch=len(train_loader))best_model_wts = copy.deepcopy(self.state_dict())print("Training SwinTransformer.....") print("===== Stage 1 Training =====")Best_Acc = 0.0for epoch in range(num_epochs_stage1):  # 训练 10 个 epochself.train()train_loss = 0for batch in tqdm(train_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)optimizer_stage1.zero_grad()# 处理图像并将其传递给模型outputs = self(images)logits = outputs.logits# 计算损失并进行反向传播loss = criterion(logits, labels)loss.backward()optimizer_stage1.step()train_loss += loss.item()print(f"Epoch {epoch+1}/{10}, Train Loss: {train_loss/len(train_loader)}")scheduler_stage1.step()self.eval()val_loss = 0correct = 0total = 0with torch.no_grad():for batch in tqdm(val_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)# 处理图像并传递给模型outputs = self(images)logits = outputs.logits# 计算损失loss = criterion(logits, labels)val_loss += loss.item()# 计算准确率_, predicted = torch.max(logits, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f"Validation Loss: {val_loss/len(val_loader)}")print(f"Accuracy: {100 * correct / total}%")if(100 * correct / total > Best_Acc):Best_Acc = 100 * correct / totalbest_model_wts = copy.deepcopy(self.state_dict())self.vit.save_pretrained('./saved/swin-transformer/', safe_serialization=False)       # 阶段1结束后加载最佳模型权重self.load_state_dict(best_model_wts)    Best_Acc = 0.0print("===== Stage 2 Training =====")# 阶段2: 微调整个网络for param in self.parameters():param.requires_grad = Trueoptimizer_stage2 = torch.optim.Adam(self.parameters(), lr=1e-6)scheduler_stage2 = torch.optim.lr_scheduler.OneCycleLR(optimizer_stage2, max_lr=5e-6, epochs=num_epochs_stage2, steps_per_epoch=len(train_loader))for epoch in range(num_epochs_stage2):  # 训练 10 个 epochself.train()train_loss = 0for batch in tqdm(train_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)optimizer_stage2.zero_grad()# 处理图像并将其传递给模型outputs = self(images)logits = outputs.logits# 计算损失并进行反向传播loss = criterion(logits, labels)loss.backward()optimizer_stage2.step()train_loss += loss.item()print(f"Epoch {epoch+1}/{10}, Train Loss: {train_loss/len(train_loader)}")scheduler_stage2.step()self.eval()val_loss = 0correct = 0total = 0with torch.no_grad():for batch in tqdm(val_loader):images, labels = batchimages, labels = images.to(device), labels.to(device)# 处理图像并传递给模型outputs = self(images)logits = outputs.logits# 计算损失loss = criterion(logits, labels)val_loss += loss.item()# 计算准确率_, predicted = torch.max(logits, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f"Validation Loss: {val_loss/len(val_loader)}")print(f"Accuracy: {100 * correct / total}%")if(100 * correct / total > Best_Acc):Best_Acc = 100 * correct / totalself.vit.save_pretrained('./saved/swin-transformer/', safe_serialization=False)       

4.分别训练,然后得到权重

    swinTransformer= SwinTransformer()swinTransformer.startTrain(train_dataloader,val_dataloader)efficientNet= EfficientNet()efficientNet.startTrain(train_dataloader,val_dataloader)resNet= ResNet()resNet.startTrain(train_dataloader,val_dataloader)resNeXt= ResNeXt()resNeXt.startTrain(train_dataloader,val_dataloader)denseNet= DenseNet()denseNet.startTrain(train_dataloader,val_dataloader)

5.构建集成分类模型

import torch
import torchvision.transforms as transforms
import torch.nn as nn
from torchvision import datasets
from torchvision import transforms
from tqdm import tqdm
from torch.utils.data import DataLoader
from torch.utils.data import random_split
from tqdm import tqdm
from PIL import Imagedef remove_prefix_from_state_dict(state_dict, prefix='resnext.'):return {"resnext50." + k[len(prefix):] if k.startswith(prefix) else k: v for k, v in state_dict.items()}# 定义集成模型
class EnsembleModel():def __init__(self, efficientNet, resNet, resNeXt, denseNet,swinTransformer):super(EnsembleModel, self).__init__()self.efficientNet= efficientNet.eval()self.resNet= resNet.eval()self.resNeXt= resNeXt.eval()self.denseNet= denseNet.eval()self.swinTransformer= swinTransformer.eval()def predict(self, x):efficientNet_out = torch.softmax(self.efficientNet(x),dim=1)resNet_out = torch.softmax(self.resNet(x),dim=1)resNeXt_out = torch.softmax(self.resNeXt(x),dim=1)denseNet_out = torch.softmax(self.denseNet(x),dim=1)swinTransformer_out = torch.softmax(self.swinTransformer(x).logits,dim=1)avg_pred = (efficientNet_out + resNet_out + resNeXt_out + denseNet_out + swinTransformer_out ) / 5return avg_pred

这样就可以提升性能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/901069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始学java--泛型

泛型 目录 泛型 引入 泛型类 泛型与多态 泛型方法 泛型的界限 类型擦除 函数式接口 Supplier供给型函数式接口: Consumer消费型函数式接口: Function函数型函数式接口: Predicate断言式函数式接口: 判空包装 引入 …

5️⃣ Coze+AI应用基础教学(2025年全新版本)

目录 一、了解应用开发 1.1 扣子应用能做什么 1.2 开发流程 1.3 开发环境 二、快速搭建一个AI应用 2.1 AI翻译应用介绍 2.2 设计你的应用功能 2.3 创建 AI 应用项目 2.4 编写业务逻辑(新建工作流) 2.5 搭建用户界面 2.6 效果测试 2.7 发布应用 一、了解应用开发 …

工会成立100周年纪念,开发职工健身AI运动小程序、APP方案推荐

时光荏苒,转眼间2025年五一将至,这一年对于中华全国总工会而言,具有非凡的历史意义——它将迎来成立100周年的辉煌时刻。为了庆祝这一盛事,各级工会组织将精心筹备了一系列丰富多彩、形式多样的纪念活动,旨在展现工会百…

【深度学习】Ubuntu 服务器配置开源项目FIGRET(PyTorch、torch-scatter、torch-sparse、Gurobi 安装)

开源项目网址:https://github.com/FIGRET/figret 该项目在SIGCOMM2024发表,用深度学习方法处理流量工程中的突发问题 1. 创建新的 Conda 环境 使用国内镜像源创建环境​ conda create -n figret python3.8.0 --override-channels -c https://mirrors.…

【SpringCloud】从入门到精通(上)

今天主播我把黑马新版微服务课程MQ高级之前的内容都看完了,虽然在看视频的时候也记了笔记,但是看完之后还是忘得差不多了,所以打算写一篇博客再温习一下内容。 课程坐标:黑马程序员SpringCloud微服务开发与实战 微服务 认识单体架构 单体架…

MySQL中动态生成SQL语句去掉所有字段的空格

在MySQL中动态生成SQL语句去掉所有字段的空格 在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况。其中,去掉字段中的空格是一项常见的操作。当表中的字段数量较少时,我们可以手动编写 UPDATE 语句来处理。但如果表中包…

【Grok 大模型深度解析】第二期:架构探秘与训练哲学

在上一期的内容中,我们对 Grok 大模型从技术溯源的角度,了解了它从 Transformer 架构局限性出发,迈向混合架构创新的历程,同时也梳理了从 Grok - 1 到 Grok - 3 的版本迭代所带来的技术跃迁以及其独特的差异化优势。这一期,我们将深入到 Grok 大模型的架构内部,探究其精妙…

c# 使用NPOI将datatable的数据导出到excel

以下是使用 NPOI 库 将 DataTable 数据导出到 Excel 的详细步骤和代码示例(支持 .xls 和 .xlsx 格式): 步骤 1:安装 NPOI NuGet 包 Install-Package NPOI Install-Package NPOI.OOXML # 若需导出 .xlsx 格式 步骤 2:完整代码实现 using NPOI.SS.UserModel; using NPOI.…

基于SpringBoot的求职招聘网站系统(源码+数据库)

473基于SpringBoot的求职招聘网站系统,本系统共分为2个角色:系统管理员、用户,主要功能如下 【前台功能】 用户角色功能: 1. 注册和登录:注册账户并登录系统,以便访问更多功能。 2. 个人信息管理&#x…

CSS 过渡与变形:让交互更丝滑

在网页设计中,动效能让用户交互更自然、流畅,提升使用体验。本文将通过 CSS 的 transition(过渡)和 transform(变形)属性,带你入门基础动效设计,结合案例演示如何实现颜色渐变、元素…

rqlite:一个基于SQLite构建的分布式数据库

今天给大家介绍一个基于 SQLite 构建的轻量级分布式关系型数据库:rqlite。 rqlite 基于 Raft 协议,结合了 SQLite 的简洁性以及高可用分布式系统的稳健性,对开发者友好,操作极其简便,其核心设计理念是以最低的复杂度实…

mujoco graspnet 仿真项目的复现记录

开源项目:https://gitee.com/chaomingsanhua/manipulator_grasp 复现使用的配置:linux系统ubuntu20.04 项目配置记录: git clone 对应的code后: 需要在graspnet-baseline文件夹中继续拉取文件,指令记录:…

【js面试题】new操作做了什么?

这些年也面试了一些外包同事,不知道其他面试官的想法,但就我而言,我更喜欢听到的是口述代码的方式: 比如下述代码 function Animal(age) {this.age age; // 设置新对象的属性 }const cat new Animal("8");最有效的回…

freecad内部python来源 + pip install 装包

cmake来源: 只能find默认地址,我试过用虚拟的python地址提示缺python3config.cmake python解释器位置: python控制台位置: pip install 装包: module_to_install "your pakage" import os import FreeCAD …

树和图论【详细整理,简单易懂!】(C++实现 蓝桥杯速查)

树和图论 树的遍历模版 #include <iostream> #include <cstring> #include <vector> #include <queue> // 添加queue头文件 using namespace std;const int MAXN 100; // 假设一个足够大的数组大小 int ls[MAXN], rs[MAXN]; // 定义左右子树数…

展讯android15源码编译之apk单编

首先找到你要单编的apk生成的路径&#xff1a; sys\out_system\target\product\ussi_arm64\system_ext\app\HelloDemo\HelloDemo.apk接着打开下面这个文件&#xff1a; sys\out_system\ussi_arm64_full-userdebug-gms.system.build.log在里面找关键字"Running command&q…

如何关闭MacOS中鼠标滚轮滚动加速

一、背景 想要关闭滚轮的 “滚动加速”&#xff0c;即希望滚动了多少就对应滚动页面固定行数&#xff0c;现在macOS是加速滚动的&#xff0c;即滚动相同的角度会根据你滚动滚轮的速度不同最终页面滚动的幅度不同。这点很烦&#xff0c;常导致很难定位。 macOS本身的设置是没有…

河北工程大学e2e平台,python

题目&#xff0c;选择题包100分&#xff01; 题目&#xff0c;选择题包100分&#xff01; 题目&#xff0c;选择题包100分&#xff01; 联系&#x1f6f0;&#xff1a;18039589633

【蓝桥杯】贪心算法

1. 区间调度 1.1. 题目 给定个区间,每个区间由开始时间start和结束时间end表示。请选择最多的互不重叠的区间,返回可以选择的区间的最大数量。 输入格式: 第一行包含一个整数n,表示区间的数量 接下来n行,每行包含两个整数,分别表示区间的开始时间和结束时间 输出格式:…

一维差分数组

2.一维差分 - 蓝桥云课 问题描述 给定一个长度为 n 的序列 a。 再给定 m 组操作&#xff0c;每次操作给定 3 个正整数 l, r, d&#xff0c;表示对 a_{l} 到 a_{r} 中的所有数增加 d。 最终输出操作结束后的序列 a。 ​​Update​​: 由于评测机过快&#xff0c;n, m 于 20…