Kaggle competition: Cassava Leaf Disease Classification
<SOS> metric: CategorizationAccuracy Kaggle data source: cassava-leaf-disease-classification<choose_model_class>
with open('.. /input/train-weights-optimization/best_weights.json', 'r')as f:
weights_dict = json.load(f)
 weights_dict
grid_xgb = GridSearchCV(XGBClassifier() , param_grid_xgb,
cv=RepeatedStratifiedKFold(n_splits=10, n_repeats=2, random_state=42),
scoring='accuracy', verbose=2, n_jobs=-1 )<train_model>
normal_configs = []
tta_configs = []
normal_model_dirs = []
tta_model_dirs = []
for model_dir in weights_dict.keys() :
assert len(glob.glob(f'{model_dir}/*.yml')) ==1
config_path = glob.glob(f'{model_dir}/*.yml')[0]
with open(config_path)as f:
config = yaml.load(f)
 if 'valid_augmentation' in config['tag'].keys() :
tta_model_dirs.append(model_dir)
 tta_configs.append(config)
 else:
normal_model_dirs.append(model_dir)
 normal_configs.append(config)
 TRAIN_PATH = '.. /input/cassava-leaf-disease-classification/train_images'
TEST_PATH = '.. /input/cassava-leaf-disease-classification/test_images'
OUTPUT_DIR = './'
grid_xgb.fit(X_train_fe, y_train )<init_hyperparams>
def get_score(y_true, y_pred):
return accuracy_score(y_true, y_pred)
 @contextmanager
def timer(name):
t0 = time.time()
LOGGER.info(f'[{name}] start')
 yield
LOGGER.info(f'[{name}] done in {time.time() - t0:.0f} s.')
 def seed_torch(seed=42):
random.seed(seed)
 os.environ['PYTHONHASHSEED'] = str(seed)
 np.random.seed(seed)
 torch.manual_seed(seed)
 torch.cuda.manual_seed(seed)
 torch.backends.cudnn.deterministic = True
params_xgb = {'colsample_bylevel': 0.7, 'learning_rate': 0.03, 'max_depth': 3,
'n_estimators': 400, 'reg_lambda': 15, 'subsample': 0.5}<choose_model_class>
test = pd.read_csv('.. /input/cassava-leaf-disease-classification/sample_submission.csv')
 test.head()
logreg = LogisticRegression(**params_logreg)
 svc = SVC(**params_svc)
 knn = KNeighborsClassifier(**params_knn)
 rfc = RandomForestClassifier(**params_random)
 gradient = GradientBoostingClassifier(**params_gradient)
 xgb = XGBClassifier(**params_xgb)
 estimators = [('logreg', logreg),('knn', knn),('svc', svc),('rfc', rfc),('gradient', gradient), 
('xgb', xgb)]
stack = StackingClassifier(estimators=estimators,
cv=10, n_jobs=-1 )<predict_on_test>
class TestDataset(Dataset):
def __init__(self, df, transform=None):
self.df = df
self.file_names = df['image_id'].values
self.transform = transform
def __len__(self):
return len(self.df)
 def __getitem__(self, idx):
file_name = self.file_names[idx]
file_path = f'{TEST_PATH}/{file_name}'
image = cv2.imread(file_path)
 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
 if self.transform:
augmented = self.transform(image=image)
 image = augmented['image']
return image
class TTADataset(Dataset):
def __init__(self, df, image_path, ttas):
self.df = df
self.file_names = df['image_id'].values
self.labels = df['label'].values
self.image_path = image_path
self.ttas = ttas
def __len__(self)-> int:
return len(self.df)
 def __getitem__(self, idx):
file_name = self.file_names[idx]
file_path = f'{self.image_path}/{file_name}'
image = cv2.imread(file_path)
 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
 imglist=[tta(image=image)['image'] for tta in self.ttas]
image=torch.stack(imglist)
 label = torch.tensor(self.labels[idx] ).long()
return image, label
y_preds = logreg.fit(X_train_fe, y_train ).predict(X_test_fe )<predict_on_test>
def _get_augmentations(aug_list, cfg):
process = []
for aug in aug_list:
if aug == 'Resize':
process.append(Resize(cfg['size'], cfg['size']))
elif aug == 'RandomResizedCrop':
process.append(RandomResizedCrop(cfg['size'], cfg['size']))
elif aug == 'CenterCrop':
process.append(CenterCrop(CFG['size'], CFG['size']))
elif aug == 'Transpose':
process.append(Transpose(p=0.5))
elif aug == 'HorizontalFlip':
process.append(HorizontalFlip(p=0.5))
elif aug == 'VerticalFlip':
process.append(VerticalFlip(p=0.5))
elif aug == 'ShiftScaleRotate':
process.append(ShiftScaleRotate(p=0.5))
elif aug == 'Normalize':
process.append(Normalize(
 mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225], 
))
else:
raise ValueError(f'{aug} is not suitable')
 process.append(ToTensorV2())
 return process
