{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import time\nimport numpy as np\nfrom skimage.transform import warp, AffineTransform\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nimport torchvision.transforms as transforms\nfrom torch.utils.data import DataLoader, Dataset, random_split\nimport torchvision.transforms as transforms\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\ndevice = \"cpu\"\nif torch.cuda.is_available():\n    device = torch.device('cuda:0')\nprint(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class DatasetMNIST(Dataset):\n    \n    def __init__(self, file_path, has_label=True):\n        self.data = pd.read_csv(file_path)\n        self._has_label = has_label\n        \n    def __len__(self):\n        return len(self.data)\n    \n    def __getitem__(self, index):\n        # load image as ndarray type (Height * Width * Channels)\n        # be carefull for converting dtype to np.uint8 [Unsigned integer (0 to 255)]\n        # in this example, i don't use ToTensor() method of torchvision.transforms\n        # so you can convert numpy ndarray shape to tensor in PyTorch (H, W, C) --> (C, H, W)\n        if self._has_label:\n            image = self.data.iloc[index, 1:].values.astype(np.float32).reshape((28, 28))\n            label = self.data.iloc[index, 0]\n        else:\n            image = self.data.iloc[index, 1:].values.astype(np.float32).reshape((28, 28))\n            label = []\n        \n        apply_ = np.random.random()\n        if apply_ >= 0.7:\n            # angle is in radian\n            tform = None\n            trans_ = np.random.random()\n            if trans_ <= 0.5:\n            # if 0.0 <= trans_ < 0.4:\n                angle = np.random.randint(35) * np.pi / 180\n                tform = AffineTransform(rotation=angle)\n                image = warp(image, tform.inverse, output_shape=image.shape)\n            # elif 0.4 <= trans_ < 0.8:\n            else:\n                angle = np.random.randint(25) * np.pi / 180\n                tform = AffineTransform(shear=angle)\n                image = warp(image, tform.inverse, output_shape=image.shape)\n            # elif 0.6 <= trans_ < 0.8:\n            # else:\n            #     image = random_noise(image, var=0.05)\n            # else:\n            #     image = image[:, ::-1]\n        image /= 255.0\n        image = torch.tensor(image.reshape(-1, 28, 28).astype(np.float32))\n        return image, label","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train = pd.read_csv(\"/kaggle/input/Kannada-MNIST/train.csv\")\ntrain.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 128\n\ntrain = DatasetMNIST(\"/kaggle/input/Kannada-MNIST/train.csv\")\ntest = DatasetMNIST(\"/kaggle/input/Kannada-MNIST/test.csv\", has_label=False)\n\ntrain_size = int(0.99 * len(train))\ntest_size = len(train) - train_size\ntrain, validation = random_split(train, [train_size, test_size])\n\ntrain_loader = DataLoader(train, batch_size=batch_size, shuffle=True)\nvalidation_loader = DataLoader(validation, batch_size=batch_size, shuffle=True)\ntest_loader = DataLoader(test, batch_size=batch_size, shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(13, 5))\nfor i, data in enumerate(train_loader):\n    inputs, labels = data\n    inputs = inputs * 255.0\n    imgs = inputs[:32]\n    for i, img in enumerate(imgs):\n        plt.subplot(4, 8, i+1)\n        plt.title(labels.numpy()[i])\n        plt.axis('off')\n        plt.imshow(img.numpy().reshape(28, 28), cmap=\"gray\")\n    break\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class NeuralNetwork(nn.Module):\n\n    def __init__(self):\n        super(NeuralNetwork, self).__init__()\n\n        self.conv1 = nn.Conv2d(1, 64, 3)\n        self.conv2 = nn.Conv2d(64, 64, 3)\n        self.conv1_bn = nn.BatchNorm2d(64)\n        self.mpool0 = nn.MaxPool2d(2, 1)\n        self.dp0 = nn.Dropout(0.1)\n        self.conv3 = nn.Conv2d(64, 64, 3)\n        self.conv4 = nn.Conv2d(64, 64, 3)\n        self.conv2_bn = nn.BatchNorm2d(64)\n        self.mpool1 = nn.MaxPool2d(2)\n        self.dp1 = nn.Dropout(0.1)\n        self.fc1 = nn.Linear(5184, 512)\n        self.fc2 = nn.Linear(512, 256)\n        self.fc2_bn = nn.BatchNorm1d(256)\n        self.dp2 = nn.Dropout(0.5)\n        self.fc3 = nn.Linear(256, 10)\n        self.softmax = nn.LogSoftmax(dim=1)\n\n    def forward(self, x):\n        x = F.relu(self.conv1(x))\n        x = self.mpool0(self.conv1_bn(F.relu(self.conv2(x))))\n        x = self.dp0(x)\n        x = F.relu(self.conv3(x))\n        x = self.mpool1(self.conv2_bn(F.relu(self.conv4(x))))\n        x = self.dp1(x)\n        x = x.view(-1, self.num_flat_features(x))\n        x = F.relu(self.fc1(x))\n        x = self.fc2_bn(F.relu(self.fc2(x)))\n        x = self.dp2(x)\n        x = self.fc3(x)\n        return self.softmax(x)\n\n    def num_flat_features(self, x):\n        size = x.size()[1:]\n        num_features = 1\n        for s in size:\n            num_features *= s\n        return num_features\n\nmodel = NeuralNetwork()\nmodel = model.to(device)\ncriterion = nn.CrossEntropyLoss().to(device)\noptimizer = optim.RMSprop(model.parameters(), lr=1e-3, weight_decay=1e-4)\nprint(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"loss_ = []\npred_ = []\nstart = time.time()\nfor epoch in range(12):\n    for i, data in enumerate(train_loader):\n        inputs, labels = data\n        # Forward\n        outputs = model(inputs.to(device))\n        loss = criterion(outputs.to(device), labels.to(device))\n        # Backward\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n    loss_.append(loss.item())\n    \n    pred = []\n    for i, data in enumerate(validation_loader):\n        inputs, labels = data\n        outputs = model(inputs.to(device))\n        _, predicted = torch.max(outputs.data, 1)\n        y_pred = predicted.cpu().numpy().ravel()\n        pred += list(y_pred == labels.cpu().numpy().ravel())\n    pred_.append(np.round(np.mean(pred), 5))\n    \n    # print statistics\n    if epoch % 1 == 0:\n        tm = time.time() - start\n        print('[%d] loss: %.10f, accuracy: %.3f, time: %.2f' % (epoch + 1, np.mean(loss_) / 2000, np.mean(pred), tm))\n        start = time.time()\n\nplt.figure(figsize=(7, 5))\nplt.subplot(1, 2, 1)\nplt.plot(loss_)\nplt.xlabel(\"Epocs\")\nplt.ylabel(\"Loss\")\nplt.subplot(1, 2, 2)\nplt.plot(pred_)\nplt.xlabel(\"Epocs\")\nplt.ylabel(\"Accuracy\")\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred = []\nfor i, data in enumerate(validation_loader):\n    inputs, labels = data\n    outputs = model(inputs.to(device))\n    _, predicted = torch.max(outputs.data, 1)\n    y_pred = predicted.cpu().numpy().ravel()\n    pred += list(y_pred == labels.cpu().numpy().ravel())\nprint(f\"{np.round(np.mean(pred) * 100, 2)}%\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred = []\nfor i, data in enumerate(test_loader):\n    inputs, labels = data\n    outputs = model(inputs.to(device))\n    _, predicted = torch.max(outputs.data, 1)\n    y_pred += list(predicted.cpu().numpy().ravel())\ny_pred = np.array(y_pred)\nprint(y_pred[:20])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = pd.DataFrame()\nsub[\"id\"] = list(range(0, y_pred.shape[0]))\nsub[\"label\"] = y_pred\nsub.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}