HomeVideos

Object detection and bounding box regression

Now Playing

Object detection and bounding box regression

Transcript

535 segments

0:00

In this video, we will have a look at

0:02

object detection, which involves both

0:04

classification and bounding box

0:06

regression to identify the location of

0:09

an object in an image.

0:11

This video serves as a basic

0:13

introduction before we have a look at

0:15

the YOLO model in the next video.

0:19

I will first show how bounding box

0:21

regression works before we have a look

0:24

at some Python code.

0:26

I here assume that you are familiar with

0:28

the CNNs, transfer learning, and image

0:31

classification. If not, have a look at

0:34

this video.

0:36

In this video, we will train a

0:38

convolutional neural network to identify

0:41

heads of cats and dogs. We will also

0:43

train the model to classify if the image

0:46

contains a cat or a dog. So, to train

0:50

such a model, we first need images of

0:53

cats and dogs. Then, we need to draw a

0:56

bounding box around the head in each

0:59

image, which will serve as the ground

1:01

truth box that the network is trained

1:04

on.

1:05

This image has 800 pixels in width and

1:09

1,200 pixels in height. When we draw

1:13

this bounding box, we'll get the

1:15

location of this box in pixel

1:17

coordinates. There are a number of tools

1:20

out there that you can use to extract

1:22

such information. Here are a few

1:25

examples. The pixel coordinate of the

1:28

top left corner is 160 and 90.

1:32

The height of the bounding box is 420

1:36

and the width is 400 pixels.

1:40

We may store our data like this.

1:43

Where these columns show the size of the

1:46

image. X and Y define the coordinates of

1:49

the top left corner of the bounding box,

1:52

and these two columns show the width and

1:55

height of the box.

1:56

Whereas the last column tells if the

1:59

image contains a cat or a dog.

2:02

Then, we collect the same information

2:05

about the following image.

2:07

Note that these two columns represent

2:09

the pixel coordinates of the top left

2:12

corner of the bounding box.

2:14

In, for example, the YOLO model, one

2:17

should instead provide the coordinates

2:19

of the center of the box.

2:22

The numbers are usually normalized

2:24

before training a neural network because

2:27

the training works best if the numbers

2:29

are between 0 and 1.

2:32

To normalize the X coordinate of the top

2:34

left corner, we simply divide it by the

2:37

width of the image.

2:40

And to normalize the Y coordinate of the

2:42

top left corner, we divide it by the

2:44

height of the image and so forth.

2:52

One nice thing with normalized values

2:55

is that we can rescale the image to a

2:57

different size

2:59

and simply multiply the normalized

3:02

values by the new width and height of

3:04

the image so that we get the coordinates

3:08

to draw the bounding box in the resized

3:10

image.

3:13

So, to train a network to classify cats

3:16

and dogs and to identify the heads, we

3:19

will use an existing network, which

3:22

means that we will utilize transfer

3:24

learning.

3:26

The network you see here is the

3:28

so-called VGG-16 model.

3:31

This network was originally trained on

3:33

the ImageNet dataset to classify images

3:37

including things like cars, flowers,

3:40

birds, and fruits.

3:42

The network has 1,000 output nodes

3:45

because the ImageNet dataset had 1,000

3:48

different categories to classify.

3:52

We will modify this network so that it

3:55

is trained to only classify cats and

3:58

dogs and to identify their heads with

4:01

bounding box regression.

4:03

We first have to delete the fully

4:05

connected layers.

4:07

This bar represents a one-dimensional

4:10

vector that includes the flattened

4:13

values from the 512 channels of the

4:17

final pooling layer.

4:19

Then we add a dense or a fully connected

4:22

layer including, for example, 64 nodes.

4:27

Finally, we add a five output nodes.

4:30

Where this node will predict the

4:31

normalized X coordinate of the top-left

4:34

corner of the bounding box.

4:37

This node will predict the normalized Y

4:39

coordinate of the top-left corner of the

4:42

box.

4:43

Whereas these two nodes will predict the

4:45

width and height of the box.

4:48

The last node will predict if the image

4:50

contains a cat or a dog.

4:53

Since we have only two classes to

4:55

predict, we only need one node for the

4:58

classification.

5:00

If you have more than two classes, you

5:02

need one node for each class and use a

5:05

softmax function.

5:07

For all output nodes, we use the sigmoid

5:11

activation function, which constrains

5:13

the predicted values between zero and

5:16

one.

5:17

One simple type of loss function that

5:20

can be used for bounding box regression

5:23

is the Huber loss function.

5:25

Suppose that the network has predicted

5:28

the following bounding box.

5:30

For example, the ground truth box of the

5:33

normalized X coordinate is here 0.2.

5:37

Whereas the predicted X coordinate is

5:39

here 0.3.

5:42

The absolute difference between these

5:44

two values is 0.1.

5:47

Delta is a tuning hyperparameter that

5:50

controls how sensitive the Huber loss is

5:53

the outliers.

5:55

A larger value makes the loss behave

5:57

more like the mean squared error, which

6:00

gives a tighter fit to small errors, but

6:02

makes the model more sensitive to

6:04

outliers.

6:06

A smaller value makes it behave more

6:09

like the mean absolute error, which is

6:11

less sensitive to outliers.

6:15

Since the absolute difference is less

6:17

than one in this case,

6:20

we basically compute the squared error.

6:24

The total loss for the bounding box is

6:26

the Huber loss based on the difference

6:29

in X and the Y coordinates and the width

6:32

and height between the values of the

6:35

ground truth box and the predicted

6:37

values.

6:39

For the classification, we can use the

6:41

standard binary cross-entropy loss

6:44

function.

6:46

For example, the target value is zero if

6:49

the image contains a cat and one if the

6:53

image contains a dog.

6:56

The predicted value comes from this

6:58

output node as a probability.

7:01

Suppose that the network predicts that

7:03

the image contains a dog with 80%

7:06

probability.

7:08

Then the loss is about 1.61.

7:13

A simple way to compute the total loss

7:15

is then to add the Huber loss with the

7:18

binary cross-entropy loss function,

7:21

where you can put different weights on

7:23

these two functions.

7:25

During the training, we like to reduce

7:27

the total loss

7:29

so that the predicted box is as close as

7:32

possible to the ground truth box

7:35

and that the predicted probability for

7:37

cats and dogs is as close as possible to

7:40

their target values.

7:43

So, during training, the network might

7:46

predict the following box

7:48

and that the image contains a dog. To

7:51

correct this incorrect classification

7:53

and the difference in location and size

7:56

between the ground truth box and a

7:58

predicted box,

8:00

the network updates its weights in the

8:03

fully connected layers. One may also

8:06

unfreeze the weights in the last

8:08

convolutional layers of the existing

8:11

network to improve the performance.

8:15

Note that the output layer can be seen

8:17

as two different heads. The first head

8:20

is predicting the location and size of

8:23

the bounding box and is controlled by

8:25

the Huber loss function,

8:27

whereas the second head predicts if the

8:29

image contains a cat or a dog and is

8:32

controlled by the binary cross entropy

8:35

loss function.

8:37

All the 64 nodes in the fully connected

8:40

layer are here connected to the five

8:42

output nodes.

8:45

But it is also possible to add one or

8:47

several layers that are separate for the

8:50

heads.

8:51

For example, this layer is only

8:53

connected to head one.

8:56

This means that head one has more

8:58

weights to optimize, which is a common

9:01

architecture because the bounding box

9:04

regression sometimes requires more

9:06

layers for training.

9:09

The goal with the training is to

9:11

optimize the weights of the network so

9:13

that the predicted box is as close as

9:16

possible to the ground truth box by

9:18

minimizing this loss function and

