I have been trying to perform object localization to provide the [x1,y1,x2,y2] coordinates of objects in an image using Keras. I was stuck for ever because I was using MobileNetV2 as my backbone classifier and my results were terrible.

Note my primary reference for this question is this Medium post - https://medium.com/analytics-vidhya/object-localization-using-keras-d78d6810d0be

Main Question

Why is VGG16 a better backbone than MobileNet for object localisation?

Google CoLab Link - https://colab.research.google.com/drive/1viYr2xbDdHxG6f9upG8Hq-BgUJVVlVXu?usp=sharing

VGG vs MobileNet output

The Code

    All coming from here - https://medium.com/analytics-vidhya/object-localization-using-keras-d78d6810d0be
    Creates a white circle of random radius and tries to run two different object localisation networks over 
    them (VGG16 & MobileNet) and compares the output against 3 sample images

import tensorflow as tf
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Model
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.patches import Rectangle

IMG_SIZE = 128

def synthetic_gen(batch_size=64):
    """Makes white circles on a black background"""
    """Taken from - https://medium.com/analytics-vidhya/object-localization-using-keras-d78d6810d0be"""
    # enable generating infinite amount of batches
    while True:
        # generate black images in the wanted size
        X = np.zeros((batch_size, IMG_SIZE, IMG_SIZE, 3))
        Y = np.zeros((batch_size, 3))
        # fill each image
        for i in range(batch_size):
            x = np.random.randint(8,IMG_SIZE-8)
            y = np.random.randint(8,IMG_SIZE-8)
            a = min(IMG_SIZE - max(x,y), min(x,y))
            r = np.random.randint(4,a)
            for x_i in range(IMG_SIZE):
                for y_i in range(IMG_SIZE):
                    if ((x_i - x)**2) + ((y_i - y)**2) < r**2:
                        X[i, x_i, y_i,:] = 1
            Y[i,0] = (x-r)/float(IMG_SIZE)
            Y[i,1] = (y-r)/float(IMG_SIZE)
            Y[i,2] = 2*r /float(IMG_SIZE)
        yield X, Y

def plot_pred(img,p):
    """Plots the image and a bounding box based upon the prediction"""
    fig, ax = plt.subplots(1)
    rect = Rectangle(xy=(p[1]*IMG_SIZE,p[0]*IMG_SIZE),width=p[2]*IMG_SIZE, height=p[2]*IMG_SIZE, linewidth=1,edgecolor='g',facecolor='none')

def create_and_compile_model(backbone_type):
    assert backbone_type in ["VGG16","MobileNet"]
    if backbone_type == "VGG16":
        backbone = tf.keras.applications.VGG16(input_shape=[IMG_SIZE, IMG_SIZE, 3], include_top=False, weights='imagenet')
    elif backbone_type == "MobileNet":
        backbone = tf.keras.applications.MobileNet(input_shape=[IMG_SIZE, IMG_SIZE, 3], include_top=False, weights='imagenet',alpha = 1.0)
    output_layers = Flatten()(backbone.output)
    output_layers = Dense(3, activation='sigmoid')(output_layers)
    model = Model(backbone.input, output_layers)
    model.compile(loss='binary_crossentropy', optimizer=Adam(learning_rate=0.001))
    return model
def check_images_against_model(model,num_images=3):
    """Used to validate the trained model and show the bounding box against num_images of images"""
    validation_images_x, _ = next(synthetic_gen()) # generate new image
    predictions = model.predict(validation_images_x) # predict
    for i, validation_img in enumerate(validation_images_x[:num_images]):

model_vgg = create_and_compile_model("VGG16")
model_mobile_net = create_and_compile_model("MobileNet")

print("finished training, showing you images for VGG backbone")
print("showing you images for mobilenet backbone")

print("put a breakpoint here")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.