杭州广众建设工程有限公司网站,数据库端口 wordpress,演示公司soap公司网站,网站开发合同里的坑分类任务实现模型#xff08;投票式#xff09;集成代码模版
简介
本实验使用上一博客的深度学习分类模型训练代码模板-CSDN博客#xff0c;自定义投票式集成#xff0c;手动实现模型集成#xff08;投票法#xff09;的代码。最后通过tensorboard进行可视化#xff0…分类任务实现模型投票式集成代码模版
简介
本实验使用上一博客的深度学习分类模型训练代码模板-CSDN博客自定义投票式集成手动实现模型集成投票法的代码。最后通过tensorboard进行可视化对每个基学习器的性能进行对比直观的看出模型集成的作用。
代码
# -*- coding:utf-8 -*-
import os
import torch
import torchvision
import torchmetrics
import torch.nn as nn
import my_utils as utils
import torchvision.transforms as transforms
from torch.utils.tensorboard import SummaryWriter
from torch.utils.data import DataLoader
from torchensemble.utils import set_module
from torchensemble.voting import VotingClassifierclasses [plane, car, bird, cat, deer, dog, frog, horse, ship, truck]def get_args_parser(add_helpTrue):import argparseparser argparse.ArgumentParser(descriptionPyTorch Classification Training, add_helpadd_help)parser.add_argument(--data-path, defaultrE:\Pytorch-Tutorial-2nd\data\datasets\cifar10-office, typestr,helpdataset path)parser.add_argument(--model, defaultresnet8, typestr, helpmodel name)parser.add_argument(--device, defaultcuda, typestr, helpdevice (Use cuda or cpu Default: cuda))parser.add_argument(-b, --batch-size, default128, typeint, helpimages per gpu, the total batch size is $NGPU x batch_size)parser.add_argument(--epochs, default200, typeint, metavarN, helpnumber of total epochs to run)parser.add_argument(-j, --workers, default4, typeint, metavarN, helpnumber of data loading workers (default: 16))parser.add_argument(--opt, defaultSGD, typestr, helpoptimizer)parser.add_argument(--random-seed, default42, typeint, helprandom seed)parser.add_argument(--lr, default0.1, typefloat, helpinitial learning rate)parser.add_argument(--momentum, default0.9, typefloat, metavarM, helpmomentum)parser.add_argument(--wd,--weight-decay,default1e-4,typefloat,metavarW,helpweight decay (default: 1e-4),destweight_decay,)parser.add_argument(--lr-step-size, default80, typeint, helpdecrease lr every step-size epochs)parser.add_argument(--lr-gamma, default0.1, typefloat, helpdecrease lr by a factor of lr-gamma)parser.add_argument(--print-freq, default80, typeint, helpprint frequency)parser.add_argument(--output-dir, default./Result, typestr, helppath to save outputs)parser.add_argument(--resume, default, typestr, helppath of checkpoint)parser.add_argument(--start-epoch, default0, typeint, metavarN, helpstart epoch)return parserdef main():args get_args_parser().parse_args()utils.setup_seed(args.random_seed)args.device torch.device(cuda if torch.cuda.is_available() else cpu)device args.devicedata_dir args.data_pathresult_dir args.output_dir# ------------------------------------ log ------------------------------------logger, log_dir utils.make_logger(result_dir)writer SummaryWriter(log_dirlog_dir)# ------------------------------------ step1: dataset ------------------------------------normMean [0.4948052, 0.48568845, 0.44682974]normStd [0.24580306, 0.24236229, 0.2603115]normTransform transforms.Normalize(normMean, normStd)train_transform transforms.Compose([transforms.Resize(32),transforms.RandomCrop(32, padding4),transforms.ToTensor(),normTransform])valid_transform transforms.Compose([transforms.ToTensor(),normTransform])# root变量下需要存放cifar-10-python.tar.gz 文件# cifar-10-python.tar.gz可从 https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz 下载train_set torchvision.datasets.CIFAR10(rootdata_dir, trainTrue, transformtrain_transform, downloadTrue)test_set torchvision.datasets.CIFAR10(rootdata_dir, trainFalse, transformvalid_transform, downloadTrue)# 构建DataLodertrain_loader DataLoader(datasettrain_set, batch_sizeargs.batch_size, shuffleTrue, num_workersargs.workers)valid_loader DataLoader(datasettest_set, batch_sizeargs.batch_size, num_workersargs.workers)# ------------------------------------ tep2: model ------------------------------------model_base utils.resnet20()# model_base utils.LeNet5()model MyEnsemble(estimatormodel_base, n_estimators3, loggerlogger, devicedevice, argsargs,classesclasses, writerwriter, save_dirlog_dir)model.set_optimizer(args.opt, lrargs.lr, weight_decayargs.weight_decay)model.fit(train_loader, test_loadervalid_loader, epochsargs.epochs)class MyEnsemble(VotingClassifier):def __init__(self, **kwargs):# logger, device, args, classes, writersuper(VotingClassifier, self).__init__(kwargs[estimator], kwargs[n_estimators])self.logger kwargs[logger]self.writer kwargs[writer]self.device kwargs[device]self.args kwargs[args]self.classes kwargs[classes]self.save_dir kwargs[save_dir]staticmethoddef save(model, save_dir, logger):Implement model serialization to the specified directory.if save_dir is None:save_dir ./if not os.path.isdir(save_dir):os.mkdir(save_dir)# Decide the base estimator nameif isinstance(model.base_estimator_, type):base_estimator_name model.base_estimator_.__name__else:base_estimator_name model.base_estimator_.__class__.__name__# {Ensemble_Model_Name}_{Base_Estimator_Name}_{n_estimators}filename {}_{}_{}_ckpt.pth.format(type(model).__name__,base_estimator_name,model.n_estimators,)# The real number of base estimators in some ensembles is not same as# n_estimators.state {n_estimators: len(model.estimators_),model: model.state_dict(),_criterion: model._criterion,}save_dir os.path.join(save_dir, filename)logger.info(Saving the model to {}.format(save_dir))# Savetorch.save(state, save_dir)returndef fit(self, train_loader, epochs100, log_interval100, test_loaderNone, save_modelTrue, save_dirNone, ):# 模型、优化器、学习率调整器、评估器 列表创建estimators []for _ in range(self.n_estimators):estimators.append(self._make_estimator())optimizers []schedulers []for i in range(self.n_estimators):optimizers.append(set_module.set_optimizer(estimators[i],self.optimizer_name, **self.optimizer_args))scheduler_ torch.optim.lr_scheduler.MultiStepLR(optimizers[i], milestones[100, 150],gammaself.args.lr_gamma) # 设置学习率下降策略# scheduler_ torch.optim.lr_scheduler.StepLR(optimizers[i], step_sizeself.args.lr_step_size,# gammaself.args.lr_gamma) # 设置学习率下降策略schedulers.append(scheduler_)acc_metrics []for i in range(self.n_estimators):# task类型与任务一致# num_classes与分类任务的类别数一致acc_metrics.append(torchmetrics.Accuracy(taskmulticlass, num_classeslen(self.classes)))self._criterion nn.CrossEntropyLoss()# epoch循环迭代best_acc 0.for epoch in range(epochs):# trainingfor model_idx, (estimator, optimizer, scheduler) in enumerate(zip(estimators, optimizers, schedulers)):loss_m_train, acc_m_train, mat_train \utils.ModelTrainerEnsemble.train_one_epoch(train_loader, estimator, self._criterion, optimizer, scheduler, epoch,self.device, self.args, self.logger, self.classes)# 学习率更新scheduler.step()# 记录self.writer.add_scalars(Loss_group, {train_loss_{}.format(model_idx):loss_m_train.avg}, epoch)self.writer.add_scalars(Accuracy_group, {train_acc_{}.format(model_idx):acc_m_train.avg}, epoch)self.writer.add_scalar(learning rate, scheduler.get_last_lr()[0], epoch)# 训练混淆矩阵图conf_mat_figure_train utils.show_conf_mat(mat_train, classes, train, save_dir, epochepoch,verboseepoch epochs - 1, saveFalse)self.writer.add_figure(confusion_matrix_train, conf_mat_figure_train, global_stepepoch)# validateloss_valid_meter, acc_valid, top1_group, mat_valid \utils.ModelTrainerEnsemble.evaluate(test_loader, estimators, self._criterion, self.device, self.classes)# 日志self.writer.add_scalars(Loss_group, {valid_loss:loss_valid_meter.avg}, epoch)self.writer.add_scalars(Accuracy_group, {valid_acc:acc_valid * 100}, epoch)# 验证混淆矩阵图conf_mat_figure_valid utils.show_conf_mat(mat_valid, classes, valid, save_dir, epochepoch,verboseepoch epochs - 1, saveFalse)self.writer.add_figure(confusion_matrix_valid, conf_mat_figure_valid, global_stepepoch)self.logger.info(Epoch: [{:03}/{:03}] Train Loss avg: {loss_train:6.4f} Valid Loss avg: {loss_valid:6.4f} Train Acc1 avg: {top1_train:7.2f}% Valid Acc1 avg: {top1_valid:7.2%} LR: {lr}.format(epoch, self.args.epochs, loss_trainloss_m_train.avg, loss_validloss_valid_meter.avg,top1_trainacc_m_train.avg, top1_validacc_valid, lrschedulers[0].get_last_lr()[0]))for model_idx, top1_meter in enumerate(top1_group):self.writer.add_scalars(Accuracy_group,{valid_acc_{}.format(model_idx): top1_meter.compute() * 100}, epoch)if acc_valid best_acc:best_acc acc_validself.estimators_ nn.ModuleList()self.estimators_.extend(estimators)if save_model:self.save(self, self.save_dir, self.logger)if __name__ __main__:main()效果图
本实验采用3个学习器进行投票式集成因此绘制了7条曲线其中各学习器在训练和验证各有2条曲线集成模型的结果通过 valid_acc输出蓝色通过下图可发现集成模型与三个基学习器相比分类准确率都能提高3-4百分点左右是非常高的提升了。 参考
7.7 TorchEnsemble 模型集成库 · PyTorch实用教程第二版 (tingsongyu.github.io)