Kaggle competition: Global Wheat Detection
<SOS> metric: custom metric Kaggle data source: global-wheat-detection<categorify>
!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
class CancerDataset(Dataset):
def __init__(self, datafolder, datatype='train', transform = transforms.Compose([transforms.CenterCrop(64),transforms.ToTensor() ]), labels_dict={}):
self.datafolder = datafolder
self.datatype = datatype
self.image_files_list = [s for s in os.listdir(datafolder)]
self.transform = transform
self.labels_dict = labels_dict
if self.datatype == 'train':
self.labels = [labels_dict[i.split('.')[0]] for i in self.image_files_list]
else:
self.labels = [0 for _ in range(len(self.image_files_list)) ]
def __len__(self):
return len(self.image_files_list)
 def __getitem__(self, idx):
img_name = os.path.join(self.datafolder, self.image_files_list[idx])
 img = cv2.imread(img_name)
 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 image = self.transform(image=img)
 image = image['image']
img_name_short = self.image_files_list[idx].split('.')[0]
if self.datatype == 'train':
label = self.labels_dict[img_name_short]
else:
label = 0
return image, label<set_options>
best_score_threshold = 0.39
best_iou_thr=0.41
best_skip_box_thr=0.41
SCORE_OPTIM = len(os.listdir('.. /input/global-wheat-detection/test/')) >11
WBF_OPTIM = False
data_transforms = albumentations.Compose([
albumentations.Resize(224, 224),
albumentations.RandomRotate90(p=0.5),
albumentations.Transpose(p=0.5),
albumentations.Flip(p=0.5),
albumentations.OneOf([
albumentations.CLAHE(clip_limit=2), albumentations.IAASharpen() , albumentations.IAAEmboss() ,
albumentations.RandomBrightness() , albumentations.RandomContrast() ,
albumentations.JpegCompression() , albumentations.Blur() , albumentations.GaussNoise() ], p=0.5),
albumentations.HueSaturationValue(p=0.5),
albumentations.ShiftScaleRotate(shift_limit=0.15, scale_limit=0.15, rotate_limit=45, p=0.5),
albumentations.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),
AT.ToTensor()
])
 data_transforms_test = albumentations.Compose([
albumentations.Resize(224, 224),
albumentations.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),
AT.ToTensor()
])
 data_transforms_tta0 = albumentations.Compose([
albumentations.Resize(224, 224),
albumentations.RandomRotate90(p=0.5),
albumentations.Transpose(p=0.5),
albumentations.Flip(p=0.5),
albumentations.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),
AT.ToTensor()
])
 data_transforms_tta1 = albumentations.Compose([
albumentations.Resize(224, 224),
albumentations.RandomRotate90(p=1),
albumentations.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),
AT.ToTensor()
])
 data_transforms_tta2 = albumentations.Compose([
albumentations.Resize(224, 224),
albumentations.Transpose(p=1),
albumentations.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),
AT.ToTensor()
])
 data_transforms_tta3 = albumentations.Compose([
albumentations.Resize(224, 224),
albumentations.Flip(p=1),
albumentations.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),
AT.ToTensor()
])
 dataset = CancerDataset(datafolder=base_dir+'train/', datatype='train', transform=data_transforms, labels_dict=img_class_dict)
 val_set = CancerDataset(datafolder=base_dir+'train/', datatype='train', transform=data_transforms_test, labels_dict=img_class_dict)
 test_set = CancerDataset(datafolder=base_dir+'test/', datatype='test', transform=data_transforms_test)
 train_sampler = SubsetRandomSampler(list(tr.index))
valid_sampler = SubsetRandomSampler(list(val.index))
batch_size = 16
num_workers = 0
train_loader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, sampler=train_sampler, num_workers=num_workers)
 valid_loader = torch.utils.data.DataLoader(val_set, batch_size=batch_size, sampler=valid_sampler, num_workers=num_workers)
 test_loader = torch.utils.data.DataLoader(test_set, batch_size=batch_size, num_workers=num_workers )<choose_model_class>
TEST_DATA_ROOT_PATH = '.. /input/global-wheat-detection/test'
TRAIN_DATA_ROOT_PATH = '.. /input/global-wheat-detection/train'
model_conv = ptcv_get_model("cbam_resnet50", pretrained=True)
 model_conv.avg_pool = nn.AdaptiveAvgPool2d(( 1, 1))
model_conv.last_linear = nn.Sequential(nn.Dropout(0.6), nn.Linear(in_features=2048, out_features=512, bias=True), nn.SELU() ,
nn.Dropout(0.8), nn.Linear(in_features=512, out_features=1, bias=True))<choose_model_class>
def get_test_transforms() :
return A.Compose([
A.Resize(height=512, width=512, p=1.0),
ToTensorV2(p=1.0),
], p=1.0 )
model_conv.cuda()
criterion = nn.BCEWithLogitsLoss()
optimizer = optim.Adam(model_conv.parameters() , lr=0.0004)
 scheduler = StepLR(optimizer, 5, gamma=0.2)
 scheduler.step()<train_model>
