{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import math\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport torch\nimport torch.nn as nn\nfrom tqdm import notebook\nimport torchvision","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_digit_dataset(df):\n    data = df.to_numpy(dtype=np.float32)\n    X = data[:,1:]\n    Y = data[:,:1]\n    X = torch.tensor(X).reshape((-1, 1, 28, 28)).to(device) / 255.0\n    Y = torch.tensor(Y, dtype=torch.int64).to(device)\n    return X, Y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# X_mnist, Y_mnist = load_digit_dataset(pd.read_csv('/kaggle/input/digit-recognizer/train.csv'))\nX_kannada, Y_kannada = load_digit_dataset(pd.read_csv('/kaggle/input/Kannada-MNIST/train.csv'))\nX_kannada_va, Y_kannada_va = load_digit_dataset(pd.read_csv('/kaggle/input/Kannada-MNIST/Dig-MNIST.csv'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # https://stackoverflow.com/a/45280846/2166741\n# plt.figure(figsize=(20,10))\n# columns = 5\n# for i in range(10):\n#     plt.subplot(10 / columns + 1, columns, i + 1)\n#     plt.imshow(X_mnist[i][0].cpu())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# https://stackoverflow.com/a/45280846/2166741\nplt.figure(figsize=(20,10))\ncolumns = 5\nfor i in range(10):\n    plt.subplot(10 / columns + 1, columns, i + 1)\n    plt.imshow(X_kannada[i][0].cpu())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# https://stackoverflow.com/a/45280846/2166741\nplt.figure(figsize=(20,10))\ncolumns = 5\nfor i in range(10):\n    plt.subplot(10 / columns + 1, columns, i + 1)\n    plt.imshow(X_kannada_va[i][0].cpu())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CustomTensorDataset(torch.utils.data.Dataset):\n    \"\"\"TensorDataset with support of transforms.\n    \"\"\"\n    def __init__(self, tensors, transform=None):\n        assert all(tensors[0].size(0) == tensor.size(0) for tensor in tensors)\n        self.tensors = tensors\n        self.transform = transform\n\n    def __getitem__(self, index):\n        x = self.tensors[0][index]\n\n        if self.transform:\n            x = self.transform(x)\n\n        y = self.tensors[1][index]\n\n        return x, y\n\n    def __len__(self):\n        return self.tensors[0].size(0)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"transform = torchvision.transforms.Compose([\n    torchvision.transforms.Lambda(lambda t: t.cpu()),\n    torchvision.transforms.ToPILImage(),\n    torchvision.transforms.RandomAffine(translate=(0.05, 0.05), scale=(0.95,1.05), degrees=5.),\n    torchvision.transforms.ToTensor(),\n    torchvision.transforms.Lambda(lambda t: t.to(device)),\n])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset = CustomTensorDataset([X_kannada, Y_kannada], transform=transform)\nte_va_dataset = CustomTensorDataset([X_kannada_va, Y_kannada_va], transform=transform)\ntr_dataset, va_dataset = torch.utils.data.random_split(dataset, [55000, 5000])\ntr_dataset = torch.utils.data.ConcatDataset([tr_dataset, te_va_dataset])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataloader = torch.utils.data.DataLoader(tr_dataset, batch_size=512, shuffle=True)\nva_dataloader = torch.utils.data.DataLoader(va_dataset, batch_size=512)\nte_va_dataloader = torch.utils.data.DataLoader(te_va_dataset, batch_size=512)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Fully convolutional network\nmodel = nn.Sequential(\n    nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3), # --> 26x26\n    nn.ReLU(),\n    nn.BatchNorm2d(64),\n    nn.Dropout2d(0.1),\n\n    nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3), # --> 24x24\n    nn.ReLU(),\n    nn.BatchNorm2d(64),\n    nn.Dropout2d(0.2),\n    \n    nn.MaxPool2d(kernel_size=2), # --> 12x12\n    \n    nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3), # --> 10x10\n    nn.ReLU(),\n    nn.BatchNorm2d(64),\n    nn.Dropout2d(0.3),\n    \n    nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3), # --> 8x8\n    nn.ReLU(),\n    nn.BatchNorm2d(64),\n    nn.Dropout2d(0.4),\n\n    nn.MaxPool2d(kernel_size=2), # --> 4x4\n\n    nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3), # --> 2x2\n    nn.ReLU(),\n    nn.BatchNorm2d(128),\n    nn.Dropout2d(0.5),\n    \n    nn.AvgPool2d(kernel_size=2), # --> 1x1\n    \n    nn.Conv2d(in_channels=128, out_channels=10, kernel_size=1, stride=1), # --> 1x1\n    nn.Flatten(),\n).to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with torch.no_grad():\n    print(model(X_kannada[:1]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# conv = list(model.modules())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # https://stackoverflow.com/a/45280846/2166741\n# plt.figure(figsize=(20,10))\n# columns = 5\n# for i in range(10):\n#     plt.subplot(10 / columns + 1, columns, i + 1)\n#     plt.imshow(conv.weight.data[i][0].cpu())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer = torch.optim.Adam(model.parameters())\ncriterion = nn.CrossEntropyLoss()\nscheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lambda epoch: 0.99 ** (epoch))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"losses = []\nva_losses = []\nte_va_losses = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_epochs = 200\nfor epoch in notebook.tqdm(range(num_epochs)):\n    model.train()\n    mean_loss = 0.\n    count = 0\n    for x, y in dataloader:\n        count += 1\n        optimizer.zero_grad()\n        y_ = model(x)\n        loss = criterion(y_, y.flatten())\n        loss.backward()\n        optimizer.step()\n        mean_loss += loss.item()\n        losses.append(loss.item())\n    scheduler.step()\n    mean_loss /= count\n    print('Train Loss: {}'.format(mean_loss))\n    \n    with torch.no_grad():\n        model.eval()\n        mean_loss = 0.\n        count = 0\n        for x, y in va_dataloader:\n            count += 1\n            y_ = model(x)\n            loss = criterion(y_, y.flatten())\n            mean_loss += loss.item()\n        mean_loss /= count\n        print('Validation Loss: {}'.format(mean_loss))\n        va_losses.append(mean_loss)\n        \n    with torch.no_grad():\n        model.eval()\n        mean_loss = 0.\n        count = 0\n        for x, y in te_va_dataloader:\n            count += 1\n            y_ = model(x)\n            loss = criterion(y_, y.flatten())\n            mean_loss += loss.item()\n        mean_loss /= count\n        print('Test Validation Loss: {}'.format(mean_loss))\n        te_va_losses.append(mean_loss)\n    \n#     if epoch % 1 == 0:\n#         # https://stackoverflow.com/a/45280846/2166741\n#         nrows = 2\n#         ncols = 5\n#         plt.figure(figsize=(20, 10))\n#         for j in range(10):\n#             plt.subplot(nrows, ncols, j + 1)\n#             plt.imshow(conv.weight.data[j][0].cpu())\n#         plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(losses)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(va_losses)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # https://stackoverflow.com/a/45280846/2166741\n# nrows = 2\n# ncols = 5\n# plt.figure(figsize=(20, 10))\n# for j in range(10):\n#     plt.subplot(nrows, ncols, j + 1)\n#     plt.imshow(conv.weight.data[j][0].cpu())\n# plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_te, _ = load_digit_dataset(pd.read_csv('/kaggle/input/Kannada-MNIST/test.csv'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with torch.no_grad():\n    model.eval()\n    Y_te_pred = model(X_te)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Y_te_pred.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Y_te_pred_class = Y_te_pred.argmax(dim=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Y_te_pred_class.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.read_csv('/kaggle/input/Kannada-MNIST/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission['label'] = Y_te_pred_class.cpu()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('submission.csv',index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}