{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.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":6318833,"sourceType":"datasetVersion","datasetId":3636171}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"#### Unet - semantic segmentation with retina-blood-vessel dataset","metadata":{}},{"cell_type":"markdown","source":"### Librarys","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nimport numpy as np\nfrom tensorflow.keras import layers, Model , Input\nimport tensorflow.image as tfi\nfrom tensorflow.keras.layers import Conv2D, Dropout, MaxPooling2D, Dropout, concatenate, UpSampling2D\nfrom keras.preprocessing.image import load_img, img_to_array\nimport os\nimport cv2\nimport matplotlib.pyplot as plt\nfrom glob import glob\nfrom keras.metrics import MeanIoU\nfrom sklearn.model_selection import train_test_split\nprint(tf.__version__)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:37:43.721978Z","iopub.execute_input":"2024-12-27T17:37:43.722441Z","iopub.status.idle":"2024-12-27T17:37:43.730442Z","shell.execute_reply.started":"2024-12-27T17:37:43.722400Z","shell.execute_reply":"2024-12-27T17:37:43.729417Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"size = 256\nbatch = 8","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:14:39.358734Z","iopub.execute_input":"2024-12-27T17:14:39.359025Z","iopub.status.idle":"2024-12-27T17:14:39.362696Z","shell.execute_reply.started":"2024-12-27T17:14:39.359003Z","shell.execute_reply":"2024-12-27T17:14:39.361755Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Helper Functions","metadata":{}},{"cell_type":"code","source":"# Paths to train images, test images, and masks\ntrain_images_path = '/kaggle/input/retina-blood-vessel/Data/train/image'\ntrain_masks_path = '/kaggle/input/retina-blood-vessel/Data/train/mask'\ntest_images_path = '/kaggle/input/retina-blood-vessel/Data/test/image'\ntest_masks_path = '/kaggle/input/retina-blood-vessel/Data/test/mask'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:36:55.353861Z","iopub.execute_input":"2024-12-27T17:36:55.354166Z","iopub.status.idle":"2024-12-27T17:36:55.358294Z","shell.execute_reply.started":"2024-12-27T17:36:55.354141Z","shell.execute_reply":"2024-12-27T17:36:55.357327Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_images_from_folder(folder):\n    images = []\n    for filename in glob(os.path.join(folder, '*.png')):\n        img = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)\n        if img is not None:\n            images.append(img)\n    return images\n\ndef resize_images(images, target_size):\n    resized_images = []\n    for img in images:\n        resized_img = cv2.resize(img, target_size)\n        resized_images.append(resized_img)\n    return np.array(resized_images)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:38:01.923739Z","iopub.execute_input":"2024-12-27T17:38:01.924063Z","iopub.status.idle":"2024-12-27T17:38:01.929138Z","shell.execute_reply.started":"2024-12-27T17:38:01.924034Z","shell.execute_reply":"2024-12-27T17:38:01.928203Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Data Loading","metadata":{}},{"cell_type":"code","source":"train_images = load_images_from_folder(train_images_path)\ntrain_masks = load_images_from_folder(train_masks_path)\ntest_images = load_images_from_folder(test_images_path)\ntest_masks = load_images_from_folder(test_masks_path)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:43:26.337679Z","iopub.execute_input":"2024-12-27T17:43:26.338017Z","iopub.status.idle":"2024-12-27T17:43:27.351951Z","shell.execute_reply.started":"2024-12-27T17:43:26.337993Z","shell.execute_reply":"2024-12-27T17:43:27.350980Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Resize images and masks\ntrain_images = resize_images(train_images, (256, 256))\ntrain_masks = resize_images(train_masks, (256, 256))\ntest_images = resize_images(test_images, (256, 256))\ntest_masks = resize_images(test_masks, (256, 256))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:43:27.630787Z","iopub.execute_input":"2024-12-27T17:43:27.631085Z","iopub.status.idle":"2024-12-27T17:43:27.647019Z","shell.execute_reply.started":"2024-12-27T17:43:27.631059Z","shell.execute_reply":"2024-12-27T17:43:27.646137Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#normalizing the images\ntrain_images = train_images / 255.0\ntrain_masks = train_masks / 255.0\ntest_images = test_images / 255.0\ntest_masks = test_masks / 255.0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:43:28.614686Z","iopub.execute_input":"2024-12-27T17:43:28.615035Z","iopub.status.idle":"2024-12-27T17:43:28.650783Z","shell.execute_reply.started":"2024-12-27T17:43:28.614989Z","shell.execute_reply":"2024-12-27T17:43:28.649845Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#adding a channel dimension\ntrain_images = tf.expand_dims(train_images, axis=-1)\ntrain_masks = tf.expand_dims(train_masks, axis=-1)\ntest_images = tf.expand_dims(test_images, axis=-1)\ntest_masks = tf.expand_dims(test_masks, axis=-1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:43:30.338748Z","iopub.execute_input":"2024-12-27T17:43:30.339076Z","iopub.status.idle":"2024-12-27T17:43:30.449777Z","shell.execute_reply.started":"2024-12-27T17:43:30.339047Z","shell.execute_reply":"2024-12-27T17:43:30.448896Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Train images shape: {train_images.shape}\")\nprint(f\"Train masks shape: {train_masks.shape}\")\nprint(f\"Test images shape: {test_images.shape}\")\nprint(f\"Test masks shape: {test_masks.shape}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:43:35.420043Z","iopub.execute_input":"2024-12-27T17:43:35.420397Z","iopub.status.idle":"2024-12-27T17:43:35.425401Z","shell.execute_reply.started":"2024-12-27T17:43:35.420365Z","shell.execute_reply":"2024-12-27T17:43:35.424565Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Model Architecture (U-Net)","metadata":{}},{"cell_type":"code","source":"def unet_model(input_size=(256, 256, 1)):\n    inputs = Input(input_size)\n\n    # Encoder\n    conv1 = Conv2D(64, (3, 3), activation='relu', padding='same')(inputs)\n    conv1 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv1)\n    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n\n    conv2 = Conv2D(128, (3, 3), activation='relu', padding='same')(pool1)\n    conv2 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv2)\n    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n\n    conv3 = Conv2D(256, (3, 3), activation='relu', padding='same')(pool2)\n    conv3 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv3)\n    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n\n    conv4 = Conv2D(512, (3, 3), activation='relu', padding='same')(pool3)\n    conv4 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv4)\n    drop4 = Dropout(0.5)(conv4)\n    pool4 = MaxPooling2D(pool_size=(2, 2))(drop4)\n\n    # Bottleneck\n    conv5 = Conv2D(1024, (3, 3), activation='relu', padding='same')(pool4)\n    conv5 = Conv2D(1024, (3, 3), activation='relu', padding='same')(conv5)\n    drop5 = Dropout(0.5)(conv5)\n\n    # Decoder\n    up6 = Conv2D(512, (2, 2), activation='relu', padding='same')(UpSampling2D(size=(2, 2))(drop5))\n    merge6 = concatenate([drop4, up6], axis=3)\n    conv6 = Conv2D(512, (3, 3), activation='relu', padding='same')(merge6)\n    conv6 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv6)\n\n    up7 = Conv2D(256, (2, 2), activation='relu', padding='same')(UpSampling2D(size=(2, 2))(conv6))\n    merge7 = concatenate([conv3, up7], axis=3)\n    conv7 = Conv2D(256, (3, 3), activation='relu', padding='same')(merge7)\n    conv7 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv7)\n\n    up8 = Conv2D(128, (2, 2), activation='relu', padding='same')(UpSampling2D(size=(2, 2))(conv7))\n    merge8 = concatenate([conv2, up8], axis=3)\n    conv8 = Conv2D(128, (3, 3), activation='relu', padding='same')(merge8)\n    conv8 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv8)\n\n    up9 = Conv2D(64, (2, 2), activation='relu', padding='same')(UpSampling2D(size=(2, 2))(conv8))\n    merge9 = concatenate([conv1, up9], axis=3)\n    conv9 = Conv2D(64, (3, 3), activation='relu', padding='same')(merge9)\n    conv9 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv9)\n    conv9 = Conv2D(1, (1, 1), activation='sigmoid')(conv9)\n\n    model = tf.keras.Model(inputs=inputs, outputs=conv9)\n\n    return model\n\n# Create the U-Net model\nmodel = unet_model(input_size=(256, 256, 1))\n\n# Print model summary\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T17:51:35.227030Z","iopub.execute_input":"2024-12-27T17:51:35.227410Z","iopub.status.idle":"2024-12-27T17:51:35.467635Z","shell.execute_reply.started":"2024-12-27T17:51:35.227378Z","shell.execute_reply":"2024-12-27T17:51:35.466792Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Model Compile\nmodel.compile(\n    optimizer='adam',\n    loss='binary_crossentropy',\n    metrics=['accuracy',MeanIoU(num_classes=2,name=\"IOU\")]\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T18:29:58.756536Z","iopub.execute_input":"2024-12-27T18:29:58.756886Z","iopub.status.idle":"2024-12-27T18:29:58.766744Z","shell.execute_reply.started":"2024-12-27T18:29:58.756855Z","shell.execute_reply":"2024-12-27T18:29:58.765867Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Model Training","metadata":{}},{"cell_type":"code","source":"# Training\nresults = model.fit(\n    train_images, train_masks,\n    validation_data = (test_images,test_masks),\n    epochs=60,\n    batch_size=batch\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T18:30:01.704756Z","iopub.execute_input":"2024-12-27T18:30:01.705074Z","iopub.status.idle":"2024-12-27T18:32:54.333484Z","shell.execute_reply.started":"2024-12-27T18:30:01.705048Z","shell.execute_reply":"2024-12-27T18:32:54.332770Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 2, figsize=(10,3))\nax[0].plot(results.epoch, results.history[\"loss\"], label=\"Train loss\")\nax[0].plot(results.epoch, results.history[\"val_loss\"], label=\"Validation loss\")\nax[0].legend()\nax[1].plot(results.epoch, results.history[\"accuracy\"], label=\"Train accuracy\")\nax[1].plot(results.epoch, results.history[\"val_accuracy\"], label=\"Validation accuracy\")\nax[1].legend()\nfig.suptitle('Loss and Accuracy', fontsize=16)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T18:32:54.334825Z","iopub.execute_input":"2024-12-27T18:32:54.335070Z","iopub.status.idle":"2024-12-27T18:32:54.625679Z","shell.execute_reply.started":"2024-12-27T18:32:54.335050Z","shell.execute_reply":"2024-12-27T18:32:54.624776Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Prediction Visualizations","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(5,3, figsize=(10,18))\ntest_images,test_masks\n\nj = np.random.randint(0,test_images.shape[0], 5)\nfor i in range(5):\n    ax[i,0].imshow(test_images[j[i]])\n    ax[i,0].set_title('Image')\n    ax[i,1].imshow(test_masks[j[i]],cmap='gray')\n    ax[i,1].set_title('Mask')\n    y_hat = model.predict(np.expand_dims(test_images[j[i]],0),verbose=0)[0]\n    threshold = 0.5\n    binary_mask = (y_hat > threshold).astype(np.uint8)\n    ax[i,2].imshow(binary_mask,cmap='gray')\n    ax[i,2].set_title('Prediction')\nfig.suptitle('Results', fontsize=16)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-27T18:32:54.627111Z","iopub.execute_input":"2024-12-27T18:32:54.627357Z","iopub.status.idle":"2024-12-27T18:32:57.569330Z","shell.execute_reply.started":"2024-12-27T18:32:54.627337Z","shell.execute_reply":"2024-12-27T18:32:57.568232Z"}},"outputs":[],"execution_count":null}]}