...

Alien vs Predator Image Classification with ResNet50 | Complete Tutorial

ResNet50 Image Classification

Introduction to Image Classification with ResNet50

Deep learning has completely transformed the way we classify and recognize images.
In this tutorial, we’ll walk through building and training an Alien vs Predator image classifier using ResNet50, one of the most popular pre-trained convolutional neural networks.
Our goal is to leverage transfer learning to distinguish between two visually unique categories: aliens and predators.

This blog post explains the Python code step by step, splitting it into digestible parts so you can follow along and understand exactly how the model works.
By the end, you’ll not only know how to train the model but also how to test it with new images and visualize the results.

Link for the dataset : https://www.kaggle.com/datasets/pmigdal/alien-vs-predator-images


Train and Test a Powerful ResNet50 Model for Alien vs Predator Image Classification

Setting up the model with ResNet50

Before diving into the code, let’s take a moment to understand what makes ResNet50 so special.

ResNet50 is a Convolutional Neural Network (CNN) with 50 layers, trained on millions of images from the ImageNet dataset.
What sets ResNet apart from earlier CNNs is the introduction of residual connections—also called “skip connections.”
These connections allow the model to pass information directly from earlier layers to later layers, effectively solving the vanishing gradient problem that made training very deep networks difficult in the past.

Think of ResNet50 as a model that doesn’t just go layer by layer but also learns shortcuts between layers.
This design allows it to train much deeper networks while keeping accuracy high and training stable.
As a result, ResNet50 is capable of capturing both low-level features (edges, textures, shapes) and high-level features (object parts, structures, and even complex patterns).
That’s why it has become one of the most widely adopted architectures in transfer learning.

In this project, we don’t train ResNet50 from scratch.
Instead, we load a pre-trained ResNet50 (trained on ImageNet) and freeze its weights.
This way, we leverage all of its rich feature extraction capabilities while saving time and computational power.
On top of it, we add new layers that learn specifically about aliens vs predators—a task ResNet50 wasn’t originally trained for but can adapt to thanks to transfer learning.

By the end of this step, we’ll have a frozen backbone of ResNet50 ready to extract features, and we’ll prepare to add custom classification layers tailored to our dataset.

Resnet50
Resnet50
### Importing essential deep learning libraries import tensorflow as tf  from tensorflow.keras.layers import Dense, Flatten  from tensorflow.keras.models import Model  from tensorflow.keras.applications.resnet50 import ResNet50  from tensorflow.keras.preprocessing.image import ImageDataGenerator  import numpy as np  from glob import glob  import matplotlib.pyplot as plt   ### Setting image size to 224x224 pixels for ResNet50 IMAGE_SIZE = [224,224]  ### Defining dataset paths for training and validation images trainMyImagesFolder = "E:/Data-sets/alien_vs_predator_thumbnails/data/train" testMyImagesFolder = "E:/Data-sets/alien_vs_predator_thumbnails/data/validation"  ### Loading ResNet50 model with ImageNet weights, excluding top layers myResnet = ResNet50(input_shape=IMAGE_SIZE + [3] , weights="imagenet", include_top=False ) print(myResnet.summary())  ### Freezing pre-trained layers so they won’t be retrained for layer in myResnet.layers:     layer.trainable = False   ### Defining number of classes from dataset folders Classes = glob('E:/Data-sets/alien_vs_predator_thumbnails/data/train/*') print(Classes) numOfClasses = len(Classes) 

Summary:
Here, we imported all required libraries, defined dataset paths, loaded ResNet50, and froze its weights.
This ensures that the pre-trained knowledge of ImageNet is preserved while we focus only on learning features specific to aliens and predators.


Adding custom layers and compiling the model

Once the base model is ready, the next step is to build our classifier on top of it.
ResNet50 is fantastic at extracting features, but it doesn’t know anything about aliens or predators.
That’s where custom layers come in.

We start by adding a Global Average Pooling layer, which reduces the feature maps into a more compact form without losing important information.
This makes the model more efficient and prevents overfitting.
Next, we flatten those pooled features into a single vector so they can be fed into a Dense layer.

The last piece is the Dense output layer with softmax activation.
This is where the actual classification happens: the model outputs probabilities for each class (alien or predator), and the highest probability becomes the predicted label.

Once the architecture is complete, we compile the model.
We use categorical cross-entropy as the loss function because this is a multi-class problem, and the Adam optimizer for faster convergence.
Metrics like accuracy help us track performance during training.

### Adding a global average pooling layer to reduce dimensions global_avg_pooling_layer = tf.keras.layers.GlobalAveragePooling2D()(myResnet.output)  ### Flattening the pooled features into a single vector PlusFlattenLayer = Flatten()(global_avg_pooling_layer)  ### Adding the final Dense layer with softmax activation for classification predictionLayer = Dense(numOfClasses, activation='softmax')(PlusFlattenLayer)  ### Defining the final model with inputs and outputs model = Model(inputs=myResnet.input , outputs=predictionLayer) print(model.summary())  ### Compiling the model with categorical crossentropy loss and Adam optimizer model.compile(loss='categorical_crossentropy', optimizer=tf.keras.optimizers.Adam(learning_rate=0.01), metrics=['accuracy']) 

Summary:
This section builds the custom classification layers and compiles the model.
The result is a powerful hybrid: ResNet50 as the backbone, with new layers trained specifically for Alien vs Predator classification.


Training, evaluating, and visualizing the results

Now comes the most exciting part: training the model.
This is where the classifier learns from the dataset and gradually improves its ability to recognize aliens and predators.

