{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Noise2Self for Neural Nets\n",
"\n",
"This is a simple notebook demonstrating the principle of using self-supervision to train denoising networks.\n",
"\n",
"For didactic purposes, we use a simple dataset (Gaussian noise on MNIST), a simple model (a small UNet), and a short training (100 iterations on a CPU). This notebook runs on a MacBook Pro in under one minute."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%gui qt"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"sys.path.append(\"..\")"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"from util import show, plot_images, plot_tensors"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We demonstrate the use of a self-supervised denoising objective on a synthetically noised version of MNIST."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"from torchvision.datasets import MNIST\n",
"from torchvision import transforms\n",
"from torch.utils.data import Dataset\n",
"\n",
"mnist_train = MNIST('../data/MNIST', download = True,\n",
" transform = transforms.Compose([\n",
" transforms.ToTensor(),\n",
" ]), train = True)\n",
"\n",
"mnist_test = MNIST('../data/MNIST', download = True,\n",
" transform = transforms.Compose([\n",
" transforms.ToTensor(),\n",
" ]), train = False)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"from torch import randn\n",
"def add_noise(img):\n",
" return img + randn(img.size())*0.4\n",
"\n",
"class SyntheticNoiseDataset(Dataset):\n",
" def __init__(self, data, mode='train'):\n",
" self.mode = mode\n",
" self.data = data\n",
" \n",
" def __len__(self):\n",
" return len(self.data)\n",
" \n",
" def __getitem__(self, index):\n",
" img = self.data[index][0]\n",
" return add_noise(img), img"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"noisy_mnist_train = SyntheticNoiseDataset(mnist_train, 'train')\n",
"noisy_mnist_test = SyntheticNoiseDataset(mnist_test, 'test')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will try to learn to predict the clean image on the right from the noisy image on the left."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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uX8866yzUrnu7u70zOy2ef78+emZjz76aCp3++23p2eyefaAAgAAUIUCCgAAQBUKKAAAAFUooAAAAFShgAIAAFCFAgoAAEAVCigAAABVKKAAAABUoYACAABQhQIKAABAFQooAAAAVSigAAAAVKGAAgAAUIUCCgAAQBVd22KhPT09cc899ww6d8IJJ6RnXnHFFancmDFj0jOvvfbaVK63tzc9c9asWanc+vXr0zNXrFiRyn33u99Nzzz++ONTufHjx6dnPvLII6ncokWL0jPvv//+VK6npyc9s5SSyp166qnpmY8//ngqt3r16vTM+fPnp3LTpk1Lz7zhhhtSuf333z8987777kvlli1blp65cuXKVO6UU05J5a688sr03xA8nWUeK/VZtWpVKjdy5Mj0zB3F3LlzU7ns46WIiEMPPTSVG8rju89+9rPpLAyFPaAAAABUoYACAABQhQIKAABAFQooAAAAVSigAAAAVKGAAgAAUIUCCgAAQBUKKAAAAFUooAAAAFShgAIAAFCFAgoAAEAVCigAAABVKKAAAABU0bUtFrrzzjvHi1/84kHnent70zPf9KY3pXJXXXVVeuasWbNSub333js983Of+1wq95rXvCY9c9q0aancT37yk/TMn//856ncS1/60vTMBQsWpHJz5sxJz+zp6Unl7r///vTME088MZX7/ve/n565bNmyVO5f//Vf0zPHjRuXymV/JxERp5xySir3vve9Lz1z2LBhqdxRRx2Vnrl06dJU7h/+4R9SuYcffjiVg6e7J554Ip390Ic+lMqddtpp6Zk33XRTKpf9vz8U2W16RMT06dNTue7u7vTMo48+OpX7+Mc/np4J24s9oAAAAFShgAIAAFCFAgoAAEAVCigAAABVKKAAAABUoYACAABQhQIKAABAFQooAAAAVSigAAAAVKGAAgAAUIUCCgAAQBUKKAAAAFUooAAAAFShgAIAAFBF17ZYaCklhg8fPujc3Llz0zN33333VO6QQw5Jz9ywYUMq9+ijj6Znjh8/vvrMO+64I5W7+eab0zOnTJmSyk2dOjU9c/LkyancwoUL0zMXLFiQyr3pTW9Kz1y0aFEqd/XVV6dn7rRT7rmu17zmNemZ73jHO1K5V7/61emZ119/fSo3Y8aM9MylS5emctddd116Zk9PTyo3e/bsVG7evHmxatWqVBaerc4///xU7tvf/nZ65rJly1K5F7/4xemZJ554Yir3b//2b+mZ3d3d6WzWL37xi1RuKNss2F7sAQUAAKAKBRQAAIAqFFAAAACqUEABAACoQgEFAACgCgUUAACAKhRQAAAAqlBAAQAAqEIBBQAAoAoFFAAAgCoUUAAAAKpQQAEAAKhCAQUAAKCKrm2x0BUrVsQ111wz6Fwm0+e+++5L5Y477rj0zOuuuy6Ve/nLX56e2d3dncpdeOGF6ZmjR49O5ZYsWZKeuf/++6dyjz32WHrmqlWrUrmDDjooPfPGG29M5davX5+e2dvbW33mPffck8rtuccT5CQAABP6SURBVOee6Zl/93d/l8qtW7cuPXPt2rWp3OrVq9Mzf/KTn6Ry55xzTnrmz372s1Ru0aJFqdxOO3muFLaWpUuXVp+5ePHi6jPPPPPMdPaLX/xiKrdhw4b0TNiR2KoDAABQhQIKAABAFQooAAAAVSigAAAAVKGAAgAAUIUCCgAAQBUKKAAAAFUooAAAAFShgAIAAFCFAgoAAEAVCigAAABVKKAAAABUoYACAABQhQIKAABAFV3bYqGllOjqGvyijznmmPTM17/+9ancmDFj0jOvuuqqVO7AAw9Mz5w7d24qt99++6Vn3n///anci170ovTMxx9/PJX7zne+k5756le/OpUbPXp0eubIkSNTuVJKeubdd9+dyv3t3/5teub555+fyt15553pmUcffXQql719IiK++tWvpnIf+9jH0jO/8pWvpHLZ+5KIiJ6enlSuu7s7lduwYUMqBzw9vPOd70xnjzrqqFTu4IMPTs887bTTUrmLL744PRN2JPaAAgAAUIUCCgAAQBUKKAAAAFUooAAAAFShgAIAAFCFAgoAAEAVCigAAABVKKAAAABUoYACAABQhQIKAABAFQooAAAAVSigAAAAVKGAAgAAUEVpmmbrLrCUOWPGjDnysMMOG3T2la98ZXrutddem8qdeOKJ6ZkjRoxI5c4///z0zKOOOiqV++pXv5qe+eY3vzmVe+KJJ9Izp0+fnsodffTR6ZnDhw9P5X7961+nZ77mNa9J5W688cb0zN133z2Vu+qqq9IzV61alcqNHTs2PfPWW29N5ZYsWZKe+eEPfziVy95/ReRvow0bNqRn9vb2pnJTpkxJ5T7/+c/HQw89dGvTNLk7QKKUMicijtze6wGDNW3atFTutttuS8/s6elJ5ebMmZOeed1116Vy//iP/5ieubU7ADuk1LbZHlAAAACqUEABAACoQgEFAACgCgUUAACAKhRQAAAAqlBAAQAAqEIBBQAAoAoFFAAAgCoUUAAAAKpQQAEAAKhCAQUAAKAKBRQAAIAqFFAAAACqUEABAACoomtbLLRpmli7du2gczvvvHN6Zk9PTyr34IMPpmdedNFFqdwHP/jB9MyJEyemcgsWLEjPHD58eCq3//77p2cuXLgwlfvCF76QnnnyySencv/1X/+Vnpm9jbq68v91995771RuxowZ6ZmLFi1K5R566KH0zNe97nWp3FDuE37wgx+kcscee2x65s0335zK3XXXXemZhx12WCq3ZMmSVG7dunWpHPDMd88996Ry7373u9Mzs48lZs+enZ6ZzY4dOzY983Of+1wqN3/+/PRMiLAHFAAAgEoUUAAAAKpQQAEAAKhCAQUAAKAKBRQAAIAqFFAAAACqUEABAACoQgEFAACgCgUUAACAKhRQAAAAqlBAAQAAqEIBBQAAoAoFFAAAgCq6tsVCJ0yYEKeffvqgc0uXLk3PPP7441O54447Lj3ziiuuSOX23Xff9MzrrrsulZs6dWp65v3335/KDeW27e7uTuUOO+yw9MwlS5akcrvuumt65k475Z4D2n///dMzV65cmcrNnj07PbOrK3dX85nPfCY9c/78+alc9v91RMSMGTNSudtvvz09c+LEiancfvvtl565atWqVG7KlCmp3IgRI1I5YMd13nnnpbN33nln9ZmHHHJIKveBD3wgPfPAAw9M5d773vemZ/72t79NZ3n2sAcUAACAKhRQAAAAqlBAAQAAqEIBBQAAoAoFFAAAgCoUUAAAAKpQQAEAAKhCAQUAAKAKBRQAAIAqFFAAAACqUEABAACoQgEFAACgCgUUAACAKhRQAAAAqujaFgtdsWJF/PjHPx50bsaMGemZe+yxRyq3bNmy9Mz3vOc9qdyaNWvSM2+//fZU7vjjj0/PHDFiRCo3d+7c9Mzs38IDDzyQnnnUUUelcnfddVd65s9+9rNUbih/Q7Nnz07l1q1bl565dOnSVG7y5Mnpmd/85jdTuZkzZ6ZnHnLIIancokWL0jOz/z/32muv9MwpU6akctdff30qt3r16lQOIOPmm29O5WbNmpWe+da3vjWV+/SnP52eecopp6Ryz3ve89IzDz300HSWZw97QAEAAKhCAQUAAKAKBRQAAIAqFFAAAACqUEABAACoQgEFAACgCgUUAACAKhRQAAAAqlBAAQAAqEIBBQAAoAoFFAAAgCoUUAAAAKpQQAEAAKiia1ssdLfddovTTz990LmDDjooPfPaa69N5X7961+nZz700EOp3LHHHpue+ZznPCeVGzVqVHpmKSWVy65rRMSCBQtSuYkTJ6ZnXn755ancK17xivTMM844I5V797vfnZ7Z09OTyq1evTo9s7e3N5U77LDD0jN//vOfp3L33ntveuasWbNSuYULF6Znjh8/PpW75JJL0jNf9apXpXI//elPU7nu7u5UDqCmxYsXp7Of/exnU7lPfepT6ZnZx3cHH3xweuZrX/vaVO7b3/52eiZPP/aAAgAAUIUCCgAAQBUKKAAAAFUooAAAAFShgAIAAFCFAgoAAEAVCigAAABVKKAAAABUoYACAABQhQIKAABAFQooAAAAVSigAAAAVKGAAgAAUIUCCgAAQBVd22Kha9asifvuu2/QuR/+8IfpmRMnTkzlmqZJz5w9e3Yqd88996Rn/vEf/3Eqt3Tp0vTMUkoqd/XVV6dn7rHHHqncEUcckZ65bt26VO473/lOeuZHP/rRVO4lL3lJeuY111yTyk2dOjU989BDD03lbrvttvTMV7/61ancsmXL0jMvv/zyVG7fffdNz9xzzz1TuaOOOio985xzzknl3v72t6dy5513Xjz66KOpLMBgzZgxI5XL3scNZeZOO9XflzSU++OhPGbi2cMeUAAAAKpQQAEAAKhCAQUAAKAKBRQAAIAqFFAAAACqUEABAACoQgEFAACgCgUUAACAKhRQAAAAqlBAAQAAqEIBBQAAoAoFFAAAgCoUUAAAAKro2hYL7e3tjQULFgw699rXvjY985FHHknlnnjiifTMSy65JJXbZ5990jMffPDBVG7lypXpmRMmTEjlurryf14nnnhiKnfdddelZ/7sZz9L5U4++eT0zJkzZ6Zyt956a3rm+9///lTujjvuSM9csWJFKtfT05Oemf2/cs0116RnvvKVr0zlsn97ERHr169P5Xp7e9MzzzjjjFQue983YsSIVA545ps+fXoqd9ZZZ6Vn/sEf/EEqN3bs2PTM7WHDhg2p3FAeO2dn8uxiDygAAABVKKAAAABUoYACAABQhQIKAABAFQoo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\n",
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"