{"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":"#load packages: numpy, matplotlib, and pytorch\nimport torch\nimport os\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import Dataset, DataLoader, TensorDataset, random_split\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nfrom torch.optim import lr_scheduler\nimport numpy as np\nimport pandas as pd\nimport csv","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Put some augmentation on training data\ntrain_transform = transforms.Compose([\n    transforms.ToPILImage(),\n    #transforms.RandomAffine(degrees=5, translate=(0.1, 0.1), scale=(0.9, 1.1), shear=5),\n    transforms.ToTensor()\n])\n\n# Test data without augmentation\ntest_transform = transforms.Compose([\n    transforms.ToPILImage(),\n    transforms.ToTensor()\n])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data = pd.read_csv(\"../input/Kannada-MNIST/train.csv\")\ndt = train_data.values\nx_data = torch.from_numpy(dt[:,1:])\ny_data = torch.from_numpy(dt[:,0])\n\nx_cnn_data = x_data.reshape(60000, 1, 28, 28).float()\nfor data in x_cnn_data:\n    data = train_transform(data)\n    \ntrain_dataset = TensorDataset(x_cnn_data, y_data)\ntrain_dataset, dev_dataset = random_split(train_dataset, [50000, 10000])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_data = pd.read_csv(\"../input/Kannada-MNIST/test.csv\")\ndt_test = test_data.values\nx_test_data = torch.from_numpy(dt_test[:,1:]).reshape(-1,1,28,28).float()\nfor data in x_test_data:\n    data = test_transform(data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#set parameters\nnum_epochs = 20\nbatch_size = 128\nlearning_rate = 0.001","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create data generators - they will produce batches\ntrain_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)\ndev_loader = DataLoader(dataset=dev_dataset, batch_size=batch_size, shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class QzCNN(nn.Module):\n    def __init__(self):\n        super(QzCNN, self).__init__()\n        self.num_channels = 1\n        self.image_size = 28\n        self.num_labels = 10\n        self.conv2d_1 = nn.Conv2d(1, 32, 3, 1, padding=1)\n        self.bn1_1 = nn.BatchNorm2d(32)\n        self.conv2d_2 = nn.Conv2d(32, 32, 3, 1, padding=1)\n        self.bn1_2 = nn.BatchNorm2d(32)\n        self.conv2d_3 = nn.Conv2d(32, 64, 3, 1, padding=1)\n        self.bn1_3 = nn.BatchNorm2d(64)\n        self.conv2d_4 = nn.Conv2d(64, 64, 3, 1, padding=1)\n        self.bn1_4 = nn.BatchNorm2d(64)\n        self.conv2d_5 = nn.Conv2d(64, 128, 3, 1)\n        self.bn1_5 = nn.BatchNorm2d(128)\n        self.conv2d_6 = nn.Conv2d(128, 128, 3, 1, padding=1)\n        self.bn1_6 = nn.BatchNorm2d(128)\n        self.conv2d_7 = nn.Conv2d(128, 256, 3, 1)\n        self.bn1_7 = nn.BatchNorm2d(256)\n        self.conv2d_8 = nn.Conv2d(256, 256, 3, 1, padding=1)\n        self.bn1_8 = nn.BatchNorm2d(256)\n    \n        self.dense_1 = nn.Linear(4 * 4 * 256, 200)\n        self.bn2_1 = nn.BatchNorm1d(200)\n        self.dense_2 = nn.Linear(200, 200)\n        self.bn2_2 = nn.BatchNorm1d(200)\n        #self.Dropout = nn.Dropout(0.5)\n        self.dense_3 = nn.Linear(200, 10)\n\n\n    def forward(self, x):\n        x = F.relu(self.bn1_1(self.conv2d_1(x)))\n        x = F.relu(self.bn1_2(self.conv2d_2(x)))\n        x = F.max_pool2d(x, 2, 2)\n        x = F.relu(self.bn1_3(self.conv2d_3(x)))\n        x = F.relu(self.bn1_4(self.conv2d_4(x)))\n        x = F.relu(self.bn1_5(self.conv2d_5(x)))\n        x = F.max_pool2d(x, 2, 2)\n        x = F.relu(self.bn1_6(self.conv2d_6(x)))\n        x = F.relu(self.bn1_7(self.conv2d_7(x)))\n        x = F.relu(self.bn1_8(self.conv2d_8(x)))\n        #x = x.permute((0, 2, 3, 1))\n\n        x = x.reshape(-1, 4 * 4 * 256)\n        x = F.relu(self.bn2_1(self.dense_1(x)))\n        x = F.relu(self.bn2_2(self.dense_2(x)))\n        #x = self.Dropout(x)\n        x = self.dense_3(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = QzCNN().to(device)\n\nlossFunction = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\nscheduler = lr_scheduler.StepLR(optimizer,step_size=5,gamma = 0.7)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train(model, device, iterator, optimizer, criterion):\n    \n    epoch_loss = 0\n    epoch_acc = 0\n    \n    model.train()\n    \n    for (x, y) in iterator:\n        \n        x = x.to(device).float()\n        y = y.to(device)\n        \n        optimizer.zero_grad()\n                \n        fx = model(x)\n        \n        loss = criterion(fx, y)\n        \n        acc = calculate_accuracy(fx, y)\n        \n        loss.backward()\n        \n        optimizer.step()\n        \n        epoch_loss += loss.item()\n        epoch_acc += acc.item()\n        \n    return epoch_loss / len(iterator), epoch_acc / len(iterator)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def evaluate(model, device, iterator, criterion):\n    \n    epoch_loss = 0\n    epoch_acc = 0\n    \n    model.eval()\n    \n    with torch.no_grad():\n        for (x, y) in iterator:\n\n            x = x.to(device).float()\n            y = y.to(device)\n\n            fx = model(x)\n\n            loss = criterion(fx, y)\n\n            acc = calculate_accuracy(fx, y)\n\n            epoch_loss += loss.item()\n            epoch_acc += acc.item()\n        \n    return epoch_loss / len(iterator), epoch_acc / len(iterator)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def calculate_accuracy(fx, y):\n    preds = fx.max(1, keepdim=True)[1]\n    correct = preds.eq(y.view_as(preds)).sum()\n    acc = correct.float()/preds.shape[0]\n    return acc","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def predict(model, test_data):\n    predict_list = []\n    i = 0\n    with torch.no_grad():\n        for image in test_data:\n            model = model.to(device)\n            image = image.to(device).float()\n            image = image.unsqueeze(0)\n            output = model(image)\n            _, predicted = torch.max(output, 1)\n            predict_list.append(int(predicted[0]))\n            i += 1\n            \n    return predict_list","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"SAVE_DIR = '../models'\nMODEL_SAVE_PATH = os.path.join(SAVE_DIR, 'mnist.pt')\n\nbest_valid_loss = float('inf')\n\nif not os.path.isdir(f'{SAVE_DIR}'):\n    os.makedirs(f'{SAVE_DIR}')\n    \n#train network\nfor epoch in range(num_epochs):\n    train_loss, train_acc = train(model, device, train_loader, optimizer, lossFunction)\n    valid_loss, valid_acc = evaluate(model, device, dev_loader, lossFunction) \n    \n    '''if valid_loss < best_valid_loss:\n        best_valid_loss = valid_loss\n        torch.save(model.state_dict(), MODEL_SAVE_PATH)'''\n    \n    #print(f'| Epoch: {epoch+1:02} | Train Loss: {train_loss:.3f} | Train Acc: {train_acc*100:05.2f}% | ')\n    print(f'| Epoch: {epoch+1:02} | Train Loss: {train_loss:.3f} | Train Acc: {train_acc*100:05.2f}% | Val. Loss: {valid_loss:.3f} | Val. Acc: {valid_acc*100:05.2f}% |')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predicted_labels = predict(model, x_test_data)\ntest = pd.read_csv('../input/Kannada-MNIST/test.csv')\nmy_submission = pd.DataFrame({'id': test.id, 'Label': predicted_labels})\nmy_submission.to_csv('submission.csv', index=False)","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}