25

Building a Brain Tumor Classification App

 3 years ago
source link: https://towardsdatascience.com/building-a-brain-tumor-classification-app-e9a0eb9f068?gi=e8490942e8bb
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Building a Brain Tumor Classification App

A Real Machine Learning App from scratch with Dash

NJ3miqi.jpg!web

Source: https://unsplash.com/photos/rmWtVQN5RzU

In the following article, I will present a machine learning app I created from scratch.

1. The goal

What I wanted to build was an app that would take as input a brain MRI image. From there, the app would return a prediction, saying if there is or not a tumor present on the image.

To achieve this goal, three steps needed to be achieved, i.e. the creation of a model to predict the class of an image, the creation of the app and finally the deployment of the app itself.

2. Building the Convolutional Neural Network model

CNNs are a class of deep neural networks that are usually applied to analyzing visual content, which is precisely what I wanted to do here.

The data I used to build the CNN comes from here .

It contains 3264 brain MRI images (2880 training and 384 testing images), separated in 4 categories: glioma tumors, meningioma tumors, pituitary tumors and no tumors.

I used Keras to build the model. For those unaware, Keras is a high-level Python neural networks library that runs on top of Tensorflow. Its simple architecture, readability and overall ease of use make it one of the most popular library when it comes to deep learning with Python.

After importing and preparing the images for the CNN, I ended up building the following model.

model = Sequential()model.add(Conv2D(32, (3, 3), input_shape=(150,150,3), use_bias=False))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3))) 
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(4))
model.add(Activation('softmax'))model.compile(loss = "categorical_crossentropy", optimizer=keras.optimizers.Adam(learning_rate=0.001), metrics=['accuracy'])

I kept the model quite simple. It only has two convolution layers and the softmax layer at the very end will return probabilities that an MRI belongs to the 4 classes.

I then trained that model on the data.

history = model.fit(trainData, trainLabel,batch_size = 128, epochs = 30 ,validation_data=(testData, testLabel))

This simple model, with only 30 epochs, achieved an accuracy of about 81%. Then, by saving the model, it means that it could easily be used in the Dash application to predict new images.

model.save('model_final.h5')

Now that this part is done, let’s move on to the creation of the app using Dash.

3. Creating the App

I used Dash to create the application. The platform allows us to produce quality enterprise-ready analytic apps without the need for developers, JavaScript or anything more than basic Python skills for that matter.

For a complete tutorial of how to build a Dash app, clickhere.

The first thing I did was import all the packages needed to run both the dash app as well as the keras model. Afterwards, the app could be built. Here is the full code for it.

That’s quite long so let’s go over a few things. First of, the names function is there so that depending what the model predicts, a specific output (i.e. the name of the tumor) will be given.

Now, let’s go over the callback. It takes as input an image, i.e. the html.Img tag from the parse_contents function. The list_of_contents[0] means that only the first image uploaded will be used afterwards (so it’s pointless to upload more than one).

Then, the following code takes the image, which Dash encoded in a base64 string, and makes it usable for the CNN:

  img_data = list_of_contents[0]
  img_data = re.sub('data:image/jpeg;base64,', '', img_data)
  img_data = base64.b64decode(img_data)  
  stream = io.BytesIO(img_data)
  img_pil = Image.open(stream)

Afterwards, the model created previously is loaded with the load_model function, the image is transformed into a numpy array with the right shape and a prediction is made with answ = model.predict(x) . What’s good here is that you could create any CNN model you want and load it, the app would still work!

Then, depending on what that prediction is, a second prediction about the likelihood that there is no tumor on the image and some facts about tumors are given.

Finally, the 4 outputs (the image, the two predictions and the facts) are returned, thus ending the long callback.

4. Deployment of Heroku

With the app created, it was time to make it available for everyone. Dash apps can be deployed on Heroku, a cloud application platform that allows you to run your apps, completely free of charge.

To learn how to deploy your Dash app on Heroku, click righthere.

The app is available right here: https://brain-mri-classifier.herokuapp.com/

Here is a short GIF showing how the app should be used. As you will see, it’s really simple:

You can try it with any brain MRI image of a healthy brain, or one with a glioma, meningioma or pituitary tumor. For instance, here is an image of a meningioma tumor that you could use to get a prediction.

RBNfYzI.jpg!web

Thanks for reading, I hope you found the article interesting!

All the codes are available in this repository: https://github.com/francoisstamant/brain-tumor-classifier-app


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK