Kaggle competition: Google Landmark Recognition 2020
<SOS> metric: GoogleGlobalAP Kaggle data source: landmark-recognition-2020<data_type_conversions>
print('Installing packages')
 !pip uninstall -y allennlp torch
!pip install /kaggle/input/torch16/torch-1.6.0cu101-cp37-cp37m-linux_x86_64.whl
!pip install /kaggle/input/pytorch-image-models/
!pip install /kaggle/input/yacs-yet-another-configuration-system/yacs
!pip install /kaggle/input/landmark-lib/
!pip install /kaggle/input/semantic-segmentation-pytorch/
!pip install /kaggle/input/superpoint-pytorch/
print('Installed packages' )
train_df = train_df.drop(['index'],axis=1)
 test_df = test_df.drop(['index','TARGET'],axis=1)
 train_df = train_df.fillna(0)
 test_df = test_df.fillna(0 )<split>
os.environ["LRU_CACHE_CAPACITY"] = "3"
cv2.setNumThreads(0)
 cv2.ocl.setUseOpenCL(False)
 torch.set_grad_enabled(False)
label = u'TARGET'
a = list(train_df.columns)
 a.remove(label)
 labels = train_df[label]
data_only = train_df[list(a)]
col_name = data_only.columns
X_train, X_test, y_train, y_test = train_test_split(data_only, labels, test_size=0.1,random_state = 42 )<choose_model_class>
seed = 42
torch.manual_seed(seed)
 np.random.seed(seed)
 random.seed(seed )
clf_lgbm = LGBMClassifier(
 nthread=4,
n_estimators=10000,
learning_rate=0.02,
num_leaves=34,
colsample_bytree=0.9497036,
subsample=0.8715623,
max_depth=8,
reg_alpha=0.041545473,
reg_lambda=0.0735294,
min_split_gain=0.0222415,
min_child_weight=39.3259775,
silent=-1,
verbose=-1,)
 clf_lgbm.fit(X_train,y_train )<predict_on_test>
from superpoint_pytorch.models.superpoint import SuperPoint as SP
from superpoint_pytorch.models.superglue import SuperGlue as SG
pred = clf_lgbm.predict_proba(test_df)
 test_df['TARGET'] = pred[:, 0]<save_to_csv>
def load_weight(model, weight):
print(f"=> loading checkpoint {weight}")
 ckpt = torch.load(weight, "cpu")
 state_dict = ckpt.pop('state_dict')
 new_state_dict = {}
for k, v in state_dict.items() :
if k.endswith('seesaw_loss.N'):
continue
new_k = k
if new_k.startswith('module.'):
new_k = new_k[7:]
new_state_dict[new_k.replace("se_module", "se")] = v
model.load_state_dict(new_state_dict)
 print('=> loaded state dict' )
test_df[['SK_ID_CURR', 'TARGET']].to_csv('submission_clf_lgbm.csv', index= False )<set_options>
INPUT_DIR = os.path.join('.. ', 'input')
 DATASET_DIR = os.path.join(INPUT_DIR, 'landmark-recognition-2020')
 TEST_IMAGE_DIR = os.path.join(DATASET_DIR, 'test')
 TRAIN_IMAGE_DIR = os.path.join(DATASET_DIR, 'train')
 TRAIN_LABELMAP_PATH = os.path.join(DATASET_DIR, 'train.csv' )
%matplotlib inline
data_path=".. /input"<load_from_csv>
NUM_PUBLIC_TRAIN_IMAGES = 1580470
MAX_NUM_EMBEDDINGS = -1
NUM_TO_RERANK = 5
TOP_K = 3
MAX_INLIER_SCORE = 200
MAX_REPROJECTION_ERROR = 4.0
MAX_RANSAC_ITERATIONS = 1000
HOMOGRAPHY_CONFIDENCE = 0.99
data = pd.concat([pd.read_csv(os.path.join(data_path, "application_train.csv"), index_col="SK_ID_CURR"), pd.read_csv(os.path.join(data_path, "application_test.csv"), index_col="SK_ID_CURR")], axis=0)
 data.head()<count_values>
stride_factor = 1
rf, stride, padding = [291.0, 16.0 * stride_factor, 145.0]
feature_depth = 128
scales =(1,)
 ABS_THRESHOLD = 175
