{"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_minor":4,"nbformat":4,"cells":[{"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)\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\nimport os\nfor 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 20GB 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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch                        # The core package of Torch\nimport torch.nn as nn               # The nn package is used for building neural networks\nimport torch.nn.functional as F     # Contains all the functions in the torch.nn library\n\nfrom sklearn.model_selection import train_test_split\nimport scikitplot as skplt\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test=pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Train data shape:\", train_data.shape)\nprint(\"Test data shape:\", test.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_counts  = train_data[\"label\"].value_counts().sort_index()\nlabel_counts.plot.bar()\nplt.hlines(xmin = -4, xmax = 100, y = 4000, linestyles='dotted')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.head(20)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_all = train_data.iloc[:,1:]     # only features (pixels)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_all.head(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_all_label = train_data[\"label\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_all_numpy = train_all.to_numpy()\ntrain_all_label_numpy = train_all_label.to_numpy()\ntest_numpy = test.to_numpy()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\ndef plot_img(data, label):\n    fig, axs = plt.subplots(4, 4) # 16 images\n    k = 0\n    for i in range(4):\n        for j in range(4):        \n            axs[i, j].imshow(data[k].astype('uint8').reshape(28, 28))   # plot image            \n            axs[i, j].set_ylabel(\"label:\" + str(label[k].item()))       # print label\n            k +=1\nplot_img(train_all_numpy, train_all_label_numpy)\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train, validation, train_label, validation_label = train_test_split(train_all_numpy, train_all_label_numpy, test_size=0.2)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train.shape)\nprint(train_label.shape)\nprint(validation.shape)\nprint(validation_label.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unique, counts_train = np.unique(train_label, return_counts=True)\nplt.subplot(1, 2, 1)\nplt.bar(unique, counts_train/len(train_label))\nunique, counts_val = np.unique(validation_label, return_counts=True)\nplt.subplot(1, 2, 2)\nplt.bar(unique, counts_val/len(validation_label))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_all_tensor = torch.as_tensor(train_all_numpy).type(torch.FloatTensor)\ntrain_all_label_tensor = torch.as_tensor(train_all_label_numpy)\ntest_tensor = torch.as_tensor(test_numpy).type(torch.FloatTensor)\n\ntrain_tensor = torch.as_tensor(train).type(torch.FloatTensor)\ntrain_label = torch.as_tensor(train_label)\n\nvalidation_tensor = torch.as_tensor(validation).type(torch.FloatTensor)\nvalidation_label = torch.as_tensor(validation_label)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class FNet(nn.Module):             \n    def __init__(self):\n        super(FNet, self).__init__()\n                   # 784 inputs, connects to hidden layer with 600 nodes\n        self.fc1 = nn.Linear(in_features=784, out_features=600)\n                   # 600 nodes connects to hidden layer with 500 nodes\n        self.fc2 = nn.Linear(in_features=600, out_features=500) \n                   # 500 nodes connects to hidden layer with 250 nodes\n        self.fc3 = nn.Linear(in_features=500, out_features=250) \n                   # connection between the last hidden layer \n                   # and the output layer (with 10 nodes)\n        self.fc4 = nn.Linear(in_features=250, out_features=10)  \n                                                                \n    def forward(self, x):\n        x = x.view(-1,784)          # Put all the entries of the image in the vector\n        x = F.relu(self.fc1(x))     # Input x into first layer and apply a ReLU\n                                    # to the nodes in this layer\n        x = F.relu(self.fc2(x))        \n        x = F.relu(self.fc3(x))\n        x = self.fc4(x)\n        return x ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_accuracy(predictions, true_labels):\n    _, predicted = torch.max(predictions, 1)\n    corrects = (predicted == true_labels).sum()\n    accuracy = 100.0 * corrects/len(true_labels)\n    return accuracy.item()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def training (dataloader, epochs, model, criterion, optimizer):\n\n    train_accuracies, train_losses = [], []\n    \n    # set the train mode\n    model.train()\n    \n    # loop over training dataset multiple times\n    for epoch in range(epochs):        \n\n        train_loss = 0 \n        train_accuracy = 0\n        num_batch = 0\n        \n        # iterate over all batches\n        for data, labels in dataloader:\n            \n            # zero the parameters gradient to not accumulate gradients from previous iteration\n            optimizer.zero_grad()\n            \n            # put data into the model\n            predictions = net(data)\n            \n            # calculate loss\n            loss = criterion(predictions, labels)\n            \n            # calculate accuracy\n            accurasy = get_accuracy(predictions, labels)\n            \n            # compute gradients\n            loss.backward()\n            \n            # change the weights\n            optimizer.step()\n            \n            num_batch += 1\n            train_loss += loss.item()\n            train_accuracy += accurasy\n    \n        epoch_accuracy = train_accuracy/num_batch\n        epoch_loss = train_loss/num_batch        \n        train_accuracies.append(epoch_accuracy)\n        train_losses.append(epoch_loss)\n        \n        print(\"Epoch: {}/{} \".format(epoch + 1, epochs),\n              \"Training Loss: {:.4f} \".format(epoch_loss),\n              \"Training accuracy: {:.4f}\".format(epoch_accuracy))\n    \n    return train_accuracies, train_losses","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.manual_seed(0)    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nbatch_size = 128                                          # Set the batch_size\ntrain_dataset = torch.utils.data.TensorDataset(train_tensor, train_label)\ntrainloader = torch.utils.data.DataLoader(train_dataset, batch_size = batch_size, shuffle = True)\n\n\nepochs = 40                                               # set number of epohs\n\nnet = FNet()                                              # initialize network\ncriterion = nn.CrossEntropyLoss()                         # set criterion\noptimizer = torch.optim.Adam(net.parameters(), lr = 3e-4) # set optimizer\n\n                                                          # start training process\ntrain_accuracies, train_losses = training(trainloader, epochs, net, criterion, optimizer)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_curves(epochs, train_losses, train_accuracies):\n    iters = range(1, epochs+1)\n    fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(15, 5))\n    fig.suptitle('Training Curve')\n    ax1.plot(iters, train_losses)\n    ax1.set_xlabel(\"Iterations\")\n    ax1.set_ylabel(\"Loss\")\n    ax2.plot(iters, train_accuracies, color = 'g')\n    ax2.set_xlabel(\"Iterations\")\n    ax2.set_ylabel(\"Training Accuracy\")\n    plt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_curves(epochs, train_losses, train_accuracies)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net.eval()    \n# get predictions\nval_predictions = net(validation_tensor)\nval_loss = criterion(val_predictions, validation_label)\nval_accurasy = get_accuracy(val_predictions, validation_label)\n \nprint(\"Loss: \", str(val_loss.item()), \"Accuracy: \", str(val_accurasy))\n\n# to get class with the maximum score as prediction\n_, val_predicted = torch.max(val_predictions.data,1)            \n\n# confusion matrix\nskplt.metrics.plot_confusion_matrix(validation_label, val_predicted, figsize=(5,5))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_img(validation, val_predicted)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_wrong = validation[validation_label != val_predicted]\nval_lab_wrong = val_predicted[validation_label != val_predicted]\n\nplot_img(val_wrong, val_lab_wrong)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.manual_seed(0)                                      # set seed to make results reproducible\n\nbatch_size = 128                                          # Set the batch_size\ntrain_all_dataset = torch.utils.data.TensorDataset(train_all_tensor, train_all_label_tensor)\ntrainloader = torch.utils.data.DataLoader(train_dataset, batch_size = batch_size, shuffle = True)\n\nepochs = 40                                               # set number of epohs\n\nnet = FNet()                                              # initialize network\ncriterion = nn.CrossEntropyLoss()                         # set criterion\noptimizer = torch.optim.Adam(net.parameters(), lr = 3e-4) # set optimizer\n\n                                                          # start training process\ntrain_accuracies, train_losses = training(trainloader, epochs, net, criterion, optimizer)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net.eval()  \n\n# get predictions for test data\ntest_predictions = net(test_tensor)\n\n# to get class with the maximum score as prediction\n_, test_predicted = torch.max(test_predictions.data,1)\n\n# Save results in the required format\noutput = pd.DataFrame({'ImageId': test.index + 1,\n                       'Label': test_predicted})\noutput.to_csv('submission.csv', index=False)\noutput.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}