Brain Tumor Prediction Through MRI Images Using CNN In Keras

In this article we will build a classification model that would take MRI images of the patient and compute if there is a tumor in the brain or not.

Computer vision techniques have shown tremendous results in some areas in the medical domain like surgery and therapy of different diseases. Even researchers are trying to experiment with the detection of different diseases like cancer in the lungs and kidneys. Different medical imaging datasets are publicly available today for researchers like Cancer Imaging Archive where we can get data access of large databases free of cost. A brain tumor is one of the problems wherein the brain of a patient’s different abnormal cells develops. They are called tumors that can again be divided into different types. 

Through this article, we will build a classification model that would take MRI images of the patient and compute if there is a tumor in the brain or not. We will be using Brain MRI Images for Brain Tumor Detection that is publicly available on Kaggle. We will first build the model using simple custom layers convolutional neural networks and then evaluate it. At last, we will compute some prediction by the model and compare the results. 

The Dataset 

The data set consists of two different folders that are Yes or No. Both the folders contain different MRI images of the patients. Yes folder has patients that have brain tumors whereas No folder has MRI images of patients with no brain tumor. There are a total of 155 images of positive patients of brain tumor and 98 images of other patients having no brain tumor. All the images are of 240X240 pixels. 

Brain Tumor Classification Model

First, we need to enable the GPU. To do so go to ‘Runtime’ in Google Colab and then click on ‘Change runtime type’ and select GPU. Once the runtime is changed we will move forward importing the required libraries and dataset. We will be directly importing the data set from kaggle. Use the below code to do the same. 

import tensorflow as tf
from zipfile import ZipFile
import os,glob
import cv2
from tqdm._tqdm_notebook import tqdm_notebook as tqdm
import numpy as np
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Convolution2D, Dropout, Dense,MaxPooling2D
from keras.layers import BatchNormalization
from keras.layers import MaxPooling2D
from keras.layers import Flatten

Downloading Dataset From Kaggle 

We first need to install the dependencies. As we will import data directly from Kaggle we need to install the package that supports that. So we have installed the Kaggle package using pip.

!pip install kaggle

Now we will import data from Kaggle. To do so we need to first add a kaggle.json file which you will get by creating a new API token on Kaggle. Go to my account in Kaggle and scroll down and you will see an option for creating a new API. Once you click on that a file ‘kaggle.json’ will be downloaded. Once you have that file upload it and change the permissions using the code shown below.

from google.colab import files
files.upload()
!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle/
!chmod 600 ~/.kaggle/kaggle.json 
kaggle datasets download -d navoneel/brain-mri-images-for-brain-tumor-detection

Once we run the above command the zip file of the data would be downloaded. We now need to unzip the file using the below code. 

from zipfile import ZipFile
file_name = "/content/brain-mri-images-for-brain-tumor-detection.zip"
with ZipFile(file_name,'r') as zip:
  zip.extractall()
  print('Done')

Now we will read the images and store it in a separate list. Use the below code to the same.

os.chdir('/content/yes')
X = []
y = []
for i in tqdm(os.listdir()):
      img = cv2.imread(i)   
      img = cv2.resize(img,(28,28))
      X.append(img)
      y.append((i[0:1]))
os.chdir('/content/no')
for i in tqdm(os.listdir()):
      img = cv2.imread(i)   
      img = cv2.resize(img,(28,28))
      X.append(img)
for i in range(1,99):
    y.append('N')

We have stored all the images in X and all the corresponding labels into y. Let us see some of the images that we just read. Use the below code to the same. 

%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
for i in range(4):
    plt.subplot(1, 4, i+1)
    plt.imshow(X[i], cmap="gray")
    plt.axis('off')
plt.show()

Output:

Brain Tumor Detection

The images are distorted because we have resized them into 28X28 pixels. We will not split the data into training and testing data. Use the below code to do the same. 

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
print ("Shape of an image in X_train: ", X_train[0].shape)
print ("Shape of an image in X_test: ", X_test[0].shape)

Output:

We have split the data into training and testing sets. We will now convert the labels into categorical using Keras. utils and also transform them into NumPy arrays. Use the below code to do so. 

le = preprocessing.LabelEncoder()
y_train = le.fit_transform(y_train)
y_test = le.fit_transform(y_test)
y_train = tf.keras.utils.to_categorical(y_train, num_classes=2)
y_test = tf.keras.utils.to_categorical(y_test, num_classes=2)
y_train = np.array(y_train)
X_train = np.array(X_train)
y_test = np.array(y_test)
X_test = np.array(X_test) 

