多模型融合预测:
多模型融合预测可以理解为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 |