LOCAL_FEATURE_NUM_TENSOR = 1000
NMS_IOU = 1.
 NUM_EMBEDDING_DIMENSIONS = 512
data.TARGET.fillna(-1 ).value_counts()<data_type_conversions>
aug = Compose([
Normalize() ,
ToTensorV2() ,
] )
for c in data.select_dtypes(include="object"):
data[c] = data[c].astype("category" )<count_values>
def get_model(config_path, weight_path):
cfg = get_cfg()
cfg.merge_from_file(config_path)
 cfg.MODEL.BACKBONE.PRETRAINED = False
INTERP = cfg.DATA.INTERP
class GEMPoolExtractor(GEMPoolCNN):
def __init__(self, cfg):
super(GEMPoolExtractor, self ).__init__(cfg)
 def forward(self, images):
with autocast() :
features = self.backbone(images)
 features = [features[f] for f in self.in_features]
_, global_features = features
global_features = self.pool(global_features)
 return global_features
model = GEMPoolExtractor(cfg)
 load_weight(model, weight_path)
 del model.cls_head; gc.collect()
model.eval()
model = model.cuda()
return model, INTERP
model1, INTERP = get_model('/kaggle/input/landmark-lib/configs/google-landmark/resnext101_32x4d.yaml',
'/kaggle/input/best-resnext101-32x4d-cluster/best_resnext101_32x4d_clusterv2.pth')
 model2, INTERP = get_model('/kaggle/input/best-seresnet101-cluster/seresnet101.yaml',
'/kaggle/input/best-seresnet101-cluster/best_seresnet101_clusterv2.pth')
 model5, INTERP = get_model('/kaggle/input/landmark-lib/configs/google-landmark/resnext101_32x4d.yaml',
'/kaggle/input/best-resnext101-32x4d-cluster/best_resnext101_32x4d_clusterv2_sz736.pth')
 model6, INTERP = get_model('/kaggle/input/best-seresnet101-cluster/seresnet101.yaml',
'/kaggle/input/best-seresnet101-cluster/best_seresnet101_clusterv2_sz736.pth')
 MODELS = [model1, model2,
model5, model6]
MODEL_NAMES = ['resnext101_clusterv2', 'seresnet101_clusterv2',
'resnext101_clusterv2_sz736', 'seresnet101_clusterv2_sz736']
MODEL_WEIGHTS = [1.0] * 4
data.dtypes.value_counts()<load_from_csv>
def extract_global_features(image_root_dir, pre_compute=False):
image_paths = [x for x in pathlib.Path(image_root_dir ).rglob('*.jpg')]
num_embeddings = len(image_paths)
 print("Num images: ", num_embeddings)
 if MAX_NUM_EMBEDDINGS > 0:
num_embeddings = min(MAX_NUM_EMBEDDINGS, num_embeddings)
 ids = num_embeddings * [None]
embeddings = np.empty(( len(MODELS), num_embeddings, NUM_EMBEDDING_DIMENSIONS))
if pre_compute:
for m, name in enumerate(MODEL_NAMES):
emb_dict = torch.load(f"/kaggle/input/train-embeddings/{name}.pth", "cpu")
 for i, image_path in tqdm(enumerate(image_paths), total=num_embeddings):
image_id = image_path.stem
if image_id in emb_dict.keys() :
ids[i] = int(image_path.name.split('.')[0], 16)
 embeddings[m, i, :] = emb_dict[image_id].squeeze(0 ).numpy()
del emb_dict; gc.collect()
for i, image_path in tqdm(enumerate(image_paths), total=num_embeddings):
if i >= num_embeddings:
break
if ids[i] != None:
continue
ids[i] = int(image_path.name.split('.')[0], 16)
 image = np.array(Image.open(image_path ).convert('RGB'))
image = thumbnail(image)
 image = aug(image=image)['image']
image.unsqueeze_(0)
 image = image.cuda(non_blocking=True)
 for m in range(len(MODELS)) :
global_descriptors = MODELS[m](image)
 embeddings[m, i, :] = F.normalize(global_descriptors.sum(dim=0), dim=0 ).cpu().numpy()
return ids, embeddings
bureau = pd.read_csv(os.path.join(data_path, "bureau.csv"))
bureau.head()<load_from_csv>
def to_hex(image_id):
return '{0:0{1}x}'.format(image_id, 16)
 def get_image_path(data_dir, image_id):