We have transformed and now we will check the shape of the training and testing sets. Use the below to code to do the same. 

print("X_train Shape: ", X_train.shape) print("X_test Shape: ", X_test.shape) print("y_train Shape: ", y_train.shape) print("y_test Shape: ", y_test.shape)

Output: 

Brain Tumor Detection

We have 169 images of 28X28 pixels in the training and 84 images of the same pixels in the testing sets. Now we will build our network for classifying the MRI images. Use the below code to define the network by adding different convents and pooling layers.

m1=Sequential()
m1.add(BatchNormalization(input_shape = (28,28,3)))
m1.add(Convolution2D(32, (3,3), activation ='relu', input_shape = (28, 28, 3))) 
m1.add(MaxPooling2D(pool_size=2))
m1.add(Convolution2D(filters=64, kernel_size=4, padding='same', activation='relu'))
m1.add(MaxPooling2D(pool_size=2))
m1.add(Convolution2D(filters=128, kernel_size=3, padding='same', activation='relu'))
m1.add(MaxPooling2D(pool_size=2))
m1.add(Convolution2D(filters=128, kernel_size=2, padding='same', activation='relu'))
m1.add(MaxPooling2D(pool_size=2))
m1.add(Dropout(0.25))
m1.add(Flatten()) 
m1.add(Dense(units=128,activation = 'relu'))
m1.add(Dense(units = 64, activation = 'relu'))
m1.add(Dense(units = 32, activation = 'relu'))
m1.add(Dense(units = 2, activation = 'softmax'))

After defining the network we will now compile the network using optimizer as adam and loss function as categorical cross_entropy. We will be using metrics as accuracy to measure the performance. Use the below code to compile the model.

m1.compile(optimizer='adam', loss = 'categorical_crossentropy',metrics = ['accuracy'])

After compiling the model we will now train the model for 50 epochs and check the results on the validation dataset. Use the below code to do the same. 

history = m1.fit(X_train,y_train,
                    epochs=50, 
                    validation_data=(X_test,y_test),
                    verbose = 1,
                    initial_epoch=0)
Brain Tumor Detection

After the training has completed for 50 epochs we will evaluate the performance of the model on validation data. Use the below code to compute the same. 

m1.evaluate(X_test,y_test)
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper left')
plt.show()

Output:

We got 86% on the validation data with a loss of 0.592. Now let’s see the training and testing accuracy and loss with graphs. Use the below code to visualize the same. 

plt.plot(history.history['accuracy'])

Output:

Brain Tumor Detection
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper left')
plt.show()

Output:

Brain Tumor Detection

After this, we will check some predictions made by the model whether they were correct or not. Use the below code to compute some predictions on some of the MRI images. 

y_predicted=m1.predict_classes(X_test)
y_actual=np.argmax(y_test,axis=1)
L = 2
W = 2
fig, axes = plt.subplots(L, W, figsize = (12,12))
axes = axes.ravel()
for i in np.arange(0, L * W):  
    axes[i].imshow(X_test[i])
    axes[i].set_title(f"Prediction Class = {y_predicted[i]:0.1f}\n Actual Label = {y_actual[i]:0.1f}")
    axes[i].axis('off')
plt.subplots_adjust(wspace=0.5)

Output:

Brain Tumor Detection

The model computed 5 out of 6 predictions right and 1 image was misclassified by the model. We will now evaluate the model performance using a classification report. Check the below code to check the classification report of the model. 

from sklearn.metrics import classification_report
print(classification_report(y_true, y_pred))

Output: 

Classification Report

Conclusion 

In this article, we made a classification model with the help of custom CNN layers to classify whether the patient has a brain tumor or not through MRI images. With a few no of training samples, the model gave 86% accuracy. If we increase the training data may be by more MRI images of patients or perform data augmentation techniques we can achieve higher classification accuracy. Also, we can make use of pre-trained architectures like Vgg16 or Resnet 34 for improving the model performance. 

Download our Mobile App

Subscribe to our newsletter

Join our editors every weekday evening as they steer you through the most significant news of the day.
Your newsletter subscriptions are subject to AIM Privacy Policy and Terms and Conditions.

Our Recent Stories

Our Upcoming Events

3 Ways to Join our Community

Telegram group

Discover special offers, top stories, upcoming events, and more.

Discord Server

Stay Connected with a larger ecosystem of data science and ML Professionals

Subscribe to our Daily newsletter

Get our daily awesome stories & videos in your inbox
MOST POPULAR