{"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"#Run 2 too check consistency in accuracy. last results : 0.98560\n\n#from fastai import *\n#from fastai.vision import *\n#DATAPATH = Path('/kaggle/input/Kannada-MNIST/')\n\n#import os\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n#    for filename in filenames:\n#        print(os.path.join(dirname, filename))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline\n\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nfrom fastai.vision import *\nfrom fastai.metrics import *\n\nimport os\npath = '/kaggle/input/Kannada-MNIST/'\nprint(os.listdir(path))\n\ndef random_seed(seed_value, use_cuda):\n    np.random.seed(seed_value) # cpu vars\n    torch.manual_seed(seed_value) # cpu  vars\n    random.seed(seed_value) # Python\n    if use_cuda: \n        torch.cuda.manual_seed(seed_value)\n        torch.cuda.manual_seed_all(seed_value) # gpu vars\n        torch.backends.cudnn.deterministic = True  #needed\n        torch.backends.cudnn.benchmark = False\n        \nrandom_seed(13,True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CustomImageList(ImageList):\n    def open(self, fn):\n        if(fn.size == 785):\n            fn = fn[1:]\n        img = fn.reshape(28,28)\n        img = np.stack((img,)*3, axis=-1)\n        return Image(pil2tensor(img, dtype=np.float32))\n    \n    @classmethod\n    def from_csv_custom(cls, path:PathOrStr, csv_name:str, imgIdx:int=1, header:str='infer', **kwargs)->'ItemList': \n        df = pd.read_csv(Path(path)/csv_name, header=header)\n        res = super().from_df(df, path=path, cols=0, **kwargs)\n        \n        res.items = df.iloc[:,imgIdx:].apply(lambda x: x.values / 255.0, axis=1).values\n        \n        return res\n    \n    @classmethod\n    def from_csv_custom_test(cls, path:PathOrStr, csv_name:str, imgIdx:int=1, header:str='infer', **kwargs)->'ItemList': \n        df = pd.read_csv(Path(path)/csv_name, header=header)\n        res = super().from_df(df, path=path, cols=0, **kwargs)\n        \n        res.items = df.iloc[:,imgIdx:].apply(lambda x: x.values / 255.0, axis=1).values\n        print(res)\n        return res\n    \n    \n    \n    @classmethod\n    def from_df_custom(cls, path:PathOrStr, df:DataFrame, imgIdx:int=1, header:str='', **kwargs)->'ItemList': \n        res = super().from_df(df, path=path, cols=0, **kwargs)\n        \n        res.items = df.iloc[:,imgIdx:].apply(lambda x: x.values / 255.0, axis=1).values\n        \n        return res","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = CustomImageList.from_csv_custom_test(path=path, csv_name='test.csv', imgIdx=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#additional_aug=[[jitter(magnitude=-0.01)]]\n\n\n\ndata = (CustomImageList.from_csv_custom(path=path, csv_name='train.csv', imgIdx=1)\n                .split_by_rand_pct(.02)\n                .label_from_df(cols='label') #cols='label'\n                .add_test(test, label=0)\n                .transform(get_transforms(do_flip=False,max_rotate=15,max_warp=0.4))\n                .databunch(bs=128, num_workers=0)\n                .normalize(imagenet_stats))\n\n#,xtra_tfms=[[jitter(magnitude=-0.01)]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.show_batch(rows=3, figsize=(5,5))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Process the training, testing and 'other' datasets, and then check to ensure the arrays look reasonable."},{"metadata":{"trusted":true},"cell_type":"code","source":"def conv2(ni,nf,stride=2,ks=5): return conv_layer(ni,nf,stride=stride,ks=ks)\n\n# Create a sequence of convolutional (`ni` to `nf`), ReLU (if `use_activ`) and batchnorm (if `bn`) layers.\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def mish(input):\n  return input * torch.tanh(F.softplus(input))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class BasicBlock(nn.Module):\n  expansion = 1\n\n  def __init__(self, in_planes, planes, stride=1):\n    super(BasicBlock, self).__init__()\n    self.conv1 = nn.Conv2d(\n        in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)\n    self.bn1 = nn.BatchNorm2d(planes)\n    self.conv2 = nn.Conv2d(\n        planes, planes, kernel_size=3, stride=1, padding=1, bias=False)\n    self.bn2 = nn.BatchNorm2d(planes)\n\n    self.shortcut = nn.Sequential()\n    if stride != 1 or in_planes != self.expansion * planes:\n      self.shortcut = nn.Sequential(\n          nn.Conv2d(\n              in_planes,\n              self.expansion * planes,\n              kernel_size=1,\n              stride=stride,\n              bias=False), nn.BatchNorm2d(self.expansion * planes))\n\n  def forward(self, x):\n    out = self.bn1(self.conv1(x))\n    out = mish(out)\n    out = self.bn2(self.conv2(out))\n    out = mish(out)\n    #out += nn.GroupNorm(Mish(self.shortcut(x)))\n    shrt = self.shortcut(x)\n    out += mish(shrt)\n    return out\n\n\nclass ResNet(nn.Module):\n\n  def __init__(self, block, num_blocks, num_classes=10):\n    super(ResNet, self).__init__()\n    self.in_planes = 64\n\n    self.conv1 = nn.Conv2d(\n        3, 64, kernel_size=3, stride=1, padding=1, bias=False)\n    self.bn1 = nn.BatchNorm2d(64)\n    self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)\n    self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)\n    self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)\n    self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)\n    self.linear = nn.Linear(512 * block.expansion, 200)\n    self.linear2 = nn.Linear(200, num_classes)\n    self.bn_1d_1 = nn.BatchNorm1d(num_features=200)\n    self.dropout = nn.Dropout(p=0.2)\n\n  def _make_layer(self, block, planes, num_blocks, stride):\n    strides = [stride] + [1] * (num_blocks - 1)\n    layers = []\n    for stride in strides:\n      layers.append(block(self.in_planes, planes, stride))\n      self.in_planes = planes * block.expansion\n    return nn.Sequential(*layers)\n\n  def forward(self, x):\n    out = self.bn1(self.conv1(x))\n    out = mish(out)\n    out = self.layer1(out)\n    out = self.layer2(out)\n    out = self.layer3(out)\n    out = self.layer4(out)\n    out = F.avg_pool2d(out, 4)\n    out = self.dropout(torch.flatten(out, 1))\n    out = self.linear(out)\n    out = self.dropout(mish(self.bn_1d_1(out)))\n    out = self.linear2(out)\n    return F.log_softmax(out, dim=1)\n\n\ndef ResNetCustom():\n  return ResNet(BasicBlock, [4, 4, 4, 4])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Reset the Seed just before the model is created to always start with the same weights. "},{"metadata":{"trusted":true},"cell_type":"code","source":"model = ResNetCustom()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nlearn = Learner(data, model, loss_func = nn.CrossEntropyLoss(), metrics=[accuracy])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(25)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit(1, 1e-5)  #Finetune loop\nlearn.fit(1, 3e-6)  #Finetune loop\nlearn.fit(1, 1e-6)\n#learn.fit(1, 3e-7)  #Finetune loop\n#learn.fit(1, 1e-7)  #Finetune loop\n#learn.fit(1, 3e-8)\n#learn.fit(1, 1e-8)  \n\n#learn.fit(3, 3e-9)#fine tune with very low LR","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# get the predictions\npredictions, *_ = learn.get_preds(DatasetType.Test)\nlabels = np.argmax(predictions, 1)\n# output to a file\nsubmission_df = pd.DataFrame({'id': list(range(0,len(labels))), 'label': labels})\nsubmission_df.to_csv(f'submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interp = ClassificationInterpretation.from_learner(learn)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interp.plot_confusion_matrix()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interp.plot_top_losses(9)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.3"}},"nbformat":4,"nbformat_minor":1}