name = to_hex(image_id)
 return os.path.join(data_dir, name[0], name[1], name[2],
'{}.jpg'.format(name))
bureau_balance = pd.read_csv(os.path.join(data_path, "bureau_balance.csv")).join(bureau.set_index("SK_ID_BUREAU" ).SK_ID_CURR, on="SK_ID_BUREAU" )<categorify>
def get_total_score(num_inliers, global_score):
local_score = min(num_inliers + 1, MAX_INLIER_SCORE)/ MAX_INLIER_SCORE
return local_score * global_score
bureau_balance_dumies = pd.get_dummies(bureau_balance.STATUS)
 bureau_balance_dumies["SK_ID_CURR"] = bureau_balance.SK_ID_CURR
bureau_balance_dumies = bureau_balance_dumies.groupby("SK_ID_CURR" ).sum()<define_variables>
local_extractor = SP({
'keypoint_threshold': 0.001,
'max_keypoints': 2048,
"seg_backbone": "hrnetv2",
'seg_mask': True,
'homographic': False,
})
 local_matcher = SG({'match_threshold': 0.2, 'weights': 'outdoor', 'sinkhorn_iterations': 150})
 local_extractor.eval()
local_matcher.eval()
local_extractor = local_extractor.cuda()
local_matcher = local_matcher.cuda()
print('Finished loading SuperPoint + SuperGlue' )
irregular = ["bureau_balance_status_" + c for c in bureau_balance_dumies if c not in ["0", "C", "X"]]
very_irregular = ["bureau_balance_status_" + c for c in bureau_balance_dumies if c not in ["0", "1", "2", "C", "X"]]<rename_columns>
def get_num_inliers_superglue(data, local_matcher=local_matcher):
scores = local_matcher(data)['matching_scores0']
num_inliers = torch.clamp(scores, 0.0, 1.0 ).sum().item()
return num_inliers
bureau_balance_dumies.columns = ["bureau_balance_status_" + c for c in bureau_balance_dumies]<feature_engineering>
HEIGHT, WIDTH = 896, 672
def rescore_and_rerank_by_num_inliers(test_image_id,
train_ids_labels_and_scores):

 def load_image(image_path):
image = np.array(Image.open(image_path ).convert("RGB"))
image = functional.resize(image, height=HEIGHT, width=WIDTH, interpolation=cv2.INTER_LINEAR)
 image = image.astype(np.float32)/ 255.
 image = torch.from_numpy(image ).permute(2, 0, 1)
 return image
image_paths = []
image_paths.append(get_image_path(TEST_IMAGE_DIR, test_image_id))
for i in range(len(train_ids_labels_and_scores)) :
train_image_id, _, _ = train_ids_labels_and_scores[i]
image_paths.append(get_image_path(TRAIN_IMAGE_DIR, train_image_id))
images = torch.stack([load_image(p)for p in image_paths], 0)
 images = images.cuda(non_blocking=True)
 outputs = local_extractor({"image": images})
 data = {}
for k, v in outputs.items() :
data[k+'0'] = v[0][None]
data['image_shape0'] = data['image_shape1'] = [HEIGHT, WIDTH]
for i in range(len(train_ids_labels_and_scores)) :
train_image_id, label, global_score = train_ids_labels_and_scores[i]
for k, v in outputs.items() :
data[k+'1'] = v[i+1][None]
num_inliers = get_num_inliers_superglue(data)
 total_score = get_total_score(num_inliers, global_score)
 train_ids_labels_and_scores[i] =(train_image_id, label, total_score)
 train_ids_labels_and_scores.sort(key=lambda x: x[2], reverse=True)
 return train_ids_labels_and_scores
bureau_balance_dumies["total_balances"] = bureau_balance_dumies.sum(axis=1)
 bureau_balance_dumies["irregular_bureau_balance"] = bureau_balance_dumies[irregular].sum(axis=1)
 bureau_balance_dumies["irregular_bureau_balance_ratio"] = bureau_balance_dumies["irregular_bureau_balance"] / bureau_balance_dumies["total_balances"]
bureau_balance_dumies["very_irregular_bureau_balance"] = bureau_balance_dumies[very_irregular].sum(axis=1)
 bureau_balance_dumies["very_irregular_bureau_balance_ratio"] = bureau_balance_dumies["very_irregular_bureau_balance"] / bureau_balance_dumies["total_balances"]
