DEV Community

Cover image for βš™οΈ How I Built My First CNN for Brain Tumor Classification
Tanmay P. Tawade
Tanmay P. Tawade

Posted on

βš™οΈ How I Built My First CNN for Brain Tumor Classification

🧠 From "I Know CNNs" to Actually Building One

In my previous two posts, I talked about what I learned and the mistakes I made while working on my first CNN project.

Now I want to show what I actually built.

The project is an MRI-based brain tumor detection and classification system using a custom Convolutional Neural Network (CNN).

The model classifies MRI images into four categories:

  • Glioma
  • Meningioma
  • Pituitary
  • No Tumor

The project also integrates Grad-CAM to visualize which regions of an MRI contributed most to a prediction.

The final system was then wrapped in a Streamlit web application so that the trained model could be used through an interactive interface.

This post focuses on the implementation pipeline rather than explaining CNN theory from scratch.


πŸ—ΊοΈ The Overall Pipeline

The system can be thought of as a sequence:

MRI Image

↓

Image Preprocessing

↓

CNN Classification

↓

Softmax Probability Distribution

↓

Prediction + Confidence Analysis

↓

Grad-CAM Visualization

↓

Report Generation

↓

Streamlit Interface

This pipeline helped me understand that a machine learning project is much more than the model itself.

The model is one component inside a larger system.


πŸ“Š Step 1 β€” Understanding the Dataset

The project uses a publicly available brain MRI dataset containing four categories:

Class Category
🧠 Glioma
🧠 Meningioma
🧠 Pituitary
🧠 No Tumor

Before training, the images were organized into training and testing data while maintaining class representation.

One of the lessons from my previous post became important here:

Don't start with the CNN. Start with the data.

Understanding the labels, class distribution, image quality, and visual characteristics of the dataset gave me a much better starting point.


πŸ–ΌοΈ Step 2 β€” Preprocessing the MRI Images

Raw images are not automatically ready to be passed into a CNN.

The project uses a preprocessing pipeline to make the input more consistent.

The main steps are:

  1. RGB image conversion
  2. Brain region extraction
  3. Contrast enhancement
  4. Gaussian noise reduction
  5. Image resizing
  6. Pixel normalization

The final input size used by the model is:

224 Γ— 224 pixels

The purpose wasn't to make the images "perfect."

It was to provide the model with a more consistent representation of the input data.


πŸ” Why Preprocessing Matters

This was another area where implementation changed my understanding.

I initially thought of preprocessing as simply:

"Resize the image and normalize it."

But in an image-classification project, preprocessing can influence what information the model actually sees.

For this project, I wanted to reduce irrelevant variation while preserving useful visual information.

The preprocessing pipeline therefore became an important part of the overall model design.


🧠 Step 3 β€” Building the CNN

For the classification model, I used a custom CNN architecture.

The main components are:

  • Convolutional layers
  • ReLU activation
  • Max pooling
  • Dropout regularization
  • Fully connected dense layers
  • Softmax output layer

The basic idea is:

Input Image

↓

Convolution

↓

Feature Extraction

↓

Pooling

↓

Deeper Feature Extraction

↓

Dense Layers

↓

Softmax

↓

4-Class Prediction

The earlier convolutional layers learn lower-level visual patterns, while deeper layers can combine those patterns into more complex representations.

The final softmax layer produces probabilities across the four classes.


πŸ”’ Step 4 β€” Why Softmax?

Because this is a four-class classification problem, the model needs to produce a probability distribution across all four possible classes.

For example, an output might look conceptually like:

Glioma       β†’ 0.02
Meningioma   β†’ 0.91
Pituitary    β†’ 0.04
No Tumor     β†’ 0.03
Enter fullscreen mode Exit fullscreen mode

The class with the highest predicted probability becomes the model's predicted class.

But this is where I had to remember something from Part 2:

A high probability is not the same thing as certainty.

The probability output is useful for understanding the model's prediction, but it should always be interpreted in the context of the model's evaluation and limitations.