class TestDatasetRetriever(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'{TEST_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]
val_auc_max = 0
patience = 25
p = 0
stop = False
n_epochs = 3
for epoch in range(1, n_epochs+1):
if stop:
print("Training stop.")
 break
print(time.ctime() , 'Epoch:', epoch)
 train_loss = []
train_auc = []
for tr_batch_i,(data, target)in enumerate(train_loader):
model_conv.train()
data, target = data.cuda() , target.cuda()
optimizer.zero_grad()
output = model_conv(data)
 loss = criterion(output[:,0], target.float())
 train_loss.append(loss.item())
 a = target.data.cpu().numpy()
try:
b = output[:,0].detach().cpu().numpy()
train_auc.append(roc_auc_score(a, b))
except:
pass
loss.backward()
optimizer.step()
if(tr_batch_i+1)%600 == 0:
model_conv.eval()
val_loss = []
val_auc = []
for val_batch_i,(data, target)in enumerate(valid_loader):
data, target = data.cuda() , target.cuda()
output = model_conv(data)
 loss = criterion(output[:,0], target.float())
 val_loss.append(loss.item())
 a = target.data.cpu().numpy()
try:
b = output[:,0].detach().cpu().numpy()
val_auc.append(roc_auc_score(a, b))
except:
pass
print('Epoch %d, batches:%d, train loss: %.4f, valid loss: %.4f.'%(epoch, tr_batch_i, np.mean(train_loss), np.mean(val_loss))
+ ' train auc: %.4f, valid auc: %.4f'%(np.mean(train_auc),np.mean(val_auc)))
 train_loss = []
train_auc = []
valid_auc = np.mean(val_auc)
 if valid_auc > val_auc_max:
print('Validation auc increased({:.6f} --> {:.6f} ).Saving model...'.format(
 val_auc_max,
valid_auc))
torch.save(model_conv.state_dict() , 'model.pt')
 val_auc_max = valid_auc
p = 0
else:
p += 1
if p > patience:
print('Early stop training')
 stop = True
break
scheduler.step()<set_options>
test_dataset = TestDatasetRetriever(
 image_ids=np.array([path.split('/')[-1][:-4] for path in glob(f'{TEST_DATA_ROOT_PATH}/*.jpg')]),
transforms=get_test_transforms() 
)
 def collate_fn(batch):
return tuple(zip(*batch))
test_data_loader = DataLoader(
 test_dataset,
batch_size=4,
shuffle=False,
num_workers=2,
drop_last=False,
collate_fn=collate_fn
)
torch.cuda.empty_cache()<find_best_params>
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=512
net.class_net = HeadNet(config, num_outputs=config.num_classes, norm_kwargs=dict(eps=.001, momentum=.01))
checkpoint = torch.load(checkpoint_path)
 net.load_state_dict(checkpoint['model_state_dict'])
 del checkpoint
gc.collect()
net = DetBenchEval(net, config)
 net.eval() ;
return net.cuda()
model_conv.eval()<define_variables>
class BaseWheatTTA:

 image_size = 512
def augment(self,image):
raise NotImplementedError
def batch_augment(self,images):
raise NotImplementedError
def deaugment_boxes(self,boxes):
raise NotImplementedError
class TTAVerticalFlip(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 TTAHorizontalFlip(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 TTARotate180(BaseWheatTTA):

 def augment(self, image):
return torch.rot90(image, 2,(1, 2))
def batch_augment(self, images):
return torch.rot90(images, 2,(2, 3))
def deaugment_boxes(self, boxes):
boxes[:, [0,1,2,3]] = self.image_size - boxes[:, [2,3,0,1]]
return boxes
class TTARotate270(BaseWheatTTA):

 def augment(self, image):
return torch.rot90(image, 3,(1, 2))
def batch_augment(self, images):
return torch.rot90(images, 3,(2, 3))
def deaugment_boxes(self, boxes):
res_boxes = boxes.copy()
res_boxes[:, [0,2]] = boxes[:, [1,3]]
res_boxes[:, [1,3]] = self.image_size - boxes[:, [2,0]]
return res_boxes
class TTAHSV_or_RBC(BaseWheatTTA):

 transform = A.OneOf([
A.HueSaturationValue(hue_shift_limit=0.2, sat_shift_limit= 0.2,
val_shift_limit=0.2,p=0.5),
A.RandomBrightnessContrast(brightness_limit=0.2,
contrast_limit=0.2, p=0.5),
],p=1)
 def augment(self,image):
image = image.permute(1,2,0 ).cpu().numpy()
image = self.transform(image=image)['image']
return ToTensorV2()(image=image)['image']
def batch_augment(self, images):
batch_size = len(images)
 for i in range(batch_size):
images[i] = self.augment(images[i])
 return images
def deaugment_boxes(self,boxes):
return boxes
class TTAToGray(BaseWheatTTA):

 transform = A.ToGray()
def augment(self,image):
image = image.permute(1,2,0 ).cpu().numpy()
image = self.transform(image=image)['image']
return ToTensorV2()(image=image)['image']
def batch_augment(self, images):
batch_size = len(images)
 for i in range(batch_size):
images[i] = self.augment(images[i])
 return images
def deaugment_boxes(self,boxes):
return 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 )
NUM_TTA = 32<feature_engineering>
def process_det(index, det, score_threshold=0.25):
boxes = det[index].detach().cpu().numpy() [:,:4]
scores = det[index].detach().cpu().numpy() [:,4]
boxes[:, 2] = boxes[:, 2] + boxes[:, 0]
boxes[:, 3] = boxes[:, 3] + boxes[:, 1]
boxes =(boxes ).clip(min=0, max=511 ).astype(int)
 indexes = np.where(scores>score_threshold)
 boxes = boxes[indexes]
scores = scores[indexes]
return boxes, scores
sigmoid = lambda x: scipy.special.expit(x )<create_dataframe>
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]))
for num_tta in range(NUM_TTA):
if num_tta==0:
test_set = CancerDataset(datafolder=base_dir+'test/', datatype='test', transform=data_transforms_test)
 test_loader = torch.utils.data.DataLoader(test_set, batch_size=batch_size, num_workers=num_workers)
 elif num_tta==1:
test_set = CancerDataset(datafolder=base_dir+'test/', datatype='test', transform=data_transforms_tta1)
 test_loader = torch.utils.data.DataLoader(test_set, batch_size=batch_size, num_workers=num_workers)
 elif num_tta==2:
test_set = CancerDataset(datafolder=base_dir+'test/', datatype='test', transform=data_transforms_tta2)
 test_loader = torch.utils.data.DataLoader(test_set, batch_size=batch_size, num_workers=num_workers)
 elif num_tta==3:
