{"cells":[{"metadata":{"_uuid":"1276316cee77b0a6813d08acac63049e041a0b11","_cell_guid":"a58aa8e4-2152-8758-b2bc-5bdc987a1087"},"cell_type":"markdown","source":"A simple example model without utlising cnn. The purpose was to keep things as simple as possible. This is partially based on one of the existing pytorch mnist examples.\n\nDecided to share this as I feel that existing mnist examples on the Internet can sometimes be too confusing for beginners.\n\nThe script achieves ~97% accuracy."},{"metadata":{"_uuid":"0f93b33ca38d505e06a27821bcaf9ca30cea0d98","_cell_guid":"43aee7cc-92bd-046b-0d76-72576828a6f1","collapsed":true,"trusted":true},"cell_type":"code","source":"import torch\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau\nfrom torch.autograd import Variable\nimport torch.nn as nn","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e0ff92fa71b1769f94854d9f26f44a7fbc5ce6e0","_cell_guid":"ebe36349-f1b0-4c1b-94b0-d7bb214cfa98","trusted":true},"cell_type":"code","source":"%matplotlib inline\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport gc\nimport matplotlib.pyplot as plt\nfrom sklearn.cross_validation import train_test_split\nfrom sklearn.metrics import accuracy_score","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"86d74b6b505de1c1d4006b9842ad7b712142a299","_cell_guid":"ac6e00c6-fc90-4012-a963-0ccb8534aead","collapsed":true,"trusted":true},"cell_type":"code","source":"def predict(x):\n    return torch.topk(model(x), 1)[1].data.numpy().flatten()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"bf3e6e3cd8da115ddce1fa2aed65fcf5045d8fc9","_cell_guid":"5c687161-13ac-439a-9e21-e6ea8cee70b6","collapsed":true,"trusted":true},"cell_type":"code","source":"train = pd.read_csv('../input/train.csv')\ny = train.label.values.astype('int')\nx = train.drop('label', axis=1).values.astype('float32')\n\ntrain_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.1)\n\ndel train\ngc.collect();","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e08044afa4885101c6498e87db094556dbd66352","_cell_guid":"14502df6-1f2e-4b87-9b5b-db5ba8b9618a","collapsed":true,"trusted":true},"cell_type":"code","source":"# N is batch size; D_in is input dimension;\n# H is hidden dimension; D_out is output dimension.\n# N, D_in, H, D_out = 64, 784, 100, 10\n\n# Create random Tensors to hold inputs and outputs, and wrap them in Variables.\n# x = Variable(torch.randn(N, D_in))\n# y = Variable(torch.randn(N, D_out), requires_grad=False)\nx = Variable(torch.from_numpy(train_x))\nxt = Variable(torch.from_numpy(test_x))\ny = torch.from_numpy(np.reshape(train_y, (-1, 1)))\ny = torch.squeeze(y)\ny = Variable(y, requires_grad=False)\n\n# Use the nn package to define our model and loss function.\nmodel = nn.Sequential(\n    nn.Linear(784, 400),\n    nn.ReLU(),\n\n    nn.Linear(400, 200),\n    nn.ReLU(),    \n   \n    nn.Linear(200, 100),\n    nn.ReLU(),\n\n    nn.Linear(100, 50),\n    nn.ReLU(),\n\n    nn.Linear(50, 25),\n    nn.ReLU(),\n\n    nn.Linear(25, 10),\n)\n# loss_fn = torch.nn.MSELoss(size_average=False)\n# loss_fn = torch.nn.NLLLoss()\nloss_fn = nn.CrossEntropyLoss()\n\n# Use the optim package to define an Optimizer that will update the weights of\n# the model for us. Here we will use Adam; the optim package contains many other\n# optimization algoriths. The first argument to the Adam constructor tells the\n# optimizer which Variables it should update.\n\n# Setting high learning rate. Use ReduceLROnPlateau to gradually reduce learning\n# rate if accuracy stops improving\nlearning_rate = 1e-3\n\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\nscheduler = ReduceLROnPlateau(optimizer, 'max', factor = 0.5, verbose=True)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fff797b0f615ab2990985e88a87dc56fd3761433","_cell_guid":"5d15460e-8fb8-41ab-8691-646bbb805e31","trusted":true},"cell_type":"code","source":"def train():\n    y_pred = model(x)\n\n    # Compute and print loss.\n    global loss\n    loss = loss_fn(y_pred, y)\n\n    # Before the backward pass, use the optimizer object to zero all of the\n    # gradients for the variables it will update (which are the learnable weights\n    # of the model)\n    optimizer.zero_grad()\n\n    # Backward pass: compute gradient of the loss with respect to model\n    # parameters\n    loss.backward()\n\n    # Calling the step function on an Optimizer makes an update to its\n    # parameters\n    optimizer.step()\n\n# Run for 200 epochs\nfor t in range(200):\n    train()\n    accuracy = accuracy_score(test_y, predict(xt)) \n    \n    # This line is needed if we want accuracy to be automatically reduced if the\n    # accuracy stops improving     \n    scheduler.step(accuracy)\n    \n    print('Epoch:{0} Loss:{1} Test accuracy:{2}'.format(scheduler.last_epoch, \n                                                        loss.data[0], accuracy),\n                                                         )","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e90872050930f0e182e94b956dae6f8609433701","_cell_guid":"4736da6f-08a8-401a-912a-0889215f05f0","trusted":true},"cell_type":"code","source":"acc = accuracy_score(test_y, predict(xt))\nprint('Achieved accuracy: {0}'.format(acc))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"51149bc2bb8374b068230ff17519a86430726c0f","_cell_guid":"8c8ba6df-c530-46d0-a0bd-09c773a300eb","collapsed":true},"cell_type":"markdown","source":"Produce predictions for the submission"},{"metadata":{"_uuid":"683ad754dbb48feb4e584cefd569a3615b2c04f1","_cell_guid":"2aaecbab-80fb-424a-bd66-a754bc033a0a","collapsed":true,"trusted":true},"cell_type":"code","source":"submit = pd.read_csv('../input/test.csv').values.astype('float32')\nsubmit = Variable(torch.from_numpy(submit))\nsubmit = pd.DataFrame({'ImageID': range(1,28001), 'Label': predict(submit)})\nsubmit.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"version":"3.6.4","pygments_lexer":"ipython3","file_extension":".py","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"name":"python","nbconvert_exporter":"python"},"_change_revision":0,"_is_fork":false},"nbformat":4,"nbformat_minor":4}