{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import numpy as np\n", "import torch\n", "import torch.optim as optim\n", "\n", "torch.set_printoptions(edgeitems=2)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "torch.Size([11, 1])" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t_c = [0.5, 14.0, 15.0, 28.0, 11.0, 8.0, 3.0, -4.0, 6.0, 13.0, 21.0]\n", "t_u = [35.7, 55.9, 58.2, 81.9, 56.3, 48.9, 33.9, 21.8, 48.4, 60.4, 68.4]\n", "t_c = torch.tensor(t_c).unsqueeze(1) # <1>\n", "t_u = torch.tensor(t_u).unsqueeze(1) # <1>\n", "\n", "t_u.shape" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(tensor([ 0, 2, 8, 4, 10, 6, 7, 3, 1]), tensor([9, 5]))" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "n_samples = t_u.shape[0]\n", "n_val = int(0.2 * n_samples)\n", "\n", "shuffled_indices = torch.randperm(n_samples)\n", "\n", "train_indices = shuffled_indices[:-n_val]\n", "val_indices = shuffled_indices[-n_val:]\n", "\n", "train_indices, val_indices" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "t_u_train = t_u[train_indices]\n", "t_c_train = t_c[train_indices]\n", "\n", "t_u_val = t_u[val_indices]\n", "t_c_val = t_c[val_indices]\n", "\n", "t_un_train = 0.1 * t_u_train\n", "t_un_val = 0.1 * t_u_val" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[3.7056],\n", " [3.0721]], grad_fn=)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import torch.nn as nn\n", "\n", "linear_model = nn.Linear(1, 1) # <1>\n", "linear_model(t_un_val)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Parameter containing:\n", "tensor([[0.5508]], requires_grad=True)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "linear_model.weight" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Parameter containing:\n", "tensor([0.3785], requires_grad=True)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "linear_model.bias" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([0.9293], grad_fn=)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = torch.ones(1)\n", "linear_model(x)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[0.9293],\n", " [0.9293],\n", " [0.9293],\n", " [0.9293],\n", " [0.9293],\n", " [0.9293],\n", " [0.9293],\n", " [0.9293],\n", " [0.9293],\n", " [0.9293]], grad_fn=)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = torch.ones(10, 1)\n", "linear_model(x)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "linear_model = nn.Linear(1, 1) # <1>\n", "optimizer = optim.SGD(\n", " linear_model.parameters(), # <2>\n", " lr=1e-2)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "linear_model.parameters()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[Parameter containing:\n", " tensor([[0.1674]], requires_grad=True), Parameter containing:\n", " tensor([-0.9106], requires_grad=True)]" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(linear_model.parameters())" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "def training_loop(n_epochs, optimizer, model, loss_fn, t_u_train, t_u_val, t_c_train, t_c_val):\n", " for epoch in range(1, n_epochs + 1):\n", " t_p_train = model(t_un_train) # <1>\n", " loss_train = loss_fn(t_p_train, t_c_train)\n", "\n", " t_p_val = model(t_un_val) # <1>\n", " loss_val = loss_fn(t_p_val, t_c_val)\n", " \n", " optimizer.zero_grad()\n", " loss_train.backward() # <2>\n", " optimizer.step()\n", "\n", " if epoch == 1 or epoch % 1000 == 0:\n", " print('Epoch {}, Training loss {}, Validation loss {}'.format(\n", " epoch, float(loss_train), float(loss_val)))\n" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1, Training loss 353.4972839355469, Validation loss 249.63314819335938\n", "Epoch 1000, Training loss 3.388845920562744, Validation loss 4.086263656616211\n", "Epoch 2000, Training loss 2.8631906509399414, Validation loss 3.975735902786255\n", "Epoch 3000, Training loss 2.85408878326416, Validation loss 3.967984914779663\n", "\n", "Parameter containing:\n", "tensor([[5.4242]], requires_grad=True)\n", "Parameter containing:\n", "tensor([-17.2498], requires_grad=True)\n" ] } ], "source": [ "def loss_fn(t_p, t_c):\n", " squared_diffs = (t_p - t_c)**2\n", " return squared_diffs.mean()\n", "\n", "linear_model = nn.Linear(1, 1) # <1>\n", "optimizer = optim.SGD(linear_model.parameters(), lr=1e-2)\n", "\n", "training_loop(\n", " n_epochs = 3000, \n", " optimizer = optimizer,\n", " model = linear_model,\n", " loss_fn = loss_fn,\n", " t_u_train = t_un_train,\n", " t_u_val = t_un_val, \n", " t_c_train = t_c_train,\n", " t_c_val = t_c_val)\n", "\n", "print()\n", "print(linear_model.weight)\n", "print(linear_model.bias)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1, Training loss 340.8567199707031, Validation loss 239.55545043945312\n", "Epoch 1000, Training loss 3.368995428085327, Validation loss 4.082926273345947\n", "Epoch 2000, Training loss 2.862844467163086, Validation loss 3.975551128387451\n", "Epoch 3000, Training loss 2.854081630706787, Validation loss 3.96795916557312\n", "\n", "Parameter containing:\n", "tensor([[5.4243]], requires_grad=True)\n", "Parameter containing:\n", "tensor([-17.2506], requires_grad=True)\n" ] } ], "source": [ "linear_model = nn.Linear(1, 1)\n", "optimizer = optim.SGD(linear_model.parameters(), lr=1e-2)\n", "\n", "training_loop(\n", " n_epochs = 3000, \n", " optimizer = optimizer,\n", " model = linear_model,\n", " loss_fn = nn.MSELoss(), # <1>\n", " t_u_train = t_un_train,\n", " t_u_val = t_un_val, \n", " t_c_train = t_c_train,\n", " t_c_val = t_c_val)\n", "\n", "print()\n", "print(linear_model.weight)\n", "print(linear_model.bias)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Sequential(\n", " (0): Linear(in_features=1, out_features=13, bias=True)\n", " (1): Tanh()\n", " (2): Linear(in_features=13, out_features=1, bias=True)\n", ")" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "seq_model = nn.Sequential(\n", " nn.Linear(1, 13), # <1>\n", " nn.Tanh(),\n", " nn.Linear(13, 1)) # <2>\n", "seq_model" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[torch.Size([13, 1]), torch.Size([13]), torch.Size([1, 13]), torch.Size([1])]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[param.shape for param in seq_model.parameters()]" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.weight torch.Size([13, 1])\n", "0.bias torch.Size([13])\n", "2.weight torch.Size([1, 13])\n", "2.bias torch.Size([1])\n" ] } ], "source": [ "for name, param in seq_model.named_parameters():\n", " print(name, param.shape)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Sequential(\n", " (hidden_linear): Linear(in_features=1, out_features=8, bias=True)\n", " (hidden_activation): Tanh()\n", " (output_linear): Linear(in_features=8, out_features=1, bias=True)\n", ")" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from collections import OrderedDict\n", "\n", "seq_model = nn.Sequential(OrderedDict([\n", " ('hidden_linear', nn.Linear(1, 8)),\n", " ('hidden_activation', nn.Tanh()),\n", " ('output_linear', nn.Linear(8, 1))\n", "]))\n", "\n", "seq_model" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "hidden_linear.weight torch.Size([8, 1])\n", "hidden_linear.bias torch.Size([8])\n", "output_linear.weight torch.Size([1, 8])\n", "output_linear.bias torch.Size([1])\n" ] } ], "source": [ "for name, param in seq_model.named_parameters():\n", " print(name, param.shape)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Parameter containing:\n", "tensor([-0.2901], requires_grad=True)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "seq_model.output_linear.bias" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1, Training loss 198.31817626953125, Validation loss 111.67463684082031\n", "Epoch 1000, Training loss 4.451472282409668, Validation loss 4.551815032958984\n", "Epoch 2000, Training loss 3.2558813095092773, Validation loss 1.3056895732879639\n", "Epoch 3000, Training loss 2.1388132572174072, Validation loss 1.9374333620071411\n", "Epoch 4000, Training loss 1.8055614233016968, Validation loss 2.4102280139923096\n", "Epoch 5000, Training loss 1.74860680103302, Validation loss 2.539191722869873\n", "output tensor([[16.3682],\n", " [ 7.9706]], grad_fn=)\n", "answer tensor([[13.],\n", " [ 8.]])\n", "hidden tensor([[ 12.7645],\n", " [ 0.3165],\n", " [-14.1103],\n", " [-13.4931],\n", " [ 13.3077],\n", " [ -0.5262],\n", " [ 0.3101],\n", " [ -0.5538]])\n" ] } ], "source": [ "optimizer = optim.SGD(seq_model.parameters(), lr=1e-3) # <1>\n", "\n", "training_loop(\n", " n_epochs = 5000, \n", " optimizer = optimizer,\n", " model = seq_model,\n", " loss_fn = nn.MSELoss(),\n", " t_u_train = t_un_train,\n", " t_u_val = t_un_val, \n", " t_c_train = t_c_train,\n", " t_c_val = t_c_val)\n", " \n", "print('output', seq_model(t_un_val))\n", "print('answer', t_c_val)\n", "print('hidden', seq_model.hidden_linear.weight.grad)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "from matplotlib import pyplot as plt\n", "\n", "t_range = torch.arange(20., 90.).unsqueeze(1)\n", "\n", "plt.plot(t_u.numpy(), t_c.numpy(), 'o')\n", "plt.plot(t_range.numpy(), seq_model(0.1 * t_range).detach().numpy(), 'c-')\n", "plt.plot(t_u.numpy(), seq_model(0.1 * t_u).detach().numpy(), 'kx')\n" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1, Training loss 206.9621124267578, Validation loss 120.10285186767578\n", "Epoch 1000, Training loss 55.983009338378906, Validation loss 3.4580602645874023\n", "Epoch 2000, Training loss 31.916854858398438, Validation loss 3.156665086746216\n", "Epoch 3000, Training loss 16.53954315185547, Validation loss 3.4310507774353027\n", "Epoch 4000, Training loss 9.367757797241211, Validation loss 4.064168453216553\n", "Epoch 5000, Training loss 6.250869274139404, Validation loss 4.493365287780762\n" ] }, { "data": { "text/plain": [ "[]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Exercises here!\n", "\n", "neuron_count = 20\n", "\n", "seq_model = nn.Sequential(OrderedDict([\n", " ('hidden_linear', nn.Linear(1, neuron_count)),\n", " ('hidden_activation', nn.Tanh()),\n", " ('output_linear', nn.Linear(neuron_count, 1))\n", "]))\n", "\n", "optimizer = optim.SGD(seq_model.parameters(), lr=1e-4)\n", "\n", "training_loop(\n", " n_epochs = 5000, \n", " optimizer = optimizer,\n", " model = seq_model,\n", " loss_fn = nn.MSELoss(),\n", " t_u_train = t_un_train,\n", " t_u_val = t_un_val, \n", " t_c_train = t_c_train,\n", " t_c_val = t_c_val)\n", "\n", "from matplotlib import pyplot as plt\n", "\n", "t_range = torch.arange(20., 90.).unsqueeze(1)\n", "\n", "plt.plot(t_u.numpy(), t_c.numpy(), 'o')\n", "plt.plot(t_range.numpy(), seq_model(0.1 * t_range).detach().numpy(), 'c-')\n", "plt.plot(t_u.numpy(), seq_model(0.1 * t_u).detach().numpy(), 'kx')\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.6" } }, "nbformat": 4, "nbformat_minor": 2 }