多模型融合预测

多模型融合预测:

多模型融合预测可以理解为1+1>2, 例如:
模型1预测结果:1111 1100 11 --> acc: 80%
模型2预测结果:1100 1111 00 --> acc: 60%
模型3预测结果:1111 0010 11 --> acc: 70%
3模型合在一起: 1111 1110 11 --> acc: 90%

代码

muti_test.py

import numpy as np
import pandas as pd
import pathlib, sys, os, random, time
import cv2, gc, glob
from tqdm import tqdm
import matplotlib.pyplot as plt

import albumentations as A

import segmentation_models_pytorch as smp
import glob
import torch
print(torch.cuda.is_available())
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.data as D

import torchvision
from torchvision import transforms as T

IMAGE_SIZE = 512
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'



trfm = A.Compose([
    A.Resize(IMAGE_SIZE, IMAGE_SIZE),
    A.HorizontalFlip(p=0.5),
    A.VerticalFlip(p=0.5),
    A.RandomRotate90(),
])

as_tensor = T.Compose([
            T.ToTensor(),
            T.Normalize([0.625, 0.448, 0.688],
                        [0.131, 0.177, 0.101]),
        ])


def rle_encode(im):
    pixels = im.flatten(order = 'F')
    pixels = np.concatenate([[0], pixels, [0]])
    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
    runs[1::2] -= runs[::2]
    return ' '.join(str(x) for x in runs)

def rle_decode(mask_rle, shape=(512, 512)):
    s = mask_rle.split()
    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]
    starts -= 1
    ends = starts + lengths
    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)
    for lo, hi in zip(starts, ends):
        img[lo:hi] = 1
    return img.reshape(shape, order='F')

def get_model():
    model_path = './model_data/'
    model = []
    model1 = smp.Unet(
        encoder_name="efficientnet-b4",  # choose encoder, e.g. mobilenet_v2 or efficientnet-b7
        encoder_weights=None,  # use `imagenet` pretreined weights for encoder initialization
        in_channels=3,  # model input channels (1 for grayscale images, 3 for RGB, etc.)
        classes=1,  # model output channels (number of classes in your dataset)
    )
    model1.to(DEVICE)
    model1.load_state_dict(torch.load(model_path+'fold4_unet_model_new4_s.pth'))
    model1.eval()


    model2 = smp.PSPNet(
        encoder_name="efficientnet-b4",  # choose encoder, e.g. mobilenet_v2 or efficientnet-b7
        encoder_weights=None,  # use `imagenet` pretreined weights for encoder initialization
        in_channels=3,  # model input channels (1 for grayscale images, 3 for RGB, etc.)
        classes=1,  # model output channels (number of classes in your dataset)
    )
    model2.to(DEVICE)
    model2.load_state_dict(torch.load(model_path+'fold4_pspnet_model_new4_s.pth'))
    model2.eval()

    model.append(model1)
    model.append(model2)
    return model

# model = get_model()

trfm = T.Compose([
                    T.ToPILImage(),
                    T.Resize(IMAGE_SIZE),
                    T.ToTensor(),
                    T.Normalize([0.625, 0.448, 0.688],
                                [0.131, 0.177, 0.101]),
])

test_mask = pd.read_csv('../IAIL/test_a_samplesubmit.csv', sep='\t', names=['name', 'mask'])
test_mask['name'] = test_mask['name'].apply(lambda x: '../IAIL/test_a/test_a/' + x)

def single_test():
    subm = []
    model_path = './model_data/'
    model = smp.PSPNet(
        encoder_name="efficientnet-b4",  # choose encoder, e.g. mobilenet_v2 or efficientnet-b7
        encoder_weights=None,  # use `imagenet` pretreined weights for encoder initialization
        in_channels=3,  # model input channels (1 for grayscale images, 3 for RGB, etc.)
        classes=1,  # model output channels (number of classes in your dataset)
    )
    model.to(DEVICE)
    for idx, name in enumerate(tqdm(test_mask['name'].iloc[:])):
        image = cv2.imread(name)
        #image= trfm(image = image)["image"]
        #image =  as_tensor(image)
        image = trfm(image)
        model.load_state_dict(torch.load(model_path+'fold4_pspnet_model_new4_s.pth'))
        model.eval()
        with torch.no_grad():
            image = image.to(DEVICE)[None]
            print(image.shape)
            # score = model(image)['out'][0][0]
            score = model(image).squeeze()
            score_sigmoid = score.sigmoid().cpu().numpy()
            score_sigmoid = (score_sigmoid > 0.5).astype(np.uint8)
            score_sigmoid = cv2.resize(score_sigmoid, (512, 512))
            subm.append([name.split('/')[-1], rle_encode(score_sigmoid)])

    subm = pd.DataFrame(subm)
    subm.to_csv('./subtt_pspnet.csv', index=None, header=None, sep='\t')


def multi_test():
    subm = []
    for idx, name in enumerate(tqdm(test_mask['name'].iloc[:])):
        image = cv2.imread(name)
        image = trfm(image)
        with torch.no_grad():
            image = image.to(DEVICE)[None]

            pred1 = None
            pred2 = None
            fold_models = get_model()
            for i, fold_model in enumerate(fold_models):
                score1 = fold_model(image)[0][0]

                score2 = fold_model(torch.flip(image, [0, 3]))
                score2 = torch.flip(score2, [3, 0])[0][0]

                score3 = fold_model(torch.flip(image, [1, 2]))
                score3 = torch.flip(score3, [2, 1])[0][0]

                score4 = fold_model(torch.flip(image, [0, 2]))
                score4 = torch.flip(score4, [2, 0])[0][0]

                #score5 = fold_model(torch.flip(image, [0, 1]))
                #score5 = torch.flip(score4, [1, 0])[0][0]

                #score_mean = (score1 + score2 + score3 + score4 + score5) / 5.0
                score_mean = (score1 + score2 + score3 + score4) / 4.0

                if pred1 is None and i == 0:
                    pred1 = np.squeeze(score_mean)
                elif pred1 is not None and i == 0:
                    pred1 += np.squeeze(score_mean)
                elif pred2 is None and i == 1:
                    pred2 = np.squeeze(score_mean)
                else:
                    pred2 += np.squeeze(score_mean)

            #number of models
            weight1 = 1.2
            weight2 = 0.8
            pred = (pred1*weight1 + pred2 *weight2) / 2.0
            # pred = (pred1 + pred2) / 2.0

            score_sigmoid = pred.sigmoid().cpu().numpy()
            score_sigmoid = (score_sigmoid > 0.39).astype(np.uint8)
            score_sigmoid = (score_sigmoid > 0.5).astype(np.uint8)
            score_sigmoid = cv2.resize(score_sigmoid, (512, 512), interpolation = cv2.INTER_CUBIC)
        subm.append([name.split('/')[-1], rle_encode(score_sigmoid)])



    subm = pd.DataFrame(subm)
    subm.to_csv('./multi_submit2.csv', index=None, header=None, sep='\t')


if __name__ == '__main__':
    multi_test()
    # single_test()

结果

模型 F1_score
PSPNet 0.84
UNet 0.89
0.6UNet+0.4PSPNet 0.92
0.5UNet+0.5PSPNet 0.90

猜你喜欢

转载自blog.csdn.net/CharmsLUO/article/details/122510249