Kaggle competition: Cassava Leaf Disease Classification
<SOS> metric: CategorizationAccuracy Kaggle data source: cassava-leaf-disease-classification<set_options>
debug = True
MODEL_DIR = '.. /input/20t-efficientnet-b3-cutmix-tta'
%matplotlib inline 
<install_modules>
OUTPUT_DIR = './'
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
 TRAIN_PATH = '.. /input/cassava-leaf-disease-classification/train_images'
TEST_PATH = '.. /input/cassava-leaf-disease-classification/test_images'
assert len(glob.glob(f'{MODEL_DIR}/*.yml')) ==1
config_path = glob.glob(f'{MODEL_DIR}/*.yml')[0]
!git clone https://github.com/radekosmulski/whale 
<import_modules>
with open(config_path)as f:
config = yaml.load(f)
 INFO = config['info']
TAG = config['tag']
CFG = config['cfg']
CFG['train'] = False
CFG['inference'] = True
inference_batch_size = 8
from whale.utils import map5<set_options>
def get_result(result_df):
preds = result_df['preds'].values
labels = result_df['label'].values
score = get_score(labels, preds)
 LOGGER.info(f'Score: {score:<.5f}')
 return score
def get_aug_name(compose):
aug_list = []
for aug in compose:
aug_list.append(aug.__class__.__name__)
 return aug_list
def get_aug_score(aug_preds, labels, tta_list):
for i in range(aug_preds.shape[1]):
aug_pred = aug_preds[:,i,:]
aug_list = get_aug_name(tta_list[i])
 score = get_score(labels, aug_pred.argmax(1))
print(score, aug_list)
 LOGGER.info(f"========== aug: {aug_list} result ==========")
 LOGGER.info(f'Score: {score:<.5f}')
 def get_aug_csv(aug_preds, oof_df, tta_list):
for i in range(aug_preds.shape[1]):
base_df = oof_df.copy() [['image_id', 'label', 'fold']]
aug_pred = aug_preds[:,i,:]
base_df[[str(c)for c in range(5)]] = aug_pred
base_df['preds'] = aug_pred.argmax(1)
 aug_pred = aug_preds[:,i,:]
aug_list = get_aug_name(tta_list[i])
 csv_name = '-'.join(aug_list)
 base_df.to_csv(f'{OUTPUT_DIR}{csv_name}.csv', index=False )
fastprogress.fastprogress.NO_BAR = True
master_bar, progress_bar = force_console_behavior()
fastai.basic_train.master_bar, fastai.basic_train.progress_bar = master_bar, progress_bar<import_modules>
test = pd.read_csv('.. /input/cassava-leaf-disease-classification/sample_submission.csv')
 test.head()
from fastai import *
from fastai.vision import *<define_variables>
class TrainDataset(Dataset):
def __init__(self, df, transform=None):
self.df = df
self.file_names = df['image_id'].values
self.labels = df['label'].values
self.transform = transform
def __len__(self):
return len(self.df)
 def __getitem__(self, idx):
file_name = self.file_names[idx]
file_path = f'{TRAIN_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']
label = torch.tensor(self.labels[idx] ).long()
return image, label
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
path = Path('.. /input/humpback-whale-identification/')
 path_test = Path('.. /input/humpback-whale-identification/test')
 path_train = Path('.. /input/humpback-whale-identification/train' )<load_from_csv>
def _get_augmentations(aug_list):
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
df = pd.read_csv(path/'train.csv')
 df.head()
val_fns = {'69823499d.jpg'}<define_variables>
def get_transforms(*, aug_list):
return Compose(
 _get_augmentations(aug_list)
 )
fn2label = {row[1].Image: row[1].Id for row in df.iterrows() }
path2fn = lambda path: re.search('\w*\.jpg$', path ).group(0 )<define_variables>
class CustomModel(nn.Module):
def __init__(self, model_name, 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, CFG['target_size'])
 elif hasattr(self.model, 'fc'):
n_features = self.model.fc.in_features
self.model.fc = nn.Linear(n_features, CFG['target_size'])
 def forward(self, x):
x = self.model(x)
 return x
name = f'res50-full-train'<define_variables>
model = CustomModel(TAG['model_name'], pretrained=False)
 model_paths = glob.glob(f'{MODEL_DIR}/*.pth')
 model_paths.sort()
states = [torch.load(path)for path in model_paths]
test_dataset = TTADataset(test, TEST_PATH, ttas=ttas)
 test_loader = DataLoader(test_dataset, batch_size=inference_batch_size, shuffle=False,
num_workers=2, pin_memory=True)
 predictions = inference(model, states, test_loader, device)
 prediction = predictions.mean(1)
 test['label'] = prediction.argmax(1)
 test[['image_id', 'label']].to_csv(OUTPUT_DIR+'submission.csv', index=False)
 test.head()
SZ = 224
BS = 64
NUM_WORKERS = 0
SEED=0<define_variables>
def valid_inference(model, state, test_loader, device):
model.to(device)
 tk0 = tqdm(enumerate(test_loader), total=len(test_loader))
probs = []
for i,(images, labels)in tk0:
images = images.to(device)
 labels = labels.to(device)
 batch_size, n_crops, c, h, w = images.size()
images = images.view(-1, c, h, w)
 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 = y_preds.to('cpu' ).numpy()
probs.append(avg_preds)
 del images, labels, y_preds, avg_preds
torch.cuda.empty_cache()
probs = np.concatenate(probs)
 return probs
MODEL_PATH = "/kaggle/working/"<train_on_grid>
if debug:
train = pd.read_csv('.. /input/cassava-leaf-disease-classification/train.csv')
 folds = train.copy()
Fold = StratifiedKFold(n_splits=CFG['n_fold'], shuffle=True, random_state=CFG['seed'])
 for n,(train_index, val_index)in enumerate(Fold.split(folds, folds[CFG['target_col']])) :
folds.loc[val_index, 'fold'] = int(n)
 folds['fold'] = folds['fold'].astype(int)
 model_paths = glob.glob(f'{MODEL_DIR}/*.pth')
 model_paths.sort()
states = [torch.load(path)for path in model_paths]
oof_df = pd.DataFrame()
oof_aug_preds = []
for fold, state in enumerate(states):
val_idx = folds[folds['fold'] == fold].index
valid_folds = folds.loc[val_idx].reset_index(drop=True)
 valid_dataset = TTADataset(valid_folds, TRAIN_PATH, ttas=ttas)
 valid_loader = DataLoader(valid_dataset,
batch_size=inference_batch_size,
shuffle=False,
num_workers=CFG['num_workers'], pin_memory=True)
 valid_preds = valid_inference(model, state, valid_loader, device)
 valid_pred = valid_preds.mean(1)
 valid_folds[[str(c)for c in range(5)]] = valid_pred
valid_folds['preds'] = valid_pred.argmax(1)
 oof_df = pd.concat([oof_df, valid_folds])
 oof_aug_preds.append(valid_preds)
 LOGGER.info(f"========== fold: {fold} result ==========")
 _ = get_result(valid_folds)
 LOGGER.info(f"========== CV result ==========")
 score = get_result(oof_df)
 score_rem3 = get_result(oof_df.query('fold!=3'))
oof_aug_preds = np.concatenate(oof_aug_preds )
<define_variables><EOS> 
if debug:
LOGGER.info(f"========== augmentation result ==========")
 get_aug_score(oof_aug_preds, oof_df['label'], ttas)
 get_aug_csv(oof_aug_preds, oof_df, ttas )