Skip to content

Instantly share code, notes, and snippets.

@stsievert
Last active February 14, 2022 21:20
Show Gist options
  • Save stsievert/8d42ebb35499e37e0ab55d7156f12fdf to your computer and use it in GitHub Desktop.
Save stsievert/8d42ebb35499e37e0ab55d7156f12fdf to your computer and use it in GitHub Desktop.
PyTorch MNIST autoencoder
from keras.datasets import mnist
import numpy as np
import skimage.util
import random
import skimage.filters
import skimage
import scipy.signal
def noise_img(x):
noises = [
{"mode": "s&p", "amount": np.random.uniform(0.1, 0.1)},
{"mode": "gaussian", "var": np.random.uniform(0.0, 0.10)},
]
# noise = random.choice(noises)
noise = noises[1]
return skimage.util.random_noise(x, **noise)
def train_formatting(img):
img = img.reshape(28, 28).astype("float32")
return img.flat[:]
def blur_img(img):
assert img.ndim == 1
n = int(np.sqrt(img.shape[0]))
img = img.reshape(n, n)
h = np.zeros((n, n))
angle = np.random.uniform(-5, 5)
w = random.choice(range(1, 3))
h[n // 2, n // 2 - w : n // 2 + w] = 1
h = skimage.transform.rotate(h, angle)
h /= h.sum()
y = scipy.signal.convolve(img, h, mode="same")
return y.flat[:]
def dataset(n=None):
(x_train, _), (x_test, _) = mnist.load_data()
x = np.concatenate((x_train, x_test))
if n:
x = x[:n]
else:
n = int(70e3)
x = x.astype("float32") / 255.
x = np.reshape(x, (len(x), 28 * 28))
y = np.apply_along_axis(train_formatting, 1, x)
clean = y.copy()
noisy = y.copy()
# order = [noise_img, blur_img]
# order = [blur_img]
order = [noise_img]
random.shuffle(order)
for fn in order:
noisy = np.apply_along_axis(fn, 1, noisy)
noisy = noisy.reshape(-1, 1, 28, 28).astype("float32")
clean = clean.reshape(-1, 1, 28, 28).astype("float32")
return noisy, clean
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook aims to show a simple example with an autoencoder. The highlights of this notebook are that\n",
"\n",
"* we can customize problem difficulty (because we control the input)\n",
"* we can customize the model expressiveness to capture problem difficulty (well, it's a todo)\n",
"\n",
"I will spend some time manually tuning these to make it a realistic problem. After this is done, we have 400 parameter combinations, each with 2 contininous variables to tune. The variables we have to tune are\n",
"\n",
"* model\n",
" * initialization\n",
" * activation function\n",
" * weight decay (which is similar to $\\ell_2$ regularization)\n",
"* optimizer\n",
" * which optimizer to use (e.g., Adam, SGD)\n",
" * batch size used to approximate gradient\n",
" * learning rate (but not for Adam)\n",
" * momentum for SGD\n",
"\n",
"I believe this is an interesting problem. For example, switching activation from ReLU to PReLU caused the loss after 1st epoch to go from ~0.20 to 0.12."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'0.4.1'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import torch\n",
"torch.__version__"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n",
"/home/ssievert/miniconda3/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88\n",
" return f(*args, **kwds)\n"
]
}
],
"source": [
"import numpy as np\n",
"import noisy_mnist"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Input data\n",
"`autoencoder` is a package I wrote to noise MNIST images. It outputs a NumPy ndarray of noisy images."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"import noisy_mnist\n",
"noisy, clean = noisy_mnist.dataset()#n=1024)\n",
"assert isinstance(noisy, np.ndarray)\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"noisy_train, noisy_test, clean_train, clean_test = train_test_split(noisy, clean)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(52500, 1, 28, 28)"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"noisy_train.shape"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAvIAAACCCAYAAAAkJiykAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzsnXmczfX+x1/fmTELs2IY2zCYyJq1rl0UQiSkpnQVpa6thGSJNmm9aZfuLW6/SmnVDUVyUdZkT2UKkSU7w5jx/f3x9Xp/P+ec78x8z5iZM2d8no9HD9M533POd/msr/dmmKYJjUaj0Wg0Go1GE1yEBPoENBqNRqPRaDQajf/ohbxGo9FoNBqNRhOE6IW8RqPRaDQajUYThOiFvEaj0Wg0Go1GE4TohbxGo9FoNBqNRhOE6IW8RqPRaDQajUYThOiFvEaj0Wg0Go1GE4TohbxGo9FoNBqNRhOE6IW8RqPRaDQajUYThOiFvEaj0Wg0Go1GE4SEBfoEggnDMMxAn0N+MU3TyOuYkn59QMm/xpJ+fUDJv8Zgvj6g5F+jbqcWJf36gJJ/jcF8fUDJv0a37VQr8hqNRqPRaDQaTRCiF/IajUaj0Wg0Gk0QohfyGo1GoymxfPDBBzh//rzHfy1atAj0aWk0Gk2BoH3kA0B0dDT69u0LAHjqqacAAOXKlUNIiLWvOnDgAACgS5cu2LBhQ2BOMsAMHz4cAPDQQw/JvVqxYkUgT0mj0QQRzZs3BwB0794dplk83WQjIiIAAHPmzAEArFu3DtOnTw/kKWk0miBDK/IajUaj0Wg0Gk0QohX5IqB8+fIAgK5duwIA7rnnHrRs2dLjmPPnz8vfZcuWBQB8+OGHaN26NQBg//79RXGqAWfYsGEAgMceewyAZb0YMGAAAK3IawofulyUL18ed999NwBg9OjRAIBff/01YOdVEHAsady4MRYvXgwAGDJkCACgTp06WLduHQDIe//73/8CcJb5p1SpUgCAm2++GQDw4osvArBVbwDYtWsXAKBZs2ZYs2ZNEZ+hL506dQIA3HjjjQCAr776KpCno9G45rLLLgMAVKtWDe3atQMATJo0yec4w7ASr6hWsUceeQQA8PjjjwMAzp07V6jnWtLRirxGo9FoNBqNRhOEaEW+kKlRowbmzZsHALjiiisAeKrvuVG9enVERkYW2rkVN8qVK4exY8cCsJR48u677wbqlPJFSkoKevbsCQAYM2YMAODw4cNihTl79mzAzk2TOw8//DAAoFu3btJPd+zYAQDSNoOJpk2biurVpk0bAECZMmWkDdI3++TJk+jRowcAYPLkyQCAV155BePGjQMAnDp1qkjP21+ioqJwww03AAD+/e9/A/BUAhcsWAAAWLZsGQDgtddeC8BZ+uI9vp85cyZAZ6IpTvTp0wcffvghAOCjjz4CAIkVCyRDhw5F1apVAdjWJNW7wCkWxek1KvcnT54EADzzzDMFfq6XElqR12gKkJSUlECfgkaj0Wg0mksErcgXEjVq1AAAfPbZZ7j88stzPG7VqlVyfKVKlYri1IodU6ZMAQCMHDkSsbGxHu/17NmzWPiyuiEyMhL79u3De++9h169egGwMxA1atQIcXFxHq8VN6699loAwJdffonq1asDAPbs2ePXd1DNDQ0Nlewbp0+fLsCzLHpoXQkmRb5bt24AgLffflsyX9EyGB0dLUq76vcfGhoKABg8eDAAYOrUqUhNTQVgZdAqjpQpUwYAMGPGDPz97393POaDDz7AwIEDAQCZmZlFdWoajQ99+vSRmDkq7YcOHfI5bvz48aJk9+7du+hO0AvG1Tz99NMAgPr163tYyy8WxrMEmyLP9V2dOnUAWAIe46ucYgKcoKWX65slS5bk+3z0Qr6QiI+PBwBUqFDB8f1PP/0UAGTymTFjBm6//fYiObfiAhs+TXRxcXHS+H///XcAlik8WAJhuGHr1asXFi1aBAASqLtv3z60b98egLWwKI7ceeedAPIegJwoV64cACuQG7Da/aZNmwBATMTBymeffRboU3BNkyZNAEA2UY888oi4kWRlZeX62ezsbADA66+/DsBaYLz55psA7AVzcXOxoQiQ0yIeAKZNm1ZsF/D79u0DYE/+rVq1EnenS4GkpCQ88cQTAOxnaBgGtm/fDsDue4899hhOnDjh8dnSpUuLm8fBgwcBAEeOHCmK0/YbJm8YP368POtq1aoB8AwQbdasGQDLJY7HzZw5syhP1QMGvLudEzjmc/52onr16mjYsCEAiHBXr149bN269WJOtdCIiYkBYKfEvv/++8UlLioqyud4twt5wuOOHj0qwfhNmzb16xy1a41GU4CsX78+0Keg0Wg0Go3mEkEr8oUEzdlz5swR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\n",
"text/plain": [
"<Figure size 864x144 with 24 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import seaborn as sns\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"import numpy as np\n",
"\n",
"w = 1.0\n",
"ncols = 12\n",
"idx = np.random.choice(len(clean_test), size=ncols)\n",
"fig, axs = plt.subplots(nrows=2, ncols=ncols, figsize=(ncols*w, 2*w))\n",
"for col, (lower, upper, i) in enumerate(zip(axs[1], axs[0], idx)):\n",
" if col == 0:\n",
" upper.text(-40, 15, 'ground truth')\n",
" lower.text(-20, 15, 'input')\n",
" clean = clean_train[i].reshape(28, 28)\n",
" noisy = noisy_train[i].reshape(28, 28)\n",
" kwargs = {'cbar': False, 'xticklabels': False, 'yticklabels': False, 'cmap': 'gray'}\n",
" sns.heatmap(clean, ax=upper, **kwargs)\n",
" sns.heatmap(noisy, ax=lower, **kwargs)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This input has random amounts of noise – it ranges everywhere from perfectly clean images to moderately corrupted images."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Model creation"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"import torch.nn as nn\n",
"import torch.nn.functional as F"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"import skorch"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This convolutional model is adaptived from https://github.com/Kaixhin/Autoencoders/blob/master/models/ConvAE.lua, which is turn adapted from https://blog.keras.io/building-autoencoders-in-keras.html.\n",
"\n",
"I have allowed custimization of\n",
"\n",
"* the activation function\n",
"* the initialization scheme\n",
"* **TODO** width/depth to allow more complex models (which is suited for random noise)\n",
"\n",
"**Notes on other models**\n",
"* https://github.com/baldassarreFe/zalando-pytorch/blob/master/notebooks/4.0-fb-autoencoder.ipynb\n",
"* Maybe go with VGG deconv net at https://github.com/csgwon/pytorch-deconvnet/blob/master/models/vgg16_deconv.py (will require ImageNet)\n",
"* A simple DAE is at https://github.com/ReyhaneAskari/pytorch_experiments/blob/master/DAE.py"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"import torch.nn as nn\n",
"from toolz import partial\n",
" \n",
"def _initialize(method, layer, gain=1):\n",
" weight = layer.weight.data\n",
" _before = weight.data.clone()\n",
" kwargs = {'gain': gain} if 'xavier' in str(method) else {}\n",
" method(weight.data, **kwargs)\n",
" assert torch.all(weight.data != _before)\n",
" \n",
"class Autoencoder(nn.Module):\n",
" \"\"\" Autoencoder adapted from [1]\n",
" \n",
" [1]:https://github.com/Kaixhin/Autoencoders/blob/master/models/ConvAE.lua\n",
" \"\"\"\n",
" def __init__(self, activation='ReLU', init='xavier_uniform_', width_factor=1):\n",
" super().__init__()\n",
" device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
" \n",
" self.activation = activation\n",
" self.init = init\n",
" \n",
" init_method = getattr(torch.nn.init, init)\n",
" act_layer = getattr(nn, activation)\n",
" print(act_layer)\n",
" \n",
" gain = 1\n",
" if self.activation in ['LeakyReLU', 'ReLU']:\n",
" name = 'leaky_relu' if self.activation == 'LeakyReLU' else 'relu'\n",
" gain = torch.nn.init.calculate_gain(name)\n",
" if self.activation != 'PReLU':\n",
" act_layer = partial(act_layer, inplace=True)\n",
" \n",
" width = int(width_factor * 32)\n",
" layers = [nn.Conv2d(1, width, kernel_size=3, padding=1, stride=1),\n",
" act_layer(),\n",
" nn.MaxPool2d(2, stride=2, padding=1),\n",
" nn.Conv2d(width, width, kernel_size=3, padding=1, stride=1),\n",
" act_layer(),\n",
" nn.MaxPool2d(2, stride=2, padding=0)]\n",
" for layer in layers:\n",
" if hasattr(layer, 'weight') and layer.weight.data.dim() > 1:\n",
" _initialize(init_method, layer)\n",
" \n",
" self.encoder = nn.Sequential(*layers).to(device)\n",
" \n",
" modules = []\n",
" modules += [[nn.Conv2d(width, width, kernel_size=3, stride=1, padding=1),\n",
" act_layer()]]\n",
" modules += [[nn.Conv2d(width, width, kernel_size=3, stride=1, padding=1),\n",
" act_layer()]]\n",
" modules += [[nn.Conv2d(width, 1, kernel_size=3, stride=1, padding=1),\n",
" nn.Sigmoid()]]\n",
" self.decoders = []\n",
" for module in modules:\n",
" [_initialize(init_method, layer) for layer in module\n",
" if hasattr(layer, 'weight') and layer.weight.data.dim() > 1]\n",
" self.decoders += [nn.Sequential(*module).to(device)]\n",
" \n",
" def forward(self, x):\n",
" x = self.encoder(x)\n",
" \n",
" for i, decoder in enumerate(self.decoders):\n",
" x = decoder(x)\n",
" if i < len(self.decoders) - 1:\n",
" x = F.interpolate(x, scale_factor=2)\n",
" return x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Hyperparameters"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"from pprint import pprint\n",
"class Trim(skorch.NeuralNetRegressor):\n",
" \"\"\"\n",
" This wrapper trims the arguments in `params` to make \n",
" sure they're accepted by the optimizer\n",
" \"\"\"\n",
" def __init__(self, verbose=True, **kwargs):\n",
" if kwargs['optimizer'] != 'Adam':\n",
" kwargs.pop('optimizer__amsgrad', None)\n",
" if kwargs['optimizer'] == 'Adam':\n",
" kwargs.pop('optimizer__lr', None)\n",
" if kwargs['optimizer'] != 'SGD':\n",
" kwargs.pop('optimizer__nesterov')\n",
" kwargs.pop('optimizer__momentum')\n",
" kwargs['optimizer'] = getattr(torch.optim, kwargs['optimizer'])\n",
" pprint({k: v for k, v in kwargs.items() if k != 'module'})\n",
" super().__init__(**kwargs)\n",
"\n",
"params = {\n",
" 'module__init': ['xavier_uniform_',\n",
" 'xavier_normal_',\n",
" 'kaiming_uniform_',\n",
" 'kaiming_normal_',\n",
" ],\n",
" 'module__activation': ['ReLU', 'LeakyReLU', 'ELU', 'PReLU'],\n",
" 'optimizer': ['SGD',\n",
" 'ASGD',\n",
" 'Adam',\n",
" 'Adagrad',\n",
" 'RMSprop'], # optimizers in Adam's paper + ASGD\n",
" 'batch_size': [32, 64, 128, 256, 512],\n",
" 'optimizer__lr': np.logspace(2, -2, num=1000), # all optimizers but Adam\n",
" 'optimizer__weight_decay': [0] + np.logspace(-8, -3, num=1000).tolist(), # all optimizers\n",
" 'optimizer__nesterov': [True], # only for SGD\n",
" 'optimizer__momentum': np.logspace(-4, 0, num=1000), # only for SGD\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Fitting"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'torch.nn.modules.activation.ReLU'>\n",
"{'batch_size': 64,\n",
" 'criterion': <class 'torch.nn.modules.loss.BCELoss'>,\n",
" 'device': 'cuda',\n",
" 'max_epochs': 20,\n",
" 'module__activation': 'PReLU',\n",
" 'module__init': 'xavier_uniform_',\n",
" 'optimizer': <class 'torch.optim.adam.Adam'>,\n",
" 'optimizer__weight_decay': 1e-05,\n",
" 'warm_start': True}\n"
]
}
],
"source": [
"from torchvision.datasets import FashionMNIST\n",
"from torchvision import transforms\n",
"\n",
"device = 'cpu'\n",
"model = Autoencoder()\n",
"if torch.cuda.is_available():\n",
" device = 'cuda'\n",
" model = model.to('cuda')\n",
" \n",
"net = Trim(\n",
" module=model,\n",
" module__init='xavier_uniform_',\n",
" module__activation='PReLU',\n",
" max_epochs=20,\n",
" optimizer='Adam',\n",
" optimizer__lr=1.0,\n",
" optimizer__weight_decay=1e-5,\n",
" optimizer__nesterov=True,\n",
" optimizer__momentum=1e-2,\n",
" batch_size=64,\n",
" # train_split=None, # if only use training data; we will eventually\n",
" #criterion=torch.nn.MSELoss,\n",
" criterion=torch.nn.BCELoss,\n",
" device='cuda',\n",
" warm_start=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Re-initializing module!\n",
"<class 'torch.nn.modules.activation.PReLU'>\n",
" epoch train_loss valid_loss dur\n",
"------- ------------ ------------ ------\n",
" 1 \u001b[36m0.1290\u001b[0m \u001b[32m0.1144\u001b[0m 4.5228\n",
" 2 \u001b[36m0.1053\u001b[0m \u001b[32m0.1074\u001b[0m 4.5657\n",
" 3 \u001b[36m0.1034\u001b[0m \u001b[32m0.1032\u001b[0m 4.5263\n",
" 4 \u001b[36m0.1021\u001b[0m \u001b[32m0.1018\u001b[0m 4.4973\n",
" 5 \u001b[36m0.1014\u001b[0m \u001b[32m0.1009\u001b[0m 4.5685\n",
" 6 \u001b[36m0.1006\u001b[0m \u001b[32m0.1000\u001b[0m 4.5073\n",
" 7 \u001b[36m0.1002\u001b[0m 0.1037 4.5860\n",
" 8 \u001b[36m0.0998\u001b[0m 0.1045 4.5521\n",
" 9 \u001b[36m0.0994\u001b[0m \u001b[32m0.0999\u001b[0m 4.5896\n",
" 10 \u001b[36m0.0991\u001b[0m 0.1010 4.5799\n",
" 11 \u001b[36m0.0989\u001b[0m \u001b[32m0.0996\u001b[0m 4.5751\n",
" 12 \u001b[36m0.0986\u001b[0m 0.1014 4.5972\n",
" 13 \u001b[36m0.0984\u001b[0m \u001b[32m0.0990\u001b[0m 4.4776\n",
" 14 \u001b[36m0.0982\u001b[0m \u001b[32m0.0987\u001b[0m 4.6029\n",
" 15 \u001b[36m0.0981\u001b[0m \u001b[32m0.0983\u001b[0m 4.6004\n",
" 16 \u001b[36m0.0980\u001b[0m \u001b[32m0.0982\u001b[0m 4.5679\n",
" 17 \u001b[36m0.0979\u001b[0m \u001b[32m0.0982\u001b[0m 4.5686\n",
" 18 \u001b[36m0.0979\u001b[0m \u001b[32m0.0979\u001b[0m 4.5877\n",
" 19 \u001b[36m0.0978\u001b[0m \u001b[32m0.0976\u001b[0m 4.5966\n",
" 20 \u001b[36m0.0978\u001b[0m 0.0989 4.6106\n"
]
},
{
"data": {
"text/plain": [
"<class '__main__.Trim'>[initialized](\n",
" module_=Autoencoder(\n",
" (encoder): Sequential(\n",
" (0): Conv2d(1, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (1): PReLU(num_parameters=1)\n",
" (2): MaxPool2d(kernel_size=2, stride=2, padding=1, dilation=1, ceil_mode=False)\n",
" (3): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (4): PReLU(num_parameters=1)\n",
" (5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
" )\n",
" ),\n",
")"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"net.fit(noisy_train, clean_train)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Output"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"clean_test_hat = net.forward(noisy_test)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 864x216 with 36 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"w = 1.0\n",
"ncols = 12\n",
"# idx = np.random.choice(len(clean_test), size=ncols)\n",
"\n",
"fig, axs = plt.subplots(nrows=3, ncols=ncols, figsize=(ncols*w, 3*w))\n",
"for col, (lower, middle, upper, i) in enumerate(zip(axs[2], axs[1], axs[0], idx)):\n",
" if col == 0:\n",
" upper.text(-40, 15, 'ground truth')\n",
" middle.text(-20, 15, 'input')\n",
" lower.text(-25, 15, 'output')\n",
"\n",
" i = np.random.randint(len(clean_test))\n",
" clean = clean_test[i].reshape(28, 28)\n",
" predicted = clean_test_hat[i].reshape(28, 28)\n",
" noisy = noisy_test[i].reshape(28, 28)\n",
" kwargs = {'cbar': False, 'xticklabels': False, 'yticklabels': False, 'cmap': 'gray'}\n",
" sns.heatmap(clean, ax=upper, **kwargs)\n",
" sns.heatmap(noisy, ax=middle, **kwargs)\n",
" sns.heatmap(predicted, ax=lower, **kwargs)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"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.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment