{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":6927,"databundleVersionId":45059,"sourceType":"competition"}],"dockerImageVersionId":30369,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport random\n\nimport cv2\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport tensorflow as tf\nimport tqdm\nfrom keras import callbacks\nfrom PIL import Image\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator","metadata":{"execution":{"iopub.status.busy":"2026-02-03T06:31:18.575709Z","iopub.execute_input":"2026-02-03T06:31:18.576099Z","iopub.status.idle":"2026-02-03T06:31:18.581782Z","shell.execute_reply.started":"2026-02-03T06:31:18.576066Z","shell.execute_reply":"2026-02-03T06:31:18.580906Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%bash\nunzip -q /kaggle/input/carvana-image-masking-challenge/train_masks.zip -d train_mask\nunzip -q /kaggle/input/carvana-image-masking-challenge/train.zip -d train_images","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:18.583821Z","iopub.execute_input":"2026-02-03T06:31:18.584265Z","iopub.status.idle":"2026-02-03T06:31:19.683572Z","shell.execute_reply.started":"2026-02-03T06:31:18.584229Z","shell.execute_reply":"2026-02-03T06:31:19.680501Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"os.mkdir('/kaggle/working/input_mask')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.685213Z","iopub.status.idle":"2026-02-03T06:31:19.685731Z","shell.execute_reply.started":"2026-02-03T06:31:19.685481Z","shell.execute_reply":"2026-02-03T06:31:19.685504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"input_path = '/kaggle/working/train_mask/train_masks/'\noutput_path = '/kaggle/working/input_mask/'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.687015Z","iopub.status.idle":"2026-02-03T06:31:19.687513Z","shell.execute_reply.started":"2026-02-03T06:31:19.687271Z","shell.execute_reply":"2026-02-03T06:31:19.687295Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for img in tqdm.tqdm(os.listdir(input_path)):\n    name = img[:-9]\n    image = Image.open(input_path+img).convert('RGB')\n    image.save(f'{output_path}{name}.jpg')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.689830Z","iopub.status.idle":"2026-02-03T06:31:19.690302Z","shell.execute_reply.started":"2026-02-03T06:31:19.690041Z","shell.execute_reply":"2026-02-03T06:31:19.690080Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"input_image_path = '/kaggle/working/train_images/train/'\ninput_mask_path = '/kaggle/working/input_mask/'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.691928Z","iopub.status.idle":"2026-02-03T06:31:19.692407Z","shell.execute_reply.started":"2026-02-03T06:31:19.692156Z","shell.execute_reply":"2026-02-03T06:31:19.692178Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(os.listdir(input_mask_path))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.693690Z","iopub.status.idle":"2026-02-03T06:31:19.694160Z","shell.execute_reply.started":"2026-02-03T06:31:19.693904Z","shell.execute_reply":"2026-02-03T06:31:19.693926Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# create empty lists to store the input and output images\nX = []\nY = []\n\n# loop through the input images in the directory\nfor input_image in tqdm.tqdm(os.listdir(input_image_path)):\n    # read the input image using cv2\n    img = cv2.resize(cv2.imread(os.path.join(input_image_path, input_image)), (224,224), cv2.INTER_CUBIC)\n    # append the input image to the x list\n    X.append(np.array(img))\n\n    # read the corresponding output image using cv2\n    img = cv2.resize(cv2.imread(os.path.join(input_mask_path, input_image)), (224,224), cv2.INTER_CUBIC)\n    # append the output image to the y list\n    Y.append(np.array(img))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.695276Z","iopub.status.idle":"2026-02-03T06:31:19.695728Z","shell.execute_reply.started":"2026-02-03T06:31:19.695490Z","shell.execute_reply":"2026-02-03T06:31:19.695512Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = np.array(X)\nY = np.array(Y)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.697421Z","iopub.status.idle":"2026-02-03T06:31:19.697747Z","shell.execute_reply.started":"2026-02-03T06:31:19.697592Z","shell.execute_reply":"2026-02-03T06:31:19.697607Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.698668Z","iopub.status.idle":"2026-02-03T06:31:19.698991Z","shell.execute_reply.started":"2026-02-03T06:31:19.698831Z","shell.execute_reply":"2026-02-03T06:31:19.698846Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Y.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.699941Z","iopub.status.idle":"2026-02-03T06:31:19.700289Z","shell.execute_reply.started":"2026-02-03T06:31:19.700119Z","shell.execute_reply":"2026-02-03T06:31:19.700135Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# U-Net Xception style model\nimage_size = (224,224,3)\ninputs = keras.Input(shape = image_size)\n\n# entry block\nx = layers.Conv2D(32,3,strides = 2,padding = 'same')(inputs)\nx = layers.BatchNormalization()(x)\nx = layers.Activation('relu')(x)\nprevious_block_activation = x  # sed aside residual\n\n# blocks 1,2,3 are identical apart from the feature depth\nfor filters in [64,128,256]:\n    x = layers.Activation('relu')(x)\n    x = layers.SeparableConv2D(filters, 3, padding = 'same')(x)\n    x = layers.BatchNormalization()(x)\n    \n    x = layers.Activation('relu')(x)\n    x = layers.SeparableConv2D(filters, 3, padding = 'same')(x)\n    x = layers.BatchNormalization()(x)\n    \n    x = layers.MaxPooling2D(3, strides= 2, padding = 'same')(x)\n    \n    # project residual \n    residual = layers.Conv2D(filters, 1, strides = 2, padding = 'same')(previous_block_activation)\n    x = layers.add([x,residual])  # add block residual\n    previous_block_activation = x  # set aside next residual\n    \n# second half of the network : upsampling inputs\nfor filters in [256,128,64,32]:\n    x = layers.Activation('relu')(x)\n    x = layers.Conv2DTranspose(filters, 3, padding = 'same')(x)\n    x = layers.BatchNormalization()(x)\n    \n    x = layers.Activation('relu')(x)\n    x = layers.Conv2DTranspose(filters, 3, padding = 'same')(x)\n    x = layers.BatchNormalization()(x)\n    \n    x = layers.UpSampling2D(2)(x)\n    \n    # project residual \n    residual = layers.UpSampling2D(2)(previous_block_activation)\n    residual = layers.Conv2D(filters, 1, padding='same')(residual)\n    x = layers.add([x,residual])   # add back residuals\n    previous_block_activation = x   # set aside next residual\n    \n# output layers \noutputs = layers.Conv2D(3,3, activation= 'relu', padding = 'same')(x)\n\n# define the model\nmodel = keras.Model(inputs, outputs)\n# free up ram in case the model definition cells were run multiple times\nkeras.backend.clear_session()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.701404Z","iopub.status.idle":"2026-02-03T06:31:19.701697Z","shell.execute_reply.started":"2026-02-03T06:31:19.701551Z","shell.execute_reply":"2026-02-03T06:31:19.701565Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.703190Z","iopub.status.idle":"2026-02-03T06:31:19.703512Z","shell.execute_reply.started":"2026-02-03T06:31:19.703360Z","shell.execute_reply":"2026-02-03T06:31:19.703375Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(\n    loss = tf.keras.losses.mean_squared_error,\n    optimizer = tf.keras.optimizers.Adam(),\n    metrics = ['accuracy']\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.704526Z","iopub.status.idle":"2026-02-03T06:31:19.704833Z","shell.execute_reply.started":"2026-02-03T06:31:19.704684Z","shell.execute_reply":"2026-02-03T06:31:19.704699Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# early stopping \nearly_stopping = callbacks.EarlyStopping(\n    monitor = 'val_loss',\n    min_delta = 0.001, # minimum amount of change to count as an improvement \n    patience = 7, # how many epochs to wait before stopping \n    restore_best_weights = True\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.705833Z","iopub.status.idle":"2026-02-03T06:31:19.706146Z","shell.execute_reply.started":"2026-02-03T06:31:19.705972Z","shell.execute_reply":"2026-02-03T06:31:19.705986Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.fit(X,Y,batch_size = 32, epochs = 100,verbose = 1, callbacks =[early_stopping], validation_split = 0.2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.706973Z","iopub.status.idle":"2026-02-03T06:31:19.707298Z","shell.execute_reply.started":"2026-02-03T06:31:19.707145Z","shell.execute_reply":"2026-02-03T06:31:19.707159Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%bash\nunzip -q /kaggle/input/carvana-image-masking-challenge/test.zip -d test","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.708147Z","iopub.status.idle":"2026-02-03T06:31:19.708460Z","shell.execute_reply.started":"2026-02-03T06:31:19.708307Z","shell.execute_reply":"2026-02-03T06:31:19.708321Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(20,10))\npath = '/kaggle/working/test/test/'\nimages = os.listdir(path)\ni = 1\nwhile i <= 12:\n    img = random.choice(images)\n    img = cv2.resize(cv2.imread(os.path.join(path, img)), (224,224), cv2.INTER_CUBIC)\n    img = np.expand_dims(img, axis=0)\n    out = model.predict(img)\n    ax = plt.subplot(3,4,i)  #(nrows, ncolumns, index)\n    plt.imshow(out[0], cmap = 'gray')\n    i += 1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-03T06:31:19.709619Z","iopub.status.idle":"2026-02-03T06:31:19.709930Z","shell.execute_reply.started":"2026-02-03T06:31:19.709781Z","shell.execute_reply":"2026-02-03T06:31:19.709795Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}