9:21

optimize the weights for the

9:23

classification head so that the network

9:25

predicts cats and dogs as good as

9:28

possible.

9:29

To evaluate the performance of the

9:31

network, we usually split the images

9:34

into training, validation, and test

9:36

data.

9:37

The training data is used to optimize

9:40

the weights of the network, whereas the

9:42

validation data is used to optimize the

9:45

hyper parameters and try different

9:48

architectures of the network and to make

9:50

sure that we do not overfit.

9:53

Once we have developed and trained our

9:55

final optimized model, we check its

9:58

performance on completely unseen images

10:01

with bounding boxes in the test data

10:04

set.

10:06

One performance metric for the

10:07

classification part of the network is to

10:10

compute the accuracy based on the

10:12

validation data and the test data. In

10:15

this example, the network correctly

10:17

predicts the class in eight out of the

10:19

10 images, which gives an accuracy of

10:23

80%.

10:25

To evaluate the performance of the

10:27

bounding box regression, one usually

10:29

computes the intersection over union.

10:32

This is our ground truth or target

10:35

bounding box.

10:37

The area of this box covers 9,000

10:40

pixels.

10:42

When the network processes this image,

10:45

it may predict the following box given

10:48

its current weights.

10:50

The predicted box has an area of 4,096

10:54

pixels.

10:56

And the intersection covers 2,560

11:00

pixels.

11:01

We can now calculate the intersection

11:04

over union where we plug in the area of

11:06

the intersection here

11:09

and the areas of the target box and the

11:11

predicted box.

11:14

Note that we subtract the area of the

11:16

intersection from the total area because

11:19

the overlapping region would otherwise

11:21

be counted twice.

11:24

This gives us an intersection over union

11:27

score of about 0.24.

11:30

If the predicted box were over

11:32

where it does not intersect the target

11:35

box,

11:36

the intersection over union score would

11:38

be zero.

11:40

And if the predicted box would have the

11:41

same size and location as the target

11:44

box,

11:45

the intersection over union would be

11:47

one. With that, we know that the

11:49

intersection over union spans between

11:52

zero and one, and that the closer to one

11:55

we are, the better the predicted box

11:58

fits the target box.

12:00

>> So, why not use the following loss

12:02

function for the bounding box

12:03

regression?

12:05

>> If the intersection over union is one,

12:09

the loss is zero.

12:11

The problem occurs if there is no

12:13

overlap between the predicted box and

12:16

the target box.

12:18

The loss would in this case be equal to

12:20

one here,

12:22

as well as here. Such a function do not

12:24

provide any moving gradient towards the

12:27

target box, which means that the model

12:30

does not know which direction to move

12:32

the box.

12:34

One method to solve this problem is to

12:36

use the distance intersection over union

12:39

loss that was presented in the following

12:42

paper.

12:43

The distance intersection over union

12:46

loss includes the following penalty

12:48

term,

12:49

where the numerator represents the

12:51

squared Euclidean distance between the

12:53

central points of the two boxes, and C

12:57

is the diagonal length of the smallest

12:59

enclosing box covering the two boxes.

13:04

I will now show some basic code in Keras

13:07

and TensorFlow that can be used on the

13:09

examples we just discussed. Note that

13:12

this code is just for educational

13:14

purposes, which explains the basics of

13:17

object detection.

13:19

In the next video, I will show how to

13:21

train a YOLO model, which works a lot

13:24

better.

13:26

As an example, we will here use the

13:28

Oxford pet data set that you can

13:30

download from the following website.

13:34

You may download the images of cats and

13:37

dogs here.

13:39

This folder contains information about

13:42

the bounding box and segmentation.

13:45

However, we will not use that folder.

13:49

Instead, I have prepared a CSV file

13:52

based on the XML files of the data set

13:55

that you can download from my home page.

13:58

This CSV file includes the file names in

14:02

the Oxford pet data set, the width

