{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport torch.utils.data as data_util\nfrom tqdm import tqdm_notebook, tqdm\nfrom copy import deepcopy\nimport matplotlib.pyplot as plt\n\nimport os\nfor 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":"train_df = pd.read_csv('/kaggle/input/Kannada-MNIST/train.csv')\nval_df = pd.read_csv('/kaggle/input/Kannada-MNIST/Dig-MNIST.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def df_to_image(df):\n    imgs = []\n    labels = []\n    for idx in tqdm_notebook(range(len(df))):\n        row = df.iloc[idx].values\n        label, img = row[0], row[1:]\n        labels.append(label)\n        imgs.append(img.reshape(1, 28, 28).astype('uint8'))\n    \n    imgs = np.concatenate(imgs, axis=0)\n    labels = np.array(labels)\n    \n    return imgs, labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_img, train_label = df_to_image(train_df)\nval_img, val_label = df_to_image(val_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def random_plot(images, labels):\n    num = len(images)\n    idxs = np.random.choice(range(num), 9, replace=False)\n    fig, axes = plt.subplots(3, 3)\n    for plot_idx, arch in enumerate(idxs):\n        i = plot_idx % 3 # Get subplot row\n        j = plot_idx // 3 # Get subplot column\n        img = images[arch]\n#         axes[i, j].imshow(img, cmap='gray')\n        axes[i, j].imshow(img,)\n        axes[i, j].axis('off')\n        axes[i, j].set_title(f'{labels[arch]}')\n    plt.subplots_adjust(wspace=0.1, hspace=0.3)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"random_plot(train_img, train_label)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Build model"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"model = torchvision.models.resnet34()\nmodel.fc","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fc = nn.Linear(512, 10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.conv1 = nn.Conv2d(1, 64, kernel_size=(3), stride=1, padding=1) # stride=2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class DigDataset(data_util.Dataset):\n    def __init__(self, imgs, labels):\n        super(DigDataset, self).__init__()\n        self.imgs = imgs.reshape(-1, 28, 28, 1)\n        self.labels = labels\n        self.trans = torchvision.transforms.ToTensor()\n        \n    \n        \n    def __len__(self):\n        return len(self.labels)\n    \n    def __getitem__(self, idx):\n        img = self.imgs[idx]\n        label = self.labels[idx]\n        \n        return self.trans(img), torch.tensor(label)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# batch_size = 50 # ORIG\nbatch_size = 40\ntrain_set = DigDataset(train_img, train_label)\nval_set = DigDataset(val_img, val_label)\n\ntrain_loader = data_util.DataLoader(train_set, batch_size=batch_size, num_workers=2, pin_memory=True, shuffle=True)\nval_loader = data_util.DataLoader(val_set, batch_size=batch_size, num_workers=2, pin_memory=True, shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cuda = torch.cuda.is_available()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cuda","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def generate_matrix(gt, pre, num_class=10):\n        mask = (gt >= 0) & (gt < num_class)\n        label = num_class * gt[mask].astype('int') + pre[mask]\n        count = np.bincount(label, minlength=num_class**2)\n        confusion_matrix = count.reshape(num_class, num_class)\n        return confusion_matrix","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def do_train(model, optim, data_loader, epoch):\n    model.train()\n    confusion_matrix = np.zeros((10, 10))\n    tbar = tqdm_notebook(train_loader)\n    for img, label in tbar:\n        if cuda:\n            img, label = img.cuda(), label.cuda()\n        \n        optim.zero_grad()\n        logit = model(img)\n        loss = F.cross_entropy(logit, label)\n        loss.backward()\n        optim.step()\n        \n        pred = torch.argmax(logit, dim=1)\n        batch_acc = (pred == label).sum() / len(pred)\n        tbar.set_description(f'Train loss: {loss.item():.4f} acc: {batch_acc}')\n        confusion_matrix += generate_matrix(label.cpu().numpy(), pred.cpu().numpy())\n    \n    acc = np.diag(confusion_matrix).sum() / confusion_matrix.sum()\n    print(f'Epoch: {epoch_idx} acc: {acc}')\n    \ndef do_eval(model, data_loader, epoch):\n    model.eval()\n    confusion_matrix = np.zeros((10, 10))\n    tbar = tqdm_notebook(train_loader)\n    for img, label in tbar:\n        if cuda:\n            img, label = img.cuda(), label.cuda()\n        \n        with torch.no_grad():\n            logit = model(img)\n        loss = F.cross_entropy(logit, label)\n        \n        pred = torch.argmax(logit, dim=1)\n        batch_acc = (pred == label).sum() / len(pred)\n        tbar.set_description(f'Val loss: {loss.item():.4f} acc: {batch_acc}')\n        confusion_matrix += generate_matrix(label.cpu().numpy(), pred.cpu().numpy())\n    \n    acc = np.diag(confusion_matrix).sum() / confusion_matrix.sum()\n    print(f'Epoch: {epoch_idx} val acc: {acc}')\n    return acc","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epoch = 20\nif cuda:\n    model = model.cuda()\n    \noptim = torch.optim.Adam(params=model.parameters())\nbst_model = None\nbst_acc = 0.\nfor epoch_idx in range(epoch):\n    do_train(model, optim, train_loader, epoch_idx)\n    \n    val_acc = do_eval(model, val_loader, epoch_idx)\n    \n    if bst_acc < val_acc:\n        bst_model = deepcopy(model)\n        bst_acc = val_acc\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Test"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv('/kaggle/input/Kannada-MNIST/test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_img, ids = df_to_image(test_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_set = DigDataset(test_img, ids)\ntest_loader = data_util.DataLoader(test_set, batch_size=batch_size, num_workers=2, shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submit = {\n    'id': [],\n    'label': []\n}\nif cuda:\n    bst_model = bst_model.cuda()\nfor b_imgs, b_ids in tqdm_notebook(test_loader):\n    if cuda:\n        b_imgs = b_imgs.cuda()\n        \n    with torch.no_grad():\n        logit = bst_model(b_imgs)\n        \n    pred = torch.argmax(logit, dim=1)\n    pred = pred.cpu().numpy()\n    submit['label'].extend(pred.tolist())\n    submit['id'].extend(b_ids.cpu().numpy().tolist())\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submit_df = pd.DataFrame(submit)\nsubmit_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submit_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!head submission.csv","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}