Created
February 7, 2022 03:39
-
-
Save CoryKornowicz/0c15c348dd25dd51a3eb50965fd3ea6f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import torch\n", | |
"import torchvision\n", | |
"import numpy as np\n", | |
"import math\n", | |
"from functorch import vmap" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<torch._C.Generator at 0x7f2728e50600>" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"n_epochs = 3\n", | |
"batch_size_train = 64\n", | |
"batch_size_test = 1000\n", | |
"learning_rate = 0.01\n", | |
"momentum = 0.5\n", | |
"log_interval = 10\n", | |
"\n", | |
"random_seed = 1\n", | |
"torch.backends.cudnn.enabled = True\n", | |
"torch.manual_seed(random_seed)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"/home/cory/miniconda3/envs/deepgen/lib/python3.6/site-packages/torchvision/datasets/mnist.py:62: UserWarning: train_data has been renamed data\n", | |
" warnings.warn(\"train_data has been renamed data\")\n", | |
"/home/cory/miniconda3/envs/deepgen/lib/python3.6/site-packages/torchvision/datasets/mnist.py:52: UserWarning: train_labels has been renamed targets\n", | |
" warnings.warn(\"train_labels has been renamed targets\")\n", | |
"/home/cory/miniconda3/envs/deepgen/lib/python3.6/site-packages/torchvision/datasets/mnist.py:67: UserWarning: test_data has been renamed data\n", | |
" warnings.warn(\"test_data has been renamed data\")\n", | |
"/home/cory/miniconda3/envs/deepgen/lib/python3.6/site-packages/torchvision/datasets/mnist.py:57: UserWarning: test_labels has been renamed targets\n", | |
" warnings.warn(\"test_labels has been renamed targets\")\n" | |
] | |
} | |
], | |
"source": [ | |
"train_dataset = torchvision.datasets.MNIST('.', train=True, download=True,\n", | |
" transform=torchvision.transforms.Compose([\n", | |
" torchvision.transforms.ToTensor(),\n", | |
" torchvision.transforms.Normalize(\n", | |
" (0.1307,), (0.3081,))\n", | |
" ]))\n", | |
"\n", | |
"\n", | |
"\n", | |
"test_dataset = torchvision.datasets.MNIST('.', train=False, download=True,\n", | |
" transform=torchvision.transforms.Compose([\n", | |
" torchvision.transforms.ToTensor(),\n", | |
" torchvision.transforms.Normalize(\n", | |
" (0.1307,), (0.3081,))\n", | |
" ]))\n", | |
"\n", | |
"\n", | |
"train_dataset.train_data.to(\"cuda\")\n", | |
"train_dataset.train_labels.to(\"cuda\")\n", | |
"\n", | |
"test_dataset.test_data.to(\"cuda\")\n", | |
"test_dataset.test_labels.to(\"cuda\")\n", | |
"\n", | |
"\n", | |
"train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size_train, shuffle=True)\n", | |
"test_loader = torch.utils.data.DataLoader( test_dataset, batch_size=batch_size_test, shuffle=True)\n", | |
"\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"examples = enumerate(test_loader)\n", | |
"batch_idx, (example_data, example_targets) = next(examples)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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88wzvdhdKnjSSSd5deE4KoCGzZ0nue2227y6M844w4vXrVuXlJcuXZqxTpJ++MMfJuXPP/88axtmz56dlMN5kwkTJiTlLVu2eHXhnE85cKcCAIiGpAIAiKZRLyk+4YQTkrJ7qylJZ511lhe3bds25/O6w1+rV6/26g466KCkXFdXl/M5i8GS4vy4wxmSNGrUKC++/PLLk3Lnzp29umz/X8Kf9+9//3svnjZtWlIO+02FsKR4Ow4++GAvXrhwYVJu166dV3fZZZd58dSpU5Py5s2b4zdOUq9evbz4+uuvT8pHH320V3fIIYd4ccQdjllSDAAoPZIKACAakgoAIJoGN6fijmlecsklXt2FF17oxbvttltS3nFHf/V0+H1v2LAhKYdjoeF8izunEp5nr732Sspr1qwJm18SzKnUz32y3qxZs7y6Ll26ZHzdypUrvTjb/5e9997bi5s1a+bFDzzwQFIeOXJk5saWD3Mqkvbff38vfvrpp714n332Scp/+ctfvLqamprSNSxH7tzxvHnzvLrFixd78YABA5JykXM+zKkAAEqPpAIAiIakAgCIpuq3aenZs6cXz5w5Myn36dMn5/OE46QPP/ywFz/++ONJedOmTV7diy++6MXt27fPeB13XL1ccyqo39VXX52UwzmUt956y4tvuummpByOoX/zzTcZrzF27FgvHjdunBe7fblFixZe3caNGzOeF6UVzsW6cyiS9PHHHyfl0aNHl6VN+XjssceS8pIlS7y6fv36efHJJ5+clB966KGStIc7FQBANCQVAEA0VbekONwR+Pbbb/ficJsE16pVqzKe6/nnn8+5Da1atfLiV155xYsPOOCApBy+f7W1tUn5hhtu8OrcYZWYWFL874YNG+bF999/f1IOn6rnLjeW4m1l8fe//92L+/bdtgIzHBqbNGlSlGvmqckuKXbff3eXX0n6+uuvvdgdQnr33XdL0ZxoDjzwQC9+++23vdgd6g37fZ5DsCwpBgCUHkkFABANSQUAEE1FlhTvvvvuXuxuHz1mzBivzt0SRZI+++yzpPyrX/3Kq7vzzjujtC9chufOoWyvTa5OnTol5XC7/VLNqeDfhUvRd9hh299P7ryXFHU78JyF4/Yord69e3vx+PHjk3K4hdOVV17pxdU+j+IK5wvDLYlGjBiRlMNt8cM5wEJxpwIAiIakAgCIhqQC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", | |
"text/plain": [ | |
"<Figure size 432x288 with 6 Axes>" | |
] | |
}, | |
"execution_count": 6, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "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88wzvdhdKnjSSSd5deE4KoCGzZ0nue2227y6M844w4vXrVuXlJcuXZqxTpJ++MMfJuXPP/88axtmz56dlMN5kwkTJiTlLVu2eHXhnE85cKcCAIiGpAIAiKZRLyk+4YQTkrJ7qylJZ511lhe3bds25/O6w1+rV6/26g466KCkXFdXl/M5i8GS4vy4wxmSNGrUKC++/PLLk3Lnzp29umz/X8Kf9+9//3svnjZtWlIO+02FsKR4Ow4++GAvXrhwYVJu166dV3fZZZd58dSpU5Py5s2b4zdOUq9evbz4+uuvT8pHH320V3fIIYd4ccQdjllSDAAoPZIKACAakgoAIJoGN6fijmlecsklXt2FF17oxbvttltS3nFHf/V0+H1v2LAhKYdjoeF8izunEp5nr732Sspr1qwJm18SzKnUz32y3qxZs7y6Ll26ZHzdypUrvTjb/5e9997bi5s1a+bFDzzwQFIeOXJk5saWD3Mqkvbff38vfvrpp714n332Scp/+ctfvLqamprSNSxH7tzxvHnzvLrFixd78YABA5JykXM+zKkAAEqPpAIAiIakAgCIpuq3aenZs6cXz5w5Myn36dMn5/OE46QPP/ywFz/++ONJedOmTV7diy++6MXt27fPeB13XL1ccyqo39VXX52UwzmUt956y4tvuummpByOoX/zzTcZrzF27FgvHjdunBe7fblFixZe3caNGzOeF6UVzsW6cyiS9PHHHyfl0aNHl6VN+XjssceS8pIlS7y6fv36efHJJ5+clB966KGStIc7FQBANCQVAEA0VbekONwR+Pbbb/ficJsE16pVqzKe6/nnn8+5Da1atfLiV155xYsPOOCApBy+f7W1tUn5hhtu8OrcYZWYWFL874YNG+bF999/f1IOn6rnLjeW4m1l8fe//92L+/bdtgIzHBqbNGlSlGvmqckuKXbff3eXX0n6+uuvvdgdQnr33XdL0ZxoDjzwQC9+++23vdgd6g37fZ5DsCwpBgCUHkkFABANSQUAEE1FlhTvvvvuXuxuHz1mzBivzt0SRZI+++yzpPyrX/3Kq7vzzjujtC9chufOoWyvTa5OnTol5XC7/VLNqeDfhUvRd9hh299P7ryXFHU78JyF4/Yord69e3vx+PHjk3K4hdOVV17pxdU+j+IK5wvDLYlGjBiRlMNt8cM5wEJxpwIAiIakAgCIhqQC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", | |
"text/plain": [ | |
"<Figure size 432x288 with 6 Axes>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"import matplotlib.pyplot as plt\n", | |
"%matplotlib inline\n", | |
"\n", | |
"fig = plt.figure()\n", | |
"for i in range(6):\n", | |
" plt.subplot(2,3,i+1)\n", | |
" plt.tight_layout()\n", | |
" plt.imshow(example_data[i][0], cmap='gray', interpolation='none')\n", | |
" plt.title(\"Ground Truth: {}\".format(example_targets[i]))\n", | |
" plt.xticks([])\n", | |
" plt.yticks([])\n", | |
"fig" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import torch.nn as nn\n", | |
"import torch.nn.functional as F\n", | |
"import torch.optim as optim\n", | |
"import functorch" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"class Net(nn.Module):\n", | |
" def __init__(self):\n", | |
" super(Net, self).__init__()\n", | |
" self.conv1 = nn.Conv2d(1, 10, kernel_size=5)\n", | |
" self.conv2 = nn.Conv2d(10, 20, kernel_size=5)\n", | |
" self.conv2_drop = nn.Dropout2d()\n", | |
" self.fc1 = nn.Linear(320, 50)\n", | |
" self.fc2 = nn.Linear(50, 10)\n", | |
"\n", | |
" def forward(self, x):\n", | |
" x = F.relu(F.max_pool2d(self.conv1(x), 2))\n", | |
" x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))\n", | |
" x = x.view(-1, 320)\n", | |
" x = F.relu(self.fc1(x))\n", | |
" x = F.dropout(x, training=self.training)\n", | |
" x = self.fc2(x)\n", | |
" return F.log_softmax(x)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"class MaxAbsPool2D(nn.Module):\n", | |
" def __init__(self, pool_size, pad_to_fit=False):\n", | |
" super(MaxAbsPool2D, self).__init__()\n", | |
" self.pad = pad_to_fit\n", | |
" self.pool_size = pool_size\n", | |
" \n", | |
"\n", | |
" def gather_nd(self, params, indices):\n", | |
" '''\n", | |
" 4D example\n", | |
" params: tensor shaped [n_1, n_2, n_3, n_4] --> 4 dimensional\n", | |
" indices: tensor shaped [m_1, m_2, m_3, m_4, 4] --> multidimensional list of 4D indices\n", | |
" \n", | |
" returns: tensor shaped [m_1, m_2, m_3, m_4]\n", | |
" \n", | |
" ND_example\n", | |
" params: tensor shaped [n_1, ..., n_p] --> d-dimensional tensor\n", | |
" indices: tensor shaped [m_1, ..., m_i, d] --> multidimensional list of d-dimensional indices\n", | |
" \n", | |
" returns: tensor shaped [m_1, ..., m_1]\n", | |
" '''\n", | |
"\n", | |
" out_shape = indices.shape[:-1]\n", | |
" indices = indices.unsqueeze(0).transpose(0, -1) # roll last axis to fring\n", | |
" ndim = indices.shape[0]\n", | |
" indices = indices.long()\n", | |
" idx = torch.zeros_like(indices[0], device=indices.device).long()\n", | |
" m = 1\n", | |
" \n", | |
" for i in range(ndim)[::-1]:\n", | |
" idx += indices[i] * m \n", | |
" m *= params.size(i)\n", | |
" out = torch.take(params, idx.cuda())\n", | |
" return out.view(out_shape)\n", | |
"\n", | |
" def forward(self, inputs):\n", | |
" if self.pad:\n", | |
" outshape = (inputs.shape[0], \n", | |
" inputs.shape[1],\n", | |
" math.ceil(inputs.shape[2] / self.pool_size), \n", | |
" math.ceil(inputs.shape[3] / self.pool_size))\n", | |
" else: \n", | |
" outshape = (inputs.shape[0], \n", | |
" inputs.shape[1],\n", | |
" (inputs.shape[2] // self.pool_size), \n", | |
" (inputs.shape[3] // self.pool_size)) \n", | |
"\n", | |
" mod_y = inputs.shape[2] % self.pool_size\n", | |
" y1 = mod_y // 2\n", | |
" y2 = mod_y - y1\n", | |
" mod_x = inputs.shape[3] % self.pool_size\n", | |
" x1 = mod_x // 2\n", | |
" x2 = mod_x - x1\n", | |
" padding = (y1, y2, x1, x2)\n", | |
"\n", | |
" if self.pad:\n", | |
" inputs = F.pad(inputs, padding)\n", | |
"\n", | |
" batch_size = inputs.shape[0]\n", | |
" max_height = (inputs.shape[2] // self.pool_size) * self.pool_size\n", | |
" max_width = (inputs.shape[3] // self.pool_size) * self.pool_size\n", | |
" \n", | |
" stacked = torch.stack(\n", | |
" [inputs[:, :, i:max_height:self.pool_size, j:max_width:self.pool_size] \n", | |
" for i in range(self.pool_size) for j in range(self.pool_size)], dim=-1)\n", | |
"\n", | |
" inds = torch.argmax(torch.abs(stacked), dim=-1).to(\"cpu\")\n", | |
" ks = stacked.shape\n", | |
" idx = torch.stack([\n", | |
" *torch.meshgrid(\n", | |
" torch.arange(0, ks[0]), \n", | |
" torch.arange(0, ks[1]),\n", | |
" torch.arange(0, ks[2]), \n", | |
" torch.arange(0, ks[3]),\n", | |
" indexing='ij'\n", | |
" ), inds], \n", | |
" dim=-1)\n", | |
"\n", | |
" x = self.gather_nd(stacked, idx)\n", | |
" x = x.reshape(outshape)\n", | |
" return x" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"class CosSim2D_REMAKE(nn.Module):\n", | |
" def __init__(self, input_channels, units=32, kernel_size=[3,3], stride=1, padding=1, depthwise_separable=False):\n", | |
" super(CosSim2D_REMAKE, self).__init__()\n", | |
" self.depthwise_separable = depthwise_separable\n", | |
" self.units = units\n", | |
" assert len(kernel_size) == 2, \"kernel of this size not supported\"\n", | |
" self.kernel_size = kernel_size\n", | |
" self.stride = stride\n", | |
" self.padding = padding\n", | |
" self.input_channels = input_channels\n", | |
"\n", | |
" if self.depthwise_separable:\n", | |
" w = torch.empty(1, np.square(kernel_size[0]), self.units)\n", | |
" nn.init.xavier_uniform_(w)\n", | |
" self.w = nn.Parameter(w, requires_grad=True)\n", | |
" else:\n", | |
" w = torch.empty(1, self.input_channels * np.square(self.kernel_size[0]), self.units)\n", | |
" nn.init.xavier_uniform_(w)\n", | |
" self.w = nn.Parameter(w, requires_grad=True)\n", | |
"\n", | |
" b = torch.empty((self.units,))\n", | |
" nn.init.zeros_(b)\n", | |
" self.b = nn.Parameter(b, requires_grad=True)\n", | |
"\n", | |
" p = torch.empty((self.units,))\n", | |
" nn.init.constant_(p, 2.0)\n", | |
" self.p = nn.Parameter(p, requires_grad=True)\n", | |
"\n", | |
" q = torch.empty((1,))\n", | |
" nn.init.uniform_(q)\n", | |
" self.q = nn.Parameter(q, requires_grad=True)\n", | |
"\n", | |
" \n", | |
" def l2_normal(self, x, axis=None, epsilon=torch.Tensor([1e-12])):\n", | |
" square_sum = torch.sum(torch.square(x), axis, keepdims=True)\n", | |
" x_inv_norm = torch.sqrt(torch.max(square_sum, epsilon.to(x.device)))\n", | |
" return x_inv_norm\n", | |
"\n", | |
" def sigplus(self, x):\n", | |
" return torch.sigmoid(x) * F.softplus(x)\n", | |
"\n", | |
" def stack(self, x):\n", | |
" x = F.pad(x, [self.padding]*4)\n", | |
" strided_x = x.unfold(2, self.kernel_size[0], self.stride).unfold(3, self.kernel_size[1], self.stride)\n", | |
" return strided_x\n", | |
" \n", | |
"\n", | |
" def forward(self, x):\n", | |
"\n", | |
" if self.depthwise_separable:\n", | |
" # print(x.shape, \"PreVex\")\n", | |
" x = vmap(self.call_body)(torch.unsqueeze(x.permute(1,0,2,3), axis=2))\n", | |
" # print(x.shape, \"PostVex\")\n", | |
" # [3, 1, 10, 28, 28]) PostVex\n", | |
" # s = x.shape\n", | |
" # print(s)\n", | |
" x = x.permute(1,0,2,3,4)\n", | |
" # print(x.shape, \"PostPermute\")\n", | |
" # [1, 3, 10, 28, 28]) PostPermute\n", | |
" b, c, f, h, w = x.shape\n", | |
" x = x.reshape(b, c*self.units, h, w)\n", | |
" # print(x.shape, \"PostView\", f)\n", | |
" return x\n", | |
" else:\n", | |
" x = self.call_body(x)\n", | |
" return x\n", | |
"\n", | |
"\n", | |
" def call_body(self, x):\n", | |
" # print(x.shape, \"PreCallBody\")\n", | |
" x = self.stack(x)\n", | |
" n, c, h, w, ks, kd = x.shape\n", | |
" x = x.reshape(n,h*w,c*ks*kd)\n", | |
" \n", | |
" q = torch.square(self.q)\n", | |
"\n", | |
" x_norm = (self.l2_normal(x, axis=2)) + q\n", | |
" w_norm = (self.l2_normal(self.w, axis=1)) + q\n", | |
"\n", | |
" x = (x / x_norm) @ (self.w / w_norm)\n", | |
" sign = torch.sign(x)\n", | |
" x = torch.abs(x) + 1e-12\n", | |
" x = x.pow(self.sigplus(self.p))\n", | |
" x = sign * x + + self.sigplus(self.b)\n", | |
"\n", | |
" x = x.reshape(-1, self.units, h, w)\n", | |
" return x\n", | |
" \n", | |
" \n", | |
" " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 137, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"7571" | |
] | |
}, | |
"execution_count": 137, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"def count_parameters(model):\n", | |
" return sum(p.numel() for p in model.parameters() if p.requires_grad)\n", | |
"\n", | |
"count_parameters(model)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 223, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"error = nn.CrossEntropyLoss()\n", | |
"\n", | |
"model = nn.Sequential(*[\n", | |
" CosSim2D_REMAKE(input_channels=1, units=10, kernel_size=[5,5], stride=2, padding=1, depthwise_separable=False),\n", | |
" CosSim2D_REMAKE(input_channels=10, units=20, kernel_size=[5,5], stride=1, padding=1, depthwise_separable=False),\n", | |
" CosSim2D_REMAKE(input_channels=20, units=8, kernel_size=[1,1], stride=1, padding=0, depthwise_separable=False),\n", | |
" # nn.Dropout(0.07),\n", | |
" # nn.MaxPool2d((2,2)),\n", | |
" CosSim2D_REMAKE(input_channels=8, units=4, kernel_size=[5,5], stride=2, padding=1, depthwise_separable=True),\n", | |
" CosSim2D_REMAKE(input_channels=32, units=10, kernel_size=[1,1], stride=1, padding=0, depthwise_separable=False),\n", | |
" # nn.Dropout(0.07),\n", | |
" nn.MaxPool2d((2,2)),\n", | |
" CosSim2D_REMAKE(input_channels=10, units=4, kernel_size=[3,3], stride=2, padding=1, depthwise_separable=True),\n", | |
" CosSim2D_REMAKE(input_channels=40, units=10, kernel_size=[3,3], stride=2, padding=1, depthwise_separable=False),\n", | |
" # nn.Dropout(0.07),\n", | |
" MaxAbsPool2D(2, True),\n", | |
" # nn.MaxPool2d((1,1)),\n", | |
" # nn.MaxPool2d(2),\n", | |
" # CosSim2D_REMAKE(input_channels=20, units=1, kernel_size=[3,3], stride=2, padding=1, depthwise_separable=True),\n", | |
" # CosSim2D_REMAKE(input_channels=20, units=10, kernel_size=[3,3], stride=2, padding=1, depthwise_separable=False),\n", | |
" # # CosSim2D_REMAKE(input_channels=20, units=10, kernel_size=[3,3], stride=2, padding=1, depthwise_separable=False),\n", | |
" # # CosSim2D_REMAKE(input_channels=20, units=10, kernel_size=[3,3], stride=2, padding=1, depthwise_separable=False),\n", | |
" # MaxAbsPool2D(2, True),\n", | |
" nn.Flatten(),\n", | |
" nn.Linear(10, 10),\n", | |
" # nn.LeakyReLU(),\n", | |
" nn.LogSoftmax(dim=1)\n", | |
" # nn.Sigmoid()\n", | |
"]).cuda()\n", | |
"\n", | |
"# model = Net().cuda()\n", | |
"\n", | |
"learning_rate = 0.01\n", | |
"# optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\n", | |
"optimizer = optim.Adam(model.parameters(), lr=learning_rate)\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 213, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"torch.Size([2, 10])" | |
] | |
}, | |
"execution_count": 213, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"test_data_x = torch.randn(2, 1, 28, 28).cuda()\n", | |
"model(test_data_x).shape" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 224, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n_epochs = 3\n", | |
"train_losses = []\n", | |
"train_counter = []\n", | |
"test_losses = []\n", | |
"test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 225, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def train(epoch):\n", | |
" model.train()\n", | |
" for batch_idx, (data, target) in enumerate(train_loader):\n", | |
" optimizer.zero_grad()\n", | |
" output = model(data.to(\"cuda\"))\n", | |
" loss = F.nll_loss(output, target.to(\"cuda\"))\n", | |
" loss.backward()\n", | |
" optimizer.step()\n", | |
" if batch_idx % log_interval == 0:\n", | |
" print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n", | |
" epoch, batch_idx * len(data), len(train_loader.dataset),\n", | |
" 100. * batch_idx / len(train_loader), loss.item()))\n", | |
" train_losses.append(loss.item())\n", | |
" train_counter.append(\n", | |
" (batch_idx*64) + ((epoch-1)*len(train_loader.dataset)))\n", | |
" # torch.save(model.state_dict(), '/results/model.pth')\n", | |
" # torch.save(optimizer.state_dict(), '/results/optimizer.pth')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 226, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def test():\n", | |
" model.eval()\n", | |
" test_loss = 0\n", | |
" correct = 0\n", | |
" with torch.no_grad():\n", | |
" for data, target in test_loader:\n", | |
" output = model(data.to(\"cuda\"))\n", | |
" test_loss += F.nll_loss(output, target.to(\"cuda\"), reduction='sum').item()\n", | |
" pred = output.to(\"cpu\").data.max(1, keepdim=True)[1]\n", | |
" correct += pred.eq(target.to(\"cpu\").data.view_as(pred)).sum()\n", | |
" test_loss /= len(test_loader.dataset)\n", | |
" test_losses.append(test_loss)\n", | |
" print('\\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n", | |
" test_loss, correct, len(test_loader.dataset),\n", | |
" 100. * correct / len(test_loader.dataset)))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 227, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"\n", | |
"Test set: Avg. loss: 2.3178, Accuracy: 1009/10000 (10%)\n", | |
"\n", | |
"Train Epoch: 1 [0/60000 (0%)]\tLoss: 2.316218\n", | |
"Train Epoch: 1 [640/60000 (1%)]\tLoss: 2.310624\n", | |
"Train Epoch: 1 [1280/60000 (2%)]\tLoss: 2.328552\n", | |
"Train Epoch: 1 [1920/60000 (3%)]\tLoss: 2.326698\n", | |
"Train Epoch: 1 [2560/60000 (4%)]\tLoss: 2.312075\n", | |
"Train Epoch: 1 [3200/60000 (5%)]\tLoss: 2.296974\n", | |
"Train Epoch: 1 [3840/60000 (6%)]\tLoss: 2.296356\n", | |
"Train Epoch: 1 [4480/60000 (7%)]\tLoss: 2.314074\n", | |
"Train Epoch: 1 [5120/60000 (9%)]\tLoss: 2.321757\n", | |
"Train Epoch: 1 [5760/60000 (10%)]\tLoss: 2.315157\n", | |
"Train Epoch: 1 [6400/60000 (11%)]\tLoss: 2.302232\n", | |
"Train Epoch: 1 [7040/60000 (12%)]\tLoss: 2.327388\n", | |
"Train Epoch: 1 [7680/60000 (13%)]\tLoss: 2.309437\n", | |
"Train Epoch: 1 [8320/60000 (14%)]\tLoss: 2.110768\n", | |
"Train Epoch: 1 [8960/60000 (15%)]\tLoss: 1.898252\n", | |
"Train Epoch: 1 [9600/60000 (16%)]\tLoss: 1.730732\n", | |
"Train Epoch: 1 [10240/60000 (17%)]\tLoss: 1.632461\n", | |
"Train Epoch: 1 [10880/60000 (18%)]\tLoss: 1.576923\n", | |
"Train Epoch: 1 [11520/60000 (19%)]\tLoss: 1.463213\n", | |
"Train Epoch: 1 [12160/60000 (20%)]\tLoss: 1.206215\n", | |
"Train Epoch: 1 [12800/60000 (21%)]\tLoss: 1.138680\n", | |
"Train Epoch: 1 [13440/60000 (22%)]\tLoss: 1.048898\n", | |
"Train Epoch: 1 [14080/60000 (23%)]\tLoss: 1.000812\n", | |
"Train Epoch: 1 [14720/60000 (25%)]\tLoss: 1.026755\n", | |
"Train Epoch: 1 [15360/60000 (26%)]\tLoss: 1.016238\n", | |
"Train Epoch: 1 [16000/60000 (27%)]\tLoss: 0.921849\n", | |
"Train Epoch: 1 [16640/60000 (28%)]\tLoss: 0.952626\n", | |
"Train Epoch: 1 [17280/60000 (29%)]\tLoss: 0.953420\n", | |
"Train Epoch: 1 [17920/60000 (30%)]\tLoss: 0.779182\n", | |
"Train Epoch: 1 [18560/60000 (31%)]\tLoss: 1.045863\n", | |
"Train Epoch: 1 [19200/60000 (32%)]\tLoss: 1.215781\n", | |
"Train Epoch: 1 [19840/60000 (33%)]\tLoss: 0.896048\n", | |
"Train Epoch: 1 [20480/60000 (34%)]\tLoss: 0.817331\n", | |
"Train Epoch: 1 [21120/60000 (35%)]\tLoss: 0.758659\n", | |
"Train Epoch: 1 [21760/60000 (36%)]\tLoss: 0.765967\n", | |
"Train Epoch: 1 [22400/60000 (37%)]\tLoss: 0.682770\n", | |
"Train Epoch: 1 [23040/60000 (38%)]\tLoss: 0.883863\n", | |
"Train Epoch: 1 [23680/60000 (39%)]\tLoss: 0.823186\n", | |
"Train Epoch: 1 [24320/60000 (41%)]\tLoss: 0.854320\n", | |
"Train Epoch: 1 [24960/60000 (42%)]\tLoss: 0.687250\n", | |
"Train Epoch: 1 [25600/60000 (43%)]\tLoss: 0.663487\n", | |
"Train Epoch: 1 [26240/60000 (44%)]\tLoss: 0.676594\n", | |
"Train Epoch: 1 [26880/60000 (45%)]\tLoss: 0.728934\n", | |
"Train Epoch: 1 [27520/60000 (46%)]\tLoss: 0.531859\n", | |
"Train Epoch: 1 [28160/60000 (47%)]\tLoss: 0.530515\n", | |
"Train Epoch: 1 [28800/60000 (48%)]\tLoss: 0.441733\n", | |
"Train Epoch: 1 [29440/60000 (49%)]\tLoss: 0.791823\n", | |
"Train Epoch: 1 [30080/60000 (50%)]\tLoss: 0.892163\n", | |
"Train Epoch: 1 [30720/60000 (51%)]\tLoss: 0.600429\n", | |
"Train Epoch: 1 [31360/60000 (52%)]\tLoss: 0.614292\n", | |
"Train Epoch: 1 [32000/60000 (53%)]\tLoss: 0.640600\n", | |
"Train Epoch: 1 [32640/60000 (54%)]\tLoss: 0.486172\n", | |
"Train Epoch: 1 [33280/60000 (55%)]\tLoss: 0.687507\n", | |
"Train Epoch: 1 [33920/60000 (57%)]\tLoss: 0.629682\n", | |
"Train Epoch: 1 [34560/60000 (58%)]\tLoss: 0.666545\n", | |
"Train Epoch: 1 [35200/60000 (59%)]\tLoss: 0.503778\n", | |
"Train Epoch: 1 [35840/60000 (60%)]\tLoss: 0.806158\n", | |
"Train Epoch: 1 [36480/60000 (61%)]\tLoss: 0.832175\n", | |
"Train Epoch: 1 [37120/60000 (62%)]\tLoss: 0.469040\n", | |
"Train Epoch: 1 [37760/60000 (63%)]\tLoss: 0.519231\n", | |
"Train Epoch: 1 [38400/60000 (64%)]\tLoss: 0.506036\n", | |
"Train Epoch: 1 [39040/60000 (65%)]\tLoss: 0.568161\n", | |
"Train Epoch: 1 [39680/60000 (66%)]\tLoss: 0.529751\n", | |
"Train Epoch: 1 [40320/60000 (67%)]\tLoss: 0.459978\n", | |
"Train Epoch: 1 [40960/60000 (68%)]\tLoss: 0.524102\n", | |
"Train Epoch: 1 [41600/60000 (69%)]\tLoss: 0.512300\n", | |
"Train Epoch: 1 [42240/60000 (70%)]\tLoss: 0.437332\n", | |
"Train Epoch: 1 [42880/60000 (71%)]\tLoss: 0.394670\n", | |
"Train Epoch: 1 [43520/60000 (72%)]\tLoss: 0.223572\n", | |
"Train Epoch: 1 [44160/60000 (74%)]\tLoss: 0.342050\n", | |
"Train Epoch: 1 [44800/60000 (75%)]\tLoss: 0.267749\n", | |
"Train Epoch: 1 [45440/60000 (76%)]\tLoss: 0.532922\n", | |
"Train Epoch: 1 [46080/60000 (77%)]\tLoss: 0.360049\n", | |
"Train Epoch: 1 [46720/60000 (78%)]\tLoss: 0.538723\n", | |
"Train Epoch: 1 [47360/60000 (79%)]\tLoss: 0.703804\n", | |
"Train Epoch: 1 [48000/60000 (80%)]\tLoss: 0.834726\n", | |
"Train Epoch: 1 [48640/60000 (81%)]\tLoss: 0.676838\n", | |
"Train Epoch: 1 [49280/60000 (82%)]\tLoss: 0.439723\n", | |
"Train Epoch: 1 [49920/60000 (83%)]\tLoss: 0.457522\n", | |
"Train Epoch: 1 [50560/60000 (84%)]\tLoss: 0.512422\n", | |
"Train Epoch: 1 [51200/60000 (85%)]\tLoss: 0.596058\n", | |
"Train Epoch: 1 [51840/60000 (86%)]\tLoss: 0.614722\n", | |
"Train Epoch: 1 [52480/60000 (87%)]\tLoss: 0.590689\n", | |
"Train Epoch: 1 [53120/60000 (88%)]\tLoss: 0.268143\n", | |
"Train Epoch: 1 [53760/60000 (90%)]\tLoss: 0.577149\n", | |
"Train Epoch: 1 [54400/60000 (91%)]\tLoss: 0.595721\n", | |
"Train Epoch: 1 [55040/60000 (92%)]\tLoss: 0.506574\n", | |
"Train Epoch: 1 [55680/60000 (93%)]\tLoss: 0.480416\n", | |
"Train Epoch: 1 [56320/60000 (94%)]\tLoss: 0.608466\n", | |
"Train Epoch: 1 [56960/60000 (95%)]\tLoss: 0.511769\n", | |
"Train Epoch: 1 [57600/60000 (96%)]\tLoss: 0.410115\n", | |
"Train Epoch: 1 [58240/60000 (97%)]\tLoss: 0.354646\n", | |
"Train Epoch: 1 [58880/60000 (98%)]\tLoss: 0.355858\n", | |
"Train Epoch: 1 [59520/60000 (99%)]\tLoss: 0.349257\n", | |
"\n", | |
"Test set: Avg. loss: 0.3909, Accuracy: 8856/10000 (89%)\n", | |
"\n", | |
"Train Epoch: 2 [0/60000 (0%)]\tLoss: 0.262621\n", | |
"Train Epoch: 2 [640/60000 (1%)]\tLoss: 0.374203\n", | |
"Train Epoch: 2 [1280/60000 (2%)]\tLoss: 0.629726\n", | |
"Train Epoch: 2 [1920/60000 (3%)]\tLoss: 0.472493\n", | |
"Train Epoch: 2 [2560/60000 (4%)]\tLoss: 0.416987\n", | |
"Train Epoch: 2 [3200/60000 (5%)]\tLoss: 0.483328\n", | |
"Train Epoch: 2 [3840/60000 (6%)]\tLoss: 0.430447\n", | |
"Train Epoch: 2 [4480/60000 (7%)]\tLoss: 0.381701\n", | |
"Train Epoch: 2 [5120/60000 (9%)]\tLoss: 0.257381\n", | |
"Train Epoch: 2 [5760/60000 (10%)]\tLoss: 0.586834\n", | |
"Train Epoch: 2 [6400/60000 (11%)]\tLoss: 0.399070\n", | |
"Train Epoch: 2 [7040/60000 (12%)]\tLoss: 0.285346\n", | |
"Train Epoch: 2 [7680/60000 (13%)]\tLoss: 0.214885\n", | |
"Train Epoch: 2 [8320/60000 (14%)]\tLoss: 0.187148\n", | |
"Train Epoch: 2 [8960/60000 (15%)]\tLoss: 0.174931\n", | |
"Train Epoch: 2 [9600/60000 (16%)]\tLoss: 0.468998\n", | |
"Train Epoch: 2 [10240/60000 (17%)]\tLoss: 0.318777\n", | |
"Train Epoch: 2 [10880/60000 (18%)]\tLoss: 0.245776\n", | |
"Train Epoch: 2 [11520/60000 (19%)]\tLoss: 0.273737\n", | |
"Train Epoch: 2 [12160/60000 (20%)]\tLoss: 0.317462\n", | |
"Train Epoch: 2 [12800/60000 (21%)]\tLoss: 0.184208\n", | |
"Train Epoch: 2 [13440/60000 (22%)]\tLoss: 0.338580\n", | |
"Train Epoch: 2 [14080/60000 (23%)]\tLoss: 0.298320\n", | |
"Train Epoch: 2 [14720/60000 (25%)]\tLoss: 0.293539\n", | |
"Train Epoch: 2 [15360/60000 (26%)]\tLoss: 0.217749\n", | |
"Train Epoch: 2 [16000/60000 (27%)]\tLoss: 0.493424\n", | |
"Train Epoch: 2 [16640/60000 (28%)]\tLoss: 0.279736\n", | |
"Train Epoch: 2 [17280/60000 (29%)]\tLoss: 0.498832\n", | |
"Train Epoch: 2 [17920/60000 (30%)]\tLoss: 0.261046\n", | |
"Train Epoch: 2 [18560/60000 (31%)]\tLoss: 0.382005\n", | |
"Train Epoch: 2 [19200/60000 (32%)]\tLoss: 0.199404\n", | |
"Train Epoch: 2 [19840/60000 (33%)]\tLoss: 0.307919\n", | |
"Train Epoch: 2 [20480/60000 (34%)]\tLoss: 0.165441\n", | |
"Train Epoch: 2 [21120/60000 (35%)]\tLoss: 0.382691\n", | |
"Train Epoch: 2 [21760/60000 (36%)]\tLoss: 0.389504\n", | |
"Train Epoch: 2 [22400/60000 (37%)]\tLoss: 0.386378\n", | |
"Train Epoch: 2 [23040/60000 (38%)]\tLoss: 0.506936\n", | |
"Train Epoch: 2 [23680/60000 (39%)]\tLoss: 0.414230\n", | |
"Train Epoch: 2 [24320/60000 (41%)]\tLoss: 0.323903\n", | |
"Train Epoch: 2 [24960/60000 (42%)]\tLoss: 0.306717\n", | |
"Train Epoch: 2 [25600/60000 (43%)]\tLoss: 0.341347\n", | |
"Train Epoch: 2 [26240/60000 (44%)]\tLoss: 0.249054\n", | |
"Train Epoch: 2 [26880/60000 (45%)]\tLoss: 0.266523\n", | |
"Train Epoch: 2 [27520/60000 (46%)]\tLoss: 0.487125\n", | |
"Train Epoch: 2 [28160/60000 (47%)]\tLoss: 0.145521\n", | |
"Train Epoch: 2 [28800/60000 (48%)]\tLoss: 0.484457\n", | |
"Train Epoch: 2 [29440/60000 (49%)]\tLoss: 0.338556\n", | |
"Train Epoch: 2 [30080/60000 (50%)]\tLoss: 0.406402\n", | |
"Train Epoch: 2 [30720/60000 (51%)]\tLoss: 0.394525\n", | |
"Train Epoch: 2 [31360/60000 (52%)]\tLoss: 0.540513\n", | |
"Train Epoch: 2 [32000/60000 (53%)]\tLoss: 0.254305\n", | |
"Train Epoch: 2 [32640/60000 (54%)]\tLoss: 0.315709\n", | |
"Train Epoch: 2 [33280/60000 (55%)]\tLoss: 0.243859\n", | |
"Train Epoch: 2 [33920/60000 (57%)]\tLoss: 0.179197\n", | |
"Train Epoch: 2 [34560/60000 (58%)]\tLoss: 0.292523\n", | |
"Train Epoch: 2 [35200/60000 (59%)]\tLoss: 0.382717\n", | |
"Train Epoch: 2 [35840/60000 (60%)]\tLoss: 0.243314\n", | |
"Train Epoch: 2 [36480/60000 (61%)]\tLoss: 0.386967\n", | |
"Train Epoch: 2 [37120/60000 (62%)]\tLoss: 0.415259\n", | |
"Train Epoch: 2 [37760/60000 (63%)]\tLoss: 0.280219\n", | |
"Train Epoch: 2 [38400/60000 (64%)]\tLoss: 0.572420\n", | |
"Train Epoch: 2 [39040/60000 (65%)]\tLoss: 0.246219\n", | |
"Train Epoch: 2 [39680/60000 (66%)]\tLoss: 0.272813\n", | |
"Train Epoch: 2 [40320/60000 (67%)]\tLoss: 0.434831\n", | |
"Train Epoch: 2 [40960/60000 (68%)]\tLoss: 0.398748\n", | |
"Train Epoch: 2 [41600/60000 (69%)]\tLoss: 0.346579\n", | |
"Train Epoch: 2 [42240/60000 (70%)]\tLoss: 0.462290\n", | |
"Train Epoch: 2 [42880/60000 (71%)]\tLoss: 0.376466\n", | |
"Train Epoch: 2 [43520/60000 (72%)]\tLoss: 0.621190\n", | |
"Train Epoch: 2 [44160/60000 (74%)]\tLoss: 0.425865\n", | |
"Train Epoch: 2 [44800/60000 (75%)]\tLoss: 0.188408\n", | |
"Train Epoch: 2 [45440/60000 (76%)]\tLoss: 0.235857\n", | |
"Train Epoch: 2 [46080/60000 (77%)]\tLoss: 0.480694\n", | |
"Train Epoch: 2 [46720/60000 (78%)]\tLoss: 0.463522\n", | |
"Train Epoch: 2 [47360/60000 (79%)]\tLoss: 0.454278\n", | |
"Train Epoch: 2 [48000/60000 (80%)]\tLoss: 0.241668\n", | |
"Train Epoch: 2 [48640/60000 (81%)]\tLoss: 0.228049\n", | |
"Train Epoch: 2 [49280/60000 (82%)]\tLoss: 0.371920\n", | |
"Train Epoch: 2 [49920/60000 (83%)]\tLoss: 0.303571\n", | |
"Train Epoch: 2 [50560/60000 (84%)]\tLoss: 0.224145\n", | |
"Train Epoch: 2 [51200/60000 (85%)]\tLoss: 0.231461\n", | |
"Train Epoch: 2 [51840/60000 (86%)]\tLoss: 0.117327\n", | |
"Train Epoch: 2 [52480/60000 (87%)]\tLoss: 0.219765\n", | |
"Train Epoch: 2 [53120/60000 (88%)]\tLoss: 0.220244\n", | |
"Train Epoch: 2 [53760/60000 (90%)]\tLoss: 0.252273\n", | |
"Train Epoch: 2 [54400/60000 (91%)]\tLoss: 0.373454\n", | |
"Train Epoch: 2 [55040/60000 (92%)]\tLoss: 0.308257\n", | |
"Train Epoch: 2 [55680/60000 (93%)]\tLoss: 0.249226\n", | |
"Train Epoch: 2 [56320/60000 (94%)]\tLoss: 0.305760\n", | |
"Train Epoch: 2 [56960/60000 (95%)]\tLoss: 0.319969\n", | |
"Train Epoch: 2 [57600/60000 (96%)]\tLoss: 0.154123\n", | |
"Train Epoch: 2 [58240/60000 (97%)]\tLoss: 0.200313\n", | |
"Train Epoch: 2 [58880/60000 (98%)]\tLoss: 0.237880\n", | |
"Train Epoch: 2 [59520/60000 (99%)]\tLoss: 0.293041\n", | |
"\n", | |
"Test set: Avg. loss: 0.4096, Accuracy: 8801/10000 (88%)\n", | |
"\n", | |
"Train Epoch: 3 [0/60000 (0%)]\tLoss: 0.357464\n", | |
"Train Epoch: 3 [640/60000 (1%)]\tLoss: 0.372117\n", | |
"Train Epoch: 3 [1280/60000 (2%)]\tLoss: 0.352286\n", | |
"Train Epoch: 3 [1920/60000 (3%)]\tLoss: 0.306995\n", | |
"Train Epoch: 3 [2560/60000 (4%)]\tLoss: 0.318805\n", | |
"Train Epoch: 3 [3200/60000 (5%)]\tLoss: 0.481552\n", | |
"Train Epoch: 3 [3840/60000 (6%)]\tLoss: 0.424677\n", | |
"Train Epoch: 3 [4480/60000 (7%)]\tLoss: 0.163365\n", | |
"Train Epoch: 3 [5120/60000 (9%)]\tLoss: 0.183975\n", | |
"Train Epoch: 3 [5760/60000 (10%)]\tLoss: 0.172799\n", | |
"Train Epoch: 3 [6400/60000 (11%)]\tLoss: 0.298142\n", | |
"Train Epoch: 3 [7040/60000 (12%)]\tLoss: 0.261880\n", | |
"Train Epoch: 3 [7680/60000 (13%)]\tLoss: 0.134764\n", | |
"Train Epoch: 3 [8320/60000 (14%)]\tLoss: 0.212339\n", | |
"Train Epoch: 3 [8960/60000 (15%)]\tLoss: 0.365209\n", | |
"Train Epoch: 3 [9600/60000 (16%)]\tLoss: 0.150135\n", | |
"Train Epoch: 3 [10240/60000 (17%)]\tLoss: 0.248458\n", | |
"Train Epoch: 3 [10880/60000 (18%)]\tLoss: 0.284270\n", | |
"Train Epoch: 3 [11520/60000 (19%)]\tLoss: 0.469098\n", | |
"Train Epoch: 3 [12160/60000 (20%)]\tLoss: 0.220207\n", | |
"Train Epoch: 3 [12800/60000 (21%)]\tLoss: 0.382031\n", | |
"Train Epoch: 3 [13440/60000 (22%)]\tLoss: 0.241649\n", | |
"Train Epoch: 3 [14080/60000 (23%)]\tLoss: 0.378085\n", | |
"Train Epoch: 3 [14720/60000 (25%)]\tLoss: 0.210836\n", | |
"Train Epoch: 3 [15360/60000 (26%)]\tLoss: 0.291862\n", | |
"Train Epoch: 3 [16000/60000 (27%)]\tLoss: 0.370690\n", | |
"Train Epoch: 3 [16640/60000 (28%)]\tLoss: 0.209308\n", | |
"Train Epoch: 3 [17280/60000 (29%)]\tLoss: 0.120709\n", | |
"Train Epoch: 3 [17920/60000 (30%)]\tLoss: 0.227081\n", | |
"Train Epoch: 3 [18560/60000 (31%)]\tLoss: 0.151938\n", | |
"Train Epoch: 3 [19200/60000 (32%)]\tLoss: 0.281668\n", | |
"Train Epoch: 3 [19840/60000 (33%)]\tLoss: 0.226762\n", | |
"Train Epoch: 3 [20480/60000 (34%)]\tLoss: 0.233312\n", | |
"Train Epoch: 3 [21120/60000 (35%)]\tLoss: 0.253970\n", | |
"Train Epoch: 3 [21760/60000 (36%)]\tLoss: 0.066867\n", | |
"Train Epoch: 3 [22400/60000 (37%)]\tLoss: 0.184917\n", | |
"Train Epoch: 3 [23040/60000 (38%)]\tLoss: 0.303674\n", | |
"Train Epoch: 3 [23680/60000 (39%)]\tLoss: 0.379502\n", | |
"Train Epoch: 3 [24320/60000 (41%)]\tLoss: 0.300051\n", | |
"Train Epoch: 3 [24960/60000 (42%)]\tLoss: 0.240761\n", | |
"Train Epoch: 3 [25600/60000 (43%)]\tLoss: 0.168751\n", | |
"Train Epoch: 3 [26240/60000 (44%)]\tLoss: 0.380870\n", | |
"Train Epoch: 3 [26880/60000 (45%)]\tLoss: 0.276003\n", | |
"Train Epoch: 3 [27520/60000 (46%)]\tLoss: 0.353058\n", | |
"Train Epoch: 3 [28160/60000 (47%)]\tLoss: 0.117650\n", | |
"Train Epoch: 3 [28800/60000 (48%)]\tLoss: 0.362679\n", | |
"Train Epoch: 3 [29440/60000 (49%)]\tLoss: 0.102341\n", | |
"Train Epoch: 3 [30080/60000 (50%)]\tLoss: 0.155397\n", | |
"Train Epoch: 3 [30720/60000 (51%)]\tLoss: 0.233923\n", | |
"Train Epoch: 3 [31360/60000 (52%)]\tLoss: 0.212420\n", | |
"Train Epoch: 3 [32000/60000 (53%)]\tLoss: 0.118900\n", | |
"Train Epoch: 3 [32640/60000 (54%)]\tLoss: 0.205148\n", | |
"Train Epoch: 3 [33280/60000 (55%)]\tLoss: 0.293114\n", | |
"Train Epoch: 3 [33920/60000 (57%)]\tLoss: 0.226733\n", | |
"Train Epoch: 3 [34560/60000 (58%)]\tLoss: 0.280164\n", | |
"Train Epoch: 3 [35200/60000 (59%)]\tLoss: 0.270935\n", | |
"Train Epoch: 3 [35840/60000 (60%)]\tLoss: 0.131049\n", | |
"Train Epoch: 3 [36480/60000 (61%)]\tLoss: 0.082124\n", | |
"Train Epoch: 3 [37120/60000 (62%)]\tLoss: 0.240775\n", | |
"Train Epoch: 3 [37760/60000 (63%)]\tLoss: 0.265926\n", | |
"Train Epoch: 3 [38400/60000 (64%)]\tLoss: 0.270410\n", | |
"Train Epoch: 3 [39040/60000 (65%)]\tLoss: 0.197535\n", | |
"Train Epoch: 3 [39680/60000 (66%)]\tLoss: 0.272590\n", | |
"Train Epoch: 3 [40320/60000 (67%)]\tLoss: 0.308527\n", | |
"Train Epoch: 3 [40960/60000 (68%)]\tLoss: 0.149671\n", | |
"Train Epoch: 3 [41600/60000 (69%)]\tLoss: 0.293707\n", | |
"Train Epoch: 3 [42240/60000 (70%)]\tLoss: 0.245622\n", | |
"Train Epoch: 3 [42880/60000 (71%)]\tLoss: 0.294179\n", | |
"Train Epoch: 3 [43520/60000 (72%)]\tLoss: 0.167644\n", | |
"Train Epoch: 3 [44160/60000 (74%)]\tLoss: 0.229727\n", | |
"Train Epoch: 3 [44800/60000 (75%)]\tLoss: 0.205174\n", | |
"Train Epoch: 3 [45440/60000 (76%)]\tLoss: 0.178458\n", | |
"Train Epoch: 3 [46080/60000 (77%)]\tLoss: 0.064823\n", | |
"Train Epoch: 3 [46720/60000 (78%)]\tLoss: 0.360851\n", | |
"Train Epoch: 3 [47360/60000 (79%)]\tLoss: 0.259635\n", | |
"Train Epoch: 3 [48000/60000 (80%)]\tLoss: 0.089917\n", | |
"Train Epoch: 3 [48640/60000 (81%)]\tLoss: 0.267852\n", | |
"Train Epoch: 3 [49280/60000 (82%)]\tLoss: 0.267209\n", | |
"Train Epoch: 3 [49920/60000 (83%)]\tLoss: 0.243634\n", | |
"Train Epoch: 3 [50560/60000 (84%)]\tLoss: 0.219475\n", | |
"Train Epoch: 3 [51200/60000 (85%)]\tLoss: 0.160179\n", | |
"Train Epoch: 3 [51840/60000 (86%)]\tLoss: 0.218679\n", | |
"Train Epoch: 3 [52480/60000 (87%)]\tLoss: 0.121615\n", | |
"Train Epoch: 3 [53120/60000 (88%)]\tLoss: 0.109723\n", | |
"Train Epoch: 3 [53760/60000 (90%)]\tLoss: 0.374123\n", | |
"Train Epoch: 3 [54400/60000 (91%)]\tLoss: 0.231701\n", | |
"Train Epoch: 3 [55040/60000 (92%)]\tLoss: 0.346988\n", | |
"Train Epoch: 3 [55680/60000 (93%)]\tLoss: 0.184595\n", | |
"Train Epoch: 3 [56320/60000 (94%)]\tLoss: 0.178899\n", | |
"Train Epoch: 3 [56960/60000 (95%)]\tLoss: 0.194567\n", | |
"Train Epoch: 3 [57600/60000 (96%)]\tLoss: 0.209761\n", | |
"Train Epoch: 3 [58240/60000 (97%)]\tLoss: 0.111838\n", | |
"Train Epoch: 3 [58880/60000 (98%)]\tLoss: 0.277517\n", | |
"Train Epoch: 3 [59520/60000 (99%)]\tLoss: 0.256277\n", | |
"\n", | |
"Test set: Avg. loss: 0.2302, Accuracy: 9327/10000 (93%)\n", | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"test()\n", | |
"for epoch in range(1, n_epochs + 1):\n", | |
" train(epoch)\n", | |
" test()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 136, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"----------------------------------------------------------------\n", | |
" Layer (type) Output Shape Param #\n", | |
"================================================================\n", | |
" CosSim2D_REMAKE-1 [-1, 10, 13, 13] 0\n", | |
" CosSim2D_REMAKE-2 [-1, 12, 11, 11] 0\n", | |
" CosSim2D_REMAKE-3 [-1, 8, 11, 11] 0\n", | |
" CosSim2D_REMAKE-4 [-1, 32, 6, 6] 0\n", | |
" CosSim2D_REMAKE-5 [-1, 10, 6, 6] 0\n", | |
" CosSim2D_REMAKE-6 [-1, 40, 3, 3] 0\n", | |
" CosSim2D_REMAKE-7 [-1, 10, 2, 2] 0\n", | |
" MaxAbsPool2D-8 [-1, 10, 1, 1] 0\n", | |
" Flatten-9 [-1, 10] 0\n", | |
" Linear-10 [-1, 10] 110\n", | |
" LogSoftmax-11 [-1, 10] 0\n", | |
"================================================================\n", | |
"Total params: 110\n", | |
"Trainable params: 110\n", | |
"Non-trainable params: 0\n", | |
"----------------------------------------------------------------\n", | |
"Input size (MB): 0.00\n", | |
"Forward/backward pass size (MB): 0.05\n", | |
"Params size (MB): 0.00\n", | |
"Estimated Total Size (MB): 0.05\n", | |
"----------------------------------------------------------------\n", | |
"7571\n" | |
] | |
} | |
], | |
"source": [ | |
"import torchsummary\n", | |
"torchsummary.summary(model, (1, 28, 28))\n", | |
"print(count_parameters(model))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 91, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"Text(0, 0.5, 'negative log likelihood loss')" | |
] | |
}, | |
"execution_count": 91, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAAEKCAYAAAAW8vJGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAABGnUlEQVR4nO2dd7gV1dX/Pwu4haZIURQExGBFBCUaxSBqYjdGY4tYo/EVC/YejRo1icmrseQnltgS7CKaV40lESV2UKTYpYlUQS6X3vbvjzXbmTN3zjlzL+fcc8v6PM95ppwpa2bO2d9Za++9tjjnMAzDMAxPi1IbYBiGYTQsTBgMwzCMDEwYDMMwjAxMGAzDMIwMTBgMwzCMDEwYDMMwjAyKJgwisqWIvCYin4jIFBE5L2GbISJSJSITgs81xbLHMAzDSEerIh57LXCRc+4DEWkPjBeRV5xzH8e2G+ucO7SIdhiGYRi1oGgeg3NujnPug2C+GvgE6Fas8xmGYRiFoZgew/eISC9gAPBuwtd7iMhHwGzgYufclFzH6ty5s+vVq1fBbTQMw2jKjB8//lvnXJc02xZdGESkHfA0cL5zbkns6w+Ans65pSJyMDAa6JNwjDOAMwB69OjBuHHjimu0YRhGE0NEZqTdtqitkkSkDBWFkc65UfHvnXNLnHNLg/kXgDIR6Zyw3T3OuYHOuYFduqQSPMMwDKOOFLNVkgB/Az5xzt2SZZuuwXaIyG6BPQuLZZNhGIaRn2KGkgYBJwKTRGRCsO5KoAeAc24EcBQwTETWAiuA45ylezUMwygpRRMG59x/AcmzzZ3AncWywTCMhs+aNWuYNWsWK1euLLUpTYLKykq6d+9OWVlZnY9RL62SDMMwsjFr1izat29Pr169CCLLRh1xzrFw4UJmzZrFVlttVefjWEoMwzBKysqVK+nUqZOJQgEQETp16rTB3pcJg2EYJcdEoXAU4l42O2F44gmYO7fUVhiGYTRcmpUwTJsGxx4Lp5xSaksMw2goLFy4kP79+9O/f3+6du1Kt27dvl9evXp1zn3HjRvH8OHDa3W+Xr168e23326IyUWnWVU+//vfOp03r7R2GIbRcOjUqRMTJkwA4Nprr6Vdu3ZcfPHF33+/du1aWrVKLioHDhzIwIED68PMeqXZeAxr1sCDD+r8BrTiMgyjGXDKKadw4YUXss8++3DZZZfx3nvvseeeezJgwAD23HNPPvvsMwDGjBnDoYdqcuhrr72WX/3qVwwZMoTevXtz++23pz7fjBkz2G+//ejXrx/77bcfM2fOBODJJ5+kb9++7LzzzgwePBiAKVOmsNtuu9G/f3/69evHF198UeCrby4ew8iRPDh8Em8u+gOVspKvPhGgotRWGYYR4/zzIXh5Lxj9+8Nf/lL7/T7//HNeffVVWrZsyZIlS3jjjTdo1aoVr776KldeeSVPP/10jX0+/fRTXnvtNaqrq9l2220ZNmxYqv4E55xzDieddBInn3wy999/P8OHD2f06NFcf/31vPTSS3Tr1o3FixcDMGLECM477zyGDh3K6tWrWbduXe0vLg9NXxhGjoQzzuC05SvoyQdMcjtx8dL/ZdHdT9Lxf44utXWGYTRQjj76aFq2bAlAVVUVJ598Ml988QUiwpo1axL3OeSQQ6ioqKCiooJNN92UefPm0b1797znevvttxk1StPJnXjiiVx66aUADBo0iFNOOYVjjjmGI488EoA99tiDG2+8kVmzZnHkkUfSp0+NvKMbTNMXhquuguXLaQHszysImnFj/DXP8lMTBsNoUNTlzb5YtG3b9vv5q6++mn322YdnnnmG6dOnM2TIkMR9KirCSETLli1Zu3Ztnc7tm5yOGDGCd999l+eff57+/fszYcIEjj/+eHbffXeef/55DjjgAO677z723XffOp0nG02/jiGI1Xl+xDsA7D//HwweDH/6UymMMgyjMVFVVUW3bjrO2IO+srKA7Lnnnjz22GMAjBw5kr322guAr776it13353rr7+ezp078/XXXzN16lR69+7N8OHD+dnPfsbEiRMLbk/TF4YePTIW27OULswHYOxYuPrqUhhlGEZj4tJLL+WKK65g0KBBBYnp9+vXj+7du9O9e3cuvPBCbr/9dh544AH69evH3//+d2677TYALrnkEnbaaSf69u3L4MGD2XnnnXn88cfp27cv/fv359NPP+Wkk07aYHviSGNLZjpw4EBXq4F6gjoGli//ftXHlbuw4qobeHOjgzjvPDjySHjqKbDOl4ZR/3zyySdsv/32pTajSZF0T0VkvHMuVdvapl/HMHSoTq+6SsNKPXqww40XwtCDKAs8sFGjYMkS2Hjj0plpGIbRUGj6oSRQcZg+Hdav12kgFv36wVln6SaWJsMwDENpHsKQg1/8Qqdz5pTWDsMwjIZCsxeGrl11ah6DYRiG0uyFYfPNdWrCYBiGoTR7YejQAcrLLZRkGIbhafqtkvIgouEk8xgMo3mycOFC9ttvPwDmzp1Ly5Yt6dKlCwDvvfce5eXlOfcfM2YM5eXl7LnnnjW+e/DBBxk3bhx33tm4hrZv9sIA6jUsWVJqKwzDKAX50m7nY8yYMbRr1y5RGBorzT6UBNC6dUb/N8MwGjIjR0KvXtCihU5Hjiz4KcaPH8/ee+/NrrvuygEHHMCcINZ8++23s8MOO9CvXz+OO+44pk+fzogRI7j11lvp378/Y8eOTXX8W265hb59+9K3b1/+EiSIWrZsGYcccgg777wzffv25fHHHwfg8ssv//6ctRGsDcE8BlQYVqwotRWGYeQlnslgxgxdhrAz6wbinOPcc8/l2WefpUuXLjz++ONcddVV3H///fzhD39g2rRpVFRUsHjxYjp06MCZZ55ZKy9j/PjxPPDAA7z77rs459h9993Ze++9mTp1KltssQXPP/88oPmZFi1axDPPPMOnn36KiHyfervYmMcAtGljwmAYjYIgW3IGy5fr+gKxatUqJk+ezE9/+lP69+/PDTfcwKxZswDNcTR06FD+8Y9/ZB3VLR///e9/OeKII2jbti3t2rXjyCOPZOzYsey00068+uqrXHbZZYwdO5aNN96YjTbaiMrKSk4//XRGjRpFmzZtCnaduTBhwEJJhtFoiGVLzru+Djjn2HHHHZkwYQITJkxg0qRJvPzyywA8//zznH322YwfP55dd921Tmm1s+Wn22abbRg/fjw77bQTV1xxBddffz2tWrXivffe4xe/+AWjR4/mwAMP3KBrS4sJA+YxGEajIZYtOe/6OlBRUcGCBQt4++23AVizZg1Tpkxh/fr1fP311+yzzz7cfPPNLF68mKVLl9K+fXuqq6tTH3/w4MGMHj2a5cuXs2zZMp555hl+/OMfM3v2bNq0acMJJ5zAxRdfzAcffMDSpUupqqri4IMP5i9/+cv3leTFxuoYsDoGw2g03HhjjWzJtGmj6wtEixYteOqppxg+fDhVVVWsXbuW888/n2222YYTTjiBqqoqnHNccMEFdOjQgcMOO4yjjjqKZ599ljvuuIMf//jHGcd78MEHGT169PfL77zzDqeccgq77bYbAKeffjoDBgzgpZde4pJLLqFFixaUlZVx1113UV1dzeGHH87KlStxznHrrbcW7Dpz0fTTbqfg/PPhgQegqqqghzUMIwW1Trs9cmRGtmRuvLFgFc9NBUu7XQAslGQYjYihQ00IiozVMaChpDVroI7DsxqGYTQpTBhQjwHMazCMUtHYQtoNmULcSxMG1GMAEwbDKAWVlZUsXLjQxKEAOOdYuHAhlZWVG3Qcq2PAhMEwSkn37t2ZNWsWCxYsKLUpTYLKykq6d+++QccomjCIyJbAw0BXYD1wj3Puttg2AtwGHAwsB05xzn1QLJuy4UNJ1snNMOqfsrIyttpqq1KbYUQopsewFrjIOfeBiLQHxovIK865jyPbHAT0CT67A3cF03rFPAbDMIyQotUxOOfm+Ld/51w18AnQLbbZ4cDDTnkH6CAimxfLpmx4YTCPwTAMo54qn0WkFzAAeDf2VTfg68jyLGqKR9GxVkmGYRgheYVBRG4WkY1EpExE/i0i34rICWlPICLtgKeB851z8eFwJGGXGk0TROQMERknIuOKUUFloSTDMIyQNB7D/kGBfij6Rr8NcEmag4tIGSoKI51zoxI2mQVsGVnuDsyOb+Scu8c5N9A5N9APuVdI/Mh9q1cX/NCGYRiNjjTCUBZMDwYedc4tSnPgoMXR34BPnHO3ZNnsOeAkUX4EVDnn5qQ5fiExYTAMwwhJ0yrpnyLyKbACOEtEugArU+w3CDgRmCQiE4J1VwI9AJxzI4AXUMH5Em2uemqtrC8QXhjWrCnF2Q3DMBoWeYXBOXe5iPwRWOKcWyciy9DWRPn2+y/JdQjRbRxwdlpji0VZ4BOZx2AYhpGu8vloYG0gCr8B/gFsUXTL6hELJRmGYYSkqWO42jlXLSJ7AQcAD6Ed0ZoMFkoyDMMISSMM64LpIcBdzrlngfLimVT/WCjJMAwjJI0wfCMidwPHAC+ISEXK/RoNFkoyDMMISVPAHwO8BBzonFsMdCRlP4bGQsuWOrVQkmEYRgphcM4tB74CDhCRc4BNnXMvF92yekREvQbzGAzDMNK1SjoPGAlsGnz+ISLnFtuw+saEwTAMQ0nTwe00YHfn3DKAoE/D28AdxTSsvikrs1CSYRgGpKtjEMKWSQTzOTuuNUbMYzAMw1DSeAwPAO+KyDPB8s/RHEhNChMGwzAMJU1KjFtEZAywF+opnOqc+7DYhtU3FkoyDMNQsgqDiHSMLE4PPt9/lzbLamPBPAbDMAwll8cwHh00x9cn+AF0JJjvXUS76h0TBsMwDCWrMDjntqpPQ0qNhZIMwzCUJpXaYkMwj8EwDEMxYQgwYTAMw1BMGAIslGQYhqGkbZVUg6bYKmnx4lJbYRiGUXrStkrqAXwXzHcAZgJNqnK6rMxCSYZhGJAjlOSc28o51xtNuX2Yc66zc64TcCgwqr4MrC/Kyy2UZBiGAenqGH7onHvBLzjnXgT2Lp5JpcEqnw3DMJQ0uZK+FZHfAP9AQ0snAAuLalUJsFCSYRiGksZj+CXQBXgGGI2OyfDLItpUEiyUZBiGoaRJorcIOE9ENgLWO+eWFt+s+sdCSYZhGEqaEdx2EpEPgUnAFBEZLyJ9i29a/WKhJMMwDCVNKOlu4ELnXE/nXE/gIuCe4ppV/1gHN8MwDCWNMLR1zr3mF5xzY4C2RbOoRLRqBWvXltoKwzCM0pOmVdJUEbka+HuwfAIwrXgmlYayMli3DpwDaXIDlxqGYaQnjcfwK7RV0ii0ZVIX4NRiGlUKWgUSuW5d7u0MwzCaOmlaJX0HDG/qrZK8MKxdG84bhmE0R6xVUkBUGAzDMJoz1iopwITBMAxDsVZJASYMhmEYirVKCvDCYH0ZDMNo7hStVZKI3C8i80Vkcpbvh4hIlYhMCD7X1MbwQmMeg2EYhpK6VVIdjv0gcCfwcI5txjrnDq3DsQtOWZlOTRgMw2ju5BUGEdkGuBjoFd3eObdvrv2cc2+ISK8NtK/eMI/BMAxDSVPH8CQwArgPKHT3rz1E5CNgNnCxc25K0kYicgZwBkCPHj0KbIJiwmAYhqGkEYa1zrm7inDuD4CezrmlInIwOtZDn6QNnXP3EDSRHThwoCuCLSYMhmEYAVkrn0Wko4h0BP4pImeJyOZ+XbB+g3DOLfG9qIOhQ8tEpPOGHreumDAYhmEouTyG8ehQnj6l3CWR7xzQe0NOLCJdgXnOOSciu6EiVbIhQ00YDMMwlKzC4JzbakMOLCKPAkOAziIyC/gtUBYcewRwFDBMRNYCK4DjnHNFCROlwfoxGIZhKFmFQUT2dc79R0SOTPreOTcq14GdcznHhXbO3Yk2Z20QmMdgGIah5Aol7Q38Bzgs4TuHdnhrMpgwGIZhKLlCSb8Npk1u7IUkrIObYRiGkiuUdGGuHZ1ztxTenNJhHoNhGIaSK5TUvt6saACYMBiGYSi5QknX1achpcaEwTAMQ0kzgts2IvJvnyVVRPqJyG+Kb1r9YsJgGIahpEm7fS9wBbAGwDk3ETiumEaVAuvHYBiGoaQRhjbOufdi65rce7V5DIZhGEoaYfhWRLZG+y4gIkcBc4pqVQkwYTAMw1DSZFc9G81sup2IfIMO6zm0qFaVAOvHYBiGoaQRhk2ccz8RkbZAC+dctYgcBswosm31inkMhmEYSqrKZxHZyTm3LBCF4wBrlWQYhtFESeMxHAU8JSJDgb2Ak4D9i2pVCTBhMAzDUPIKg3NuauAljAa+BvZ3zq0otmH1jQmDYRiGkitX0iSClkgBHYGWwLsignOuX7GNq0+sH4NhGIaSy2M4tN6saAC0bKlT8xgMw2ju5BKG75xzSwoxvnNjoEUL/ZgwGIbR3MklDI+gXkN87GcowJjPDZFWrUwYDMMwcmVXPTSYbtDYz42JsjITBsMwjFyVz7vk2tE590HhzSkt5jEYhmHkDiX9b47vHLBvgW0pOSYMhmEYuUNJ+9SnIQ0BEwbDMIx0KTGaDW3aQHV1qa0wDMMoLSYMEXr1gmnTSm2FYRhGaTFhiLD11vDVV6W2wjAMo7TkzZWUpXVSFTDDOdekIvJbbw3z58PSpdCuXamtMQzDKA1psqv+P2AXYCLaya1vMN9JRM50zr1cRPvqld5Bl72pU6Ffk8oEZRiGkZ40oaTpwADn3EDn3K7AAGAy8BPg5iLaVu9066bTuXNLa4dhGEYpSSMM2znnpvgF59zHqFBMLZ5ZpaF1a52uXFlaOwzDMEpJmlDSZyJyF/BYsHws8LmIVABNKkl1ZaVOTRgMw2jOpPEYTgG+BM4HLgCmBuvWAE2qE5z3GFY0uWGIDMMw0pNmBLcVInIH8DKaCuMz55z3FJYW07j6xnsMJgyGYTRn0jRXHQI8hFZCC7CliJzsnHujqJaVAKtjMAzDSBdK+l90nOe9nXODgQOAW/PtJCL3i8h8EZmc5XsRkdtF5EsRmZgvm2t9YKEkwzCMdMJQ5pz7zC845z4HylLs9yBwYI7vDwL6BJ8zgLtSHLOolJeDiAmDYRjNmzStksaJyN+AvwfLQ9FR3XLinHtDRHrl2ORw4GHnnAPeEZEOIrK5c25OCpuKgojWM1goyTCM5kwaj2EYMAUYDpwHfAycWYBzdwO+jizPCtaVlNatYcIETahnHd0Mw2iOpGmVtAq4JfgUEklY5xI3FDkDDTfRo0ePApuRSWUlvPKKzj/zDAwbVtTTGYZhNDhyDe05iSwFNYBzbkOzCc0CtowsdwdmZznXPcA9AAMHDsxqUyHwFdCgoSXDMIzmRi6P4dAin/s54BwReQzYHagqZf2Cx/dlABMGwzCaJ7mG9pyxIQcWkUeBIUBnEZkF/JagNZNzbgTwAnAw2qt6OXDqhpyvUJjHYBhGcydNq6Q64Zz7ZZ7vHXB2sc5fV0wYDMNo7tgIbjEslGQYRnMnlTCISGsR2bbYxjQEzGMwDKO5k1cYROQwYALwr2C5v4g8V2S7SoYJg2EYzZ00HsO1wG7AYgDn3ASgV7EMKjXRUNLaJjWitWEYRjrSCMNa51xV0S1pIEQ9hjVNahgiwzCMdKRplTRZRI4HWopIHzQ1xlvFNat0tG0bzq9eXTo7DMMwSkUaj+FcYEdgFfAIUIWO5tYkMWEwDKO5k8Zj2NY5dxVwVbGNaQi0aRPOWyjJMIzmSBqP4RYR+VREficiOxbdohJjHoNhGM2dvMLgnNsHTW2xALhHRCaJyG+KbVipMGEwDKO5k6qDm3NurnPudnQchgnANcU0qpREhcFCSYZhNEfSdHDbXkSuDcZuvhNtkdS96JaVCPMYDMNo7qSpfH4AeBTY3zmXOF5CU8KEwTCM5k6aEdx+VB+GNBSsVZJhGM2dXCO4PeGcOyZhJDdBs2Zv6AhuDRLzGAzDaO7k8hjOC6bFHsmtQWHCYBhGcydr5XNkmM2znHMzoh/grPoxr/6xVkmGYTR30jRX/WnCuoMKbUhDwTwGwzCaO7nqGIahnkFvEZkY+ao98GaxDSsV0eyqq1fD00/Dd9/B6aeXzibDMIz6JFcdwyPAi8Dvgcsj66udc4uKalUJiQ7Os2YNHHWUzpdKGN59F7p2hZ49S3N+wzCaH7nqGKqcc9Odc78M6hVWoK2T2olIj3qzsAS89hpsv31hQ0mXXFK3EeF+9CPo1atwdhiGYeQj1dCeIvIFMA14HZiOehJNliFDYKutCisMf/6zTtetK9wxDcMwikGayucbgB8BnzvntgL2ownXMXjKyzNbJTmXfdvasHJlYY5jGIZRLNIIwxrn3EKghYi0cM69BvQvrlmlp6wMli4NlwvlPaxYUZjjGIZhFIs0wrBYRNoBbwAjReQ2YG1xzSo9G28MU6eGy9XVOl2/Hn7/e22p5KmqxYjY5jEYhtHQSSMMh6MVzxcA/wK+Ag4rplENga23zlz2wvCf/8CVV8LZZ+vyCy9Ahw7wZsrgmnkMhmE0dNIk0VsWWXyoiLY0KH7wg8zlqMcAMH++Th9/XKeffAKDBuU/rnkMhmE0dNK0SqoWkSWxz9ci8oyI9K4PI0tBXBh8fUNZmU59ncPMmTrt0iXdcZuSxzBlivUON4ymSKoxn4FLgG7oAD0XA/cCjwH3F8+00pItlOQLwlWrdOqFIV8B6fsw1MZj8N5JQ2T2bOjbF847L/+2hmE0LtIIw4HOubudc9XOuSXOuXuAg51zjwObFNm+ktG+PdxzDzzyiC57YfBv/L6AnzFDp14ostGiReb+aWjIfR4WBX3fx44trR2GYRSeNMKwXkSOEZEWweeYyHcFat3fMPn1r2GPPXTeC8Py5Tr1QuAL77gwvPFGZnNXLwy18RgasjDUpRe3YRiNgzTCMBQ4EZgPzAvmTxCR1sA5RbStQdC+vU7jHkNcCKIF/vz5sPfecOKJ4bq6eAxrszQKnj07syltKWjIYa5crF2b/b4ahqGkaZU0lezNU/9bWHMaHh06QKtWMG+eLvuCPV6nEBUK7yl89FG4ri51DNkKsG7ddFqo3th1obFWOrdpowkJv/ii1JYYadl3Xxg8GK69ttSWNB/StEraRkT+LSKTg+V+IvKbNAcXkQNF5DMR+VJELk/4foiIVInIhOBzTe0vobi0bAk9esD06boc9RiioZ5oge/Xt4jc3UJ6DA0BL4SlFKe6sGYNfPllqa0wasNrr8F115XaiuZFmlDSvcAVwBoA59xE4Lh8O4lIS+Cv6KA+OwC/FJEdEjYd65zrH3yuT215PdKrV01hqK7O9BJWrdIU2f/8Z/g2HY3D5/MYdtoJunfPXNcYhMEwjKZHGmFo45x7L7YuTZG1G/Clc26qc2412rz18Noa2BDo1QumTdN5X/m8ejXcdFO4zcqVmiL7Zz8LxaM2HsPkyfDNN5nrGnLlc2MShtWrVbSN5sns2fDtt6W2onGRRhi+FZGtCVogichRwJzcuwDa7+HryPKsYF2cPUTkIxF5UUR2THHceqdXL5gzRwv/FSs0Tr3ppvDvf4fbRD0BP9+yZbjOh1wKUcdQG37+c7joosx1b70Ff/nLhlUgNyZhOO88FW0LITVPunVL3wHVUNIIw9nA3cB2IvINcD4wLMV+SQ0a4xHpD4CezrmdgTuA0YkHEjlDRMaJyLgFCxakOHVh2XJLnX7zjQrDRhtBnz5hWgyAjz8O571XEA0l+YK0kHUMy5bpJxfPPgu33KLzvjPeTTfBBRfAnXemtwXgF7+ARx/V+boIw4oVGjKrS9+HRYt0jIwPPtDliRMh7U/hnXd0umRJ7c9rGM2RvMIQhIJ+AnQBtnPO7eWcm57i2LOALSPL3YHZsWMvcc4tDeZfAMpEpHOCDfc45wY65wZ2KYH0d+2q03nztHBr3VrFIVowvf9+OO+9Ah8+Wr8+HNuhrh5D27Y1v99sM+jYUednzICHH85+rNdf19Y4jzwSNsH95JPMbW66CW69NXn/detg1Cg4/nhdroswTJmiIbO69Jb++mut5/HCsPPO0K9fun39fWyR5jXIaFA0tsYNTYW8zVVFpAL4BdALaCXBa3CKiuL3gT4ishXwDVphfXzs2F2Bec45JyK7oUK1sJbXUHQ220ync+dmCoPv2wCZqbd9PYT3GKJNO+vqMfhjRol6Cz/5iYZKjjkGKitrnnfiRJ2+9VZYqC+Kjdz96KOabvyCC2qeKy5odREG/yevS+c4L6xRm+fOzb3PsmWa5NDvGx14yWgcNOQGGE2ZvMIAPAtUAeOB1MWBc26tiJwDvAS0BO53zk0RkTOD70cARwHDRGQtmtr7OOca3jtC1GNYvlyFwb91J+HHapg0CY49VlNreIrV89lXrlVVhcKwMCKxvjB2LhSMhTEJji9HiQranDn1X8fgbY6LWS6uuALuuCNcbkqZbd97T+u6+vYttSXFpbH2l2nspBGG7s65A+ty8CA89EJs3YjI/J1ALSPd9U+XLlqwxj2GbEQLryeeyCycVqzQDjtHHgnn5Ok3Hn9bci7723br1rB4sX68h5OtoE/yGJzT7aMV5lGiwrBgQTphuP56+PBDeOYZXfZCt6EeQ9q3yLiIZKuPmTABvvpK61AaC7vvrtOG9xqlHTtnztTnfOihG3ashurlzZsHI0bA1Vc3zRBlGmF4S0R2cs5NKro1DZRWraBz57COYaON0gsDZBaiK1dqh53XXksWhssu0zj6E0/ULABXrQq9gSjr1+vbI6gweKJN9JI8hqidy5bp+mhILCpEUWFYsyadMPz2tzXtrytRm9Mex98TT7Ty2V+bczBgQLjO2DDWrYP+/cPlyZP1Pu+Q1IMpBQ3VY3juOe2JfcIJNTMxNwXSaN1ewPigB/NEEZkkIhOLbVhDo2tX9RiWLoV27TKFYeONM7eNDvsJmSGMpLfWqADcdhu8+io89VRNYcgWCqmuThaGbKGkJI/Bz1dX65/7nHNgxx3DwjJax7F6dWhLvMnrp5/quSZPrmmn3yetx/Dll1rfsW5dpsdQV2GIip6/t9FGA02FI45IrieqD+J1aH376u+orjRUYfBpb5pSeDJKGmE4COgD7I/mTDqUZjC0Z5zNNlNhWLQIOnXKFAY/75u1xj2GcePC+aQmltEf1+ab63TevJrCMCmLz1ZVldtjaNMmuelsdXVY4EZFZMIE+OtftdWSF7lsHkP8j/vkkzr1I9tFqa0wnHaa9rcYPz7TY0j7Z8zlMfhjRJ9VY+qbkYvRo/W+eebP19Bl9LdRLJIaSWwISaGkNWvg+ecLe57a4l/wmspvJk6a5qozkj71YVxDwnsMixZpE9Fo5bMvXH74w8xlz7nnalPRfffN7PvgSeocN39+zcrnwYN1jOk4VVVhc9bon9/3pN544/DNPxpKAhgzRqdRYYgm//N9H7IJQ7yQ9h5EtPCvS+c+gPJynS5aVDePoXXrzOWoMPhjRI/VVPs5/OEPWs/zt78V/1z5+tXUliSP4dprte4i2sE0G8UKD/rrbM4eg4F6DDNmaEHSsWOmx+B/JD/+sU6TWvscfLDWUyR1zY/+uHy4Y8GC5ErW//yn5rqoxxANl0yZolORzKR3q1aFlcz771/T5mjm0XzC4KfbbquVt0lNUuN9OEQy7cyG76OxcGHd6hji9y/JY4je+zTCsH59eNzx43O35GqIrF+voabXXivO8QvtMUSFwf+2vvpKp0kvWXGKVXldF2GYNg3OPz+3TfPnw0knFV5ga4sJQ0p8k1WoKQyebB4DaIbWeMWxDz1FC10/P39+sjDE8ymBFrK+oI96DF4YVq/OLExXr4bDYsHAaAEXTR2RJAzR4/np559rB7gkYYiPejd1qqYzv/vumtcSxQvD3Lnhn2nZssz+I7mIv21GxaiuHsNJJ4Xjfg8cCHvtlc6WhoCIXuPo0ZoqpRhkE4a6vrlHC1E/H60vq83+hcTXMdQmlHTFFVqH+K9/1fzuiy+gokKbt//97zByZGHsrCsmDCnxTUBBC6xoJtTnntMH3qGDLicJQ8+eNUMbs2bpNOmt46OPkusjfEEdpaoq/ANEhcEPO7pmTWZl8apVKnQ+lfGaNckeQ1lZeIx8HoPH/1mffjpc5wsLb4P3mvywqTNnasuOaFoRCENJs2dnFvJz0mTqSrAtKZRUW4/B/2F9mO/TT9PZUkiiIcY0TXejBWhS5t9ly7LXX9WGrl2zj5lQm46dUaLP3T+z2ghDsSqv6+Ix+JfLKVP0E/XMH31UbfWh3VJjwpCSuMcQFYYDDoDhw8OCP+ktomfP5KamkPzjWrgQTj655nqf/ju+rf8D+MriaMuhaEH+/PPqjZSXh4nFvv22psfQqZN6NL4QziYMa9ZktkzyhVa0VVLcY/D4N/hXXlEv4sorNcyx6aaZ+82enfnmNzuSWGXevOx//vj6pFBSXesYogJ83XXJrbCyMW9eKLigLxK1OXfU5tqGHJLyeN19N+y224YVosuW6XUl1YFB3etvos/dX3c01Uw+Ro+u23nzURdh8C+XH3+srbW22Sb8rqENlWvCkJKoMHTqlNmpxYcW4q1goiR5DKA/iNoM0xlvWVJernmE/B/Iexk+3NK2bWboxxf0FRWhMCxYoMLgK9SXLdPvOnQIC+9oiCDejyE6n+TR5BMGf1/GjtU/sr8Gv99jj2X2+Yh6DF27auV+lEWLYNiwUCS9IMc9hjFj4JJLwnW1Kbyi8e1rr9WXg7R07aoZe70dnTrBgbXoQhq937Wp4xBJbhm2YIGuX7JEp1ddVXvBSQpxRslXp+Rc6EFH2RCP4bPP4Fe/yr1NXYm2SjriCDjllPz7ePuT/u8NrZNcAzOn4dKzZzjvY98e/0NNKvivvx5OP12boWbzGF55JXP50kuz2xGP4fbooW+f/g80f742N/3s9pcA6LRsBmvXwsqJn2fsF/UYvDD07h1+36WLtmbyQhT1GKZP1wGJPNHvkkIr+YTBF8jxEFy2t7GoxwCaciRaSNx4o/ZKfeQR9Xqqq7XiP1o4rVwJ++xTd48hXvGZNn1JvMD12Wrffjt5+2HDNGFglOh92XrrzGtPChtF1yWNFeLXLVmizZRvuinMyBtn3rzkZI1ff11zXZR89/bCC/VZxfNf5RKGuMfw+usan/fE73UhWyhFPYbRo+Ghh/LvE20mHseEoZGy0UZw9tk67wvU667L7PWY5DEMGQL33qsPPkk4oKYbudNOcOaZ6ezq1StTGGbPhiGDVnPeDZqktjMa0F86ZlzGfkkew2abhc1evceQJAy+/sB7UdE3+M8+q2ljWmGIcvnl2skviaQ6hp/9LJyPhh9at9ae65WVyXUMUTZEGNq1S7dffDsfGsyWKXbEiDABou81H7e9ulp/Z6+/nilQvvDyBeK6dZmhpFde0c5nXpCXLAkLrWxhpZ//XEOcfgx0T9LbfpRcHsP69WG/i/h9TQolJSWnBL0HJ50ULscL20JURK9YoSKQ1MHtH//I3YTWb5t0r+K2lroXvglDLbjzTv1hVFTo8jXXZLbgKSvTN9MovgIVsnsM8R94mzbpBxbp2VNHJxs/XpcXLoSq5eWMW78rAJ2CZLVL12WePEkYOnUKe3F7j6GqSvMdRd8I/Z/33nt1Gu09HH0b6hYMy7R8uf7542m+/RtfUoH8xz9mv+aox9C/P2y3XdCJcORI6NWLFnfc9v33/v7HhSEuUq1apWtC66mLMCQVtj4UtGKFfs48s6ZH5Bk2TPvC+NZmns8/V1HYZ5/MMEX8jXnVqkxhOPdcjXd/+KGuW7IkFJYbbtC+AvExO7yQxcUpn8cwc6bG1aN9ZJLs9AWuJ5fHEH2GvgkrhNcY9+KyCcOjj9a0f+7cmhkMQJ/BKaeEv+XofTjxRM1ynI2kTpXZMg5/9hkcfXTp+kmYMNSSbIW7x7dM8vj6B8juMcT7NrRuXVNgspFvOy8M1WSmgy0v15BYZaW2r/bC4O33wvD117DLLvDgg2GT2AULVFh8nPzUU5PPfc01Ol2xQvMmvfRSzW2WLKndm3qLFpkeQ6dO2n9iwfz1rPv1mTBjBusjY0RVLNPrr6zMLHTidTXt2mWPq3/4Yc0QWVwYvKd12GEwdGjycZJCG14Yli7VAYXuvlsLhDjOhQMOxQssH150TvuTePz1+pZLK1dm1jF4D9d7eVFhAG2ocO65mW+vXszj15LPYzjtNBU0/5uIEn2ZiAtDtDCPt6jy1+KcjtDnySZeScKwdKmOMXLwweGxJk/W0O8WW9TcPhpCjdqQhqRt/fXGbbv1VvWYi9XfJB8mDAUm3r8hKiTZRCX6tgO18xh8eAsyRciTTRgqKrSg33lnTeG8eHFNjyEucv67tWv1u2gT3iT8H2vFirBpapxp02onDJtskhmH7thR7Vi3vgULV6jyLiKsBCqfPR2oee9vvjlzuU2b5Db469apMG6/feab3vWx0Ui8F/l//6fXOmeOtq567rlwm3iht2pVpjD47996q2YoYfXq0L64qGVLRX7DDdpKKNq0OOoxeDHzhdKSJcmFZzRs5IUhfi3x0FI24m/xzmU2la2NxxCtG4m+XHlhiBfESR6bt9sL/dlnayg3af9589LXgyWRtO2cOZktCOP431V9Y8JQYAYP1umLL2oF3vbbh99l8xjiwlAbj2HLLbVVBIRNaPt0DUva74VBMhXLh1h23VVDUZApBt5jiBK1qUMHFZJc+FDSihXZ38bffFML07T4XFKejh0j42WgSvUtoaEVq/RexIUhHtbywvD++xqeu/JKXf/66+E2L7+c3a54O/2xY9WzOvxw+POfdV280Fu+PBSG6moVSU903u/rhSHeEunFF5NtGjkSDjkks5d3tPI5Xnm7ZEmyOEYrm33BHvdacgnDxReH8/Fz3ntvZossf48++khbjEUL85UrNZTzwAPhMtSsc8omDLlEz7fIizcEiRLPFhy1N8rcuckVzEn1Wttuq02Fs/Xz2JBx2TcEE4YC88c/6o/rwAM1w2U0dpjNY4h3UqqNxwDhj/qHP9S0HL/9cygCnX0dQ8eeGfv4N5Fddw3P/4Mf1KxjiOJ7aoMKQ76WFL7AXrw4ORUI6BvawoXpW2XsskvmclQY5qIzUWEor9T4V1Jq5IEDw3kvDO+8o/FwX38SFa2kQsAzd27m/Yq+BfuEb/H9ly3LLOSjQ56OHZtZkF1+eSiufh9f4EYHgkoiSRhEahbmVVXJifYuuyysS/MF1QEHaGXrfffB3nvnFoZon59FizILwXh40d+jffZRQY02g50/Xyvj49cVr5PxTabzhZKeekpfTCD8D+XqTzB9emadISR7a5tvXvN3GrU3zkcfZRcG/8wXL9awbn0JhQlDgSkvz14B5R/+zjvX9AiiYZnWrTP7TeTDV3x27QpvvAFHHRV+t8nfbwdgqUsYNBoVBs+222Z6DPE/wRZbhOviYaYk/J9t2rSaIYTNNsussE37g48W5qBvxN8PvVrekyW0ZzzhRhXbaxvcpEF44i3Kli8PC7iWLfWt+Omnw+aiuUJe06dnfv/RRzoGwSmnhDH8uNe0cKF+WsVGRenQAf7738y38vvuC38/XmR7Zmp9VqKd+XIJw5Il2TOwzpmj6RqiFfSPPw6//rX+5ubMyRSAKNH1774betVQ00PxwuDt9L3zoWZfiRUr9GVm+PCatkJuj2HNGq3L8U3DfQg4V66n+fPDejVPtn4k0UYpnlxhp3zCcN992jS9vnIomTDUI/6Huf/+NSsvt9oqnE/rMfg6BV/A+uVoXNLPx11b/za1ww66TUWFegRRjyH+I9x88/AcXhgmTKhp1+DBGorxoTPv2v/1r3DWWTrfqpX+0GvLHnuE8ytWwKBBEY/hyLO4uv1tGduX99ZSaf/9tWlmp07hNfzgB+F2bdpoqOjGG3W5uhqOO07fPn3FZFKKkptvhv/5n5rrJ05Uod12Wy2oHn20pscwYICeJ34fBg1SYchWSPvCaJNNkr+P439r0crnFStq2pMkDL5vy3ff6eBRUaJ1WitWqHCcemrNuHi0Qhwy09AnCcPw4TUL0RYtagrDhx9qGDbeSssLQ9xjiIal4sfy9S3x/4mv8Ae9j3ExzjfU7HffhS2eotcUv0fZRMP/B6vf0jbLbTdqqepU5GRKJgz1yDHHaEFy3XX6xhZtcRAVhk02yRxic9Ys/XNFQw0Qvml6YYi6weecA336hH9e/4Y0bJgu+z9NWZk2+dxmGz3ndttppWmXLtq65te/Dgu+du3C4/lCKd75CrQt+Y036vHatw9zwuyyS+hif/ddmPoC0otE1MPxobn27dWuhT13YdqQU+nWTVNNQ/gHrKjQ8M78+eG9zdUHZfnysNPZ8OG6jy9go/UcQ4cmj//9zTf6FuoLxeOPz94cNl7YDBqkraCiuXSi+LqOjh+la7LimxOPGRMWiL5Ai9Z7JQmDf9tPejOOezo77gj3369NaqPkqi9LEoboULie3r1rtnx6773kY86cmSmCHv9iduutGgaLsnq1VoTHxXKPPbRwdq5uwrDttuFve9Wq8P8TD21m8xiWLgVGjmTpP8fQlqW0YL12XDrjjKKKgwlDPdKqlVao+T/jkCFhBW1UGOJ1EZtvrgXFDTdkrvdhnXjrEtA/1+efZ4aD2rQJC8ron+auu8KY+skn6xtOWZkKwT33ZHokcY8hiWhB0LlzGErZbLOwYF++PPSKttoqe8/fOCL6Ruhjw35dp05aeM2erZ3FvBcRvX4RffP0dSrRP2fbhEhbdbWmSe7aVb9/7DFd70UH9Fkl9WFYu1b3GTIkXBdPEuiJFzbeK8pVEQrQ8e+35d4gxvz5cPvtmev69AnnFyzIzOEE4e8zXlkPNUe/y9ZKLcmz+ewzLVSjBWvbttnrcXr1yt9XwvPpp/qbSqpjmDdPe1lffXXmd4sX62BGSSHN998PE1XGn1W+lCRRL3PlyvC/Ec0yAGE/pDjLlgFXXUX12kraEbk5y5dr7pIiYcJQYnyBFBWGOL5iNlp4bbNNWKnpC/uk5nhRd79btzAsEg3JDBgQDi4vUrNuwdvWu3c6YYi2VoqKxKabZg7z6IXhJz/R+oukN+8kunaFPfesec6FC1U0ttgi9EaSmvv5+o54KCnbufz3/u02+qZcWRkKsk+77mnbVgvF//5Xl2+6Kfkc0cJmyy3DQiPfQDQd52ZRmloQFYYXX6wZPtxsM/WWkgqueELHbF5f/Blsuql6prvtlllxvNlm2cNn3bqFHfEAOvEt13ENB5GZtc+fa+7cmh7GmjU1+yF4xo/PnnDvzTdDbzF6jS1a5B4VLxqWWrZMhcH/N6INOSC76C1dCsycSTXtaU8szpWUmKxAmDCUGF8g+ULq0EOzbxsNFT3+uIYcICzI8wlD9+7w059qARcVhnwMG6YidPTR6Sqf4x4D6HW2bav2bLmlprDwwuAFId4H5Jxzwph/Pjp10j/v3LnqYfm317jIgbaEOfrozAr+fMIQFeVo4VBZGfY2HjYsswD1+2y3XW7b/X3o2VPDXVtsoYVxvoytXbbM09syBfHK1Hh4yItbtF4gG17QovVjSU20/W/yq68yPdeNN67ZTBf03EOGZLbeK2MN1/A7diSzgiHayME3E/a8+WZm8+O0vP9+KAzxLMu5ePXVcH7+/ExhyNcHyLNsGdCjB0tpV1MY6lJJlxIThhLjC6SddtImitEKvj//ueazP/ZYnUbrIHzhl9ROOlow+rBAtv4U2WjRQj0Nkbp7DNH6hJkz4dlnwxCMd9/jHsMdd9R8C891zjff1GPtsEP4x0vyGH76U73P0SayUWGIJpCLh6TOOy8UZNBj+MyaBxyQGTbxwtCpU+4+H75w/vnPtXBs1Sp8VtF+MFFeeAE6/P6y7AdNSbwlUefOGj7ztG6t17RkiYrggAHZj+Xv4R13hB0I4x0BzzwzeybWVauSBWiXXeCXv8xctxp9IL6fjuc3v9EK8CQxvvTSzMrkfFx6qf7up0wJvY9ob+iox5lEtPOpF4bu3fW3lG9fz7JlwI03Ut1i48xQUps26d+a6oAJQ4lp21YLr44ddTSwaKF90UU1Y74PPQRPPql5Zzy+8EsShrjHsKGkEYZo4eiFIe46R4/l3wSjwuDf9tKKmH972313Fc8uXVTI8qUwAS3c/XZXXaXC4fHC4L2xPn1qtnXff3+tnNxii2RhgNzt/PfeW99k//SncJ2/b9mE8aCDyJ57oxZ4AfJ07KiVsz7NeevWYS/sX/4SPvggc/t4wQ/q+V1yie7n+1qMHauhoFw5pfwws3FE9Df+wQewxSYaz1uF/ujjwtC9u1aAR+uBonz5Zfi723lntdV3EI1z0UV6/7/6KqxjiXpY0f9gEkuXwu9/r/Pz5oUDZH3+ubZ4y0fv3nrffjFqKLM37U/71mv1ZvTsqZV/BXj+2TBhKDHt22uhmXagjooK7acQ3T5XHUPUYyikMCRVKI4apZ36ouEIX9j375/bNghDSS+8oH9KyPSMcuH3HTxYC/rycq0sPv303PuNHauhIB+CqKzMFD0vaF508zUR3Wij8NlEhSHXdbRtq3ZHRdyHWM44Q5Oz1ZbRo8MxyKOthP7zn8z6Ge/9+OuMX1+rVmEdiu8vEBX5vffWabxHepy99tLfQJIwXH21psu+9dbcxxgwAN78QN2S1ZSDCJ26aBHm/wNexHK1hPJiO2SIVipHB8yBMCTWvr0W/s6pAHbpkmm/T53hueKKcP7QQ9X7Of54Xf78c32mFRVarif9HkS0AvzYY/WedOyoQjZqFHwxdyPa/2xfdYmnTy+qKIAJQ8n57W/hb3/bsGPkilsmvb1vCEl1DF4IDjqoZh5/HzaIt2UHbdZ68slhCxFfuEcrQNOmH/atP6KVqccck78T2F576TZeVMvL9T61bathI++JeGHwy/ffHzb9jdKiRXhv4i2dfAVnVVXmdSW9FDz0kLYUGzQoM9f/vvtmT1oYbcW0ww56/aD3fvp07Vy2zz5hYVVerl6Oc6GAJjUAGD1aK8K9uM+cGT6rLbbQVkBphwZNEoZjjoETTtD5f/1LGyhEn2MUb98aymH9en7w6t3fXy+EYcloPUc8EZ1P0e5byMVfqB57TOs6WrdWwfZeazwXWbQhhXOZgwLddpsKjrfjkkv05SPJgx00SNN8TJqkHSofe0yFKP77SZvavRC0yr+JUUyy5eGvDT/+seazOfLImt/16KG9cLt1K8xgIEmhpLff1h9zUjz/oou0aWI8Rgz6w3/wwXB5113hmWcyjx39M0bfyOJ4AUjqV5EG/1ZcVqZ/3sWLMz2fuMdw6qnZC+hNNtF+GvE/drQfRz4GDgx7eUeF4+GHM8M/H34Yxv2jPe7Ly0PP4Igj9P74e+TtihaIvqBPSsSY5O35eofNN09u6puNpMItWv9ywAHhaHhJghkXrn79tMHBvffqvfAvP1FhiDZL7tRJ6w722CP0qOI92jt0CENGm26qIaztt6+ZesOL11576TTastDb2bq1phTxaeSTMhrcc08obFHi9VJpW+0VAhOGJoBI7nBDIcTH4wuOaF6gaCEWZ/vtNVyThssv1/TJ++2Xeezf/U7faHOlCbnmGs1Ptdtu6c4VJ+oxQM3WOXGPIRdePPIVmIcfnjsFQxLxgjWp0Aa9jl12UcGLX8sRR6iQR0XUP8+0obtXXlEvojaiAPmFIU78Zaa8XG2M1rtutpn+drbbLqwviP4+t9xS78OWW2poSCQzLYcXhs031+bO8dZx222nnm18+NUePbSj3EEH6XL03kWv8w9/0JeImTMzf9uebPfwr39V0Zk7Vyvzs3WCKwYmDEatKCvTt6BipANu2bLmH0dEW5rko7w8fHOrC/5NPhoeiOKFI00airTCUJeB6tMWxNkEDrTQ/Ne/Mtf5FkW+cMsXwuvTJ3u4JxdJ9ic1KQYtSJNCL/Gkk6DXGc0RFheUVq100KF4ZTuEdQpPPZXZ1DlK1LONki3UH7fbp0dJIldT6QsuCFsqxtPoFBMTBqNWlJWlS6DX2DjtNA29JLn0oIXHV1+lu3YvDMWICScV9FHKy1XEkkJCufCxeX983yyzEPVSUbwI7LhjOFhUNpJasm0ISYkUQeP5BxxQs9NkXZgyRUOraRuTQH6x903WswlIMTBhMGpF69bpwimNDZHsogBagTluXP6CGdJ7DIXirLPCTKxHHqlhomxv4dnwb+HeY7jkEi2Y0zSrrA1eLE8+Wc9RTLp3T+fZlpdrpXxapkzJ3uN5hx1y/46i/OlPeg/yNanefXeth0iqQywW4ko96nQtGThwoBuXphumURQmTtSY7IaEbZo6l1+ulY3ffVc478q/geb7u65apS3B4rl48lFVpXUe992XvvNVXXn3Xa0Lqs1bdV1Yv17PUezzNBZEZLxzLkttYCbmMRi1opAV2U2V/v21VUt9Ni/0VFTUXhRA6x3GjCm4OYn4vFzFphCt8JorRb11InKgiHwmIl+KyOUJ34uI3B58P1FEUjbmM4yGy3HHaTv4NGGntLz4oo7pYBj1QdE8BhFpCfwV+CkwC3hfRJ5zzkVTQh4E9Ak+uwN3BVPDMCLEm0oaRjEppsewG/Clc26qc2418BhweGybw4GHnfIO0EFE8nSuNwzDMIpJMYWhGxDNMj4rWFfbbQzDMIx6pJjCkNQWIN6mIs02iMgZIjJORMYtSBp41zAMwygYxRSGWUC0i0p3YHYdtsE5d49zbqBzbmCXaBIUwzAMo+AUUxjeB/qIyFYiUg4cBzwX2+Y54KSgddKPgCrn3Jwi2mQYhmHkoWitkpxza0XkHOAloCVwv3NuioicGXw/AngBOBj4ElgOZMlXaRiGYdQXRe3g5px7ATJH6w4Ewc874Oz4foZhGEbpsL6BhmEYRgaNLleSiCwAZuTdMJnOwLcFNKeU2LU0TJrKtTSV6wC7Fk9P51yq1juNThg2BBEZlzaJVEPHrqVh0lSupalcB9i11AULJRmGYRgZmDAYhmEYGTQ3Ybin1AYUELuWhklTuZamch1g11JrmlUdg2EYhpGf5uYxGIZhGHloNsKQb9CgUiEi00VkkohMEJFxwbqOIvKKiHwRTDeJbH9FcA2ficgBkfW7Bsf5Mhj8SIL1FSLyeLD+XRHpVUDb7xeR+SIyObKuXmwXkZODc3whIicX6VquFZFvgmczQUQObujXIiJbishrIvKJiEwRkfOC9Y3uueS4lkb1XESkUkTeE5GPguu4LljfcJ+Jc67Jf9CUHF8BvYFy4CNgh1LbFdg2HegcW3czcHkwfznwx2B+h8D2CmCr4JpaBt+9B+yBZqx9ETgoWH8WMCKYPw54vIC2DwZ2ASbXp+1AR2BqMN0kmN+kCNdyLXBxwrYN9lqAzYFdgvn2wOeBvY3uueS4lkb1XIJztgvmy4B3gR815GfSXDyGNIMGNSQOBx4K5h8Cfh5Z/5hzbpVzbhqaY2o30cGNNnLOve301/BwbB9/rKeA/fxbxobinHsDWFQC2w8AXnHOLXLOfQe8AmzQGGdZriUbDfZanHNznHMfBPPVwCfoGCeN7rnkuJZsNMhrccrSYLEs+Dga8DNpLsLQkAcEcsDLIjJeRM4I1m3mgiyzwXTTYH226+gWzMfXZ+zjnFsLVAGdinAdnvqwvT6f5zmi45HfH3H1G8W1BOGEAegbaqN+LrFrgUb2XESkpYhMAOajBXWDfibNRRhSDQhUIgY553ZBx78+W0QG59g223Xkur6Gcu2FtL2+rukuYGugPzAH+N8NsKter0VE2gFPA+c755bk2rQOdpX6Whrdc3HOrXPO9UfHnNlNRPrm2Lzk19FchCHVgEClwDk3O5jOB55Bw17zAreRYDo/2DzbdcwK5uPrM/YRkVbAxqQPmdSF+rC9Xp6nc25e8IdeD9yLPpsMu2LnbxDXIiJlaEE60jk3KljdKJ9L0rU01ucS2L4YGIOGcxruM6lLZUpj+6DpxaeiFTm+8nnHBmBXW6B9ZP6t4AfzJzIrpW4O5ncks1JqKmGl1PtohZavlDo4WH82mZVSTxT4GnqRWWFbdNvRirRpaGXaJsF8xyJcy+aR+QvQuG+DvpbgvA8Df4mtb3TPJce1NKrnAnQBOgTzrYGxwKEN+ZmUtGCszw86INDnaA3/VaW2J7Cpd/AD+AiY4u1CY4P/Br4Iph0j+1wVXMNnBC0SgvUDgcnBd3cSdl6sBJ5EK7DeA3oX0P5HUVd+Dfpmclp92Q78Klj/JXBqka7l78AkYCI62uDmDf1agL3QUMFEYELwObgxPpcc19KongvQD/gwsHcycE19/s/rch3W89kwDMPIoLnUMRiGYRgpMWEwDMMwMjBhMAzDMDIwYTAMwzAyMGEwDMMwMjBhMAqOiIwRkaKPSysiw4PMmyNj6/tHM27W4nhbiMhTKbZ7QUQ61Pb4DRURGSIi/1dqO4yGQ6tSG2AYUUSkldNcL2k4C23jPS22vj/a3vuF2hzfaS/0o/Kd1DlXa9ExjMaEeQzNFBHpFbxt3xvkiH9ZRFoH333/xi8inUVkejB/ioiMFpF/isg0ETlHRC4UkQ9F5B0R6Rg5xQki8paITBaR3YL92wZJz94P9jk8ctwnReSfwMsJtl4YHGeyiJwfrBuBdhB8TkQuiGxbDlwPHCuaq/9Y0fz994jIy8DDwbWPFZEPgs+ekXsyOWLTKBH5V5DH/ubIOaYH9yXXPfxhkOTtbRH5k0TGeYhd2yXB/ZgoYZ7+I0TkVVE2F5HPRaRrDruHiMjrIvJEsO0fRGSo6BgAk0Rk62C7B0VkRHCMz0Xk0AR7sj2jHYPjTQhs7RPbr2Vw/MnBOS8I1m8d3MPxwXm3C9Z3EZGng/O8LyKDgvXXBucfIyJTRWR40n0zikwhesDap/F90PQPa4H+wfITwAnB/BhgYDDfGZgezJ+C9p5sj3bzrwLODL67FU1y5ve/N5gfTJBmArgpco4OaE/0tsFxZ5HQVR/YFe3l2hZoh/YQHxB8N53YWBYRO++MLF8LjAdaB8ttgMpgvg8wLnJPJkeOMRXNOVMJzAC2jJ43zz2cDOwZzP+BSKqNiF37o2P4CvqS9n/A4OC7fwDnBOt+mcfuIcBidPyCCuAb4Lrgu/MIUkoADwL/Cs7VJ7jnlcH+/5fnGd0BDA3Wl/t7GXtOr0SWOwTTfwN9gvndgf8E848AewXzPYBPIs/qreA6OgMLgbJS/1+a28dCSc2bac65CcH8eLSgy8drTnPjV4tIFfDPYP0ktOu/51HQcQ5EZCPRmPz+wM9E5OJgm0q0UIAgZ3zC+fYCnnHOLQMQkVHAj9EUA7XhOefcimC+DLhTRPoD64Btsuzzb+dcVXDej4GeZKYwhoR7GFxre+fcW8H6R9DcOHH2Dz7+WtqhBfYbwLmouLzjnHs0hd3vuyCFs4h8Reh5TQL2iWz3hNPkc1+IyFRguwSbkp7R28BVItIdGOWc+yK231Sgt4jcATyPppJvB+wJPCnhECAVwfQnwA6R9RuJSPtg/nnn3CpglYjMBzYjM920UWRMGJo3qyLz69AEX6BvwT7MWJljn/WR5fVk/p7iuVYc+mb8C+fcZ9EvRGR3YFkWGwsyqFDs+BcA84Cd0etcmWWf+P1J+r8k3cO0Ngvwe+fc3QnfdUPv6WYi0iIozHPZvSHPJW5TjWcEfCIi7wKHAC+JyOnOuf98fxDnvhORndGBYc4GjgHOBxY7TTcdpwWwR0Ss9eQqFGnuu1FErI7BSGI6GhqAFJWxWTgWQET2AqqCN++XgHNFvh+ndkCK47wB/FxE2ohIW+AINDtlLqrRcFc2NgbmBIXtiejQrwXD6UhZ1SLyo2DVcVk2fQn4VfBmjYh0E5FNRdMmPwAcj45admEB7T5aRFoE9Q690SRtcZtqPCMR6Q1Mdc7djiaui3qHiEhnoIVz7mnganRIziXANBE5OthGAvEA9WjOiezfvw7XYhQJEwYjiT8Dw0TkLTTOWxe+C/YfgWYqBfgdGg6ZGFTG/i7fQZwO7fggmjHyXeA+51y+MNJraJhigogcm/D9/wNOFpF30HBMNm9lQzgNuEdE3kbfwqviGzjnXkbDTG+LyCR0SMb2wJXAWOfcWFQUTheR7Qtk92fA62jK5jOdc3FvKdszOhaYLDoK2XZoOuwo3YAxwfcPAlcE64cCp4mIzyB8eLB+ODAwqMj+GDizDtdiFAnLrmoYRUBE2rlgnF8RuRxNDX1eiW16EK1kzttXw2jeWOzOMIrDISJyBfofm4G2cjKMRoF5DIZhGEYGVsdgGIZhZGDCYBiGYWRgwmAYhmFkYMJgGIZhZGDCYBiGYWRgwmAYhmFk8P8BhPJN54q4QfwAAAAASUVORK5CYII=", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": { | |
"needs_background": "light" | |
}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"fig = plt.figure()\n", | |
"plt.plot(train_counter, train_losses, color='blue')\n", | |
"plt.scatter(test_counter, test_losses, color='red')\n", | |
"plt.legend(['Train Loss', 'Test Loss'], loc='upper right')\n", | |
"plt.xlabel('number of training examples seen')\n", | |
"plt.ylabel('negative log likelihood loss')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"with torch.no_grad():\n", | |
" output = model(example_data.to(\"cuda\"))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"fig = plt.figure()\n", | |
"for i in range(6):\n", | |
" plt.subplot(2,3,i+1)\n", | |
" plt.tight_layout()\n", | |
" plt.imshow(example_data[i][0], cmap='gray', interpolation='none')\n", | |
" plt.title(\"Prediction: {}\".format(\n", | |
" output.data.max(1, keepdim=True)[1][i].item()))\n", | |
" plt.xticks([])\n", | |
" plt.yticks([])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"test_data_x = torch.randn(1,1,28,28)\n", | |
"max_abs = MaxAbsPool2D(2, True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"print(test_data_x.shape)\n", | |
"print(max_abs(test_data_x).shape)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"fig = plt.figure()\n", | |
"for i in range(2):\n", | |
" plt.subplot(1,2,i+1)\n", | |
" plt.tight_layout()\n", | |
" if i % 2 == 0: data = example_data[i+2][0]\n", | |
" # else: data = max_abs(example_data)[i-1].permute(1,2,0)\n", | |
" else: data = F.max_pool2d(example_data, 2)[i+1].permute(1,2,0)\n", | |
" plt.imshow(data, cmap='gray', interpolation='none')\n", | |
" plt.xticks([])\n", | |
" plt.yticks([])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"fig = plt.figure()\n", | |
"for i in range(2):\n", | |
" plt.subplot(1,2,i+1)\n", | |
" plt.tight_layout()\n", | |
" if i % 2 == 0: data = example_data[i+2][0]\n", | |
" else: data = max_abs(example_data)[i+1].permute(1,2,0)\n", | |
"# else: data = F.max_pool2d(example_data, 2)[i-1].permute(1,2,0)\n", | |
" plt.imshow(data, cmap='gray', interpolation='none')\n", | |
" plt.xticks([])\n", | |
" plt.yticks([])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"interpreter": { | |
"hash": "0d6e8431264d1160935736f310d9f0e1db684933f77421304180850f988bc540" | |
}, | |
"kernelspec": { | |
"display_name": "Python 3.6.15 ('deepgen')", | |
"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.15" | |
}, | |
"orig_nbformat": 4 | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment