{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"![](https://storage.googleapis.com/kaggle-competitions/kaggle/36073/logos/header.png?t=2022-04-12-20-53-30)","metadata":{"execution":{"iopub.status.busy":"2022-04-21T18:39:54.474251Z","iopub.execute_input":"2022-04-21T18:39:54.474986Z","iopub.status.idle":"2022-04-21T18:39:55.157888Z","shell.execute_reply.started":"2022-04-21T18:39:54.474943Z","shell.execute_reply":"2022-04-21T18:39:55.157081Z"}}},{"cell_type":"markdown","source":"# The task is to denoise “shabby” pages, reversing the effects imposed on them by Augraphy","metadata":{}},{"cell_type":"markdown","source":"### Importing some basic libraries required to play with the images","metadata":{}},{"cell_type":"code","source":"from glob import glob\nimport numpy as np\nfrom matplotlib import pylab as plt\nimport cv2\nimport tensorflow as tf\nprint(tf.__version__)\nimport tensorflow.keras.layers as layers\nfrom tensorflow.keras.models import Model\nimport time\nimport os\nimport os\nimport cv2\nimport glob\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-01T18:22:33.202374Z","iopub.execute_input":"2022-07-01T18:22:33.202685Z","iopub.status.idle":"2022-07-01T18:22:39.119324Z","shell.execute_reply.started":"2022-07-01T18:22:33.202605Z","shell.execute_reply":"2022-07-01T18:22:39.118579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Project Root directory:\nBASE_DIR = \"/kaggle/input/denoising-shabby-pages\"","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:39.120969Z","iopub.execute_input":"2022-07-01T18:22:39.121200Z","iopub.status.idle":"2022-07-01T18:22:39.124423Z","shell.execute_reply.started":"2022-07-01T18:22:39.121168Z","shell.execute_reply":"2022-07-01T18:22:39.123818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"glob.glob(BASE_DIR+'/*')","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:40.812497Z","iopub.execute_input":"2022-07-01T18:22:40.813099Z","iopub.status.idle":"2022-07-01T18:22:40.824236Z","shell.execute_reply.started":"2022-07-01T18:22:40.813060Z","shell.execute_reply":"2022-07-01T18:22:40.823536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cleaned_img_paths = sorted(glob.glob(BASE_DIR+\"/train_cleaned/train_cleaned/*.png\"))\ntrain_shabby_paths = sorted(glob.glob(BASE_DIR+\"/train/train/*.png\"))","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:41.531186Z","iopub.execute_input":"2022-07-01T18:22:41.531676Z","iopub.status.idle":"2022-07-01T18:22:41.657774Z","shell.execute_reply.started":"2022-07-01T18:22:41.531641Z","shell.execute_reply":"2022-07-01T18:22:41.657132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(cleaned_img_paths),len(train_shabby_paths)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:41.988316Z","iopub.execute_input":"2022-07-01T18:22:41.988748Z","iopub.status.idle":"2022-07-01T18:22:41.993268Z","shell.execute_reply.started":"2022-07-01T18:22:41.988719Z","shell.execute_reply":"2022-07-01T18:22:41.992598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Display some of the shabby images given for training","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(20, 5))\nprint(\"Input samples:\")\nfor i,pth in enumerate(train_shabby_paths[0:20]):\n    im = cv2.imread(pth)\n    plt.subplot(2, 10, i+1)\n    plt.imshow(im, cmap='gray')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:43.382611Z","iopub.execute_input":"2022-07-01T18:22:43.383162Z","iopub.status.idle":"2022-07-01T18:22:45.283947Z","shell.execute_reply.started":"2022-07-01T18:22:43.383121Z","shell.execute_reply":"2022-07-01T18:22:45.283308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20, 5))\nprint(\"Target samples:\")\nfor i,pth in enumerate(cleaned_img_paths[0:20]):\n    im = cv2.imread(pth)\n    plt.subplot(2, 10, i+1)\n    plt.imshow(im, cmap='gray')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:45.285560Z","iopub.execute_input":"2022-07-01T18:22:45.286016Z","iopub.status.idle":"2022-07-01T18:22:47.801134Z","shell.execute_reply.started":"2022-07-01T18:22:45.285973Z","shell.execute_reply":"2022-07-01T18:22:47.799414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport matplotlib.pyplot as plt\nfrom PIL import Image, ImageFilter\nimport numpy as np\nfrom PIL import ImageFont, ImageDraw, ImageOps\nfrom random import randint\nimport matplotlib.font_manager as fm\nimport pandas as pd\nfrom IPython import display\n#from utils import Logger\n\nimport torch\nfrom torch import nn, optim\nfrom torch.autograd.variable import Variable\nfrom torchvision import transforms, datasets\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.nn as nn\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:47.802670Z","iopub.execute_input":"2022-07-01T18:22:47.803398Z","iopub.status.idle":"2022-07-01T18:22:49.413903Z","shell.execute_reply.started":"2022-07-01T18:22:47.803361Z","shell.execute_reply":"2022-07-01T18:22:49.413157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"clean_image_path = BASE_DIR+'/train_cleaned/train_cleaned/'\nblur_image_path = BASE_DIR+'/train/train/'\n\nclean_image = np.asarray(cv2.imread(clean_image_path + '0001-USPS-dmm300_608.pdf-01.png',0))\nblur_image = np.asarray(cv2.imread(blur_image_path + '0001-USPS-dmm300_608.pdf-01.png',0))\n\n_, ax = plt.subplots(1,2, figsize=(20,10))\nax[0].imshow(clean_image, cmap='gray')\nax[0].title.set_text('Clean Image')\n\nax[1].imshow(blur_image, cmap='gray')\nax[1].title.set_text('Blur Image')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:49.415113Z","iopub.execute_input":"2022-07-01T18:22:49.415364Z","iopub.status.idle":"2022-07-01T18:22:49.929730Z","shell.execute_reply.started":"2022-07-01T18:22:49.415330Z","shell.execute_reply":"2022-07-01T18:22:49.929146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(clean_image.shape, blur_image.shape)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:49.931169Z","iopub.execute_input":"2022-07-01T18:22:49.931876Z","iopub.status.idle":"2022-07-01T18:22:49.936791Z","shell.execute_reply.started":"2022-07-01T18:22:49.931838Z","shell.execute_reply":"2022-07-01T18:22:49.936197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Function to get patches in each page\ndef getPatches(blur_image,clean_image,mystride):\n    blure_patches=[]\n    clean_patches=[]\n    #Defining the dimension of each patch\n    h =  ((blur_image.shape [0] // 256) +1)*256 \n    w =  ((blur_image.shape [1] // 256 ) +1)*256\n    image_padding=np.ones((h,w))\n    #Slicing method to zoom/crop in certain part of the page\n    image_padding[:blur_image.shape[0],:blur_image.shape[1]]=blur_image\n    #\n    for j in range (0,h-256,mystride):  #128 not 64\n        for k in range (0,w-256,mystride):\n            blure_patches.append(image_padding[j:j+256,k:k+256])\n    \n    h =  ((clean_image.shape [0] // 256) +1)*256 \n    w =  ((clean_image.shape [1] // 256 ) +1)*256\n\n    image_padding=np.ones((h,w))\n    image_padding[:clean_image.shape[0],:clean_image.shape[1]]=clean_image\n\n    for j in range (0,h-256,mystride):    #128 not 64\n        for k in range (0,w-256,mystride):\n            clean_patches.append(image_padding[j:j+256,k:k+256])  \n            \n    return np.array(blure_patches),np.array(clean_patches)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:49.938114Z","iopub.execute_input":"2022-07-01T18:22:49.938631Z","iopub.status.idle":"2022-07-01T18:22:49.952087Z","shell.execute_reply.started":"2022-07-01T18:22:49.938596Z","shell.execute_reply":"2022-07-01T18:22:49.951208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n%%time\n_blur_patches , _cleanimage_patches = getPatches(blur_image, clean_image, mystride=128+64)\nprint(_blur_patches.shape, _cleanimage_patches.shape)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:50.920126Z","iopub.execute_input":"2022-07-01T18:22:50.920656Z","iopub.status.idle":"2022-07-01T18:22:50.931127Z","shell.execute_reply.started":"2022-07-01T18:22:50.920617Z","shell.execute_reply":"2022-07-01T18:22:50.930036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_files = os.listdir(BASE_DIR+\"/train/train/\")\nlen(all_files)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:51.389719Z","iopub.execute_input":"2022-07-01T18:22:51.390207Z","iopub.status.idle":"2022-07-01T18:22:51.396573Z","shell.execute_reply.started":"2022-07-01T18:22:51.390169Z","shell.execute_reply":"2022-07-01T18:22:51.395942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_patches():\n  blur_patches = []\n  clean_patches = []\n\n  for file in all_files:\n    clean_image = np.asarray(cv2.imread(clean_image_path + file,0))\n    blur_image = np.asarray(cv2.imread(blur_image_path + file,0))\n\n    _blur_patches , _clean_patches = getPatches(blur_image, clean_image, mystride=128+64)\n    blur_patches.append(_blur_patches)    \n    clean_patches.append(_clean_patches)\n\n  blur_patches = np.concatenate(blur_patches, axis=0)\n  clean_patches = np.concatenate(clean_patches, axis=0)\n\n  return blur_patches, clean_patches","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:51.704715Z","iopub.execute_input":"2022-07-01T18:22:51.705312Z","iopub.status.idle":"2022-07-01T18:22:51.711205Z","shell.execute_reply.started":"2022-07-01T18:22:51.705279Z","shell.execute_reply":"2022-07-01T18:22:51.710428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"blur_patches, clean_patches = create_patches()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:22:51.992177Z","iopub.execute_input":"2022-07-01T18:22:51.993005Z","iopub.status.idle":"2022-07-01T18:23:08.271471Z","shell.execute_reply.started":"2022-07-01T18:22:51.992968Z","shell.execute_reply":"2022-07-01T18:23:08.270644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(blur_patches.shape, clean_patches.shape)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:08.272966Z","iopub.execute_input":"2022-07-01T18:23:08.273354Z","iopub.status.idle":"2022-07-01T18:23:08.279896Z","shell.execute_reply.started":"2022-07-01T18:23:08.273318Z","shell.execute_reply":"2022-07-01T18:23:08.278541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class blur(Dataset):\n\n  def __init__(self, blur_patches, clean_patches, transform=None):\n    self.clean_patches = clean_patches\n    self.blur_patches = blur_patches\n    self.transform = transform\n\n  def __len__(self):\n    return len(self.clean_patches)\n\n  def __getitem__(self, idx):\n    clean_image = self.clean_patches[idx]\n    blur_image = self.blur_patches[idx]\n\n    clean_image = np.asarray(clean_image)\n    blur_image = np.asarray(blur_image)\n\n    clean_image = Image.fromarray(clean_image.astype(np.uint8))\n    blur_image = Image.fromarray(blur_image.astype(np.uint8))\n\n    if self.transform:\n       clean_image = self.transform(clean_image)\n       blur_image = self.transform(blur_image)\n\n    return blur_image, clean_image\n\ndataset = blur(blur_patches, clean_patches, transform=transforms.Compose(\n            [transforms.ToTensor(), \n             transforms.Normalize([0.5], [0.5])]))\n\nbs = 4\ndata_loader = DataLoader(dataset, batch_size=bs, shuffle=True)\nnum_batches = len(data_loader)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:08.281696Z","iopub.execute_input":"2022-07-01T18:23:08.282137Z","iopub.status.idle":"2022-07-01T18:23:08.299062Z","shell.execute_reply.started":"2022-07-01T18:23:08.282075Z","shell.execute_reply":"2022-07-01T18:23:08.297997Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x,y = next(iter(data_loader))\n_, ax = plt.subplots(1,2)\nax[0].imshow(x[0].squeeze(), cmap='gray')\nax[1].imshow(y[0].squeeze(), cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:08.304122Z","iopub.execute_input":"2022-07-01T18:23:08.306470Z","iopub.status.idle":"2022-07-01T18:23:08.665283Z","shell.execute_reply.started":"2022-07-01T18:23:08.306433Z","shell.execute_reply":"2022-07-01T18:23:08.664627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(x.shape, y.shape)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:09.681193Z","iopub.execute_input":"2022-07-01T18:23:09.682033Z","iopub.status.idle":"2022-07-01T18:23:09.690713Z","shell.execute_reply.started":"2022-07-01T18:23:09.681950Z","shell.execute_reply":"2022-07-01T18:23:09.689278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DoubleConv(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(DoubleConv, self).__init__()\n        self.conv = nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, 3, 1, 1, bias=False),\n            nn.BatchNorm2d(out_channels),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(out_channels, out_channels, 3, 1, 1, bias=False),\n            nn.BatchNorm2d(out_channels),\n            nn.ReLU(inplace=True),\n        )\n\n    def forward(self, x):\n        return self.conv(x)\n\nclass GeneratorNet(nn.Module):\n    def __init__(\n            self, in_channels=3, out_channels=1, features=[64, 128, 256, 512],\n    ):\n        super(GeneratorNet, self).__init__()\n        self.ups = nn.ModuleList()\n        self.downs = nn.ModuleList()\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)\n\n        # Down part of UNET :  Refer to pdf file in architecture of generator to understand more about U-net\n        for feature in features:\n            self.downs.append(DoubleConv(in_channels, feature))\n            in_channels = feature\n\n        # Up part of UNET: Refer to pdf file in architecture of generator to understand more about U-net\n        for feature in reversed(features):\n            self.ups.append(\n                nn.ConvTranspose2d(\n                    feature*2, feature, kernel_size=2, stride=2,\n                )\n            )\n            self.ups.append(DoubleConv(feature*2, feature))\n\n        self.bottleneck = DoubleConv(features[-1], features[-1]*2)\n        self.final_conv = nn.Conv2d(features[0], out_channels, kernel_size=1)\n\n    def forward(self, x):\n        skip_connections = []\n\n        for down in self.downs:\n            x = down(x)\n            skip_connections.append(x)\n            x = self.pool(x)\n\n        x = self.bottleneck(x)\n        skip_connections = skip_connections[::-1]\n\n        for idx in range(0, len(self.ups), 2):\n            x = self.ups[idx](x)\n            skip_connection = skip_connections[idx//2]\n\n            if x.shape != skip_connection.shape:\n                x = TF.resize(x, size=skip_connection.shape[2:])\n\n            concat_skip = torch.cat((skip_connection, x), dim=1)\n            x = self.ups[idx+1](concat_skip)\n\n        return self.final_conv(x)\n    \ndef images_to_vectors(images):\n    return images.view(images.size(0), 784)\n\ndef vectors_to_images(vectors):\n    return vectors.view(vectors.size(0), 1, 256, 256)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:10.412729Z","iopub.execute_input":"2022-07-01T18:23:10.413159Z","iopub.status.idle":"2022-07-01T18:23:10.430810Z","shell.execute_reply.started":"2022-07-01T18:23:10.413124Z","shell.execute_reply":"2022-07-01T18:23:10.430039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DiscriminatorNet(nn.Module):\n    def __init__(self, in_channels):\n        super().__init__()\n        self.disc = nn.Sequential(            \n            nn.Conv2d(in_channels, 64, 3, 1, 1), # layer 1 64x256x256\n            nn.LeakyReLU(0.01, inplace=True),                     \n            nn.MaxPool2d(2),                     # layer 2 64x128x128\n            nn.Conv2d(64, 128, 3, 1, 1),         # layer 3 128x128x128\n            nn.LeakyReLU(0.01, inplace=True), \n            nn.MaxPool2d(2),                     # layer 4 128x64x64\n            nn.Conv2d(128, 256, 3, 1, 1),        # layer 5 256x64x64\n            nn.LeakyReLU(0.01, inplace=True),    # batch norm next\n            nn.BatchNorm2d(256),\n            nn.MaxPool2d(2),                     # layer 6 256x32x32\n            nn.Conv2d(256, 256, 3, 1, 1),        # layer 7 256x32x32\n            nn.LeakyReLU(0.01, inplace=True),    # batch norm next\n            nn.BatchNorm2d(256),\n            nn.MaxPool2d(2),                     # layer 8 256x16x16\n            nn.Conv2d(256, 256, 3, 1, 1),        # layer 9 256x16x16\n            nn.LeakyReLU(0.01, inplace=True),    # batch norm next\n            nn.BatchNorm2d(256),\n            nn.Conv2d(256, 1, 3, 1, 1),          # layer 10 1x16x16\n        )\n\n    def forward(self, x,y):\n        input = torch.cat([x,y], axis=1)\n        return self.disc(input)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:11.102668Z","iopub.execute_input":"2022-07-01T18:23:11.103394Z","iopub.status.idle":"2022-07-01T18:23:11.115228Z","shell.execute_reply.started":"2022-07-01T18:23:11.103357Z","shell.execute_reply":"2022-07-01T18:23:11.114529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def noise(size):\n    n = Variable(torch.randn(size, 100))\n    if torch.cuda.is_available(): return n.cuda() \n    return n","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:11.809585Z","iopub.execute_input":"2022-07-01T18:23:11.809888Z","iopub.status.idle":"2022-07-01T18:23:11.816737Z","shell.execute_reply.started":"2022-07-01T18:23:11.809853Z","shell.execute_reply":"2022-07-01T18:23:11.814681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndiscriminator = DiscriminatorNet(in_channels=2)\ngenerator = GeneratorNet(in_channels=1, out_channels=1)\n\ndiscriminator.cuda()\ngenerator.cuda()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:12.282588Z","iopub.execute_input":"2022-07-01T18:23:12.282887Z","iopub.status.idle":"2022-07-01T18:23:17.623339Z","shell.execute_reply.started":"2022-07-01T18:23:12.282856Z","shell.execute_reply":"2022-07-01T18:23:17.622642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# Optimizers\nd_optimizer = optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))\ng_optimizer = optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))\n#e of image. Let us take an image of size 399×399 and imagine we only have 3×3 convolutions at our disposal. How many convolution layers will it take to reach RF of 399 ? Approxi\n# Loss function\nloss1 = nn.MSELoss()\nloss2 = nn.BCELoss()\nloss3 = nn.BCEWithLogitsLoss()\n\n# Number of steps to apply to the discriminator\nd_steps = 1  \n# Number of epochs\nnum_epochs = 150\n","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:17.625942Z","iopub.execute_input":"2022-07-01T18:23:17.626168Z","iopub.status.idle":"2022-07-01T18:23:17.634345Z","shell.execute_reply.started":"2022-07-01T18:23:17.626136Z","shell.execute_reply":"2022-07-01T18:23:17.633629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test_noise():\n  x,y = next(iter(data_loader))\n  return Variable(x).float().cuda()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:17.635638Z","iopub.execute_input":"2022-07-01T18:23:17.635901Z","iopub.status.idle":"2022-07-01T18:23:17.645946Z","shell.execute_reply.started":"2022-07-01T18:23:17.635868Z","shell.execute_reply":"2022-07-01T18:23:17.645115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#logger = Logger(model_name='DE-GAN', data_name='blur')\nnum_test_samples = bs\nfrom tqdm import tqdm\n\nfor epoch in tqdm(range(num_epochs)):\n    for n_batch, (blur_batch, clean_batch) in enumerate(data_loader):\n\n        real_data = clean_batch.float().cuda()\n        noised_data = blur_batch.float().cuda()\n        \n        # 1. Train Discriminator\n        # Generate fake data\n        fake_data = generator(noised_data)\n\n        # Reset gradients\n        d_optimizer.zero_grad()\n        \n        # 1.1 Train on Real Data\n        prediction_real = discriminator(real_data, noised_data)\n\n        # Calculate error and backpropagate\n        real_data_target = torch.ones_like(prediction_real)\n        loss_real = loss1(prediction_real, real_data_target)\n\n        # 1.2 Train on Fake Data, you would need to add one more component\n        prediction_fake = discriminator(fake_data, noised_data)\n\n        # Calculate error and backpropagate\n        fake_data_target = torch.zeros_like(prediction_real)\n        loss_fake = loss1(prediction_fake, fake_data_target)\n\n        loss_d = (loss_real + loss_fake)/2\n        loss_d.backward(retain_graph=True)\n        \n        # 1.3 Update weights with gradients\n        d_optimizer.step()\n  \n        # 2. Train Generator\n        g_optimizer.zero_grad()\n\n        # Sample noise and generate fake data\n        prediction = discriminator(fake_data, real_data)\n        \n        # Calculate error and backpropagate\n        real_data_target = torch.ones_like(prediction)\n        #import pdb; pdb.set_trace();\n\n        loss_g1 = loss1(prediction, real_data_target)\n        loss_g2 = loss1(fake_data, real_data)*500\n        loss_g = loss_g1 + loss_g2\n\n        loss_g.backward()\n\n        # Update weights with gradients\n        g_optimizer.step()\n                \n            \n    print(loss_d, loss_g, epoch, n_batch, num_batches)\n        # Log error\n        #logger.log(loss_d, loss_g, epoch, n_batch, num_batches)\n#         print(loss_d, loss_g, epoch, n_batch, num_batches)\n\n        # Display Progress\n#         if (n_batch) % 100 == 0:\n#             display.clear_output(True)\n#             # Display Images\n#             test_images = vectors_to_images(generator(test_noise())).data.cpu()\n            #logger.log_images(test_images, num_test_samples, epoch, n_batch, num_batches);\n            # Display status Logs\n#             logger.display_status(\n#                 epoch, num_epochs, n_batch, num_batches,\n#                 loss_d, loss_g, prediction_real, prediction_fake\n#             )\n#         # Model Checkpoints\n#         logger.save_models(generator, discriminator, epoch)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:23:33.847654Z","iopub.execute_input":"2022-07-01T18:23:33.848042Z","iopub.status.idle":"2022-07-01T18:33:27.731735Z","shell.execute_reply.started":"2022-07-01T18:23:33.848007Z","shell.execute_reply":"2022-07-01T18:33:27.730574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path ='./'\ntorch.save(generator.state_dict(), path + 'generator-deblur-final.pt')\ntorch.save(discriminator.state_dict(), path + 'discriminator-deblur-final.pt')\n\nmodel = GeneratorNet(in_channels=1, out_channels=1)\nmodel.load_state_dict(torch.load(path + 'generator-deblur-final.pt'))\nmodel.cuda()\nmodel.eval()\n\ndef calculate_psnr(img1, img2, max_value=255):\n    \"\"\"\"Calculating peak signal-to-noise ratio (PSNR) between two images.\"\"\"\n    mse = np.mean((np.array(img1, dtype=np.float32) - np.array(img2, dtype=np.float32)) ** 2)\n    if mse == 0:\n        return 100\n    return 20 * np.log10(max_value / (np.sqrt(mse)))","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:33:33.640169Z","iopub.execute_input":"2022-07-01T18:33:33.640836Z","iopub.status.idle":"2022-07-01T18:33:34.339678Z","shell.execute_reply.started":"2022-07-01T18:33:33.640786Z","shell.execute_reply":"2022-07-01T18:33:34.338922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"blur_image, clean_image = next(iter(data_loader))\noutput = model(blur_image.cuda().float())\n\npsnr = calculate_psnr(blur_image[0].detach().cpu(), output[0].detach().cpu())\nprint()\nprint('PSNR between Clean Image and Deblur Image: ', psnr)\nprint()\n_, ax = plt.subplots(1,3, figsize=(22,10))\nax[0].imshow(blur_image[0].squeeze(), cmap='gray')\nax[0].title.set_text('Blur Image')\n\nax[1].imshow(output[0].detach().cpu().squeeze(), cmap='gray')\nax[1].title.set_text('Predicted Image')\nax[2].imshow(clean_image[0].detach().cpu().squeeze(), cmap='gray')\nax[2].title.set_text('Clean Image')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:35:06.417363Z","iopub.execute_input":"2022-07-01T18:35:06.418062Z","iopub.status.idle":"2022-07-01T18:35:06.974411Z","shell.execute_reply.started":"2022-07-01T18:35:06.418027Z","shell.execute_reply":"2022-07-01T18:35:06.973807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Once the solution is ready, make the submission with the following steps:","metadata":{}},{"cell_type":"code","source":"TEST_DIR = BASE_DIR+\"/test/test/\"\nOUTPUT_DIR = \"/kaggle/working/results\"\n\ntry:\n    os.mkdir(OUTPUT_DIR)\nexcept Exception:\n    pass","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:36:22.269149Z","iopub.execute_input":"2022-07-01T18:36:22.269418Z","iopub.status.idle":"2022-07-01T18:36:22.275596Z","shell.execute_reply.started":"2022-07-01T18:36:22.269388Z","shell.execute_reply":"2022-07-01T18:36:22.274542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final_img_paths = sorted(glob.glob(TEST_DIR+\"*.png\"))","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:36:23.817442Z","iopub.execute_input":"2022-07-01T18:36:23.817698Z","iopub.status.idle":"2022-07-01T18:36:23.977646Z","shell.execute_reply.started":"2022-07-01T18:36:23.817668Z","shell.execute_reply":"2022-07-01T18:36:23.976992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(final_img_paths)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:36:24.231965Z","iopub.execute_input":"2022-07-01T18:36:24.232169Z","iopub.status.idle":"2022-07-01T18:36:24.237191Z","shell.execute_reply.started":"2022-07-01T18:36:24.232146Z","shell.execute_reply":"2022-07-01T18:36:24.236480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.path.exists(TEST_DIR+pth.strip())","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:36:26.752234Z","iopub.execute_input":"2022-07-01T18:36:26.752794Z","iopub.status.idle":"2022-07-01T18:36:26.759127Z","shell.execute_reply.started":"2022-07-01T18:36:26.752732Z","shell.execute_reply":"2022-07-01T18:36:26.758422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"blur_image.shape","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:42:07.155426Z","iopub.execute_input":"2022-07-01T18:42:07.155674Z","iopub.status.idle":"2022-07-01T18:42:07.161076Z","shell.execute_reply.started":"2022-07-01T18:42:07.155645Z","shell.execute_reply":"2022-07-01T18:42:07.160396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### We have to predict/recreate 300 cleaned images from the given test set to make submissions","metadata":{}},{"cell_type":"code","source":"import torchvision.transforms as transforms\ntransform = transforms.ToTensor()\n\nfor i,full_pth in enumerate(final_img_paths):\n    \n    name = i+1\n    input_image = cv2.resize(cv2.imread(full_pth,0),(256,256))\n    tensor = transform(input_image)\n    tensor = tensor.unsqueeze(0)\n    res = model(tensor.cuda().float())[0][0].detach().cpu().numpy()\n    \n    res = (res*255)\n    res = cv2.resize(res, (400,400))\n    cv2.imwrite(f'{OUTPUT_DIR}/{i}.png',res)","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:49:26.610863Z","iopub.execute_input":"2022-07-01T18:49:26.611140Z","iopub.status.idle":"2022-07-01T18:49:32.840389Z","shell.execute_reply.started":"2022-07-01T18:49:26.611114Z","shell.execute_reply":"2022-07-01T18:49:32.839435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20, 5))\nfor i,pth in enumerate(final_img_paths[0:20]):\n    im = cv2.imread(pth,0)\n    plt.subplot(2, 10, i+1)\n    plt.imshow(im, cmap='gray')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:49:32.843108Z","iopub.execute_input":"2022-07-01T18:49:32.843718Z","iopub.status.idle":"2022-07-01T18:49:34.732180Z","shell.execute_reply.started":"2022-07-01T18:49:32.843648Z","shell.execute_reply":"2022-07-01T18:49:34.730589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visualize the test set:","metadata":{}},{"cell_type":"code","source":"results_img_paths = glob.glob(f'{OUTPUT_DIR}/*.png')\nplt.figure(figsize=(20, 5))\nprint(\"Results\")\nfor i,pth in enumerate(results_img_paths[0:20]):\n    im = cv2.imread(pth,0)\n    print(im.shape)\n    plt.subplot(2, 10, i+1)\n    plt.imshow(im, cmap='gray')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:49:37.075969Z","iopub.execute_input":"2022-07-01T18:49:37.076223Z","iopub.status.idle":"2022-07-01T18:49:39.141203Z","shell.execute_reply.started":"2022-07-01T18:49:37.076195Z","shell.execute_reply":"2022-07-01T18:49:39.140590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visualize some of the results:","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Make a submission:","metadata":{}},{"cell_type":"markdown","source":"To create submission.csv file, run the following code block...","metadata":{}},{"cell_type":"code","source":"# Make_submission.py:\nimport random\nimport os\nimport cv2\n\n################################################################################\n# CHANGE THIS\n################################################################################\ncleaned_images_dir = OUTPUT_DIR\n\n################################################################################\n# DON'T CHANGE ANYTHING BELOW HERE\n################################################################################\ndef select_pixels(img):\n    y,x = img.shape\n\n    pixels = list()\n\n    for i in range(10000):\n        pixel = (random.randrange(y), random.randrange(x))\n\n        if pixel not in pixels:\n            pixels.append(pixel)\n\n    return pixels\n\nrandom.seed(0)\ncleaned_images = sorted(os.listdir(cleaned_images_dir))\n\nwith open(\"submission.csv\", \"w\") as submission_file:\n    submission_file.write(\"id,predicted\\n\")\n\n    filenum = 1\n    for image in cleaned_images:\n\n        img = cv2.imread(\"{}/{}\".format(cleaned_images_dir, image), cv2.IMREAD_GRAYSCALE)\n        pixels = select_pixels(img)\n\n        for pixel in pixels:\n            y,x = pixel\n            submission_file.write(\"{}_{}_{},{}\\n\".format(filenum, y, x, img[y][x]/255.0))\n\n        filenum += 1","metadata":{"execution":{"iopub.status.busy":"2022-07-01T18:49:44.898626Z","iopub.execute_input":"2022-07-01T18:49:44.899412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# The world belongs to those who READ! Let's make shabby pages readable, those are not to be thrown in the trash! :D\n# Thanks!","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> ","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}