{"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\n\nimport 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\nfrom torch.utils.data import DataLoader\nimport torch.optim as optim\nfrom torchvision import transforms\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint (device)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\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))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"print (\"Reading data\")\ntrain_set = pd.read_csv(\"/kaggle/input/Kannada-MNIST/train.csv\")\nval_set = pd.read_csv(\"/kaggle/input/Kannada-MNIST/Dig-MNIST.csv\")\ntest_set = pd.read_csv(\"/kaggle/input/Kannada-MNIST/test.csv\")\n\ntrain_set = pd.concat([train_set, val_set], ignore_index=True)\n\ntrain_images = train_set.iloc[:, 1:]\ntrain_labels = train_set.iloc[:, 0]\nval_images = val_set.iloc[:, 1:]\nval_labels = val_set.iloc[:, 0]\ntest_images = test_set.iloc[:, 1:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_transform = transforms.Compose(([\n        transforms.ToPILImage(),\n        transforms.RandomCrop(28),\n        transforms.RandomAffine(degrees=5, translate=(0.1, 0.1)),\n        transforms.ToTensor(), # divides by 255\n        ]))\n\ntest_transform = transforms.Compose(([\n        transforms.ToPILImage(),\n        transforms.ToTensor(), # divides by 255\n        ]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class KannadaDataset(torch.utils.data.Dataset):\n    def __init__(self, images, labels=None, transforms=None):\n        self.X = images\n        self.y = labels\n        self.transforms = transforms\n                    \n    def __len__(self):\n        return len(self.X)\n    \n    def __getitem__(self, i):\n        #get item and convert it to numpy array\n        data = self.X.iloc[i, :]\n        data = np.array(data).astype(np.uint8).reshape(28, 28, 1) \n        \n        # perform transforms if there are any\n        if self.transforms:\n            data = self.transforms(data)\n        \n        if self.y is not None: # train/val\n            return (data, self.y[i])\n        else: # test\n            return data\n        \n\nprint (\"Dataset class created\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print (\"Defining network architecture\")\nclass network(nn.Module):\n    def __init__(self):\n        super(network, self).__init__()\n        self.conv1_5 = nn.Conv2d(in_channels=1, out_channels=64, kernel_size=5, padding=2)\n        self.conv1_5_bn = nn.BatchNorm2d(num_features=64)\n        self.conv1_3 = nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, padding=1)\n        self.conv1_3_bn = nn.BatchNorm2d(num_features=64)\n\n        self.conv2_5 = nn.Conv2d(in_channels=128, out_channels=128, kernel_size=5, padding=2)\n        self.conv2_5_bn = nn.BatchNorm2d(num_features=128)\n        self.conv2_3 = nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, padding=1)\n        self.conv2_3_bn = nn.BatchNorm2d(num_features=128)\n\n        self.conv3_5 = nn.Conv2d(in_channels=256, out_channels=256, kernel_size=5, padding=2)\n        self.conv3_5_bn = nn.BatchNorm2d(num_features=256)\n        self.conv3_3 = nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, padding=1)\n        self.conv3_3_bn = nn.BatchNorm2d(num_features=256)\n\n        self.fc1 = nn.Linear(in_features=512*6*6, out_features=512)\n        self.fc1_bn = nn.BatchNorm1d(num_features=512)\n\n        self.fc2 = nn.Linear(in_features=512, out_features=256)\n        self.fc2_bn = nn.BatchNorm1d(num_features=256)\n        \n        self.fc3 = nn.Linear(in_features=256, out_features=128)\n        self.fc3_bn = nn.BatchNorm1d(num_features=128)\n\n        self.fc4 = nn.Linear(in_features=128, out_features=64)\n        self.fc4_bn = nn.BatchNorm1d(num_features=64)\n\n        self.out = nn.Linear(in_features=64, out_features=10)\n\n\n    def forward(self, x):\n        x_5 = F.relu(self.conv1_5_bn(self.conv1_5(x))) #(64, 28, 28)\n        x_3 = F.relu(self.conv1_3_bn(self.conv1_3(x))) #(64, 28, 28)\n        x = F.max_pool2d(torch.cat((x_5, x_3), dim=1), kernel_size=2, stride=2) #(128, 14, 14)\n\n        x_5 = F.relu(self.conv2_5_bn(self.conv2_5(x))) #(128, 14, 14)\n        x_3 = F.relu(self.conv2_3_bn(self.conv2_3(x))) #(128, 14, 14)\n        x = F.max_pool2d(torch.cat((x_5, x_3), dim=1), kernel_size=2, stride=2) #(256, 7, 7)\n\n        x_5 = F.relu(self.conv3_5_bn(self.conv3_5(x))) #(256, 7, 7)\n        x_3 = F.relu(self.conv3_3_bn(self.conv3_3(x))) #(256, 7, 7)\n        x = F.max_pool2d(torch.cat((x_5, x_3), dim=1), kernel_size=2, stride=1) #(512, 6, 6)\n\n        x = F.relu(self.fc1_bn(self.fc1(x.view(-1, 6*6*512)))) #(512)\n        x = F.relu(self.fc2_bn(self.fc2(x))) #(256)\n        x = F.relu(self.fc3_bn(self.fc3(x))) #(128)\n        x = F.relu(self.fc4_bn(self.fc4(x))) #(64)\n        x = self.out(x) #(10)\n\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"net = network().to(device)\nlr = 0.001\nbatch_size = 100\nmax_epochs = 15","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_set = KannadaDataset(train_images, train_labels, train_transform)\nval_set = KannadaDataset(val_images, val_labels, test_transform)\ntrain_data = DataLoader(train_set, batch_size=batch_size, shuffle=True)\nval_data = DataLoader(val_set, batch_size=batch_size, shuffle=False)\n\nprint (\"Begin training\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = optim.SGD(net.parameters(), lr=lr, momentum=0.9)\nscheduler = optim.lr_scheduler.StepLR(optimizer, 4, gamma=0.1)\nfor epoch in range(max_epochs):\n    epoch_loss = 0.\n    epoch_accuracy = 0.\n\n    net.train()\n    for i, (images, labels) in enumerate(train_data):\n        images = images.to(device)\n        labels = labels.to(device)\n\n        optimizer.zero_grad()\n        outputs = net(images)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        _, predicted = torch.max(outputs, 1)\n        if (i+1) % 100 == 0:\n            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, max_epochs, i+1, len(train_set)//batch_size, loss.item()))\n    \n#     net.eval()\n#     with torch.no_grad():\n#         val_accuracy = 0.\n#         for images, labels in val_data:\n#             images = images.to(device)\n#             labels = labels.to(device)\n\n#             outputs = net(images)\n#             _, predicted = torch.max(outputs, 1)\n#             val_accuracy += (predicted==labels).sum().item()\n#     print('Validation accuracy is: {} %'.format(100 * val_accuracy / len(val_set)))\n    scheduler.step()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_set = KannadaDataset(images=test_images, transforms=test_transform)\ntest_data = DataLoader(test_set, batch_size=1, shuffle=False)\n\nnet.eval()\npredictions = torch.LongTensor().to(device)\nwith torch.no_grad():\n    for images in test_data:\n        images = images.to(device)\n\n        outputs = net(images)\n        predictions = torch.cat((predictions, outputs.argmax(dim=1)), dim=0)\n\nsubmission = pd.read_csv(\"/kaggle/input/Kannada-MNIST/sample_submission.csv\")\nsubmission['label'] = predictions.cpu().numpy()\nsubmission.to_csv(\"/kaggle/working/submission.csv\", index=False)\nprint (\"Output written to csv file!\")","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":4}