Kaggle competition: Digit Recognizer
labels = [str(i)for i in range(19)]
for x in labels: df[x] = df['image_labels'].apply(lambda r: int(x in r.split('|')) )<count_unique_values>
!curl https://raw.githubusercontent.com/pytorch/xla/master/contrib/scripts/env-setup.py -o pytorch-xla-env-setup.py
unique_counts = {}
for lbl in labels:
unique_counts[lbl] = len(dfs[dfs.image_labels == lbl])
 full_counts = {}
for lbl in labels:
count = 0
for row_label in dfs['image_labels']:
if lbl in row_label.split('|'): count += 1
full_counts[lbl] = count
counts = list(zip(full_counts.keys() , full_counts.values() , unique_counts.values()))
counts = np.array(sorted(counts, key=lambda x:-x[1]))
counts = pd.DataFrame(counts, columns=['label', 'full_count', 'unique_count'])
 counts.set_index('label' ).T 
<prepare_x_and_y>
!python pytorch-xla-env-setup.py
nfold = 5
seed = 42
y = dfs[labels].values
X = dfs[['image_id', 'cell_id']].values
dfs['fold'] = np.nan
mskf = MultilabelStratifiedKFold(n_splits=nfold, random_state=seed)
 for i,(_, test_index)in enumerate(mskf.split(X, y)) :
dfs.iloc[test_index, -1] = i
dfs['fold'] = dfs['fold'].astype('int' )<feature_engineering>
!pip install pytorch_lightning --quiet
dfs['is_valid'] = False
dfs['is_valid'][dfs['fold'] == 0] = True<count_values>
torch_xla._XLAC._xla_get_devices()
dfs.is_valid.value_counts()<prepare_x_and_y>
torch.manual_seed(100)
 np.random.seed(100 )
def get_y(r): return r['image_labels'].split('|')
 get_y(dfs.loc[12] )<define_variables>
df = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')
 df.iloc[:3,:10]
sample_stats =([0.07237246, 0.04476176, 0.07661699], [0.17179589, 0.10284516, 0.14199627] )<define_variables>
df_train, df_val = train_test_split(df, test_size=.1, stratify=df.label )
dls.show_batch(nrows=3, ncols=3 )<choose_model_class>
def toX(df):
return df.values.astype(np.float32 ).reshape(-1,1,28,28)/ 127.5 - 1.
 class MnistDataLoader(object):
def __init__(self, df, bs):
self.X = toX(df.iloc[:, 1:])
 self.y = df.values[:, 0]
self.bs = bs
self.n_batches = int(np.ceil(df.shape[0] / bs))
def __len__(self):
return self.n_batches
def __iter__(self):
m = self.y.shape[0]
for i in range(self.n_batches):
idx = np.random.randint(0, m, self.bs)
 X = torch.tensor(self.X[idx])
 y = torch.tensor(self.y[idx])
 yield X, y
def get_learner(lr=1e-3):
opt_func = partial(Adam, lr=lr, wd=0.01, eps=1e-8)
 model = EfficientNet.from_pretrained("efficientnet-b5", advprop=True)
 model._fc = nn.Linear(2048, dls.c)
 learn = Learner(
 dls, model, opt_func=opt_func,
metrics=[accuracy_multi, PrecisionMulti() ]
).to_fp16()
return learn 
<choose_model_class>
class ResnetBlock(nn.Module):
def __init__(self, channels):
super(ResnetBlock, self ).__init__()
self.conv = nn.Sequential(
 nn.Conv2d(channels, channels, 3, 1, 1, bias=False),
nn.BatchNorm2d(channels),
nn.ReLU() ,
nn.Conv2d(channels, channels, 3, 1, 1, bias=False),
nn.BatchNorm2d(channels))
def forward(self, x):
x = F.relu(self.conv(x)+ x)
 x = F.max_pool2d(x, 2)
 return F.dropout2d(x,.2, self.training)
 class MiniResnet(nn.Module):
def __init__(self, channels=32):
super(MiniResnet, self ).__init__()
self.backbone = nn.Sequential(
 nn.Conv2d(1, channels, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(channels),
nn.ReLU() ,
ResnetBlock(channels),
ResnetBlock(channels)
)
 self.head = nn.Sequential(
 nn.Linear(channels*49, 256),
nn.ReLU() ,
nn.Dropout (.2),
nn.Linear(256,10))
def forward(self, x):
x = self.backbone(x)
 dims = np.prod(x.shape[1:])
 logits = self.head(x.view(-1, dims))
return logits
learn=get_learner()<find_best_params>
class MnistModule(pl.LightningModule):
def __init__(self):
super().__init__()
self.model = MiniResnet()
self.loss_fn = nn.CrossEntropyLoss()
def forward(self, X):
return self.model(X)
 def training_step(self, batch, batch_i):
X, y = batch
h = self.model(X)
 loss = self.loss_fn(h, y)
 self.log('train_loss', loss, on_step=False, on_epoch=True, prog_bar=True, logger=True)
 return loss
def validation_step(self, batch, batch_idx):
x, y = batch
h = self.model(x)
 loss = self.loss_fn(h, y)
 accuracy =(h.argmax(1)== y ).float().mean()
self.log('valid_loss', loss, on_step=False, on_epoch=True, logger=True)
 self.log('accuracy', accuracy, on_step=False, on_epoch=True, logger=True)
 def configure_optimizers(self):
opt = torch.optim.Adam(self.parameters())
 scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(opt, patience=2)
 return [opt], [{ 'scheduler': scheduler, 'monitor': 'valid_loss'}]
def predict(self, X):
with torch.no_grad() :
self.eval()
logits = self.model(X)
 return F.softmax(logits, 1)
 batch_size = 512
train_dl = MnistDataLoader(df_train, batch_size)
 val_dl = MnistDataLoader(df_val, batch_size)
 module = MnistModule()
trainer = pl.Trainer(max_epochs=30, tpu_cores=1,logger=SimpleLogger())
 trainer.fit(module, train_dl, val_dl )
learn.lr_find()<define_search_space>
x = torch.tensor(val_dl.X, device=module.device)
 h = module.predict(x ).cpu().numpy()
lr=3e-2<find_best_params>
y_hat = h.argmax(1)
(y_hat == val_dl.y ).mean()
learn.fine_tune(6,base_lr=lr )<import_modules>
df_test = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')
 df_sub = pd.read_csv('/kaggle/input/digit-recognizer/sample_submission.csv' )
from sklearn.metrics import multilabel_confusion_matrix as cm<split>
X = torch.tensor(toX(df_test), device = module.device)
 %time preds = module.predict(X )
val_targ = dfs[labels][dfs.is_valid == True].values<predict_on_test>
df_sub['Label'] = preds.argmax(1 ).cpu().numpy()
df_sub.to_csv('submission.csv', index=False )
<data_type_conversions><EOS> 
!rm *.whl
!rm *.py
!rm *.ckpt
!ls