{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport random\nimport time","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# load data into pytorch tensors\ntrain_csv = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\n\ntrain_tensor = torch.tensor(train_csv.values)\ntrain_x = train_tensor[:-4000,1:].float()\ntrain_y = train_tensor[:-4000,:1].flatten()\n\nval_x = train_tensor[-4000:,1:].float()\nval_y = train_tensor[-4000:,:1].flatten()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# define neural net class\nclass Net(nn.Module):\n    def __init__(self, dims):\n        super(Net, self).__init__()\n        \n        self.layers_n = len(dims) - 1\n        self.layers = []\n\n        for i in range(1, self.layers_n + 1):\n            command = f\"self.fc{i} = nn.Linear(dims[0], dims[1])\\nself.layers.append(self.fc{i})\"\n            exec(command)\n            dims.pop(0)\n        \n        self.optimizer = optim.SGD(self.parameters(), lr=.001, momentum=.9)\n        self.loss_func = nn.CrossEntropyLoss()\n        \n    def forward(self, x):\n        for i in range(len(self.layers)-1):\n            layer = self.layers[i]\n            x = F.relu(layer(x))\n        last_layer = self.layers[-1]\n        x = last_layer(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# training loop\ndef train(net):\n    epochs = 2\n    batch_size = 64\n    batch_num = train_x.size()[0] // batch_size\n\n    loss_progress = []\n    for epoch in range(1):\n        for i in range(batch_num):\n            start_i = i * batch_size\n            end_i = start_i + batch_size\n            batch_x = train_x[start_i:end_i]\n            batch_y = train_y[start_i:end_i]\n\n            net.optimizer.zero_grad()\n            out = net(batch_x)\n            loss = net.loss_func(out, batch_y)\n            loss.backward()\n            net.optimizer.step()\n\n            if i % 10 == 0:\n                loss_progress.append(loss.item())\n    return loss_progress","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# define function to find accuracy of model from validation data\ndef accuracy(output, y):\n    preds = torch.argmax(output, dim=1)\n    return (preds == y).float().mean()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# initialize neural net\ndims = [[28*28, 100, 100, 100, 10], [28*28, 100, 100, 100, 100, 100, 10], [28*28, 1000, 1000, 10]]\nnets = list(map(lambda dim: Net(dim.copy()), dims))\n\ntimings = []\nloss_traces = []\nfor n in nets:\n    start_time = time.time()\n    \n    loss_trace = train(n)\n    loss_traces.append(loss_trace)\n    \n    end_time = time.time()\n    timings.append(end_time - start_time)\n\naccuracies = list(map(lambda net:\n                      {\"ta\": accuracy(net(train_x), train_y).item(),\n                      \"va\": accuracy(net(val_x),val_y).item()},\n                      nets))\nreport = []\n\nfor i in range(len(nets)):\n    d = {**accuracies[i], \"timing\":timings[i]}\n    report.append(d)\n\nfor i,d in enumerate(report):\n    print(i,d)\n    plt.plot(loss_traces[i])\n    plt.show()","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}