Kaggle competition: RANZCR CLiP - Catheter and Line Position Challenge
!cp -r.. /input/yolov5train/* .<load_from_csv>
ROOT = Path.cwd().parent
INPUT = ROOT / "input"
OUTPUT = ROOT / "output"
DATA = INPUT / "ranzcr-clip-catheter-line-classification"
TRAIN = DATA / "train"
TEST = DATA / "test"
TRAINED_MODEL = INPUT/ 'ranzer-models'
TMP = ROOT / "tmp"
TMP.mkdir(exist_ok=True)
 RANDAM_SEED = 1086
N_CLASSES = 11
FOLDS = [0, 1, 2, 3, 4]
N_FOLD = len(FOLDS)
 IMAGE_SIZE =(640, 640)
 CONVERT_TO_RANK = False
FAST_COMMIT = True
CLASSES = [
'ETT - Abnormal',
'ETT - Borderline',
'ETT - Normal',
'NGT - Abnormal',
'NGT - Borderline',
'NGT - Incompletely Imaged',
'NGT - Normal',
'CVC - Abnormal',
'CVC - Borderline',
'CVC - Normal',
'Swan Ganz Catheter Present'
]
with open(".. /input/valdata/val4.txt")as f:
content = f.readlines()
` at the end of each line
content = [x.strip().split('/')[-1].split('.')[0] for x in content]
content<install_modules>
for p in DATA.iterdir() :
print(p.name)
 train = pd.read_csv(DATA / "train.csv")
 smpl_sub = pd.read_csv(DATA / "sample_submission.csv" )
!pip install --no-deps '.. /input/weightedboxesfusion/' > /dev/null<feature_engineering>
if FAST_COMMIT and len(smpl_sub)== 3582:
smpl_sub = smpl_sub.iloc[:64 * 2].reset_index(drop=True )
def convertTrainLabel() :
df = pd.read_csv('.. /input/global-wheat-detection/train.csv')
 bboxs = np.stack(df['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))
 for i, column in enumerate(['x', 'y', 'w', 'h']):
df[column] = bboxs[:,i]
df.drop(columns=['bbox'], inplace=True)
 df['x_center'] = df['x'] + df['w']/2
df['y_center'] = df['y'] + df['h']/2
df['classes'] = 0
df = df[['image_id','x', 'y', 'w', 'h','x_center','y_center','classes']]
index = list(set(df.image_id))
source = 'train'
if True:
for fold in [0]:
val_index = index[len(index)*fold//5:len(index)*(fold+1)//5]
for name,mini in tqdm(df.groupby('image_id')) :
if name in content:
path2save = 'val2017/'
else:
path2save = 'train2017/'
if not os.path.exists('convertor/fold{}/labels/'.format(fold)+path2save):
os.makedirs('convertor/fold{}/labels/'.format(fold)+path2save)
 with open('convertor/fold{}/labels/'.format(fold)+path2save+name+".txt", 'w+')as f:
row = mini[['classes','x_center','y_center','w','h']].astype(float ).values
row = row/1024
row = row.astype(str)
 for j in range(len(row)) :
text = ' '.join(row[j])
 f.write(text)
 f.write("
")
 if not os.path.exists('convertor/fold{}/images/{}'.format(fold,path2save)) :
os.makedirs('convertor/fold{}/images/{}'.format(fold,path2save))
sh.copy(".. /input/global-wheat-detection/{}/{}.jpg".format(source,name),'convertor/fold{}/images/{}/{}.jpg'.format(fold,path2save,name)) 
<compute_train_metric>
def multi_label_stratified_group_k_fold(label_arr: np.array, gid_arr: np.array, n_fold: int, seed: int=42):

 np.random.seed(seed)
 random.seed(seed)
 start_time = time.time()
n_train, n_class = label_arr.shape
gid_unique = sorted(set(gid_arr))
n_group = len(gid_unique)
 gid2aid = dict(zip(gid_unique, range(n_group)))
 aid_arr = np.vectorize(lambda x: gid2aid[x] )(gid_arr)
 cnts_by_class = label_arr.sum(axis=0)
 col, row = np.array(sorted(enumerate(aid_arr), key=lambda x: x[1])).T
cnts_by_group = coo_matrix(
(np.ones(len(label_arr)) ,(row, col))
).dot(coo_matrix(label_arr)).toarray().astype(int)
 del col
del row
cnts_by_fold = np.zeros(( n_fold, n_class), int)
 groups_by_fold = [[] for fid in range(n_fold)]
group_and_cnts = list(enumerate(cnts_by_group))
np.random.shuffle(group_and_cnts)
 print("finished preparation", time.time() - start_time)
 for aid, cnt_by_g in sorted(group_and_cnts, key=lambda x: -np.std(x[1])) :
best_fold = None
min_eval = None
for fid in range(n_fold):
cnts_by_fold[fid] += cnt_by_g
fold_eval =(cnts_by_fold / cnts_by_class ).std(axis=0 ).mean()
cnts_by_fold[fid] -= cnt_by_g
if min_eval is None or fold_eval < min_eval:
min_eval = fold_eval
best_fold = fid
cnts_by_fold[best_fold] += cnt_by_g
groups_by_fold[best_fold].append(aid)
 print("finished assignment.", time.time() - start_time)
 gc.collect()
idx_arr = np.arange(n_train)
 for fid in range(n_fold):
val_groups = groups_by_fold[fid]
val_indexs_bool = np.isin(aid_arr, val_groups)
 train_indexs = idx_arr[~val_indexs_bool]
val_indexs = idx_arr[val_indexs_bool]
print("[fold {}]".format(fid), end=" ")
 print("n_group:(train, val)=({}, {})".format(n_group - len(val_groups), len(val_groups)) , end=" ")
 print("n_sample:(train, val)=({}, {})".format(len(train_indexs), len(val_indexs)))
 yield train_indexs, val_indexs
def run_wbf(boxes, scores, image_size=1023, iou_thr=0.5, skip_box_thr=0.7, weights=None):
labels = [np.zeros(score.shape[0])for score in scores]
boxes = [box/(image_size)for box in boxes]
boxes, scores, labels = weighted_boxes_fusion(boxes, scores, labels, weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)
 boxes = boxes*(image_size)
 return boxes, scores, labels
def TTAImage(image, index):
image1 = image.copy()
if index==0:
rotated_image = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)
 return rotated_image
elif index==1:
rotated_image2 = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)
 rotated_image2 = cv2.rotate(rotated_image2, cv2.ROTATE_90_CLOCKWISE)
 return rotated_image2
elif index==2:
rotated_image3 = cv2.rotate(image1, cv2.ROTATE_90_CLOCKWISE)
 rotated_image3 = cv2.rotate(rotated_image3, cv2.ROTATE_90_CLOCKWISE)
 rotated_image3 = cv2.rotate(rotated_image3, cv2.ROTATE_90_CLOCKWISE)
 return rotated_image3
elif index == 3:
return image1
def rotBoxes90(boxes, im_w, im_h):
ret_boxes =[]
for box in boxes:
x1, y1, x2, y2 = box
x1, y1, x2, y2 = x1-im_w//2, im_h//2 - y1, x2-im_w//2, im_h//2 - y2
x1, y1, x2, y2 = y1, -x1, y2, -x2
x1, y1, x2, y2 = int(x1+im_w//2), int(im_h//2 - y1), int(x2+im_w//2), int(im_h//2 - y2)
 x1a, y1a, x2a, y2a = min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2)
 ret_boxes.append([x1a, y1a, x2a, y2a])
 return np.array(ret_boxes)
 def detect1Image(im0, imgsz, model, device, conf_thres, iou_thres):
img = letterbox(im0, new_shape=imgsz)[0]
img = img[:, :, ::-1].transpose(2, 0, 1)
 img = np.ascontiguousarray(img)
 img = torch.from_numpy(img ).to(device)
 img = img.float()
img /= 255.0
if img.ndimension() == 3:
img = img.unsqueeze(0)
 pred = model(img, augment=False)[0]
pred = non_max_suppression(pred, conf_thres, iou_thres)
 boxes = []
scores = []
for i, det in enumerate(pred):
if det is not None and len(det):
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape ).round()
for *xyxy, conf, cls in det:
boxes.append([int(xyxy[0]), int(xyxy[1]), int(xyxy[2]), int(xyxy[3])])
 scores.append(conf)
 return np.array(boxes), np.array(scores )<load_pretrained>
label_arr = train[CLASSES].values
group_id = train.PatientID.values
train_val_indexs = list(
 multi_label_stratified_group_k_fold(label_arr, group_id, N_FOLD, RANDAM_SEED))
def makePseudolabel() :
source = '.. /input/global-wheat-detection/test/'
weights = '.. /input/ckpts41/best_fold4.pt'
imgsz = 1024
conf_thres = 0.5
iou_thres = 0.6
is_TTA = True
imagenames = os.listdir(source)
 device = torch.device('cuda')if torch.cuda.is_available() else torch.device('cpu')
 model = torch.load(weights, map_location=device)['model'].float()
model.to(device ).eval()
dataset = LoadImages(source, img_size=imgsz)
 path2save = 'train2017/'
if not os.path.exists('convertor/fold0/labels/'+path2save):
os.makedirs('convertor/fold0/labels/'+path2save)
 if not os.path.exists('convertor/fold0/images/{}'.format(path2save)) :
os.makedirs('convertor/fold0/images/{}'.format(path2save))
for name in imagenames:
image_id = name.split('.')[0]
im01 = cv2.imread('%s/%s.jpg'%(source,image_id))
if im01.shape[0]!=1024 or im01.shape[1]!=1024:
continue
assert im01 is not None, 'Image Not Found '
im_w, im_h = im01.shape[:2]
if is_TTA:
enboxes = []
enscores = []
for i in range(4):
im0 = TTAImage(im01, i)
 boxes, scores = detect1Image(im0, imgsz, model, device, conf_thres, iou_thres)
 for _ in range(3-i):
boxes = rotBoxes90(boxes, im_w, im_h)
 enboxes.append(boxes)
 enscores.append(scores)
 boxes, scores, labels = run_wbf(enboxes, enscores, image_size = im_w, iou_thr=0.4, skip_box_thr=0.4)
 boxes = boxes.astype(np.int32 ).clip(min=0, max=im_w)
 else:
boxes, scores = detect1Image(im01, imgsz, model, device, conf_thres, iou_thres)
 boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
boxes = boxes[scores >= 0.05].astype(np.int32)
 scores = scores[scores >=float(0.05)]
lineo = ''
for box in boxes:
x1, y1, w, h = box
xc, yc, w, h =(x1+w/2)/1024,(y1+h/2)/1024, w/1024, h/1024
lineo += '0 %f %f %f %f
'%(xc, yc, w, h)
 fileo = open('convertor/fold0/labels/'+path2save+image_id+".txt", 'w+')
 fileo.write(lineo)
 fileo.close()
sh.copy(".. /input/global-wheat-detection/test/{}.jpg".format(image_id),'convertor/fold0/images/{}/{}.jpg'.format(path2save,image_id)) 
<install_modules>
train["fold"] = -1
for fold_id,(trn_idx, val_idx)in enumerate(train_val_indexs):
train.loc[val_idx, "fold"] = fold_id
train.groupby("fold")[CLASSES].sum()
!cp 'weights/best.pt' 'best_psuedolblf4.pt'<define_variables>
def resize_images(img_id, input_dir, output_dir, resize_to=(640, 640), ext="png"):
img_path = input_dir / f"{img_id}.jpg"
save_path = output_dir / f"{img_id}.{ext}"
img = cv2.imread(str(img_path), cv2.IMREAD_GRAYSCALE)
 img = cv2.resize(img, resize_to)
 cv2.imwrite(str(save_path), img,)
 TEST_RESIZED = TMP / "test_{0}x{1}".format(*IMAGE_SIZE)
 TEST_RESIZED.mkdir(exist_ok=True)
 TEST_RESIZED
_ = Parallel(n_jobs=2, verbose=5 )([
delayed(resize_images )(img_id, TEST, TEST_RESIZED, IMAGE_SIZE, "png")
 for img_id in smpl_sub.StudyInstanceUID.values
] )
def format_prediction_string(boxes, scores):
pred_strings = []
for j in zip(scores, boxes):
pred_strings.append("{0:.4f} {1} {2} {3} {4}".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))
return " ".join(pred_strings )<load_pretrained>
def get_activation(activ_name: str="relu"):

 act_dict = {
"relu": nn.ReLU(inplace=True),
"tanh": nn.Tanh() ,
"sigmoid": nn.Sigmoid() ,
"identity": nn.Identity() }
if activ_name in act_dict:
return act_dict[activ_name]
else:
raise NotImplementedError
class Conv2dBNActiv(nn.Module):

 def __init__(
 self, in_channels: int, out_channels: int,
kernel_size: int, stride: int=1, padding: int=0,
bias: bool=False, use_bn: bool=True, activ: str="relu" 
):

 super(Conv2dBNActiv, self ).__init__()
layers = []
layers.append(nn.Conv2d(
 in_channels, out_channels,
kernel_size, stride, padding, bias=bias))
if use_bn:
layers.append(nn.BatchNorm2d(out_channels))
layers.append(get_activation(activ))
self.layers = nn.Sequential(*layers)
 def forward(self, x):

 return self.layers(x)
 class SSEBlock(nn.Module):

 def __init__(self, in_channels: int):

 super(SSEBlock, self ).__init__()
self.channel_squeeze = nn.Conv2d(
 in_channels=in_channels, out_channels=1,
kernel_size=1, stride=1, padding=0, bias=False)
 self.sigmoid = nn.Sigmoid()
def forward(self, x):

 h = self.sigmoid(self.channel_squeeze(x))
return x * h
class SpatialAttentionBlock(nn.Module):

 def __init__(
 self, in_channels: int,
out_channels_list: tp.List[int], 
):

 super(SpatialAttentionBlock, self ).__init__()
self.n_layers = len(out_channels_list)
 channels_list = [in_channels] + out_channels_list
assert self.n_layers > 0
assert channels_list[-1] == 1
for i in range(self.n_layers - 1):
in_chs, out_chs = channels_list[i: i + 2]
layer = Conv2dBNActiv(in_chs, out_chs, 3, 1, 1, activ="relu")
 setattr(self, f"conv{i + 1}", layer)
 in_chs, out_chs = channels_list[-2:]
layer = Conv2dBNActiv(in_chs, out_chs, 3, 1, 1, activ="sigmoid")
 setattr(self, f"conv{self.n_layers}", layer)
 def forward(self, x):

 h = x
for i in range(self.n_layers):
h = getattr(self, f"conv{i + 1}" )(h)
 h = h * x
return h
def detect() :
source = '.. /input/global-wheat-detection/test/'
weights = 'weights/best.pt'
if not os.path.exists(weights):
weights = '.. /input/ckpts41/best_fold4.pt'
imgsz = 1024
conf_thres = 0.5
iou_thres = 0.6
is_TTA = True
imagenames = os.listdir(source)
 device = torch.device('cuda')if torch.cuda.is_available() else torch.device('cpu')
 model = torch.load(weights, map_location=device)['model'].float()
model.to(device ).eval()
dataset = LoadImages(source, img_size=imgsz)
 results = []
fig, ax = plt.subplots(5, 2, figsize=(30, 70))
count = 0
for name in imagenames:
image_id = name.split('.')[0]
im01 = cv2.imread('%s/%s.jpg'%(source,image_id))
assert im01 is not None, 'Image Not Found '
im_w, im_h = im01.shape[:2]
if is_TTA:
enboxes = []
enscores = []
for i in range(4):
im0 = TTAImage(im01, i)
 boxes, scores = detect1Image(im0, imgsz, model, device, conf_thres, iou_thres)
 for _ in range(3-i):
boxes = rotBoxes90(boxes, im_w, im_h)
 if 1:
enboxes.append(boxes)
 enscores.append(scores)
 boxes, scores = detect1Image(im01, imgsz, model, device, conf_thres, iou_thres)
 enboxes.append(boxes)
 enscores.append(scores)
 boxes, scores, labels = run_wbf(enboxes, enscores, image_size = im_w, iou_thr=0.4, skip_box_thr=0.4)
 boxes = boxes.astype(np.int32 ).clip(min=0, max=im_w)
 else:
boxes, scores = detect1Image(im01, imgsz, model, device, conf_thres, iou_thres)
 boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
boxes = boxes[scores >= 0.05].astype(np.int32)
 scores = scores[scores >=float(0.05)]
if count<10:
for box, score in zip(boxes,scores):
cv2.rectangle(im0, 
(box[0], box[1]), 
(box[2]+box[0], box[3]+box[1]), 
(220, 0, 0), 2)
 cv2.putText(im0, '%.2f'%(score),(box[0], box[1]), cv2.FONT_HERSHEY_SIMPLEX ,
0.5,(255,255,255), 2, cv2.LINE_AA)
 ax[count%5][count//5].imshow(im0)
 count+=1
result = {
'image_id': image_id,
'PredictionString': format_prediction_string(boxes, scores)
 }
results.append(result)
 return results<save_to_csv>
class MultiHeadResNet200D(nn.Module):
def __init__(
 self, out_dims_head: tp.List[int]=[3, 4, 3, 1], pretrained=False 
):

 self.base_name = "resnet200d_320"
self.n_heads = len(out_dims_head)
 super(MultiHeadResNet200D, self ).__init__()
base_model = timm.create_model(
 self.base_name, num_classes=sum(out_dims_head), pretrained=False)
 in_features = base_model.num_features
if pretrained:
pretrained_model_path = '.. /input/startingpointschestx/resnet200d_320_chestx.pth'
state_dict = dict()
for k, v in torch.load(pretrained_model_path, map_location='cpu')["model"].items() :
if k[:6] == "model.":
k = k.replace("model.", "")
 state_dict[k] = v
base_model.load_state_dict(state_dict)
 base_model.reset_classifier(0, '')
 self.backbone = base_model
for i, out_dim in enumerate(out_dims_head):
layer_name = f"head_{i}"
layer = nn.Sequential(
 SpatialAttentionBlock(in_features, [64, 32, 16, 1]),
nn.AdaptiveAvgPool2d(output_size=1),
nn.Flatten(start_dim=1),
nn.Linear(in_features, in_features),
nn.ReLU(inplace=True),
nn.Dropout(0.5),
nn.Linear(in_features, out_dim))
setattr(self, layer_name, layer)
 def forward(self, x):

 h = self.backbone(x)
 hs = [
getattr(self, f"head_{i}" )(h)for i in range(self.n_heads)]
y = torch.cat(hs, axis=1)
 return y
m = MultiHeadResNet200D([3, 4, 3, 1], False)
 m = m.eval()
x = torch.rand(1, 3, 256, 256)
 with torch.no_grad() :
y = m(x)
 print("[forward test]")
 print("input:\t{}
output:\t{}".format(x.shape, y.shape))
del m; del x; del y
gc.collect()
results = detect()
test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])
 test_df.to_csv('submission.csv', index=False)
 test_df.head()<install_modules>
class LabeledImageDataset(data.Dataset):

 def __init__(
 self,
file_list: tp.List[
tp.Tuple[tp.Union[str, Path], tp.Union[int, float, np.ndarray]]],
transform_list: tp.List[tp.Dict], 
):

 self.file_list = file_list
self.transform = ImageTransformForCls(transform_list)
 def __len__(self):

 return len(self.file_list)
 def __getitem__(self, index):

 img_path, label = self.file_list[index]
img = self._read_image_as_array(img_path)
 img, label = self.transform(( img, label))
return img, label
def _read_image_as_array(self, path: str):

 img_arr = cv2.imread(str(path))
img_arr = cv2.cvtColor(img_arr, cv2.COLOR_BGR2RGB)
 return img_arr
!pip install --no-deps '.. /input/timm-package/timm-0.1.26-py3-none-any.whl' > /dev/null
!pip install --no-deps '.. /input/pycocotools/pycocotools-2.0-cp37-cp37m-linux_x86_64.whl' > /dev/null<define_variables>
def get_dataloaders_for_inference(
 file_list: tp.List[tp.List], batch_size=64, 
):

 dataset = LabeledImageDataset(
 file_list,
transform_list=[
["Normalize", {
"always_apply": True, "max_pixel_value": 255.0,
"mean": ["0.4887381077884414"], "std": ["0.23064819430546407"]}],
["ToTensorV2", {"always_apply": True}],
])
 loader = data.DataLoader(
 dataset,
batch_size=batch_size, shuffle=False,
num_workers=2, pin_memory=True,
drop_last=False)
 return loader
img_sz = 640
device = 'cuda' if torch.cuda.is_available() else 'cpu'
device<normalization>
class ImageTransformBase:

 def __init__(self, data_augmentations: tp.List[tp.Tuple[str, tp.Dict]]):

 augmentations_list = [
self._get_augmentation(aug_name )(**params)
 for aug_name, params in data_augmentations]
self.data_aug = albumentations.Compose(augmentations_list)
 def __call__(self, pair: tp.Tuple[np.ndarray])-> tp.Tuple[np.ndarray]:

 raise NotImplementedError
def _get_augmentation(self, aug_name: str)-> tp.Tuple[ImageOnlyTransform, DualTransform]:

 if hasattr(albumentations, aug_name):
return getattr(albumentations, aug_name)
 else:
return eval(aug_name)
 class ImageTransformForCls(ImageTransformBase):

 def __init__(self, data_augmentations: tp.List[tp.Tuple[str, tp.Dict]]):

 super(ImageTransformForCls, self ).__init__(data_augmentations)
 def __call__(self, in_arrs: tp.Tuple[np.ndarray])-> tp.Tuple[np.ndarray]:

 img, label = in_arrs
augmented = self.data_aug(image=img)
 img = augmented["image"]
return img, label
def get_valid_transforms() :
return A.Compose([A.Resize(height=img_sz, width=img_sz, p=1.0),
ToTensorV2(p=1.0)], p=1.0 )<data_type_conversions>
def load_setting_file(path: str):

 with open(path)as f:
settings = yaml.safe_load(f)
 return settings
def set_random_seed(seed: int = 42, deterministic: bool = False):

 random.seed(seed)
 np.random.seed(seed)
 os.environ["PYTHONHASHSEED"] = str(seed)
 torch.manual_seed(seed)
 torch.cuda.manual_seed(seed)
 torch.backends.cudnn.deterministic = deterministic
def run_inference_loop(stgs, model, loader, device):
model.to(device)
 model.eval()
pred_list = []
with torch.no_grad() :
for x, t in tqdm(loader):
y_preds1 = model(x.to(device))
y_preds2 = model(x.flip(-1 ).to(device))
y_preds =(y_preds1.sigmoid().to('cpu' ).numpy() *0.6 + y_preds2.sigmoid().to('cpu' ).numpy() *0.4)
 pred_list.append(y_preds)
 pred_arr = np.concatenate(pred_list)
 del pred_list
return pred_arr
DATA_ROOT_PATH = '.. /input/global-wheat-detection/test'
class DatasetRetriever(Dataset):
def __init__(self, image_ids, transforms=None):
super().__init__()
self.image_ids = image_ids
self.transforms = transforms
def __getitem__(self, index: int):
image_id = self.image_ids[index]
image = cv2.imread(f'{DATA_ROOT_PATH}/{image_id}.jpg', cv2.IMREAD_COLOR)
 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB ).astype(np.float32)
 image /= 255.0
if self.transforms:
sample = {'image': image}
sample = self.transforms(**sample)
 image = sample['image']
return image, image_id
def __len__(self)-> int:
return self.image_ids.shape[0]<create_dataframe>
if not torch.cuda.is_available() :
device = torch.device("cpu")
 else:
device = torch.device("cuda")
 print(device )
dataset = DatasetRetriever(image_ids=np.array([path.split('/')[-1][:-4] for path in glob(f'{DATA_ROOT_PATH}/*.jpg')]),
transforms=get_valid_transforms())
 def collate_fn(batch):
return tuple(zip(*batch))
data_loader = DataLoader(dataset, batch_size=2, shuffle=False, num_workers=4,
drop_last=False, collate_fn=collate_fn )<load_pretrained>
model_dir = TRAINED_MODEL
test_dir = TEST_RESIZED
test_file_list = [ 
(test_dir / f"{img_id}.png", [-1] * 11)
 for img_id in smpl_sub["StudyInstanceUID"].values]
test_loader = get_dataloaders_for_inference(test_file_list, batch_size=32)
 test_preds_arr = np.zeros(( N_FOLD , len(smpl_sub), N_CLASSES))
for fold_id in [0,1,2,3,4]:
print(f"[fold {fold_id}]")
 stgs = load_setting_file(".. /input/ranzer-models/settings.yml")
 stgs["model"]["params"]["pretrained"] = False
model = MultiHeadResNet200D(**stgs["model"]["params"])
 model_path = model_dir / f"best_model_fold{fold_id}.pth"
print(model_path)
 model.load_state_dict(torch.load(model_path, map_location=device))
test_pred = run_inference_loop(stgs, model,test_loader, device)
 test_preds_arr[fold_id] = test_pred
del model
torch.cuda.empty_cache()
gc.collect()
def load_net(checkpoint_path):
config = get_efficientdet_config('tf_efficientdet_d5')
 net = EfficientDet(config, pretrained_backbone=False)
 config.num_classes = 1
config.image_size=img_sz
net.class_net = HeadNet(config, num_outputs=config.num_classes, norm_kwargs=dict(eps=.001, momentum=.01))
checkpoint = torch.load(checkpoint_path, map_location=torch.device(device))
if 'model_state_dict' in checkpoint.keys() :
net.load_state_dict(checkpoint['model_state_dict'])
 else:
net.load_state_dict(checkpoint)
 del checkpoint
gc.collect()
net = DetBenchEval(net, config)
 net.eval() ;
return net.cuda()
nets = [load_net('.. /input/global-wheat-models/best-fold-4-640sz.bin'),
load_net('.. /input/global-wheat-models/best-fold-1-640sz.bin'),
load_net('.. /input/global-wheat-models/best-fold-2-640sz.bin'),
load_net('.. /input/global-wheat-models/best-fold-3-640sz.bin')] 
<categorify>
if CONVERT_TO_RANK:
test_preds_arr = test_preds_arr.argsort(axis=1 ).argsort(axis=1)
 sub = smpl_sub.copy()
sub[CLASSES] = test_preds_arr.mean(axis=0)
 sub.to_csv("submission.csv", index=False )
class BaseWheatTTA:
image_size = img_sz
def augment(self, image): raise NotImplementedError
def batch_augment(self, images): raise NotImplementedError
def deaugment_boxes(self, boxes): raise NotImplementedError
class TTAHorizontalFlip(BaseWheatTTA):
def augment(self, image): return image.flip(1)
 def batch_augment(self, images): return images.flip(2)
 def deaugment_boxes(self, boxes):
boxes[:, [1,3]] = self.image_size - boxes[:, [3,1]]
return boxes
class TTAVerticalFlip(BaseWheatTTA):
def augment(self, image): return image.flip(2)
 def batch_augment(self, images): return images.flip(3)
 def deaugment_boxes(self, boxes):
boxes[:, [0,2]] = self.image_size - boxes[:, [2,0]]
return boxes
class TTARotate90(BaseWheatTTA):
def augment(self, image):
return torch.rot90(image, 1,(1, 2))
def batch_augment(self, images):
return torch.rot90(images, 1,(2, 3))
def deaugment_boxes(self, boxes):
res_boxes = boxes.copy()
res_boxes[:, [0,2]] = self.image_size - boxes[:, [1,3]]
res_boxes[:, [1,3]] = boxes[:, [2,0]]
return res_boxes
class TTACompose(BaseWheatTTA):
def __init__(self, transforms): self.transforms = transforms
def augment(self, image):
for transform in self.transforms:
image = transform.augment(image)
 return image
def batch_augment(self, images):
for transform in self.transforms:
images = transform.batch_augment(images)
 return images
def prepare_boxes(self, boxes):
result_boxes = boxes.copy()
result_boxes[:,0] = np.min(boxes[:, [0,2]], axis=1)
 result_boxes[:,2] = np.max(boxes[:, [0,2]], axis=1)
 result_boxes[:,1] = np.min(boxes[:, [1,3]], axis=1)
 result_boxes[:,3] = np.max(boxes[:, [1,3]], axis=1)
 return result_boxes
def deaugment_boxes(self, boxes):
for transform in self.transforms[::-1]:
boxes = transform.deaugment_boxes(boxes)
 return self.prepare_boxes(boxes )<concatenate>
model_dir = TRAINED_MODEL
test_dir = TEST_RESIZED
test_file_list = [ 
(test_dir / f"{img_id}.png", [-1] * 11)
 for img_id in smpl_sub["StudyInstanceUID"].values]
test_loader = get_dataloaders_for_inference(test_file_list, batch_size=4)
 N_FOLD = len([1024])
 test_preds_arr = np.zeros(( N_FOLD , len(smpl_sub), N_CLASSES))
for i,fold_id in enumerate([1024]):
print(f"[fold {fold_id}]")
 stgs = load_setting_file(".. /input/ranzer-models/settings.yml")
 stgs["model"]["params"]["pretrained"] = False
model = MultiHeadResNet200D(**stgs["model"]["params"])
 model_path = model_dir / f"best_model_fold{fold_id}.pth"
print(model_path)
 model.load_state_dict(torch.load(model_path, map_location=device))
test_pred = run_inference_loop(stgs, model,test_loader, device)
 test_preds_arr[i] = test_pred
del model
torch.cuda.empty_cache()
gc.collect()
tta_transforms = []
for tta_combination in product([TTAHorizontalFlip() , None],
[TTAVerticalFlip() , None],
[TTARotate90() , None]):
tta_transforms.append(TTACompose([tta_transform for tta_transform in tta_combination if tta_transform]))<predict_on_test>
sub_2 = smpl_sub.copy()
sub_2[CLASSES] = test_preds_arr.mean(axis=0 )
def make_predictions(net, images, score_threshold=0.22):
images = torch.stack(images ).cuda().float()
predictions = []
with torch.no_grad() :
det = net(images, torch.tensor([1]*images.shape[0] ).float().cuda())
 for i in range(images.shape[0]):
boxes = det[i].detach().cpu().numpy() [:,:4]
scores = det[i].detach().cpu().numpy() [:,4]
indexes = np.where(scores > score_threshold)[0]
boxes = boxes[indexes]
boxes[:, 2] = boxes[:, 2] + boxes[:, 0]
boxes[:, 3] = boxes[:, 3] + boxes[:, 1]
predictions.append({
'boxes': boxes[indexes],
'scores': scores[indexes],
})
 return [predictions]
def make_tta_predictions(net, images, score_threshold=0.25):
with torch.no_grad() :
images = torch.stack(images ).cuda().float()
predictions = []
for tta_transform in tta_transforms:
result = []
det = net(tta_transform.batch_augment(images.clone()), torch.tensor([1]*images.shape[0] ).float().cuda())
 for i in range(images.shape[0]):
boxes = det[i].detach().cpu().numpy() [:,:4]
scores = det[i].detach().cpu().numpy() [:,4]
indexes = np.where(scores > score_threshold)[0]
boxes = boxes[indexes]
boxes[:, 2] = boxes[:, 2] + boxes[:, 0]
boxes[:, 3] = boxes[:, 3] + boxes[:, 1]
boxes = tta_transform.deaugment_boxes(boxes.copy())
 result.append({
'boxes': boxes,
'scores': scores[indexes],
})
 predictions.append(result)
 return predictions
def run_wbf(predictions, image_index, image_size=img_sz, iou_thr=0.44, skip_box_thr=0.43, weights=None):
boxes = [(prediction[image_index]['boxes']/(image_size-1)).tolist() for prediction in predictions]
scores = [prediction[image_index]['scores'].tolist() for prediction in predictions]
labels = [np.ones(prediction[image_index]['scores'].shape[0] ).tolist() for prediction in predictions]
boxes, scores, labels = weighted_boxes_fusion(boxes, scores, labels, weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)
 boxes = boxes*(image_size-1)
 return boxes, scores, labels<define_variables>
sub[CLASSES] = 0.6 * sub[CLASSES] + 0.4 * sub_2[CLASSES]
<categorify><EOS> 
sub.to_csv("submission.csv", index=False )