14:06

and the height of the images.

14:09

It also includes the X coordinate of the

14:11

top left corner of the bounding box

14:14

around the heads

14:16

and the corresponding Y coordinate

14:19

as well as the width and height.

14:22

This column includes the breed, which we

14:25

will not use.

14:27

Instead, we'll use this column which

14:29

tells if the image contains a cat or a

14:32

dog.

14:34

I will now explain a simple Python code

14:36

for object detection that you can try.

14:39

This code is available on my home page.

14:43

We begin by importing the following

14:46

libraries.

14:49

Next, we define the path to our CSV file

14:52

that contains all the information about

14:55

the bounding boxes and the labels for

14:57

each image.

14:59

Note that you need to change this path

15:01

to where you have saved the file.

15:04

The information in the CSV file will be

15:07

saved as a Pandas data frame.

15:10

We also save the path to the folder

15:13

where we have the images of cats and

15:15

dogs.

15:18

Make sure that the image folder contains

15:20

the images.

15:23

Then we define the input image size for

15:25

our network.

15:27

We will here use VGG16,

15:29

which takes images of size 224 * 224.

15:35

This code creates three empty lists that

15:38

will later store the images, bounding

15:40

boxes, and labels.

15:45

Then we'll loop through all the rows in

15:47

the data frame that stores the

15:49

information in the CSV file.

15:53

Where each iteration constructs the full

15:56

path to an image file by combining the

15:58

path to the image directory with the

16:01

file name in the data frame.

16:04

Then we store the image and make sure

16:06

that the image loads successfully.

16:09

This code stores the height and width of

16:12

the loaded image,

16:14

which is used to normalize the bounding

16:16

box coordinates of the top left corner

16:19

and the width and height.

16:21

Next we code cats as zeros and dogs as

16:25

ones and store these in the variable

16:27

label.

16:29

Then we resize the image to 224 * 224

16:33

and normalize the pixel values in the

16:36

range between 0 and 1 by dividing them

16:39

by 255.

16:43

Finally, we store the image, bounding

16:45

box, and the label in the lists.

16:49

Next we convert the data into NumPy

16:52

arrays

16:53

and split the data set into training and

16:55

test data, where 20% of the images are

16:59

used as unseen test data.

17:03

We now start to build our network, where

17:05

we first import VGG16

17:09

and use its optimized weights based on

17:11

the ImageNet dataset.

17:14

By setting the parameter include top to

17:17

false, we do not include the fully

17:20

connected layers of VGG16.

17:23

Then we make sure to freeze the layers,

17:25

which means that we do not update the

17:28

weights during the training.

17:31

We will here unfreeze the last four

17:33

layers, which corresponds to all layers

17:36

in the last block, so that these are

17:38

updated during the training.

17:41

You may try to change this value to

17:43

unfreeze more or less layers.

17:48

Then we build the head for the bounding

17:50

box regression,

17:52

where we flatten the last layer from

17:54

VGG16,

17:57

and add three fully connected layers

18:00

to the four output nodes.

18:02

The output nodes involve the sigmoid

18:04

activation function to constrain the

18:07

predicted values between zero and one,

18:10

because we have normalized data, but you

18:12

may also try a linear activation

18:14

function.

18:16

Note that you may change the structure

18:18

of the head and the activation functions

18:20

to test if you get a better performance.

18:23

For this example, I tried a few existing

18:26

networks,

18:27

but VGG16 performed best for bounding

18:30

box regression, but a bit worse for the

18:33

classification.

18:36

For the classification head, we use

18:38

global average pooling of the last layer

18:41

from VGG16,

18:43

which usually works better than flatten

18:46

for classification.

18:48

We here use only one dense layer with 32

18:51

nodes, because the classification tends

18:54

to overfit if we use more. After this

18:57

line, one may also add a dropout layer

19:00

to prevent overfitting.

19:03

Since the classification only involves

