{"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-06-19T06:29:09.777316Z","iopub.execute_input":"2022-06-19T06:29:09.777664Z","iopub.status.idle":"2022-06-19T06:29:14.814534Z","shell.execute_reply.started":"2022-06-19T06:29:09.777575Z","shell.execute_reply":"2022-06-19T06:29:14.813843Z"},"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-06-19T06:29:14.816354Z","iopub.execute_input":"2022-06-19T06:29:14.816645Z","iopub.status.idle":"2022-06-19T06:29:14.821543Z","shell.execute_reply.started":"2022-06-19T06:29:14.816609Z","shell.execute_reply":"2022-06-19T06:29:14.820267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"glob.glob(BASE_DIR+'/*')","metadata":{"execution":{"iopub.status.busy":"2022-06-19T06:29:14.82316Z","iopub.execute_input":"2022-06-19T06:29:14.823508Z","iopub.status.idle":"2022-06-19T06:29:14.836413Z","shell.execute_reply.started":"2022-06-19T06:29:14.823473Z","shell.execute_reply":"2022-06-19T06:29:14.835516Z"},"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-06-19T06:29:14.837954Z","iopub.execute_input":"2022-06-19T06:29:14.838248Z","iopub.status.idle":"2022-06-19T06:29:15.283237Z","shell.execute_reply.started":"2022-06-19T06:29:14.838215Z","shell.execute_reply":"2022-06-19T06:29:15.282438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(cleaned_img_paths),len(train_shabby_paths)","metadata":{"execution":{"iopub.status.busy":"2022-06-19T06:29:15.284347Z","iopub.execute_input":"2022-06-19T06:29:15.284763Z","iopub.status.idle":"2022-06-19T06:29:15.291829Z","shell.execute_reply.started":"2022-06-19T06:29:15.284726Z","shell.execute_reply":"2022-06-19T06:29:15.290825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!git clone https://github.com/dali92002/DocEnTR","metadata":{"execution":{"iopub.status.busy":"2022-06-19T06:29:42.648375Z","iopub.execute_input":"2022-06-19T06:29:42.648653Z","iopub.status.idle":"2022-06-19T06:29:46.863187Z","shell.execute_reply.started":"2022-06-19T06:29:42.648623Z","shell.execute_reply":"2022-06-19T06:29:46.862249Z"},"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-05-23T15:13:06.651297Z","iopub.execute_input":"2022-05-23T15:13:06.651491Z","iopub.status.idle":"2022-05-23T15:13:08.718463Z","shell.execute_reply.started":"2022-05-23T15:13:06.651467Z","shell.execute_reply":"2022-05-23T15:13:08.717715Z"},"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-05-23T15:13:08.72004Z","iopub.execute_input":"2022-05-23T15:13:08.720701Z","iopub.status.idle":"2022-05-23T15:13:10.426269Z","shell.execute_reply.started":"2022-05-23T15:13:08.720664Z","shell.execute_reply":"2022-05-23T15:13:10.424578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\n\nimport os\nimport pathlib\nimport time\nimport datetime\n\nfrom matplotlib import pyplot as plt\nfrom IPython import display","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:10.427562Z","iopub.execute_input":"2022-05-23T15:13:10.428262Z","iopub.status.idle":"2022-05-23T15:13:10.432757Z","shell.execute_reply.started":"2022-05-23T15:13:10.428219Z","shell.execute_reply":"2022-05-23T15:13:10.432059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_image = tf.io.read_file(str(train_shabby_paths[2]))\nsample_image = tf.io.decode_jpeg(sample_image)\nprint(sample_image.shape)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:10.435103Z","iopub.execute_input":"2022-05-23T15:13:10.435815Z","iopub.status.idle":"2022-05-23T15:13:10.452208Z","shell.execute_reply.started":"2022-05-23T15:13:10.435778Z","shell.execute_reply":"2022-05-23T15:13:10.451366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure()\nplt.imshow(sample_image)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:10.455042Z","iopub.execute_input":"2022-05-23T15:13:10.456619Z","iopub.status.idle":"2022-05-23T15:13:10.686324Z","shell.execute_reply.started":"2022-05-23T15:13:10.45659Z","shell.execute_reply":"2022-05-23T15:13:10.685682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We have 700 shabby pages and corresponding cleaned images with the size of 400x400","metadata":{}},{"cell_type":"markdown","source":"Various approaches are available to denoise shabby images.\n\nFeel free to experiment and find best suitable algo/model","metadata":{}},{"cell_type":"code","source":"def load(input_image, real_image):\n    # Read and decode an image file to a uint8 tensor\n    input_image = tf.io.read_file(input_image)\n    #input_image = tf.io.decode_jpeg(input_image)\n    input_image = tf.io.decode_image(input_image, expand_animations = False, dtype=tf.float32, channels=3)*255.0\n\n    real_image = tf.io.read_file(real_image)\n    #real_image = tf.io.decode_jpeg(real_image)\n    real_image = tf.io.decode_image(real_image, expand_animations = False, dtype=tf.float32, channels=1)*255.0\n\n#     real_image = tf.io.decode_image(real_image, expand_animations = False, dtype=tf.float32, channels=3)*255.0\n\n    # Convert both images to float32 tensors\n    input_image = tf.cast(input_image, tf.float32)\n    real_image = tf.cast(real_image, tf.float32)\n    print(input_image.shape, real_image.shape)\n\n    return input_image, real_image","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:10.68766Z","iopub.execute_input":"2022-05-23T15:13:10.688135Z","iopub.status.idle":"2022-05-23T15:13:10.694929Z","shell.execute_reply.started":"2022-05-23T15:13:10.688098Z","shell.execute_reply":"2022-05-23T15:13:10.69431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inp, re = load(train_shabby_paths[1],cleaned_img_paths[1])\n# Casting to int for matplotlib to display the images\n#inp\nplt.figure()\nplt.imshow(inp / 255.0)\nplt.figure()\nplt.imshow(re / 255.0)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:10.696129Z","iopub.execute_input":"2022-05-23T15:13:10.69685Z","iopub.status.idle":"2022-05-23T15:13:11.143207Z","shell.execute_reply.started":"2022-05-23T15:13:10.69681Z","shell.execute_reply":"2022-05-23T15:13:11.142552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The facade training set consist of 400 images\nBUFFER_SIZE = 400\n# The batch size of 1 produced better results for the U-Net in the original pix2pix experiment\nBATCH_SIZE = 1\n# Each image is 256x256 in size\nIMG_WIDTH = 256\nIMG_HEIGHT = 256\n\ndef resize(input_image, real_image, height, width):\n  input_image = tf.image.resize(input_image, [height, width],\n                                method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)\n  real_image = tf.image.resize(real_image, [height, width],\n                               method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)\n\n  return input_image, real_image","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.144783Z","iopub.execute_input":"2022-05-23T15:13:11.145267Z","iopub.status.idle":"2022-05-23T15:13:11.151895Z","shell.execute_reply.started":"2022-05-23T15:13:11.145226Z","shell.execute_reply":"2022-05-23T15:13:11.151173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"# def random_crop(input_image, real_image):\n#     stacked_image = tf.stack([input_image, real_image], axis=0)\n#     cropped_image = tf.image.random_crop(\n#       stacked_image, size=[2, IMG_HEIGHT, IMG_WIDTH, 3])\n\n#     return cropped_image[0], cropped_image[1]","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.154242Z","iopub.execute_input":"2022-05-23T15:13:11.155125Z","iopub.status.idle":"2022-05-23T15:13:11.162711Z","shell.execute_reply.started":"2022-05-23T15:13:11.155087Z","shell.execute_reply":"2022-05-23T15:13:11.161915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Normalizing the images to [-1, 1]\ndef normalize(input_image, real_image):\n    input_image = (input_image / 127.5) - 1\n    real_image = (real_image / 127.5) - 1\n\n    return input_image, real_image","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.166139Z","iopub.execute_input":"2022-05-23T15:13:11.16658Z","iopub.status.idle":"2022-05-23T15:13:11.172515Z","shell.execute_reply.started":"2022-05-23T15:13:11.16654Z","shell.execute_reply":"2022-05-23T15:13:11.171764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# @tf.function()\n# def random_jitter(input_image, real_image):\n#     # Resizing to 286x286\n#     input_image, real_image = resize(input_image, real_image, 256, 256)\n\n#     # Random cropping back to 256x256\n#     #input_image, real_image = random_crop(input_image, real_image)\n\n#     if tf.random.uniform(()) > 0.5:\n#         # Random mirroring\n#         input_image = tf.image.flip_left_right(input_image)\n#         real_image = tf.image.flip_left_right(real_image)\n\n#     return input_image, real_image","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.173697Z","iopub.execute_input":"2022-05-23T15:13:11.174019Z","iopub.status.idle":"2022-05-23T15:13:11.184337Z","shell.execute_reply.started":"2022-05-23T15:13:11.17398Z","shell.execute_reply":"2022-05-23T15:13:11.183639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plt.figure(figsize=(6, 6))\n# for i in range(4):\n#     rj_inp, rj_re = random_jitter(inp, re)\n#     plt.subplot(2, 2, i + 1)\n#     plt.imshow(rj_inp / 255.0)\n#     plt.axis('off')\n# plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.186143Z","iopub.execute_input":"2022-05-23T15:13:11.186627Z","iopub.status.idle":"2022-05-23T15:13:11.193917Z","shell.execute_reply.started":"2022-05-23T15:13:11.186588Z","shell.execute_reply":"2022-05-23T15:13:11.193159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_image_train(image_file):\n    input_image, real_image = load(image_file,tf.strings.regex_replace(image_file, \"train\", \"train_cleaned\"))\n    input_image, real_image = resize(input_image, real_image, 256, 256)\n    #input_image, real_image = random_jitter(input_image, real_image)\n    input_image, real_image = normalize(input_image, real_image)\n\n    return input_image, real_image","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.195277Z","iopub.execute_input":"2022-05-23T15:13:11.195731Z","iopub.status.idle":"2022-05-23T15:13:11.203Z","shell.execute_reply.started":"2022-05-23T15:13:11.195694Z","shell.execute_reply":"2022-05-23T15:13:11.202316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_image_test(image_file):\n    input_image, real_image = load(image_file)\n    input_image, real_image = resize(input_image, real_image,\n                                   IMG_HEIGHT, IMG_WIDTH)\n    input_image, real_image = normalize(input_image, real_image)\n\n    return input_image, real_image","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.204218Z","iopub.execute_input":"2022-05-23T15:13:11.204701Z","iopub.status.idle":"2022-05-23T15:13:11.212117Z","shell.execute_reply.started":"2022-05-23T15:13:11.204664Z","shell.execute_reply":"2022-05-23T15:13:11.211438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# merged_paths = []\n# for each in zip(cleaned_img_paths, train_shabby_paths):\n#     merged_paths.append([each[0],each[1]])\n# merged_paths[0:2]","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.214615Z","iopub.execute_input":"2022-05-23T15:13:11.214801Z","iopub.status.idle":"2022-05-23T15:13:11.22096Z","shell.execute_reply.started":"2022-05-23T15:13:11.214773Z","shell.execute_reply":"2022-05-23T15:13:11.220252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = tf.data.Dataset.list_files(train_shabby_paths)\ntrain_dataset = train_dataset.map(load_image_train,\n                                  num_parallel_calls=tf.data.AUTOTUNE)\ntrain_dataset = train_dataset.shuffle(BUFFER_SIZE)\ntrain_dataset = train_dataset.batch(BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.222352Z","iopub.execute_input":"2022-05-23T15:13:11.222841Z","iopub.status.idle":"2022-05-23T15:13:11.416236Z","shell.execute_reply.started":"2022-05-23T15:13:11.222805Z","shell.execute_reply":"2022-05-23T15:13:11.415506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"OUTPUT_CHANNELS = 1","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.417733Z","iopub.execute_input":"2022-05-23T15:13:11.418237Z","iopub.status.idle":"2022-05-23T15:13:11.422606Z","shell.execute_reply.started":"2022-05-23T15:13:11.4182Z","shell.execute_reply":"2022-05-23T15:13:11.421883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def downsample(filters, size, apply_batchnorm=True):\n  initializer = tf.random_normal_initializer(0., 0.02)\n\n  result = tf.keras.Sequential()\n  result.add(\n      tf.keras.layers.Conv2D(filters, size, strides=2, padding='same',\n                             kernel_initializer=initializer, use_bias=False))\n\n  if apply_batchnorm:\n    result.add(tf.keras.layers.BatchNormalization())\n\n  result.add(tf.keras.layers.LeakyReLU())\n\n  return result","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.423834Z","iopub.execute_input":"2022-05-23T15:13:11.424302Z","iopub.status.idle":"2022-05-23T15:13:11.433222Z","shell.execute_reply.started":"2022-05-23T15:13:11.424263Z","shell.execute_reply":"2022-05-23T15:13:11.432484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"down_model = downsample(3, 4)\ndown_result = down_model(tf.expand_dims(inp, 0))\nprint (down_result.shape)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.434781Z","iopub.execute_input":"2022-05-23T15:13:11.435057Z","iopub.status.idle":"2022-05-23T15:13:11.465648Z","shell.execute_reply.started":"2022-05-23T15:13:11.435022Z","shell.execute_reply":"2022-05-23T15:13:11.464953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def upsample(filters, size, apply_dropout=False):\n  initializer = tf.random_normal_initializer(0., 0.02)\n\n  result = tf.keras.Sequential()\n  result.add(\n    tf.keras.layers.Conv2DTranspose(filters, size, strides=2,\n                                    padding='same',\n                                    kernel_initializer=initializer,\n                                    use_bias=False))\n\n  result.add(tf.keras.layers.BatchNormalization())\n\n  if apply_dropout:\n      result.add(tf.keras.layers.Dropout(0.5))\n\n  result.add(tf.keras.layers.ReLU())\n\n  return result","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.466893Z","iopub.execute_input":"2022-05-23T15:13:11.467128Z","iopub.status.idle":"2022-05-23T15:13:11.473673Z","shell.execute_reply.started":"2022-05-23T15:13:11.467094Z","shell.execute_reply":"2022-05-23T15:13:11.47286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"up_model = upsample(3, 4)\nup_result = up_model(down_result)\nprint (up_result.shape)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.475372Z","iopub.execute_input":"2022-05-23T15:13:11.475698Z","iopub.status.idle":"2022-05-23T15:13:11.510021Z","shell.execute_reply.started":"2022-05-23T15:13:11.475663Z","shell.execute_reply":"2022-05-23T15:13:11.509303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def Generator():\n  inputs = tf.keras.layers.Input(shape=[256, 256, 3])\n\n  down_stack = [\n    downsample(64, 4, apply_batchnorm=False),  # (batch_size, 128, 128, 64)\n    downsample(128, 4),  # (batch_size, 64, 64, 128)\n    downsample(256, 4),  # (batch_size, 32, 32, 256)\n    downsample(512, 4),  # (batch_size, 16, 16, 512)\n    downsample(512, 4),  # (batch_size, 8, 8, 512)\n    downsample(512, 4),  # (batch_size, 4, 4, 512)\n    downsample(512, 4),  # (batch_size, 2, 2, 512)\n    downsample(512, 4),  # (batch_size, 1, 1, 512)\n  ]\n\n  up_stack = [\n    upsample(512, 4, apply_dropout=True),  # (batch_size, 2, 2, 1024)\n    upsample(512, 4, apply_dropout=True),  # (batch_size, 4, 4, 1024)\n    upsample(512, 4, apply_dropout=True),  # (batch_size, 8, 8, 1024)\n    upsample(512, 4),  # (batch_size, 16, 16, 1024)\n    upsample(256, 4),  # (batch_size, 32, 32, 512)\n    upsample(128, 4),  # (batch_size, 64, 64, 256)\n    upsample(64, 4),  # (batch_size, 128, 128, 128)\n  ]\n\n  initializer = tf.random_normal_initializer(0., 0.02)\n  last = tf.keras.layers.Conv2DTranspose(OUTPUT_CHANNELS, 4,\n                                         strides=2,\n                                         padding='same',\n                                         kernel_initializer=initializer,\n                                         activation='tanh')  # (batch_size, 256, 256, 3)\n\n  x = inputs\n\n  # Downsampling through the model\n  skips = []\n  for down in down_stack:\n    x = down(x)\n    skips.append(x)\n\n  skips = reversed(skips[:-1])\n\n  # Upsampling and establishing the skip connections\n  for up, skip in zip(up_stack, skips):\n    x = up(x)\n    x = tf.keras.layers.Concatenate()([x, skip])\n\n  x = last(x)\n\n  return tf.keras.Model(inputs=inputs, outputs=x)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.511269Z","iopub.execute_input":"2022-05-23T15:13:11.511498Z","iopub.status.idle":"2022-05-23T15:13:11.524034Z","shell.execute_reply.started":"2022-05-23T15:13:11.511467Z","shell.execute_reply":"2022-05-23T15:13:11.523317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generator = Generator()\n# tf.keras.utils.plot_model(generator, show_shapes=True, dpi=64)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.525259Z","iopub.execute_input":"2022-05-23T15:13:11.525925Z","iopub.status.idle":"2022-05-23T15:13:11.983238Z","shell.execute_reply.started":"2022-05-23T15:13:11.525888Z","shell.execute_reply":"2022-05-23T15:13:11.982488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# gen_output = generator(inp[tf.newaxis, ...], training=False)\n# plt.imshow(gen_output[0, ...])","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.984493Z","iopub.execute_input":"2022-05-23T15:13:11.984812Z","iopub.status.idle":"2022-05-23T15:13:11.989585Z","shell.execute_reply.started":"2022-05-23T15:13:11.984775Z","shell.execute_reply":"2022-05-23T15:13:11.988669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LAMBDA = 100\nloss_object = tf.keras.losses.BinaryCrossentropy(from_logits=True)\n\ndef generator_loss(disc_generated_output, gen_output, target):\n  gan_loss = loss_object(tf.ones_like(disc_generated_output), disc_generated_output)\n\n  # Mean absolute error\n  l1_loss = tf.reduce_mean(tf.abs(target - gen_output))\n\n  total_gen_loss = gan_loss + (LAMBDA * l1_loss)\n\n  return total_gen_loss, gan_loss, l1_loss","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:11.991287Z","iopub.execute_input":"2022-05-23T15:13:11.991543Z","iopub.status.idle":"2022-05-23T15:13:11.999065Z","shell.execute_reply.started":"2022-05-23T15:13:11.991505Z","shell.execute_reply":"2022-05-23T15:13:11.998133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def Discriminator():\n  initializer = tf.random_normal_initializer(0., 0.02)\n\n  inp = tf.keras.layers.Input(shape=[256, 256, 3], name='input_image')\n  tar = tf.keras.layers.Input(shape=[256, 256, 1], name='target_image')\n\n  x = tf.keras.layers.concatenate([inp, tar])  # (batch_size, 256, 256, channels*2)\n\n  down1 = downsample(64, 4, False)(x)  # (batch_size, 128, 128, 64)\n  down2 = downsample(128, 4)(down1)  # (batch_size, 64, 64, 128)\n  down3 = downsample(256, 4)(down2)  # (batch_size, 32, 32, 256)\n\n  zero_pad1 = tf.keras.layers.ZeroPadding2D()(down3)  # (batch_size, 34, 34, 256)\n  conv = tf.keras.layers.Conv2D(512, 4, strides=1,\n                                kernel_initializer=initializer,\n                                use_bias=False)(zero_pad1)  # (batch_size, 31, 31, 512)\n\n  batchnorm1 = tf.keras.layers.BatchNormalization()(conv)\n#   batchnorm1 = conv\n  leaky_relu = tf.keras.layers.LeakyReLU()(batchnorm1)\n\n  zero_pad2 = tf.keras.layers.ZeroPadding2D()(leaky_relu)  # (batch_size, 33, 33, 512)\n\n  last = tf.keras.layers.Conv2D(1, 4, strides=1,\n                                kernel_initializer=initializer)(zero_pad2)  # (batch_size, 30, 30, 1)\n\n  return tf.keras.Model(inputs=[inp, tar], outputs=last)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:12.000545Z","iopub.execute_input":"2022-05-23T15:13:12.001062Z","iopub.status.idle":"2022-05-23T15:13:12.012127Z","shell.execute_reply.started":"2022-05-23T15:13:12.001025Z","shell.execute_reply":"2022-05-23T15:13:12.011356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"discriminator = Discriminator()\n# tf.keras.utils.plot_model(discriminator, show_shapes=True, dpi=64)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:12.013314Z","iopub.execute_input":"2022-05-23T15:13:12.014222Z","iopub.status.idle":"2022-05-23T15:13:12.116612Z","shell.execute_reply.started":"2022-05-23T15:13:12.014184Z","shell.execute_reply":"2022-05-23T15:13:12.115915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def discriminator_loss(disc_real_output, disc_generated_output):\n  real_loss = loss_object(tf.ones_like(disc_real_output), disc_real_output)\n\n  generated_loss = loss_object(tf.zeros_like(disc_generated_output), disc_generated_output)\n\n  total_disc_loss = real_loss + generated_loss\n\n  return total_disc_loss","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:12.121201Z","iopub.execute_input":"2022-05-23T15:13:12.121773Z","iopub.status.idle":"2022-05-23T15:13:12.126598Z","shell.execute_reply.started":"2022-05-23T15:13:12.121746Z","shell.execute_reply":"2022-05-23T15:13:12.125898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)\ndiscriminator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:12.128214Z","iopub.execute_input":"2022-05-23T15:13:12.128685Z","iopub.status.idle":"2022-05-23T15:13:12.139041Z","shell.execute_reply.started":"2022-05-23T15:13:12.128648Z","shell.execute_reply":"2022-05-23T15:13:12.138288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint_dir = './training_checkpoints'\ncheckpoint_prefix = os.path.join(checkpoint_dir, \"ckpt\")\ncheckpoint = tf.train.Checkpoint(generator_optimizer=generator_optimizer,\n                                 discriminator_optimizer=discriminator_optimizer,\n                                 generator=generator,\n                                 discriminator=discriminator)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:12.140637Z","iopub.execute_input":"2022-05-23T15:13:12.141109Z","iopub.status.idle":"2022-05-23T15:13:12.151593Z","shell.execute_reply.started":"2022-05-23T15:13:12.141073Z","shell.execute_reply":"2022-05-23T15:13:12.150922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_images(model, test_input, tar):\n  prediction = model(test_input, training=True)\n  plt.figure(figsize=(15, 15))\n\n  display_list = [test_input[0], tar[0], prediction[0]]\n  title = ['Input Image', 'Ground Truth', 'Predicted Image']\n\n  for i in range(3):\n    print(display_list[i].shape)\n    plt.subplot(1, 3, i+1)\n    plt.title(title[i])\n    # Getting the pixel values in the [0, 1] range to plot.\n    plt.imshow(display_list[i] * 0.5 + 0.5)\n    plt.axis('off')\n  plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:12.153151Z","iopub.execute_input":"2022-05-23T15:13:12.153611Z","iopub.status.idle":"2022-05-23T15:13:12.161251Z","shell.execute_reply.started":"2022-05-23T15:13:12.153572Z","shell.execute_reply":"2022-05-23T15:13:12.160536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for example_input, example_target in train_dataset.take(1):\n  generate_images(generator, example_input, example_target)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:12.162345Z","iopub.execute_input":"2022-05-23T15:13:12.162705Z","iopub.status.idle":"2022-05-23T15:13:17.281694Z","shell.execute_reply.started":"2022-05-23T15:13:12.162669Z","shell.execute_reply":"2022-05-23T15:13:17.280919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(example_input[0])","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:17.283288Z","iopub.execute_input":"2022-05-23T15:13:17.28356Z","iopub.status.idle":"2022-05-23T15:13:17.503112Z","shell.execute_reply.started":"2022-05-23T15:13:17.28352Z","shell.execute_reply":"2022-05-23T15:13:17.502454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"log_dir=\"logs/\"\n\nsummary_writer = tf.summary.create_file_writer(\n  log_dir + \"fit/\" + datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\"))","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:17.504265Z","iopub.execute_input":"2022-05-23T15:13:17.504575Z","iopub.status.idle":"2022-05-23T15:13:17.511372Z","shell.execute_reply.started":"2022-05-23T15:13:17.504536Z","shell.execute_reply":"2022-05-23T15:13:17.510563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@tf.function\ndef train_step(input_image, target, step):\n  with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:\n    gen_output = generator(input_image, training=True)\n\n    disc_real_output = discriminator([input_image, target], training=True)\n    disc_generated_output = discriminator([input_image, gen_output], training=True)\n\n    gen_total_loss, gen_gan_loss, gen_l1_loss = generator_loss(disc_generated_output, gen_output, target)\n    disc_loss = discriminator_loss(disc_real_output, disc_generated_output)\n\n  generator_gradients = gen_tape.gradient(gen_total_loss,\n                                          generator.trainable_variables)\n  discriminator_gradients = disc_tape.gradient(disc_loss,\n                                               discriminator.trainable_variables)\n\n  generator_optimizer.apply_gradients(zip(generator_gradients,\n                                          generator.trainable_variables))\n  discriminator_optimizer.apply_gradients(zip(discriminator_gradients,\n                                              discriminator.trainable_variables))\n\n  with summary_writer.as_default():\n    tf.summary.scalar('gen_total_loss', gen_total_loss, step=step//1000)\n    tf.summary.scalar('gen_gan_loss', gen_gan_loss, step=step//1000)\n    tf.summary.scalar('gen_l1_loss', gen_l1_loss, step=step//1000)\n    tf.summary.scalar('disc_loss', disc_loss, step=step//1000)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:17.512683Z","iopub.execute_input":"2022-05-23T15:13:17.513286Z","iopub.status.idle":"2022-05-23T15:13:17.558878Z","shell.execute_reply.started":"2022-05-23T15:13:17.513248Z","shell.execute_reply":"2022-05-23T15:13:17.558181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def fit(train_ds, test_ds, steps):\n  example_input, example_target = next(iter(test_ds.take(1)))\n  start = time.time()\n\n  for step, (input_image, target) in train_ds.repeat().take(steps).enumerate():\n    if (step) % 1000 == 0:\n      display.clear_output(wait=True)\n\n      if step != 0:\n        print(f'Time taken for 1000 steps: {time.time()-start:.2f} sec\\n')\n\n      start = time.time()\n\n      generate_images(generator, example_input, example_target)\n      print(f\"Step: {step//1000}k\")\n\n    train_step(input_image, target, step)\n\n    # Training step\n    if (step+1) % 10 == 0:\n      print('.', end='', flush=True)\n\n\n    # Save (checkpoint) the model every 5k steps\n    if (step + 1) % 5000 == 0:\n      checkpoint.save(file_prefix=checkpoint_prefix)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:17.564859Z","iopub.execute_input":"2022-05-23T15:13:17.565075Z","iopub.status.idle":"2022-05-23T15:13:17.571922Z","shell.execute_reply.started":"2022-05-23T15:13:17.565048Z","shell.execute_reply":"2022-05-23T15:13:17.571173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fit(train_dataset, train_dataset, steps=100000)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:13:17.573248Z","iopub.execute_input":"2022-05-23T15:13:17.573698Z","iopub.status.idle":"2022-05-23T15:15:31.816684Z","shell.execute_reply.started":"2022-05-23T15:13:17.573661Z","shell.execute_reply":"2022-05-23T15:15:31.815741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Result preparation:","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}},{"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-05-23T15:15:34.415612Z","iopub.execute_input":"2022-05-23T15:15:34.416211Z","iopub.status.idle":"2022-05-23T15:15:34.420085Z","shell.execute_reply.started":"2022-05-23T15:15:34.41617Z","shell.execute_reply":"2022-05-23T15:15:34.419388Z"},"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-05-23T15:15:35.137306Z","iopub.execute_input":"2022-05-23T15:15:35.137913Z","iopub.status.idle":"2022-05-23T15:15:35.145805Z","shell.execute_reply.started":"2022-05-23T15:15:35.137848Z","shell.execute_reply":"2022-05-23T15:15:35.144933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(final_img_paths)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:15:36.08014Z","iopub.execute_input":"2022-05-23T15:15:36.080705Z","iopub.status.idle":"2022-05-23T15:15:36.086071Z","shell.execute_reply.started":"2022-05-23T15:15:36.080666Z","shell.execute_reply":"2022-05-23T15:15:36.08524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.path.exists(TEST_DIR+pth.strip())","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:15:36.6578Z","iopub.execute_input":"2022-05-23T15:15:36.658334Z","iopub.status.idle":"2022-05-23T15:15:36.672186Z","shell.execute_reply.started":"2022-05-23T15:15:36.65829Z","shell.execute_reply":"2022-05-23T15:15:36.671385Z"},"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":"for i,full_pth in enumerate(final_img_paths):\n    name = i+1\n    pth = full_pth.split('/')[-1]\n    input_image, real_image = load(full_pth,full_pth)\n    input_image, real_image = resize(input_image/255.0, real_image, 256, 256)\n    input_image = tf.expand_dims(input_image, axis=0)\n    \n    res = generator(input_image, training=True)[0].cpu().numpy()\n    res = (res*255)\n    res = cv2.resize(res, (400,400))\n    \n    cv2.imwrite(f'{OUTPUT_DIR}/{i}.png',res)","metadata":{"execution":{"iopub.status.busy":"2022-05-23T15:17:11.097359Z","iopub.execute_input":"2022-05-23T15:17:11.09761Z","iopub.status.idle":"2022-05-23T15:17:24.317223Z","shell.execute_reply.started":"2022-05-23T15:17:11.09758Z","shell.execute_reply":"2022-05-23T15:17:24.31602Z"},"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-05-23T15:17:24.318832Z","iopub.execute_input":"2022-05-23T15:17:24.319094Z","iopub.status.idle":"2022-05-23T15:17:26.178303Z","shell.execute_reply.started":"2022-05-23T15:17:24.31906Z","shell.execute_reply":"2022-05-23T15:17:26.177683Z"},"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-05-23T15:19:38.536471Z","iopub.execute_input":"2022-05-23T15:19:38.536729Z","iopub.status.idle":"2022-05-23T15:19:40.2716Z","shell.execute_reply.started":"2022-05-23T15:19:38.536699Z","shell.execute_reply":"2022-05-23T15:19:40.271004Z"},"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-05-23T15:15:31.829762Z","iopub.status.idle":"2022-05-23T15:15:31.830331Z","shell.execute_reply.started":"2022-05-23T15:15:31.830086Z","shell.execute_reply":"2022-05-23T15:15:31.83011Z"},"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":[]}]}