bureau_balance_dumies["super_irregular_bureau_balance_ratio"] = bureau_balance_dumies["bureau_balance_status_5"] / bureau_balance_dumies["total_balances"]
bureau_balance_dumies.head(100 )<drop_column>
def load_labelmap() :
with open(TRAIN_LABELMAP_PATH, mode='r')as csv_file:
csv_reader = csv.DictReader(csv_file)
 labelmap = {row['id']: row['landmark_id'] for row in csv_reader}
return labelmap
extended_data = [bureau_balance_dumies]
del bureau_balance_dumies, bureau_balance<count_values>
def get_prediction_map(test_ids, train_ids_labels_and_scores):

 prediction_map = dict()
for test_index, test_id in enumerate(test_ids):
hex_test_id = to_hex(test_id)
 aggregate_scores = {}
for _, label, score in train_ids_labels_and_scores[test_index][:TOP_K]:
aggregate_scores[label] = aggregate_scores.get(label, 0)+ score
label, score = max(aggregate_scores.items() , key=operator.itemgetter(1))
prediction_map[hex_test_id] = {'score': score, 'class': label}
return prediction_map
for c in bureau.select_dtypes(["object"]):
display(bureau[c].value_counts(dropna=False ).to_frame() )<count_values>
def get_predictions(labelmap):

 test_ids, test_embeddings = extract_global_features(TEST_IMAGE_DIR)
 train_ids, train_embeddings = extract_global_features(TRAIN_IMAGE_DIR, pre_compute=True)
 test_embeddings = np.transpose(test_embeddings,(1, 0, 2)).reshape(test_embeddings.shape[0], -1)
 train_embeddings = np.transpose(train_embeddings,(1, 0, 2)).reshape(train_embeddings.shape[0], -1)
 train_ids_labels_and_scores = [None] * test_embeddings.shape[0]
for test_index in range(test_embeddings.shape[0]):
similarities = spatial.distance.cdist(test_embeddings[test_index][np.newaxis,...],
train_embeddings, 'cosine')
 distances = 1 - similarities
partition = np.argpartition(distances, NUM_TO_RERANK)[:NUM_TO_RERANK]
nearest = sorted([(train_ids[p], distances[p])for p in partition],
key=lambda x: x[1])
 train_ids_labels_and_scores[test_index] = [ 
(train_id, labelmap[to_hex(train_id)], 1.- cosine_distance)
 for train_id, cosine_distance in nearest
]
del test_embeddings
del train_embeddings
del labelmap
gc.collect()
pre_verification_predictions = get_prediction_map(
 test_ids, train_ids_labels_and_scores)
 for test_index, test_id in enumerate(test_ids):
train_ids_labels_and_scores[test_index] = rescore_and_rerank_by_num_inliers(
 test_id, train_ids_labels_and_scores[test_index])
 post_verification_predictions = get_prediction_map(
 test_ids, train_ids_labels_and_scores)
 return pre_verification_predictions, post_verification_predictions
bureau.groupby("SK_ID_CURR" ).CREDIT_CURRENCY.unique().apply(len ).value_counts()<categorify>
def save_submission_csv(predictions=None):

 if predictions is None:
shutil.copyfile(
 os.path.join(DATASET_DIR, 'sample_submission.csv'), 'submission.csv')
 return
with open('submission.csv', 'w')as submission_csv:
csv_writer = csv.DictWriter(submission_csv, fieldnames=['id', 'landmarks'])
 csv_writer.writeheader()
for image_id, prediction in predictions.items() :
label = prediction['class']
score = prediction['score']
csv_writer.writerow({'id': image_id, 'landmarks': f'{label} {score}'})
<concatenate><EOS> 
def subsample(x, n=32):
out = dict()
for k in list(x.keys())[:n]:
out[k] = x[k]
return out
labelmap = load_labelmap()
num_training_images = len(labelmap.keys())
 print(f'Found {num_training_images} training images.')
 if num_training_images == NUM_PUBLIC_TRAIN_IMAGES:
TEST_IMAGE_DIR = "sample"
TRAIN_IMAGE_DIR = "sample"
_, post_verification_predictions = get_predictions(labelmap)
 if num_training_images == NUM_PUBLIC_TRAIN_IMAGES:
save_submission_csv()
else:
save_submission_csv(post_verification_predictions )