πŸ§ͺ Step 5 β€” Training the Model

Once the preprocessing pipeline and CNN architecture were ready, the next step was training.

This is where the earlier mistakes started becoming useful.

Instead of treating training as:

Run β†’ Get Accuracy β†’ Done

I started paying attention to what was happening during training.

I looked at:

  • Training loss
  • Validation loss
  • Training accuracy
  • Validation accuracy
  • Precision
  • Recall
  • F1-score
  • Confusion matrix
  • Changes in performance across experiments

πŸ”„ Training Wasn't Just "Press Run"

One of the biggest changes in my approach was that I stopped treating training as a single event.

A typical experiment became:

Choose configuration

↓

Train the model

↓

Monitor training and validation behavior

↓

Evaluate the results

↓

Identify problems

↓

Modify the configuration

↓

Train again

This made the process much more iterative.

For example, if training performance continued improving while validation performance stopped improving, that raised a question about overfitting.

Instead of simply celebrating the higher training accuracy, I had to look at what was happening on data the model wasn't directly learning from.

βš™οΈ What I Experimented With

During development, I experimented with model configuration and training choices such as:

  • Model architecture
  • Learning rate
  • Number of epochs
  • Batch size
  • Regularization
  • Data preprocessing

The important lesson wasn't that one particular value was "correct."

It was that these choices should be treated as experiments rather than magic numbers.

I wanted to understand:

What am I changing?

Why am I changing it?

What effect should I expect?

Did the result actually improve?

That mindset made training much more meaningful than simply trying different values until the accuracy increased.


πŸ“ˆ Step 6 β€” Evaluating the Model

The final evaluation wasn't based on accuracy alone.

The project evaluates the model using:

  • Accuracy
  • Precision
  • Recall
  • F1-score
  • Confusion matrix
  • Softmax probability distribution

The current project documentation reports an overall classification accuracy of approximately 91%.

But the number I found more interesting was not the accuracy itself.

It was being able to look at the model from multiple perspectives.

For example:

Which classes are being confused?

Is the model performing consistently across classes?

Are the predictions supported by reasonable confidence values?

Those questions provide much more context than a single accuracy number.

πŸ“Š Looking Beyond Accuracy

For a multi-class classifier, the confusion matrix can reveal patterns that overall accuracy hides.

For example, if the model correctly identifies most images from one class but frequently confuses another class with a similar category, the overall accuracy may not immediately communicate how important that problem is.

This connected directly to the lesson from Part 2:

A model should be evaluated by how it behaves across classes, not just by one overall number.


πŸ”₯ Step 7 β€” Adding Grad-CAM

After getting the classifier working, I wanted to answer another question:

What part of the MRI is influencing the prediction?

This is where Grad-CAM (Gradient-weighted Class Activation Mapping) became part of the project.

Grad-CAM generates a heatmap showing image regions that contribute most to the model's prediction.

The workflow becomes:

MRI Image

↓

CNN Prediction

↓

Target Class

↓

Grad-CAM

↓

Heatmap

This doesn't give me an exact tumor segmentation.

Instead, it provides a visual way to inspect the regions that were influential for the model's prediction.

That distinction is important.

Grad-CAM helps interpret model behavior; it does not prove that the highlighted region is the tumor.


🧩 Step 8 β€” Turning the Model Into an Application

A trained model sitting inside a notebook isn't very useful to someone who wants to interact with it.

So I built a Streamlit application around the model.

The application allows a user to:

  • Upload an MRI image
  • Run the trained CNN
  • View the predicted class
  • Inspect confidence and probability information
  • Generate a Grad-CAM visualization
  • Generate a downloadable PDF report

The application therefore connects the machine learning pipeline to an actual user interface.

This was an important step for me because it changed the project from:

"I trained a model."

into:

"I built an application around a trained model."


🌐 The Final Workflow