To make training more effective, we use data augmentation.
This involves applying random transformations like zooming, flipping, and shearing to the training images, which helps the model generalize better and prevents overfitting.
Meanwhile, the test set is only rescaled, ensuring we evaluate performance on clean, untouched data.

We also introduce callbacks to control the training process.
For example, ModelCheckpoint saves the best model based on validation accuracy.
ReduceLROnPlateau automatically lowers the learning rate if progress slows down.
EarlyStopping halts training if validation accuracy doesn’t improve after a set patience, saving time and preventing overfitting.

Finally, we plot the training and validation accuracy and loss curves.
These visualizations help us see if the model is learning correctly, underfitting, or overfitting.
A well-trained model will show training and validation curves that improve together.

### Setting up training data augmentation train_datagen = ImageDataGenerator(rescale = 1./255 ,                                    shear_range = 0.2 ,                                    zoom_range = 0.2 ,                                    horizontal_flip = True)  ### Setting up test data preprocessing test_datagen = ImageDataGenerator(rescale = 1./255 )  ### Preparing training dataset training_set = train_datagen.flow_from_directory(trainMyImagesFolder,                                                  target_size = (224,224),                                                  batch_size=32 ,                                                  class_mode = 'categorical')  ### Preparing validation dataset test_set = test_datagen.flow_from_directory(testMyImagesFolder,                                                  target_size = (224,224),                                                  batch_size=32 ,                                                  class_mode = 'categorical')  ### Setting training parameters EPOCHS = 200 best_model_file = 'e:/temp/alien-predator-model.h5'  ### Importing callbacks for better training control from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau , EarlyStopping  callbacks = [     ModelCheckpoint(best_model_file, verbose=1 , save_best_only=True , monitor='val_accuracy'),     ReduceLROnPlateau(monitor='val_accuracy', patience=10 , factor=0.1 , verbose=1, min_lr=1e-6),     EarlyStopping(monitor='val_accuracy', patience=30 , verbose=1) ]  ### Training the model with validation data and callbacks r = model.fit(     training_set,     validation_data = test_set,     epochs=EPOCHS,     steps_per_epoch=len(training_set),     validation_steps=len(test_set),     callbacks=callbacks )  ### Printing best validation accuracy best_val_acc = max(r.history['val_accuracy']) print(f"Best validation Accuracy : {best_val_acc}")  ### Plotting accuracy curves plt.plot(r.history['accuracy'], label='Train acc') plt.plot(r.history['val_accuracy'], label='Val acc') plt.legend() plt.show()  ### Plotting loss curves plt.plot(r.history['loss'], label='Train loss') plt.plot(r.history['val_loss'], label='Val loss') plt.legend() plt.show() 

Summary:
We augmented our data, trained the model, and visualized performance.
Callbacks ensured training efficiency, and accuracy/loss plots helped confirm model improvements.


Testing the trained model on new images

Once training is complete, the next step is to put the model to the test.
Here, we take the best saved model and feed it new, unseen images to check its predictions.
This helps us verify whether the model generalizes well beyond the training data.

The first step is preprocessing: resizing the input image, converting it into an array, and normalizing pixel values.
Without this step, the model would not recognize the input correctly.
We then expand the dimensions to make it batch-compatible before feeding it into the model.

After prediction, we get an array of probabilities for each class.
Using argmax, we find the index of the class with the highest probability, and then map that index back to the class name (alien or predator).

To make it more interactive, we also overlay the predicted label directly on the image using OpenCV.
This allows us to visually confirm whether the prediction matches the content of the image.

The Test Image :

### Importing libraries for prediction import tensorflow as tf  import cv2  import os  from keras.utils import load_img, img_to_array import numpy as np   ### Defining image size and dataset classes IMAGE_SIZE = 224 trainMyImagesFolder = "E:/Data-sets/alien_vs_predator_thumbnails/data/train" CLASSES = os.listdir(trainMyImagesFolder) num_classes = len(CLASSES)  ### Loading the trained model best_model_file = 'e:/temp/alien-predator-model.h5' model = tf.keras.models.load_model(best_model_file)  ### Function to preprocess test images def prepareImage(pathForImage) :     image = load_img(pathForImage, target_size=(IMAGE_SIZE, IMAGE_SIZE))     imgResult = img_to_array(image)     imgResult = np.expand_dims(imgResult, axis=0)     imgResult = imgResult / 255.      return imgResult  ### Path to test image testImagePath = "Best-image-classification-models/ResNet-50-Alien-Vs-Predator/test-alien.jpg"  ### Reading test image img = cv2.imread(testImagePath)  ### Preparing image for model prediction imgForModel = prepareImage(testImagePath)  ### Making predictions resultArray = model.predict(imgForModel , verbose=1) print(resultArray)  ### Getting predicted class answer = np.argmax(resultArray , axis=1) print(answer)  ### Mapping index to class name index = answer[0] className = CLASSES[index] print("The predicted class is : " + className)  ### Displaying prediction result on the image cv2.putText(img , className , (220,20), cv2.FONT_HERSHEY_SIMPLEX, 1 , (0,255,0) , 2, cv2.LINE_AA) cv2.imshow("img", img) cv2.waitKey(0) 

Summary:
We successfully tested the model, displaying predictions directly on the image with OpenCV.
This completes the full workflow from training to real-world application.


Connect :

☕ Buy me a coffee — https://ko-fi.com/eranfeit

🖥️ Email : feitgemel@gmail.com

🌐 https://eranfeit.net

🤝 Fiverr : https://www.fiverr.com/s/mB3Pbb

Enjoy,

Eran

Leave a Comment

Your email address will not be published. Required fields are marked *

error: Content is protected !!
Eran Feit