test_set = CancerDataset(datafolder=base_dir+'test/', datatype='test', transform=data_transforms_tta3)
 test_loader = torch.utils.data.DataLoader(test_set, batch_size=batch_size, num_workers=num_workers)
 elif num_tta<8:
test_set = CancerDataset(datafolder=base_dir+'test/', datatype='test', transform=data_transforms_tta0)
 test_loader = torch.utils.data.DataLoader(test_set, batch_size=batch_size, num_workers=num_workers)
 else:
test_set = CancerDataset(datafolder=base_dir+'test/', datatype='test', transform=data_transforms)
 test_loader = torch.utils.data.DataLoader(test_set, batch_size=batch_size, num_workers=num_workers)
 preds = []
for batch_i,(data, target)in enumerate(test_loader):
data, target = data.cuda() , target.cuda()
output = model_conv(data ).detach()
pr = output[:,0].cpu().numpy()
for i in pr:
preds.append(sigmoid(i)/NUM_TTA)
 if num_tta==0:
test_preds = pd.DataFrame({'imgs': test_set.image_files_list, 'preds': preds})
 test_preds['imgs'] = test_preds['imgs'].apply(lambda x: x.split('.')[0])
 else:
test_preds['preds']+=np.array(preds)
 print(num_tta)
 sub = pd.read_csv('.. /input/sample_submission.csv')
 sub = pd.merge(sub, test_preds, left_on='id', right_on='imgs')
 sub = sub[['id', 'preds']]
sub.columns = ['id', 'label']
sub.to_csv('sub_tta.csv', index=False )<train_model>
def make_tta_predictions(images, score_threshold=best_score_threshold,nets=None):
with torch.no_grad() :
images = torch.stack(images ).float().cuda()
predictions = []
for net in nets:
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=512,iou_thr=best_iou_thr, skip_box_thr=best_skip_box_thr, 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] ).astype(int ).tolist() for prediction in predictions]
boxes, scores, labels = ensemble_boxes.ensemble_boxes_wbf.weighted_boxes_fusion(boxes, scores, labels, weights=None, iou_thr=best_iou_thr, skip_box_thr=best_skip_box_thr)
 boxes = boxes*(image_size-1)
 return boxes, scores, labels
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 )
print("Finished" )<set_options>
@jit(nopython=True)
 def calculate_iou(gt, pr, form='pascal_voc')-> float:

 if form == 'coco':
gt = gt.copy()
pr = pr.copy()
gt[2] = gt[0] + gt[2]
gt[3] = gt[1] + gt[3]
pr[2] = pr[0] + pr[2]
pr[3] = pr[1] + pr[3]
dx = min(gt[2], pr[2])- max(gt[0], pr[0])+ 1
if dx < 0:
return 0.0
dy = min(gt[3], pr[3])- max(gt[1], pr[1])+ 1
if dy < 0:
return 0.0
overlap_area = dx * dy
union_area =(
(gt[2] - gt[0] + 1)*(gt[3] - gt[1] + 1)+ 
(pr[2] - pr[0] + 1)*(pr[3] - pr[1] + 1)-
overlap_area 
)
 return overlap_area / union_area
@jit(nopython=True)
 def find_best_match(gts, pred, pred_idx, threshold = 0.5, form = 'pascal_voc', ious=None)-> int:

 best_match_iou = -np.inf
best_match_idx = -1
for gt_idx in range(len(gts)) :
if gts[gt_idx][0] < 0:
continue
iou = -1 if ious is None else ious[gt_idx][pred_idx]
if iou < 0:
iou = calculate_iou(gts[gt_idx], pred, form=form)
 if ious is not None:
ious[gt_idx][pred_idx] = iou
if iou < threshold:
continue
if iou > best_match_iou:
best_match_iou = iou
best_match_idx = gt_idx
return best_match_idx
@jit(nopython=True)
 def calculate_precision(gts, preds, threshold = 0.5, form = 'coco', ious=None)-> float:

 n = len(preds)
 tp = 0
fp = 0
for pred_idx in range(n):
best_match_gt_idx = find_best_match(gts, preds[pred_idx], pred_idx,
threshold=threshold, form=form, ious=ious)
 if best_match_gt_idx >= 0:
tp += 1
gts[best_match_gt_idx] = -1
else:
fp += 1
fn =(gts.sum(axis=1)> 0 ).sum()
return tp /(tp + fp + fn)
 @jit(nopython=True)
 def calculate_image_precision(gts, preds, thresholds =(0.5,), form = 'coco')-> float:

 n_threshold = len(thresholds)
 image_precision = 0.0
ious = np.ones(( len(gts), len(preds)))* -1
for threshold in thresholds:
precision_at_threshold = calculate_precision(gts.copy() , preds, threshold=threshold,
form=form, ious=ious)
 image_precision += precision_at_threshold / n_threshold
return image_precision
def show_result(sample_id, preds, gt_boxes):
sample = cv2.imread(f'{TRAIN_DATA_ROOT_PATH}/{sample_id}.jpg', cv2.IMREAD_COLOR)
 sample = cv2.cvtColor(sample, cv2.COLOR_BGR2RGB)
 fig, ax = plt.subplots(1, 1, figsize=(16, 8))
for pred_box in preds:
cv2.rectangle(
 sample, 
(pred_box[0], pred_box[1]), 
(pred_box[2], pred_box[3]), 
(220, 0, 0), 2 
)
 for gt_box in gt_boxes:
cv2.rectangle(
 sample, 
(gt_box[0], gt_box[1]), 
(gt_box[2], gt_box[3]), 
(0, 0, 220), 2 
)
 ax.set_axis_off()
ax.imshow(sample)
 ax.set_title("RED: Predicted | BLUE - Ground-truth")
 iou_thresholds = numba.typed.List()
for x in [0.5, 0.55, 0.6, 0.65, 0.7, 0.75]:
iou_thresholds.append(x )
warnings.filterwarnings("ignore")
 %load_ext autoreload
%autoreload<import_modules>
def predict_test(data_loader,nets,detection_threshold = 0.5):
testdf_pseudo = []
for images, image_ids in data_loader:
predictions = make_tta_predictions(images,nets=nets)
 for i, image in enumerate(images):
boxes, scores, labels = run_wbf(predictions, image_index=i)
 boxes =(boxes*2 ).round().astype(np.int32 ).clip(min=0, max=1023)
 boxes = boxes[scores >= detection_threshold].astype(np.int32)
 scores = scores[scores >= detection_threshold]
image_id = image_ids[i]
boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
for box in boxes:
result = {
'image_id': 'gzyou'+image_id,
'width':1024,
'height':1024,
'source': 'gzyou',
'x': box[0],
'y': box[1],
'w': box[2],
'h': box[3]
}
testdf_pseudo.append(result)
 print(len(testdf_pseudo))
test_df_pseudo = pd.DataFrame(testdf_pseudo, columns=['image_id', 'width', 'height', 'source', 'x', 'y', 'w', 'h'])
 return test_df_pseudo
from torchvision.models import *<define_variables>
print(best_score_threshold,best_iou_thr,best_skip_box_thr )
model_path='.'
path='.. /input/histopathologic-cancer-detection/'
train_folder=f'{path}train'
test_folder=f'{path}test'
train_lbl=f'{path}train_labels.csv'
ORG_SIZE=96
bs=64
num_workers=None
sz=96<define_variables>
nets = [load_net('.. /input/efficientdet-pseudo-best-checkpoint-fold1/best-checkpoint-014epoch.bin')]
test_df_pseudo = predict_test(test_data_loader,nets )
test_fnames=[str(file)for file in Path(test_folder ).iterdir() ] 
<load_from_csv>
class DatasetRetriever(Dataset):
def __init__(self, marking, image_ids, transforms=None, test=False):
super().__init__()
self.image_ids = image_ids
self.marking = marking
self.transforms = transforms
self.test = test
def __getitem__(self, index: int):
image_id = self.image_ids[index]
if self.test or random.random() > 0.5:
image, boxes = self.load_image_and_boxes(index)
 else:
image, boxes = self.load_cutmix_image_and_boxes(index)
 labels = torch.ones(( boxes.shape[0],), dtype=torch.int64)
 target = {}
target['boxes'] = boxes
target['labels'] = labels
target['image_id'] = torch.tensor([index])
 if self.transforms:
for i in range(10):
sample = self.transforms(**{
'image': image,
'bboxes': target['boxes'],
'labels': labels
})
 assert len(sample['bboxes'])== len(sample['labels']), 'not equal!'
if len(sample['bboxes'])> 0:
image = sample['image']
target['boxes'] = torch.stack(tuple(map(torch.tensor, zip(*sample['bboxes'])))).permute(1, 0)
 target['boxes'][:, [0, 1, 2, 3]] = target['boxes'][:, [1, 0, 3, 2]]
changed = True
break
return image, target, image_id
def __len__(self)-> int:
return self.image_ids.shape[0]
def load_image_and_boxes(self, index):
image_id = self.image_ids[index]
records = self.marking[self.marking['image_id'] == image_id]
if 'gzyou' in image_id:
image_id = image_id[5:]
image = cv2.imread(f'{TEST_DATA_ROOT_PATH}/{image_id}.jpg', cv2.IMREAD_COLOR)
 else:
image = cv2.imread(f'{TRAIN_DATA_ROOT_PATH}/{image_id}.jpg', cv2.IMREAD_COLOR)
 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB ).astype(np.float32)
 image /= 255.0
boxes = records[['x', 'y', 'w', 'h']].values
boxes[:, 2] = boxes[:, 0] + boxes[:, 2]
boxes[:, 3] = boxes[:, 1] + boxes[:, 3]
return image, boxes
def load_cutmix_image_and_boxes(self, index, imsize=1024):

 w, h = imsize, imsize
s = imsize // 2
xc, yc = [int(random.uniform(imsize * 0.25, imsize * 0.75)) for _ in range(2)]
indexes = [index] + [random.randint(0, self.image_ids.shape[0] - 1)for _ in range(3)]
result_image = np.full(( imsize, imsize, 3), 1, dtype=np.float32)
 result_boxes = []
for i, index in enumerate(indexes):
image, boxes = self.load_image_and_boxes(index)
 if i == 0:
x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc
x1b, y1b, x2b, y2b = w -(x2a - x1a), h -(y2a - y1a), w, h
elif i == 1:
x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc
x1b, y1b, x2b, y2b = 0, h -(y2a - y1a), min(w, x2a - x1a), h
elif i == 2:
x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h)
 x1b, y1b, x2b, y2b = w -(x2a - x1a), 0, max(xc, w), min(y2a - y1a, h)
 elif i == 3:
x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h)
 x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h)
 result_image[y1a:y2a, x1a:x2a] = image[y1b:y2b, x1b:x2b]