The complete system looks like this:

              MRI Image
                  β”‚
                  β–Ό
          Image Preprocessing
                  β”‚
                  β–Ό
            Custom CNN
                  β”‚
                  β–Ό
        Softmax Probabilities
                  β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”
          β–Ό               β–Ό
     Prediction      Confidence
          β”‚               β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                  β–Ό
              Grad-CAM
                  β”‚
                  β–Ό
          Visual Explanation
                  β”‚
                  β–Ό
            PDF Report
Enter fullscreen mode Exit fullscreen mode

This was one of the most important things I learned from the project:

Building the model is only one part of building a machine learning application.


πŸ“‚ How I Structured the Project

I also tried to keep the project separated into meaningful components rather than putting everything into one Python file.

The repository currently has areas for:

Explainable-Brain-Tumor-Detection/
β”‚
β”œβ”€β”€ assets/
β”œβ”€β”€ dataset/
β”œβ”€β”€ docs/
β”œβ”€β”€ model/
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ gradcam.py
β”‚   β”œβ”€β”€ preprocess.py
β”‚   └── report.py
β”‚
β”œβ”€β”€ app.py
β”œβ”€β”€ requirements.txt
└── README.md
Enter fullscreen mode Exit fullscreen mode

The separation helped me understand the difference between:

  • Model loading
  • Preprocessing
  • Explainability
  • Report generation
  • Application logic

That became increasingly important as the project grew.


🧠 What I Learned From Building the Entire Pipeline

After completing the project, I don't think the biggest lesson was:

"I know how to build a CNN."

It was more like:

"I understand how many different pieces have to work together for a CNN project to become an actual application."

I learned about:

Data

How important it is to understand and prepare the dataset before training.

Models

How architecture decisions affect what the network can learn.

Training

How training is an iterative process rather than simply running a model once and checking the accuracy.

Evaluation

Why accuracy alone isn't enough.

Explainability

How Grad-CAM can help inspect model behavior.

Deployment

How a trained model can be turned into an interactive application.

Engineering

How project structure becomes important once the codebase grows.


⚠️ Important Limitations

This project is an academic and learning project, not a clinical diagnostic system.

There are several limitations.

The model was trained on a limited publicly available dataset, so its performance may not generalize to real-world clinical data.

Performance can also depend on MRI image quality and differences between datasets.

Grad-CAM provides an interpretation of influential regions, but it is not a precise tumor segmentation method.

For these reasons, the application should not be used as a substitute for professional medical diagnosis.

These limitations are part of the project itself, not something I want to hide behind the model's accuracy.


πŸš€ What I Would Improve Next

If I continued developing this system, some areas I'd explore are:

  • Larger and more diverse datasets
  • Transfer learning with stronger architectures
  • More rigorous validation
  • 3D MRI analysis
  • Tumor segmentation
  • Multi-modal MRI support
  • Better inference performance
  • More robust deployment architecture

The goal would not simply be to make the model bigger.

It would be to make the entire system more reliable, interpretable, and generalizable.


πŸ”— Try the Project

The complete implementation is available on GitHub:

πŸ‘‰ GitHub Repository

You can also try the deployed Streamlit application:

πŸ‘‰ Live Demo β€” Streamlit

Note: This application is intended for educational and research purposes only. It is not a medical diagnostic tool.


πŸ”— Part of My CNN Learning Series

This is the third post in my CNN learning series.

🧠 Part 1 β€” What My First CNN Project Taught Me

Read Part 1 β†’

⚠️ Part 2 β€” 5 Mistakes I Made in My First CNN Project

Read Part 2 β†’

βš™οΈ Part 3 β€” How I Built the CNN Model

You're reading this one.

πŸ” Part 4 β€” Understanding Model Predictions with Grad-CAM

Coming next.


πŸ‘‹ Let's Connect

I'm continuing to learn by building practical software and machine learning projects.

If you're interested in CNNs, computer vision, deep learning, or building ML applications, I'd be happy to hear what you're working on.

🌐 Portfolio

πŸ’» GitHub

πŸ’Ό LinkedIn

Top comments (0)