{ "cells": [ { "cell_type": "markdown", "id": "29217d64", "metadata": {}, "source": [ "Import Libraries" ] }, { "cell_type": "code", "execution_count": 1, "id": "a91c1fde", "metadata": {}, "outputs": [], "source": [ "import tensorflow as tf\n", "from tensorflow.keras.layers import Conv2D, Input, ZeroPadding2D, BatchNormalization, Activation, MaxPooling2D, Flatten, Dense\n", "from tensorflow.keras.models import Model, load_model\n", "from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.metrics import f1_score\n", "from sklearn.utils import shuffle\n", "import cv2\n", "import imutils\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import time\n", "from os import listdir\n", "from ProcessImage import *\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "id": "04d74859", "metadata": {}, "source": [ "Load Dataset and store them in Dictionary" ] }, { "cell_type": "code", "execution_count": 2, "id": "688f728d", "metadata": {}, "outputs": [], "source": [ "def load_data(dir_list, image_size):\n", " # load all images in a directory\n", " X = []\n", " y = []\n", " image_width, image_height = image_size\n", " \n", " for directory in dir_list:\n", " for filename in listdir(directory):\n", " # load the image\n", " image = cv2.imread(directory + '\\\\' + filename)\n", " # crop the brain and ignore the unnecessary rest part of the image\n", " image = crop_brain_contour(image, plot=False)\n", " # resize image\n", " image = cv2.resize(image, dsize=(image_width, image_height), interpolation=cv2.INTER_CUBIC)\n", " # normalize values\n", " image = image / 255.\n", " # convert image to numpy array and append it to X\n", " X.append(image)\n", " # append a value of 1 to the target array if the image\n", " # is in the folder named 'yes', otherwise append 0.\n", " if directory[-3:] == 'yes':\n", " y.append([1])\n", " else:\n", " y.append([0])\n", " \n", " X = np.array(X)\n", " y = np.array(y)\n", " \n", " # Shuffle the data\n", " X, y = shuffle(X, y)\n", " \n", " print(f'Number of examples is: {len(X)}')\n", " print(f'X shape is: {X.shape}')\n", " print(f'y shape is: {y.shape}')\n", " \n", " return X, y" ] }, { "cell_type": "code", "execution_count": 3, "id": "8c8d8638", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number of examples is: 2064\n", "X shape is: (2064, 240, 240, 3)\n", "y shape is: (2064, 1)\n" ] } ], "source": [ "path = 'aug_data/'\n", "\n", "path_yes = path + 'yes' \n", "path_no = path + 'no'\n", "\n", "IMG_WIDTH, IMG_HEIGHT = (240, 240)\n", "\n", "X, y = load_data([path_yes, path_no], (IMG_WIDTH, IMG_HEIGHT))" ] }, { "cell_type": "code", "execution_count": 4, "id": "f0238690", "metadata": {}, "outputs": [], "source": [ "def split_data(X, y, test_size=0.2):\n", " \n", " X_train, X_test_val, y_train, y_test_val = train_test_split(X, y, test_size=test_size)\n", " X_test, X_val, y_test, y_val = train_test_split(X_test_val, y_test_val, test_size=0.5)\n", " \n", " return X_train, y_train, X_val, y_val, X_test, y_test" ] }, { "cell_type": "code", "execution_count": 5, "id": "016d8190", "metadata": {}, "outputs": [], "source": [ "X_train, y_train, X_val, y_val, X_test, y_test = split_data(X, y, test_size=0.3)" ] }, { "cell_type": "code", "execution_count": 6, "id": "369b1f31", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "number of training examples = 1444\n", "number of development examples = 310\n", "number of test examples = 310\n", "X_train shape: (1444, 240, 240, 3)\n", "Y_train shape: (1444, 1)\n", "X_val (dev) shape: (310, 240, 240, 3)\n", "Y_val (dev) shape: (310, 1)\n", "X_test shape: (310, 240, 240, 3)\n", "Y_test shape: (310, 1)\n" ] } ], "source": [ "print (\"number of training examples = \" + str(X_train.shape[0]))\n", "print (\"number of development examples = \" + str(X_val.shape[0]))\n", "print (\"number of test examples = \" + str(X_test.shape[0]))\n", "print (\"X_train shape: \" + str(X_train.shape))\n", "print (\"Y_train shape: \" + str(y_train.shape))\n", "print (\"X_val (dev) shape: \" + str(X_val.shape))\n", "print (\"Y_val (dev) shape: \" + str(y_val.shape))\n", "print (\"X_test shape: \" + str(X_test.shape))\n", "print (\"Y_test shape: \" + str(y_test.shape))" ] }, { "cell_type": "code", "execution_count": 7, "id": "63083d7e", "metadata": {}, "outputs": [], "source": [ "# Nicely formatted time string\n", "def hms_string(sec_elapsed):\n", " h = int(sec_elapsed / (60 * 60))\n", " m = int((sec_elapsed % (60 * 60)) / 60)\n", " s = sec_elapsed % 60\n", " return f\"{h}:{m}:{round(s,1)}\"" ] }, { "cell_type": "code", "execution_count": 8, "id": "8eb1a346", "metadata": {}, "outputs": [], "source": [ "def compute_f1_score(y_true, prob):\n", " # convert the vector of probabilities to a target vector\n", " y_pred = np.where(prob > 0.5, 1, 0)\n", " \n", " score = f1_score(y_true, y_pred)\n", " \n", " return score" ] }, { "cell_type": "code", "execution_count": 9, "id": "0811cc0b", "metadata": {}, "outputs": [], "source": [ "def build_model(input_shape):\n", " # Define the input placeholder as a tensor with shape input_shape. \n", " X_input = Input(input_shape) # shape=(?, 240, 240, 3)\n", " \n", " # Zero-Padding: pads the border of X_input with zeroes\n", " X = ZeroPadding2D((2, 2))(X_input) # shape=(?, 244, 244, 3)\n", " \n", " # CONV -> BN -> RELU Block applied to X\n", " X = Conv2D(32, (7, 7), strides = (1, 1), name = 'conv0')(X)\n", " X = BatchNormalization(axis = 3, name = 'bn0')(X)\n", " X = Activation('relu')(X) # shape=(?, 238, 238, 32)\n", " \n", " # MAXPOOL\n", " X = MaxPooling2D((4, 4), name='max_pool0')(X) # shape=(?, 59, 59, 32) \n", " \n", " # MAXPOOL\n", " X = MaxPooling2D((4, 4), name='max_pool1')(X) # shape=(?, 14, 14, 32)\n", " \n", " # FLATTEN X \n", " X = Flatten()(X) # shape=(?, 6272)\n", " # FULLYCONNECTED\n", " X = Dense(1, activation='sigmoid', name='fc')(X) # shape=(?, 1)\n", " \n", " # Create model. This creates your Keras model instance, you'll use this instance to train/test the model.\n", " model = Model(inputs = X_input, outputs = X, name='BrainDetectionModel')\n", " \n", " return model\n" ] }, { "cell_type": "code", "execution_count": 10, "id": "129704fd", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Model: \"BrainDetectionModel\"\n", "_________________________________________________________________\n", " Layer (type) Output Shape Param # \n", "=================================================================\n", " input_1 (InputLayer) [(None, 240, 240, 3)] 0 \n", " \n", " zero_padding2d (ZeroPadding (None, 244, 244, 3) 0 \n", " 2D) \n", " \n", " conv0 (Conv2D) (None, 238, 238, 32) 4736 \n", " \n", " bn0 (BatchNormalization) (None, 238, 238, 32) 128 \n", " \n", " activation (Activation) (None, 238, 238, 32) 0 \n", " \n", " max_pool0 (MaxPooling2D) (None, 59, 59, 32) 0 \n", " \n", " max_pool1 (MaxPooling2D) (None, 14, 14, 32) 0 \n", " \n", " flatten (Flatten) (None, 6272) 0 \n", " \n", " fc (Dense) (None, 1) 6273 \n", " \n", "=================================================================\n", "Total params: 11,137\n", "Trainable params: 11,073\n", "Non-trainable params: 64\n", "_________________________________________________________________\n" ] } ], "source": [ "IMG_SHAPE = (IMG_WIDTH, IMG_HEIGHT, 3)\n", "model = build_model(IMG_SHAPE)\n", "model.summary()" ] }, { "cell_type": "code", "execution_count": 11, "id": "1499c665", "metadata": {}, "outputs": [], "source": [ "model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n", "\n", "tensorboard = EarlyStopping(monitor = 'val_accuracy', min_delta = 0.01, patience = 5, verbose = 1, mode = 'auto')\n", "# checkpoint\n", "# save the model with the best validation (development) accuracy till now\n", "checkpoint = ModelCheckpoint(monitor ='val_accuracy', filepath = './bestmodel.h5', verbose = 1, save_best_only = True, mode = 'auto')" ] }, { "cell_type": "code", "execution_count": 12, "id": "3f6bf736", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/10\n", "46/46 [==============================] - ETA: 0s - loss: 1.0042 - accuracy: 0.5713\n", "Epoch 1: val_accuracy improved from -inf to 0.49355, saving model to .\\bestmodel.h5\n", "46/46 [==============================] - 128s 2s/step - loss: 1.0042 - accuracy: 0.5713 - val_loss: 0.7599 - val_accuracy: 0.4935\n", "Epoch 2/10\n", "46/46 [==============================] - ETA: 0s - loss: 0.5417 - accuracy: 0.7327\n", "Epoch 2: val_accuracy improved from 0.49355 to 0.73548, saving model to .\\bestmodel.h5\n", "46/46 [==============================] - 96s 2s/step - loss: 0.5417 - accuracy: 0.7327 - val_loss: 0.6053 - val_accuracy: 0.7355\n", "Epoch 3/10\n", "46/46 [==============================] - ETA: 0s - loss: 0.4462 - accuracy: 0.7881\n", "Epoch 3: val_accuracy did not improve from 0.73548\n", "46/46 [==============================] - 95s 2s/step - loss: 0.4462 - accuracy: 0.7881 - val_loss: 0.5667 - val_accuracy: 0.7194\n", "Epoch 4/10\n", "46/46 [==============================] - ETA: 0s - loss: 0.4665 - accuracy: 0.7798\n", "Epoch 4: val_accuracy improved from 0.73548 to 0.77419, saving model to .\\bestmodel.h5\n", "46/46 [==============================] - 93s 2s/step - loss: 0.4665 - accuracy: 0.7798 - val_loss: 0.5191 - val_accuracy: 0.7742\n", "Epoch 5/10\n", "46/46 [==============================] - ETA: 0s - loss: 0.4247 - accuracy: 0.8096\n", "Epoch 5: val_accuracy did not improve from 0.77419\n", "46/46 [==============================] - 89s 2s/step - loss: 0.4247 - accuracy: 0.8096 - val_loss: 0.5469 - val_accuracy: 0.6935\n", "Epoch 6/10\n", "46/46 [==============================] - ETA: 0s - loss: 0.3253 - accuracy: 0.8622\n", "Epoch 6: val_accuracy did not improve from 0.77419\n", "46/46 [==============================] - 92s 2s/step - loss: 0.3253 - accuracy: 0.8622 - val_loss: 0.5043 - val_accuracy: 0.7323\n", "Epoch 7/10\n", "46/46 [==============================] - ETA: 0s - loss: 0.3763 - accuracy: 0.8262\n", "Epoch 7: val_accuracy did not improve from 0.77419\n", "46/46 [==============================] - 313s 7s/step - loss: 0.3763 - accuracy: 0.8262 - val_loss: 0.5446 - val_accuracy: 0.7194\n", "Epoch 8/10\n", "46/46 [==============================] - ETA: 0s - loss: 0.3089 - accuracy: 0.8747\n", "Epoch 8: val_accuracy did not improve from 0.77419\n", "46/46 [==============================] - 96s 2s/step - loss: 0.3089 - accuracy: 0.8747 - val_loss: 0.6839 - val_accuracy: 0.6387\n", "Epoch 9/10\n", "46/46 [==============================] - ETA: 0s - loss: 0.3058 - accuracy: 0.8767\n", "Epoch 9: val_accuracy improved from 0.77419 to 0.77742, saving model to .\\bestmodel.h5\n", "46/46 [==============================] - 91s 2s/step - loss: 0.3058 - accuracy: 0.8767 - val_loss: 0.4711 - val_accuracy: 0.7774\n", "Epoch 9: early stopping\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.fit(x=X_train, y=y_train, batch_size=32, epochs=10, validation_data=(X_val, y_val), callbacks=[tensorboard, checkpoint])" ] }, { "cell_type": "code", "execution_count": 14, "id": "623c8720", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10/10 [==============================] - 5s 441ms/step - loss: 0.4452 - accuracy: 0.7935\n" ] } ], "source": [ "loss, acc = model.evaluate(x=X_test, y=y_test)" ] }, { "cell_type": "code", "execution_count": 23, "id": "7506c142", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Test Loss = 0.4451896548271179\n", "Test Accuracy = 0.7935484051704407\n" ] } ], "source": [ "print (f\"Test Loss = {loss}\")\n", "print (f\"Test Accuracy = {acc}\")" ] }, { "cell_type": "code", "execution_count": 44, "id": "a237318e", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1/1 [==============================] - 0s 78ms/step\n", "Tumor Detected\n", "[[0.9980207]]\n" ] } ], "source": [ "model = load_model('bestmodel.h5')\n", "\n", "img = cv2.imread('Dataset/yes/Y2.jpg')\n", "#img = cv2.imread('Dataset/no/N3.jpg')\n", "test_img = crop_brain_contour(img)\n", "image = cv2.resize(test_img, dsize=(240, 240), interpolation=cv2.INTER_CUBIC)\n", "image = image / 255.\n", "image = image.reshape((1, 240, 240, 3))\n", "\n", "res = model.predict(image)\n", "\n", "if res > 0.5:\n", " print(\"Tumor Detected\")\n", "else:\n", " print(\"NO Tumor\")\n", "\n", "print(res)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 5 }