19:05

two classes, it is enough to have just

19:08

one output node for the classification

19:10

head.

19:12

This line defines the final neural

19:14

network with two output heads.

19:18

Finally, we compile the model where we

19:20

say that we like to use the Adam

19:22

optimizer with a learning rate of

19:25

0.0001,

19:27

the Huber loss function for the bounding

19:30

box regression, and the binary cross

19:32

entropy loss function for the

19:34

classification.

19:36

Here we can define how much weight we

19:38

should put on the two loss functions.

19:41

I here use an equal weight, but you may

19:43

try to change these values to improve

19:45

the performance.

19:47

With this line, we can define what

19:49

performance metrics that should be shown

19:52

during the training.

19:55

This is the total training loss,

19:58

which is the sum of the bounding box

20:00

loss and the classification loss when we

20:03

use equal weights for the two loss

20:05

functions.

20:06

The mean squared error of the bounding

20:08

box regression is also shown,

20:12

as well as the classification accuracy.

20:15

After each epoch, the corresponding

20:17

validation performances will be printed.

20:22

This code defines the training of the

20:24

network on the images in the training

20:27

data

20:28

based on the target boxes and the target

20:31

classes.

20:33

We run 20 epochs, use a batch size of

20:36

eight, and 10% of the images as

20:39

validation data.

20:41

The data is shuffled before splitting

20:44

into training and validation sets, but

20:47

the split is here not stratified.

20:50

So, after each epoch, the performance

20:53

metric is shown based on this validation

20:55

data.

20:57

Finally, we check the performance

20:59

metrics based on the test data set after

21:02

the training is done.

21:04

We see that we correctly classified 97%

21:08

of the images.

21:10

And that the bounding box regression

21:12

means squared error is about 0.0047.

21:16

You may also compute the intersection of

21:19

a union to evaluate the performance of

21:21

the bounding box regression.

21:24

To see how well the predicted bounding

21:26

box fits the head of the cats and dogs,

21:30

we can pick an arbitrary image from the

21:32

test data set and multiply the pixel

21:35

values by 255 because we previously

21:38

normalized the images by dividing by

21:40

255.

21:43

The current width and height of the

21:45

images are 224 pixels.

21:50

We extract the normalized X and Y

21:51

coordinates and the width and height of

21:54

the ground truth box.

21:57

And multiply the width and height of the

21:59

image.

22:01

Then we use our trained model to predict

22:03

the class and the bounding box.

22:07

And extract the bounding box and class

22:10

probability from the prediction.

22:13

Next, we compute the X and Y coordinates

22:15

and the width and height of the

22:17

predicted box.

22:21

If the predicted probability is greater

22:23

than 0.5, we classify the image as

22:26

containing a dog. Else, as a cat.

22:30

If the ground truth label is one, we

22:33

know that it is a dog and a cat if the

22:36

target value is equal to zero.

22:40

Finally, we plot the image.

22:43

And draw the ground truth box in blue

22:46

color.

22:47

And the predicted box in green color.

22:51

And place the ground truth label.

22:54

And the predicted label here.

22:58

Here are some examples based on the

23:00

images in the test data set.

23:03

Our simple code seems to work quite

23:05

well.

23:07

Put a comment below if you managed to

23:09

improve the performance.

23:11

This was the end of this video about

23:13

object detection and bounding box

23:15

regression. Thanks for watching.

Interactive Summary

This video provides an introduction to object detection, focusing on the combination of image classification and bounding box regression. The tutorial explains the process of preparing data, including normalizing coordinates, and demonstrates how to modify the VGG-16 architecture using transfer learning to create a multi-headed neural network. It covers the use of Huber loss for box regression, binary cross-entropy for classification, and introduces the intersection over union (IoU) metric. The video concludes with a practical walkthrough of implementing this architecture in Python using Keras and TensorFlow.

Suggested questions

4 ready-made prompts