padw = x1a - x1b
padh = y1a - y1b
boxes[:, 0] += padw
boxes[:, 1] += padh
boxes[:, 2] += padw
boxes[:, 3] += padh
result_boxes.append(boxes)
 result_boxes = np.concatenate(result_boxes, 0)
 np.clip(result_boxes[:, 0:], 0, 2 * s, out=result_boxes[:, 0:])
 result_boxes = result_boxes.astype(np.int32)
 result_boxes = result_boxes[
np.where(( result_boxes[:, 2] - result_boxes[:, 0])*(result_boxes[:, 3] - result_boxes[:, 1])> 0)]
return result_image, result_boxes
df_trn=pd.read_csv(train_lbl )<load_from_csv>
def generate_new_marking(marking,test_df_pseudo):
bboxs = np.stack(marking['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))
 for i, column in enumerate(['x', 'y', 'w', 'h']):
marking[column] = bboxs[:,i]
marking.drop(columns=['bbox'], inplace=True)
 new_marking = pd.concat([marking, test_df_pseudo])
 return new_marking
df_WSI=pd.read_csv('.. /input/histopathologiccancerwsi/patch_id_wsi.csv' )<feature_engineering>
def get_train_valid_dataset1(marking,new_marking,test_df_pseudo,fold_number = 0):
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
 df_folds = marking[['image_id']].copy()
df_folds.loc[:, 'bbox_count'] = 1
df_folds = df_folds.groupby('image_id' ).count()
df_folds.loc[:, 'source'] = marking[['image_id', 'source']].groupby('image_id' ).min() ['source']
df_folds.loc[:, 'stratify_group'] = np.char.add(
 df_folds['source'].values.astype(str),
df_folds['bbox_count'].apply(lambda x: f'_{x // 15}' ).values.astype(str)
)
 df_folds.loc[:, 'fold'] = 0
for fold_number,(train_index, val_index)in enumerate(skf.split(X=df_folds.index, y=df_folds['stratify_group'])) :
df_folds.loc[df_folds.iloc[val_index].index, 'fold'] = fold_number
train_dataset = DatasetRetriever(
 image_ids=np.append(df_folds[df_folds['fold'] != fold_number].index.values,test_df_pseudo['image_id'].unique()),
marking=new_marking,
transforms=get_train_transforms() ,
test=False, 
)
 validation_dataset = DatasetRetriever(
 image_ids=df_folds[df_folds['fold'] == fold_number].index.values,
marking=new_marking,
transforms=get_valid_transforms() ,
test=True, 
)
 return train_dataset,validation_dataset
tfms = get_transforms(do_flip=True, flip_vert=True, max_rotate=0.0, max_zoom=.15,
max_lighting=0.1, max_warp=0.15 )<drop_column>
def get_train_valid_dataset2(new_marking):
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
 df_folds = new_marking[['image_id']].copy()
df_folds.loc[:, 'bbox_count'] = 1
df_folds = df_folds.groupby('image_id' ).count()
df_folds.loc[:, 'source'] = new_marking[['image_id', 'source']].groupby('image_id' ).min() ['source']
df_folds.loc[:, 'stratify_group'] = np.char.add(
 df_folds['source'].values.astype(str),
df_folds['bbox_count'].apply(lambda x: f'_{x // 15}' ).values.astype(str)
)
 df_folds.loc[:, 'fold'] = 0
for fold_number,(train_index, val_index)in enumerate(skf.split(X=df_folds.index, y=df_folds['stratify_group'])) :
df_folds.loc[df_folds.iloc[val_index].index, 'fold'] = fold_number
train_dataset = DatasetRetriever(
 image_ids=df_folds[df_folds['fold'] != fold_number].index.values,
marking=new_marking,
transforms=get_train_transforms() ,
test=False, 
)
 validation_dataset = DatasetRetriever(
 image_ids=df_folds[df_folds['fold'] == fold_number].index.values,
marking=new_marking,
transforms=get_valid_transforms() ,
test=True, 
)
 return train_dataset,validation_dataset
df_notinWSI=df_trn.set_index('id' ).drop(df_WSI.id )<groupby>
marking = pd.read_csv('.. /input/global-wheat-detection/train.csv')
 bboxs = np.stack(marking['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))
 for i, column in enumerate(['x', 'y', 'w', 'h']):
marking[column] = bboxs[:,i]
marking.drop(columns=['bbox'], inplace=True)
 skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
 df_folds = marking[['image_id']].copy()
df_folds.loc[:, 'bbox_count'] = 1
df_folds = df_folds.groupby('image_id' ).count()
df_folds.loc[:, 'source'] = marking[['image_id', 'source']].groupby('image_id' ).min() ['source']
df_folds.loc[:, 'stratify_group'] = np.char.add(
 df_folds['source'].values.astype(str),
df_folds['bbox_count'].apply(lambda x: f'_{x // 15}' ).values.astype(str)
)
 df_folds.loc[:, 'fold'] = 0
for fold_number,(train_index, val_index)in enumerate(skf.split(X=df_folds.index, y=df_folds['stratify_group'])) :
df_folds.loc[df_folds.iloc[val_index].index, 'fold'] = fold_number
valWSI=df_WSI.groupby(by='wsi')['id'].count().sample(frac=0.23 ).index<groupby>
marking = pd.concat([marking, test_df_pseudo])
 train_dataset = DatasetRetriever(
 image_ids=np.append(df_folds[df_folds['fold'] >1 ].index.values,test_df_pseudo['image_id'].unique()),
marking=marking,
transforms=get_train_transforms() ,
test=False, 
)
 validation_dataset = DatasetRetriever(
 image_ids=df_folds[df_folds['fold'] <= 1].index.values,
marking=marking,
transforms=get_valid_transforms() ,
test=True,
)
trnWSI=[i[0] for i in df_WSI.groupby(by='wsi')['id'] if i[0] not in valWSI]<concatenate>
print(train_dataset.image_ids,validation_dataset.image_ids )
val_idx=np.hstack([df_WSI.groupby(by='wsi')['id'].indices[WSI] for WSI in valWSI] )<concatenate>
class AverageMeter(object):

 def __init__(self):
self.reset()
def reset(self):
self.val = 0
self.avg = 0
self.sum = 0
self.count = 0
def update(self, val, n=1):
self.val = val
self.sum += val * n
self.count += n
self.avg = self.sum / self.count
val_idx=np.append(df_notinWSI.index.values,df_WSI.id[val_idx])
<concatenate>
warnings.filterwarnings("ignore")
 class Fitter:
def __init__(self, model, device, config):
self.config = config
self.epoch = 0
self.base_dir = f'./{config.folder}'
if not os.path.exists(self.base_dir):
os.makedirs(self.base_dir)
 self.log_path = f'{self.base_dir}/log.txt'
self.best_summary_loss = 10**5
self.model = model
self.device = device
param_optimizer = list(self.model.named_parameters())
 no_decay = ['bias', 'LayerNorm.bias', 'LayerNorm.weight']
optimizer_grouped_parameters = [
{'params': [p for n, p in param_optimizer if not any(nd in n for nd in no_decay)], 'weight_decay': 0.001},
{'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)], 'weight_decay': 0.0}
]
self.optimizer = torch.optim.AdamW(self.model.parameters() , lr=config.lr)
 self.scheduler = config.SchedulerClass(self.optimizer, **config.scheduler_params)
 self.log(f'Fitter prepared.Device is {self.device}')
 def fit(self, train_loader, validation_loader):
for e in range(self.config.n_epochs):
if self.config.verbose:
lr = self.optimizer.param_groups[0]['lr']
timestamp = datetime.utcnow().isoformat()
self.log(f'
{timestamp}
LR: {lr}')
 t = time.time()
summary_loss = self.train_one_epoch(train_loader)
 self.log(f'[RESULT]: Train.Epoch: {self.epoch}, summary_loss: {summary_loss.avg:.5f}, time: {(time.time() - t):.5f}')
 self.save(f'{self.base_dir}/last-checkpoint.bin')
 t = time.time()
summary_loss = self.validation(validation_loader)
 self.log(f'[RESULT]: Val.Epoch: {self.epoch}, summary_loss: {summary_loss.avg:.5f}, time: {(time.time() - t):.5f}')
 if summary_loss.avg < self.best_summary_loss:
self.best_summary_loss = summary_loss.avg
self.model.eval()
print("better model find at epoch:{}".format(self.epoch))
best_weight=self.model.model.state_dict()
self.save(f'{self.base_dir}/best-checkpoint-{str(self.epoch ).zfill(3)}epoch.bin')
 for path in sorted(glob(f'{self.base_dir}/best-checkpoint-*epoch.bin')) [:-3]:
os.remove(path)
 if self.config.validation_scheduler:
self.scheduler.step(metrics=summary_loss.avg)
 self.epoch += 1
return best_weight
def validation(self, val_loader):
self.model.eval()
summary_loss = AverageMeter()
t = time.time()
for step,(images, targets, image_ids)in enumerate(val_loader):
if self.config.verbose:
if step % self.config.verbose_step == 0:
print(
 f'Val Step {step}/{len(val_loader)}, ' + \
f'summary_loss: {summary_loss.avg:.5f}, ' + \
f'time: {(time.time() - t):.5f}', end='\r' 
)
 with torch.no_grad() :
images = torch.stack(images)
 batch_size = images.shape[0]
images = images.to(self.device ).float()
boxes = [target['boxes'].to(self.device ).float() for target in targets]
labels = [target['labels'].to(self.device ).float() for target in targets]
loss, _, _ = self.model(images, boxes, labels)
 summary_loss.update(loss.detach().item() , batch_size)
 return summary_loss
def train_one_epoch(self, train_loader):
self.model.train()
summary_loss = AverageMeter()
t = time.time()
for step,(images, targets, image_ids)in enumerate(train_loader):
if self.config.verbose:
if step % self.config.verbose_step == 0:
print(
 f'Train Step {step}/{len(train_loader)}, ' + \
f'summary_loss: {summary_loss.avg:.5f}, ' + \
f'time: {(time.time() - t):.5f}', end='\r' 
)
 images = torch.stack(images)
 images = images.to(self.device ).float()
batch_size = images.shape[0]
boxes = [target['boxes'].to(self.device ).float() for target in targets]
labels = [target['labels'].to(self.device ).float() for target in targets]
self.optimizer.zero_grad()
loss, _, _ = self.model(images, boxes, labels)
 loss.backward()
summary_loss.update(loss.detach().item() , batch_size)
 self.optimizer.step()
if self.config.step_scheduler:
self.scheduler.step()
return summary_loss
def save(self, path):
self.model.eval()
torch.save({
'model_state_dict': self.model.model.state_dict() ,
'optimizer_state_dict': self.optimizer.state_dict() ,
'scheduler_state_dict': self.scheduler.state_dict() ,
'best_summary_loss': self.best_summary_loss,
'epoch': self.epoch,
}, path)
 def load(self, path):
checkpoint = torch.load(path)
 self.model.model.load_state_dict(checkpoint['model_state_dict'])
 self.optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
 self.scheduler.load_state_dict(checkpoint['scheduler_state_dict'])
 self.best_summary_loss = checkpoint['best_summary_loss']
self.epoch = checkpoint['epoch'] + 1
def log(self, message):
if self.config.verbose:
print(message)
 with open(self.log_path, 'a+')as logger:
logger.write(f'{message}
' )
trn_idx=np.hstack([df_WSI.groupby(by='wsi')['id'].indices[WSI] for WSI in trnWSI])
 trn_idx=df_WSI.id[trn_idx]<filter>
class TrainGlobalConfig:
num_workers = 4
batch_size = 4
n_epochs = 25
lr = 0.0001
folder = 'effdet5-cutmix-augmix'
verbose = True
verbose_step = 1
step_scheduler = False
validation_scheduler = True
SchedulerClass = torch.optim.lr_scheduler.ReduceLROnPlateau
scheduler_params = dict(
 mode='min',
factor=0.5,
patience=1,
verbose=False,
threshold=0.0001,
threshold_mode='abs',
cooldown=0,
min_lr=1e-8,
eps=1e-08
)
val_idx=df_trn.reset_index().set_index('id' ).loc[val_idx,'index'].values
trn_idx=df_trn.reset_index().set_index('id' ).loc[trn_idx,'index'].values<count_duplicates>
def run_training(train_dataset,validation_dataset,train_net=None):
device = torch.device('cuda:0')
 train_net.to(device)
 train_loader = torch.utils.data.DataLoader(
 train_dataset,
batch_size=TrainGlobalConfig.batch_size,
sampler=RandomSampler(train_dataset),
pin_memory=False,
drop_last=True,
num_workers=TrainGlobalConfig.num_workers,
collate_fn=collate_fn, 
)
 val_loader = torch.utils.data.DataLoader(
 validation_dataset,
batch_size=TrainGlobalConfig.batch_size,
num_workers=TrainGlobalConfig.num_workers,
shuffle=False,
sampler=SequentialSampler(validation_dataset),
pin_memory=False,
collate_fn=collate_fn, 
)
 fitter = Fitter(model=train_net, device=device, config=TrainGlobalConfig)
 best_weight = fitter.fit(train_loader, val_loader)
 return best_weight
np.random.shuffle(val_idx)
 np.random.shuffle(trn_idx )<split>
def get_train_net(eval_net):
config = get_efficientdet_config('tf_efficientdet_d5')
 net = EfficientDet(config, pretrained_backbone=False)
 config.num_classes = 1
config.image_size = 512
net.class_net = HeadNet(config, num_outputs=config.num_classes, norm_kwargs=dict(eps=.001, momentum=.01))
net.load_state_dict(eval_net.model.state_dict())
 gc.collect()
net = DetBenchTrain(net, config)
 net = net.train()
return net.cuda()
src =(ImageList.from_df(df_trn, path=path, suffix='.tif',folder='train')
.split_by_idxs(trn_idx,val_idx)
.label_from_df(label_delim=' '))
src.add_test(test_fnames);<categorify>
def get_test_net(best_weigth):
config = get_efficientdet_config('tf_efficientdet_d5')
 net = EfficientDet(config, pretrained_backbone=False)
 config.num_classes = 1
config.image_size = 512
net.class_net = HeadNet(config, num_outputs=config.num_classes, norm_kwargs=dict(eps=.001, momentum=.01))
net.load_state_dict(best_weigth)
 gc.collect()
net = DetBenchEval(net, config)
 net = net.eval()
return net.cuda()
data=ImageDataBunch.create_from_ll(src, ds_tfms=tfms, size=sz,bs=bs)
 stats=data.batch_stats()
data.normalize(stats);<compute_train_metric>
Round_N = 1
test_net = nets[0]
PSEUDO_LABELING = len(os.listdir('.. /input/global-wheat-detection/test/')) >11
if PSEUDO_LABELING:
for i in range(Round_N):
train_net = get_train_net(test_net)
 best_weight = run_training(train_dataset=train_dataset,validation_dataset=validation_dataset,train_net=train_net)
 new_test_net = get_test_net(best_weight)
 test_net = new_test_net
def auc_score(y_pred,y_true,tens=True):
score=roc_auc_score(y_true[:,1],torch.sigmoid(y_pred)[:,1])
 if tens:
score=tensor(score)
 else:
score=score
return score
class FocalLoss(nn.Module):
def __init__(self, alpha=1, gamma=2, logits=False, reduce=True):
super(FocalLoss, self ).__init__()
self.alpha = alpha
self.gamma = gamma
self.logits = logits
self.reduce = reduce
def forward(self, inputs, targets):
if self.logits:
BCE_loss = F.binary_cross_entropy_with_logits(inputs, targets, reduce=False)
 else:
BCE_loss = F.binary_cross_entropy(inputs, targets, reduce=False)
 pt = torch.exp(-BCE_loss)
 F_loss = self.alpha *(1-pt)**self.gamma * BCE_loss
if self.reduce:
return torch.mean(F_loss)
 else:
return F_loss 
<choose_model_class>
validation_loader = torch.utils.data.DataLoader(
 validation_dataset,
batch_size=4,
num_workers=4,
shuffle=False,
sampler=SequentialSampler(validation_dataset),
pin_memory=False,
collate_fn=collate_fn,
)
learn = create_cnn(
 data,
densenet169,
path='.',
metrics=[auc_score],
ps=0.5
)<predict_on_test>
def process_det(index,det,transform,score_threshold=0):
boxes = det[index].detach().cpu().numpy() [:,:4]
scores = det[index].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 = transform.deaugment_boxes(boxes.copy())
 boxes =(boxes*2 ).clip(min=0, max=1023 ).astype(int)
 scores = scores[indexes]
return boxes, scores
x,y=learn.get_preds()<compute_test_metric>
def calculate_final_score(all_predictions, score_threshold):
final_scores = []
for i in range(len(all_predictions)) :
gt_boxes = all_predictions[i]['gt_boxes'].copy()
image_id = all_predictions[i]['image_id']
for transform_number in range(len(tta_transforms)) :
pred_boxes = all_predictions[i][f'pred_boxes_transform{transform_number}'].copy()
scores = all_predictions[i][f'scores_transform{transform_number}'].copy()
indexes = np.where(scores>score_threshold)
 pred_boxes = pred_boxes[indexes]
scores = scores[indexes]
rank = np.argsort(scores)[::-1]
scores = scores[rank]
pred_boxes = pred_boxes[rank]
image_precision = calculate_image_precision(gt_boxes, pred_boxes,thresholds=iou_thresholds,form='pascal_voc')
 final_scores.append(image_precision)
 return np.mean(final_scores )
auc_score(x,y )<train_model>
def search_best_score_threshold(all_predictions):
best_final_score, best_score_threshold = 0, 0
for score_threshold in tqdm(np.arange(0, 1, 0.01), total=np.arange(0, 1, 0.01 ).shape[0]):
final_score = calculate_final_score(all_predictions, score_threshold)
 if final_score > best_final_score:
best_final_score = final_score
best_score_threshold = score_threshold
print('-'*30)
 print(f'[Best Score Threshold]: {best_score_threshold}')
 print(f'[OOF Score]: {best_final_score:.4f}')
 print('-'*30)
 return best_score_threshold
learn.fit_one_cycle(1,1e-2)
 learn.recorder.plot()
learn.recorder.plot_losses()<find_best_params>
if SCORE_OPTIM:
all_predictions = validate(model=test_net)
 gt_boxes = all_predictions[0]['gt_boxes'].copy()
pred_boxes = all_predictions[0]['pred_boxes_transform1'].copy()
scores = all_predictions[0]['scores_transform1'].copy()
image_id = all_predictions[0]['image_id']
indexes = np.where(scores>best_score_threshold)
 pred_boxes = pred_boxes[indexes]
scores = scores[indexes]
show_result(image_id, pred_boxes, gt_boxes)
 best_score_threshold = search_best_score_threshold(all_predictions)
learn.unfreeze()
learn.lr_find()<train_model>
def calculate_final_score_wbf(
 all_predictions,
iou_thr,
skip_box_thr,
method,
sigma=0.5, 
):
final_scores = []
for i in range(len(all_predictions)) :
gt_boxes = all_predictions[i]['gt_boxes'].copy()
image_id = all_predictions[i]['image_id']
folds_boxes, folds_scores, folds_labels = [], [], []
for transform_number in range(len(tta_transforms)) :
pred_boxes = all_predictions[i][f'pred_boxes_transform{transform_number}'].copy()
scores = all_predictions[i][f'scores_transform{transform_number}'].copy()
folds_boxes.append(pred_boxes)
 folds_scores.append(scores)
 folds_labels.append(np.ones(pred_boxes.shape[0]))
if method == 'weighted_boxes_fusion':
boxes, scores, labels = weighted_boxes_fusion(folds_boxes, folds_scores, folds_labels, weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)
 elif method == 'nms':
boxes, scores, labels = nms(folds_boxes, folds_scores, folds_labels, weights=None, iou_thr=iou_thr)
 elif method == 'soft_nms':
boxes, scores, labels = soft_nms(folds_boxes, folds_scores, folds_labels, weights=None, iou_thr=iou_thr, thresh=skip_box_thr, sigma=sigma)
 elif method == 'non_maximum_weighted':
boxes, scores, labels = non_maximum_weighted(folds_boxes, folds_scores, folds_labels, weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)
 else:
raise
image_precision = calculate_image_precision(gt_boxes, boxes, thresholds=iou_thresholds, form='pascal_voc')
 final_scores.append(image_precision)
 return np.mean(final_scores )
learn.fit_one_cycle(10,slice(1e-4,1e-3))<predict_on_test>
def log(text):
with open('opt.log', 'a+')as logger:
logger.write(f'{text}
')
 def optimize(space, all_predictions, method, n_calls=10):
@use_named_args(space)
 def score(**params):
log('-'*5 + f'{method}' + '-'*5)
 log(params)
 final_score = calculate_final_score_wbf(all_predictions, method=method, **params)
 log(f'final_score = {final_score}')
 log('-'*10)
 return -final_score
return gp_minimize(func=score, dimensions=space, n_calls=n_calls )
preds,y,losses = learn.get_preds(with_loss=True)
 interp = ClassificationInterpretation(learn, preds, y.long() , losses )<compute_test_metric>
if WBF_OPTIM:
all_predictions = validate(model=test_net,score_threshold=best_score_threshold)
 gt_boxes = all_predictions[0]['gt_boxes'].copy()
pred_boxes = all_predictions[0]['pred_boxes_transform1'].copy()
scores = all_predictions[0]['scores_transform1'].copy()
image_id = all_predictions[0]['image_id']
indexes = np.where(scores>best_score_threshold)
 pred_boxes = pred_boxes[indexes]
scores = scores[indexes]
show_result(image_id, pred_boxes, gt_boxes)
 space = [
Real(0, 1, name='iou_thr'),
Real(0.25, 1, name='skip_box_thr'),
]
opt_result = optimize(
 space,
all_predictions,
method='weighted_boxes_fusion',
n_calls=50, 
)
 best_final_score = -opt_result.fun
best_iou_thr = opt_result.x[0]
best_skip_box_thr = opt_result.x[1]
print('-'*13 + 'WBF' + '-'*14)
 print(f'[Best Iou Thr]: {best_iou_thr:.3f}')
 print(f'[Best Skip Box Thr]: {best_skip_box_thr:.3f}')
 print(f'[Best Score]: {best_final_score:.4f}')
 print('-'*30 )
preds,y=learn.get_preds()
pred_score=auc_score(preds,y)
 pred_score<compute_test_metric>
print(best_skip_box_thr)
 results = []
fig, ax = plt.subplots(5, 2, figsize=(30, 70))
count = 0
for images, image_ids in test_data_loader:
predictions = make_tta_predictions(images,score_threshold=best_score_threshold,nets=[test_net])
 for i, image in enumerate(images):
boxes, scores, labels = run_wbf(predictions, image_index=i, iou_thr=best_iou_thr, skip_box_thr=best_skip_box_thr)
 boxes =(boxes * 2 ).astype(np.int32 ).clip(min=0, max=1023)
 image_id = image_ids[i]
boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
boxes[:, 3] = boxes[:, 3] - boxes[:, 1]
if count<10:
sample = cv2.resize(image.permute(1,2,0 ).cpu().numpy() ,(1024,1024))
for box, score in zip(boxes,scores):
cv2.rectangle(sample, 
(box[0], box[1]), 
(box[2]+box[0], box[3]+box[1]), 
(220, 0, 0), 2)
 cv2.putText(sample, '%.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(sample)
 count+=1
result = {
'image_id': image_id,
'PredictionString': format_prediction_string(boxes, scores)
 }
results.append(result)
<predict_on_test><EOS> 
test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])
 test_df.to_csv('submission.csv', index=False)
 test_df.head()