y_preds = svc.fit(X_train_fe, y_train ).predict(X_test_fe )<predict_on_test>
def get_transforms(*, aug_list, cfg):
return Compose(
 _get_augmentations(aug_list, cfg)
 )
y_preds = knn.fit(X_train_fe, y_train ).predict(X_test_fe )<train_model>
class CustomModel(nn.Module):
def __init__(self, model_name, target_size, pretrained=False):
super().__init__()
self.model = timm.create_model(model_name, pretrained=pretrained)
 if hasattr(self.model, 'classifier'):
n_features = self.model.classifier.in_features
self.model.classifier = nn.Linear(n_features, target_size)
 elif hasattr(self.model, 'fc'):
n_features = self.model.fc.in_features
self.model.fc = nn.Linear(n_features, target_size)
 elif hasattr(self.model, 'head'):
n_features = self.model.head.in_features
self.model.head = nn.Linear(n_features, target_size)
 def forward(self, x):
x = self.model(x)
 return x
y_preds = rfc.fit(X_train_fe, y_train ).predict(X_test_fe )<train_model>
def inference_normal(model, states, test_loader, device):
model.to(device)
 tk0 = tqdm(enumerate(test_loader), total=len(test_loader))
probs = []
for i,(images)in tk0:
images = images.to(device)
 avg_preds = []
for state in states:
model.load_state_dict(state['model'])
 model.eval()
with torch.no_grad() :
y_preds = model(images)
 avg_preds.append(y_preds.softmax(1 ).to('cpu' ).numpy())
 avg_preds = np.mean(avg_preds, axis=0)
 probs.append(avg_preds)
 probs = np.concatenate(probs)
 return probs
def inference_tta(model, states, tta_loader, device):
model.to(device)
 tk0 = tqdm(enumerate(tta_loader), total=len(tta_loader))
probs = []
for i,(images, _)in tk0:
images = images.to(device)
 batch_size, n_crops, c, h, w = images.size()
images = images.view(-1, c, h, w)
 avg_preds = []
for state in states:
model.load_state_dict(state['model'])
 model.eval()
with torch.no_grad() :
y_preds = model(images ).softmax(1)
 y_preds = y_preds.view(batch_size, n_crops,-1)
 avg_preds.append(y_preds.to('cpu' ).numpy())
 avg_preds = np.mean(avg_preds, axis=0)
 probs.append(avg_preds)
 del images, _, y_preds, avg_preds
torch.cuda.empty_cache()
probs = np.concatenate(probs)
 return probs.mean(1 )
y_preds = gradient.fit(X_train_fe, y_train ).predict(X_test_fe )<predict_on_test>
def main(config, model_dir):
INFO = config['info']
TAG = config['tag']
CFG = config['cfg']
CFG['train'] = False
CFG['inference'] = True
inference_batch_size = 64
seed_torch(seed=CFG['seed'])
 model = CustomModel(TAG['model_name'], CFG['target_size'], pretrained=False)
 states = [torch.load(path)for path in glob.glob(f'{model_dir}/*.pth')]
test_dataset = TestDataset(test, transform=get_transforms(aug_list=['Resize', 'Normalize'], cfg=CFG))
test_loader = DataLoader(test_dataset, batch_size=inference_batch_size, shuffle=False,
num_workers=CFG['num_workers'], pin_memory=True)
 predictions = inference_normal(model, states, test_loader, device)
 return predictions
def main_tta(config, model_dir):
INFO = config['info']
TAG = config['tag']
CFG = config['cfg']
CFG['train'] = False
CFG['inference'] = True
inference_batch_size = 8
seed_torch(seed=CFG['seed'])
 model = CustomModel(TAG['model_name'], CFG['target_size'], pretrained=False)
 states = [torch.load(path)for path in glob.glob(f'{model_dir}/*.pth')]
ttas = get_ttas(CFG)
 tta_dataset = TTADataset(test, TEST_PATH, ttas=ttas)
 tta_loader = DataLoader(tta_dataset, batch_size=inference_batch_size, shuffle=False,
num_workers=2, pin_memory=True)
 predictions = inference_tta(model, states, tta_loader, device)
 return predictions
y_preds = xgb.fit(X_train_fe, y_train ).predict(X_test_fe )<create_dataframe>
predictions_list = []
model_dir_list = []
for config, model_dir in zip(normal_configs, normal_model_dirs):
predictions_list.append(main(config, model_dir))
model_dir_list.append(model_dir)
 for config, model_dir in zip(tta_configs, tta_model_dirs):
predictions_list.append(main_tta(config, model_dir))
model_dir_list.append(model_dir)
submission = pd.DataFrame({'PassengerId':test.index,
'Survived':y_preds} )<save_to_csv>
predictions = np.zeros(predictions_list[0].shape, dtype=predictions_list[0].dtype)
 for i, key in zip(range(len(predictions_list)) , model_dir_list):
predictions += predictions_list[i] * weights_dict[key]
test['label'] = predictions.argmax(1)
 test[['image_id', 'label']].to_csv(OUTPUT_DIR+'submission.csv', index=False)
 test.head()