pytorch模型融合

本文介绍了如何使用PyTorch进行模型融合,特别是在验证码识别任务中,通过平均融合多个不同尺寸模型的输出来提高预测性能。代码示例展示了加载多个模型,对测试数据进行预处理,然后将每个模型的输出取平均值作为最终预测结果的过程。这种方法对于提升模型的综合预测能力十分有效。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


pytorch模型融合

做论文基本上用不到,但是,打比赛的人肯定常用,那就是模型融合。采用不同方式训练的模型一般表现不同,为了综合各个模型之间的差异,拿到最好的结果,我们一般会对模型的输出结果进行融合,而其融合结果在性能表现上都会有不同的提升。下面直接上代码。


一、思路

其实思路很简单,就是把网络输出结果取均值,当然,也可以分别赋予不同的权重。假设你有三个 模型,分别为A,B,C,取均值就是各占三分之一,那么,你想2:2:6也行,自己设参数就好,我记得还有其他的模型融合方式。比如,投票表决,这个我没去写,思路很简单,其实,就是分别得到每个模型的当前预测样本的类别,然后,少数服从多数。下面我展示一下我之前做验证码识别的比赛的模型融合代码。

这个验证码识别是多标签多分类问题,就是每张图4个字母,我们要做到的是预测出每个字母的类别,(区分大小写),意味着62*4=248个类别。就是248多分类问题。

二、使用步骤

代码如下(示例):

import os
import cv2 as cv
import torch
from PIL import Image
import torch.nn as nn
import numpy as np
from torchvision import transforms
import csv
from tqdm import tqdm
from captcha_dataset import CaptchaDataTest, img_loader

# 这就是62类别
source = [str(i) for i in range(0, 10)]
source += [chr(i) for i in range(97, 97 + 26)]
source += [chr(i) for i in range(65, 65 + 26)]
alphabet = ''.join(source)


def predict():

	这里是你自己的模型的路径,分别需要的输入图像的尺寸大小
    model_paths = {
        (160, 400): [
            '../b7/best_model.pth',
            ],
        (200, 440): [
            '../b6/best_model.pth',
            ],
        (220, 460): [
            '../b5/best_model.pth',
            ],
    }
    test_dir = '测试集路径'
    test_mean = [0.485, 0.456, 0.406]
    test_std = [0.229, 0.224, 0.225]
    
    print(torch.cuda.is_available())
    model_dict = {}
    for image_size, model_paths in model_paths.items():
        models = []
        for model_path in model_paths:
        	# 分别加载模型
            model = torch.load(model_path)
            if torch.cuda.is_available():
                model = model.cuda()
                model.eval()
            models.append(model)
        model_dict[image_size] = models

    dataset = sorted(os.listdir(test_dir), key=lambda x: int(x[:-4]))
    res = []
    for i, name in enumerate(tqdm(dataset)):
        path = os.path.join(test_dir, name)
        img = img_loader(path)
        scores = []
        for image_size, models in model_dict.items():
            transform = transforms.Compose([
                transforms.Resize(image_size),
                transforms.ToTensor(),
                transforms.Normalize(
                    mean=test_mean,
                    std=test_std
                )
            ])
            image = transform(img)[None, ...]
            image = image.cuda()
            with torch.no_grad():
                for model in models:
                	# 这里就是关键了,就是把当前的数据分别给模型。
                    outputs = model(image)
                    outputs = outputs.view(-1, 4, 62)  # 1, 4, 62
                    outputs = nn.functional.softmax(outputs, dim=-1).cpu().numpy()
                    # 先用一个scores存起来,每张图对应3个outputs,下一张图的时候,又重新创建一个scores
                    scores.append(outputs)
        # print(np.array(scores).max(axis=-1))
        # 最重要的一步,就是,把这个scores,按照行做均值处理。
        scores = np.mean(scores, axis=0)
        scores = np.argmax(scores, axis=-1)
        img_name = name[:-4]
        pred = ''.join([alphabet[i] for i in scores[0]])
        # print(img_name, pred)
        res.append({'num': int(img_name), 'tag': pred})

    header = ['num', 'tag']
    os.makedirs('sub', exist_ok=True)
    with open('../merge.csv', 'w', encoding='utf_8_sig') as f:
        f_csv = csv.DictWriter(f, header)
        f_csv.writeheader()
        f_csv.writerows(res)


if __name__ == '__main__':
    predict()


总结

这里如果采用权重融合的方式的话,就应该是分别设置不同的权重,在把它们和原始输出相乘,挨个加起来。在进行argmax操作。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yez1011

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值