Title: ImageNet: VGGNet, ResNet, Inception, and Xception with Keras - PyImageSearch

URL Source: https://pyimagesearch.com/2017/03/20/imagenet-vggnet-resnet-inception-xception-keras/

Published Time: 2017-03-20T14:00:10+00:00

Markdown Content:
A few months ago, I wrote a [tutorial](https://pyimagesearch.com/2016/08/10/imagenet-classification-with-python-and-keras/) on how to classify images using Convolutional Neural Networks (specifically, VGG16) pre-trained on the ImageNet dataset with Python and the Keras deep learning library.

![Image 1](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20364'%3E%3C/svg%3E)

The pre-trained networks inside of Keras are capable of recognizing _1,000 different object categories_, similar to objects we encounter in our day-to-day lives with high accuracy.

Back then, the pre-trained ImageNet models were **_separate_** from the core Keras library, requiring us to clone a [free-standing GitHub repo](https://github.com/fchollet/deep-learning-models) and then _manually_ copy the code into our projects.

This solution worked well enough; however, since my original blog post was published, the pre-trained networks (VGG16, VGG19, ResNet50, Inception V3, and Xception) have been **_fully integrated into the Keras core_** (no need to clone down a separate repo anymore) — these implementations can be found inside the [applications sub-module](https://github.com/fchollet/keras/tree/master/keras/applications).

Because of this, I’ve decided to create a _new, updated tutorial_ that demonstrates how to utilize these state-of-the-art networks in your own classification projects.

Specifically, we’ll create a special Python script that can load _any_ of these networks using _either_ a TensorFlow or Theano backend, and then classify your own custom input images.

**To learn more about classifying images with VGGNet, ResNet, Inception, and Xception, _just keep reading._**

![Image 2](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20128%20128'%3E%3C/svg%3E)

#### Looking for the source code to this post?

[Jump Right To The Downloads Section](#download-the-code)

_**2020-06-15 Update:** This blog post is now TensorFlow 2+ compatible!_

In the first half of this blog post, I’ll briefly discuss the VGG, ResNet, Inception, and Xception network architectures included in the Keras library.

We’ll then create a custom Python script using Keras that can load these pre-trained network architectures from disk and classify your own input images.

Finally, we’ll review the results of these classifications on a few sample images.

### State-of-the-art deep learning image classifiers in Keras

Keras ships out-of-the-box with five Convolutional Neural Networks that have been pre-trained on the ImageNet dataset:

1.  VGG16
2.  VGG19
3.  ResNet50
4.  Inception V3
5.  Xception

Let’s start with a overview of the ImageNet dataset and then move into a brief discussion of each network architecture.

#### What is ImageNet?

[ImageNet](http://image-net.org/) is formally a project aimed at (manually) labeling and categorizing images into almost 22,000 separate object categories for the purpose of computer vision research.

However, when we hear the term _“ImageNet”_ in the context of deep learning and Convolutional Neural Networks, we are likely referring to the [_ImageNet Large Scale Visual Recognition Challenge_](http://www.image-net.org/challenges/LSVRC/), or ILSVRC for short.

The goal of this image classification challenge is to train a model that can correctly classify an input image into 1,000 separate object categories.

Models are trained on ~1.2 million training images with another 50,000 images for validation and 100,000 images for testing.

These 1,000 image categories represent object classes that we encounter in our day-to-day lives, such as species of dogs, cats, various household objects, vehicle types, and much more. You can find the full list of object categories in the ILSVRC challenge [here](http://image-net.org/challenges/LSVRC/2014/browse-synsets).

When it comes to image classification, the ImageNet challenge is the _de facto_ benchmark for computer vision classification algorithms — and the leaderboard for this challenge has been **_dominated_** by Convolutional Neural Networks and deep learning techniques since 2012.

The state-of-the-art pre-trained networks included in the Keras core library represent some of the highest performing Convolutional Neural Networks on the ImageNet challenge over the past few years. These networks also demonstrate a strong ability to _generalize_ to images outside the ImageNet dataset via _transfer learning_, such as feature extraction and fine-tuning.

#### VGG16 and VGG19

![Image 3](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20470%20276'%3E%3C/svg%3E)

**Figure 1:** A visualization of the VGG architecture ([source](https://www.cs.toronto.edu/~frossard/post/vgg16/)).

The VGG network architecture was introduced by Simonyan and Zisserman in their 2014 paper, [_Very Deep Convolutional Networks for Large Scale Image Recognition_](https://arxiv.org/abs/1409.1556).

This network is characterized by its simplicity, using only _3×3_ convolutional layers stacked on top of each other in increasing depth. Reducing volume size is handled by max pooling. Two fully-connected layers, each with 4,096 nodes are then followed by a softmax classifier (above).

The “16” and “19” stand for the number of weight layers in the network (columns D and E in **Figure 2** below):

In 2014, 16 and 19 layer networks were considered _very_ deep (although we now have the ResNet architecture which can be successfully trained at depths of 50-200 for ImageNet and over 1,000 for CIFAR-10).

Simonyan and Zisserman found training VGG16 and VGG19 challenging (specifically regarding convergence on the deeper networks), so in order to make training easier, they first trained _smaller_ versions of VGG with less weight layers (columns A and C) first.

The smaller networks converged and were then used as _initializations_ for the larger, deeper networks — this process is called _**pre-training**_.

While making logical sense, pre-training is a very time consuming, tedious task, requiring an _entire network_ to be trained **before** it can serve as an initialization for a deeper network.

We no longer use pre-training (in most cases) and instead prefer Xaiver/Glorot initialization or MSRA initialization (sometimes called He et al. initialization from the paper, [_Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification_](https://arxiv.org/abs/1502.01852)). You can read more about the importance of weight initialization and the convergence of deep neural networks inside [_All you need is a good init_](https://arxiv.org/abs/1511.06422), Mishkin and Matas (2015).

Unfortunately, there are two major drawbacks with VGGNet:

1.  It is _painfully slow_ to train.
2.  The network architecture weights themselves are quite large (in terms of disk/bandwidth).

Due to its depth and number of fully-connected nodes, VGG is over 533MB for VGG16 and 574MB for VGG19. This makes deploying VGG a tiresome task.

We still use VGG in many deep learning image classification problems; however, smaller network architectures are often more desirable (such as SqueezeNet, GoogLeNet, etc.).

#### ResNet

Unlike traditional _sequential_ network architectures such as AlexNet, OverFeat, and VGG, ResNet is instead a form of “exotic architecture” that relies on micro-architecture modules (also called “network-in-network architectures”).

The term _micro-architecture_ refers to the set of “building blocks” used to construct the network. A collection of micro-architecture building blocks (along with your standard CONV, POOL, etc. layers) leads to the _macro-architecture_ (i.e,. the end network itself).

First introduced by He et al. in their 2015 paper, [_Deep Residual Learning for Image Recognition_](https://arxiv.org/abs/1512.03385), the ResNet architecture has become a seminal work, demonstrating that _extremely deep_ networks can be trained using standard SGD (and a reasonable initialization function) through the use of residual modules:

![Image 4](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20159%20333'%3E%3C/svg%3E)

**Figure 3:** The residual module in ResNet as originally proposed by He et al. in 2015.

Further accuracy can be obtained by updating the residual module to use _identity mappings_, as demonstrated in their 2016 followup publication, [_Identity Mappings in Deep Residual Networks_](https://arxiv.org/abs/1603.05027):

![Image 5](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20299%20365'%3E%3C/svg%3E)

**Figure 4:** _(Left)_ The original residual module. _(Right)_ The updated residual module using pre-activation.

That said, keep in mind that the ResNet50 (as in 50 weight layers) implementation in the Keras core is based on the former 2015 paper.

Even though ResNet is _much_ deeper than VGG16 and VGG19, the model size is actually _substantially smaller_ due to the usage of global average pooling rather than fully-connected layers — this reduces the model size down to 102MB for ResNet50.

#### Inception V3

The “Inception” micro-architecture was first introduced by Szegedy et al. in their 2014 paper, [_Going Deeper with Convolutions_](https://arxiv.org/abs/1409.4842):

![Image 6](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20323'%3E%3C/svg%3E)

**Figure 5:** The original Inception module used in GoogLeNet.

The goal of the inception module is to act as a “multi-level feature extractor” by computing _1×1_, _3×3_, and _5×5_ convolutions within the _same_ module of the network — the output of these filters are then stacked along the channel dimension and before being fed into the next layer in the network.

The original incarnation of this architecture was called _GoogLeNet_, but subsequent manifestations have simply been called _Inception vN_ where _N_ refers to the version number put out by Google.

The Inception V3 architecture included in the Keras core comes from the later publication by Szegedy et al., _[Rethinking the Inception Architecture for Computer Vision](https://arxiv.org/abs/1512.00567)_ (2015) which proposes updates to the inception module to further boost ImageNet classification accuracy.

The weights for Inception V3 are smaller than both VGG and ResNet, coming in at 96MB.

#### Xception

![Image 7](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20409'%3E%3C/svg%3E)

**Figure 6:** The Xception architecture.

Xception was proposed by none other than [François Chollet](https://twitter.com/fchollet) himself, the creator and chief maintainer of the Keras library.

Xception is an extension of the Inception architecture which replaces the standard Inception modules with depthwise separable convolutions.

The original publication, _Xception: Deep Learning with Depthwise Separable Convolutions_ can be found [here](https://arxiv.org/abs/1610.02357).

Xception sports the smallest weight serialization at only 91MB.

#### What about SqueezeNet?

![Image 8](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20594%20370'%3E%3C/svg%3E)

**Figure 7:** The “fire” module in SqueezeNet, consisting of a “squeeze” and an “expand”. ([Iandola et al., 2016](https://arxiv.org/abs/1602.07360)).

For what it’s worth, the [SqueezeNet architecture](https://arxiv.org/abs/1602.07360) can obtain AlexNet-level accuracy (~57% rank-1 and ~80% rank-5) at only 4.9MB through the usage of “fire” modules that “squeeze” and “expand”.

While leaving a small footprint, SqueezeNet can also be _very_ tricky to train.

That said, I demonstrate how to train SqueezeNet from scratch on the ImageNet dataset inside my upcoming book, _[Deep Learning for Computer Vision with Python](https://pyimagesearch.com/deep-learning-computer-vision-python-book/)._

### Configuring your development environment

To configure your system for this tutorial, I recommend following either of these tutorials:

*   [_How to install TensorFlow 2.0 on Ubuntu_](https://pyimagesearch.com/2019/12/09/how-to-install-tensorflow-2-0-on-ubuntu/)
*   [_How to install TensorFlow 2.0 on macOS_](https://pyimagesearch.com/2019/12/09/how-to-install-tensorflow-2-0-on-macos/)

Either tutorial will help you configure you system with all the necessary software for this blog post in a convenient Python virtual environment.

Please note that [PyImageSearch does not recommend or support Windows for CV/DL projects](https://pyimagesearch.com/faqs/single-faq/can-you-help-me-do-___-on-windows/).

### Classifying images with VGGNet, ResNet, Inception, and Xception with Python and Keras

Let’s learn how to classify images with pre-trained Convolutional Neural Networks using the Keras library.

Open up a new file, name it `classify_image.py` , and insert the following code:

\# import the necessary packages
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.applications import InceptionV3
from tensorflow.keras.applications import Xception # TensorFlow ONLY
from tensorflow.keras.applications import VGG16
from tensorflow.keras.applications import VGG19
from tensorflow.keras.applications import imagenet\_utils
from tensorflow.keras.applications.inception\_v3 import preprocess\_input
from tensorflow.keras.preprocessing.image import img\_to\_array
from tensorflow.keras.preprocessing.image import load\_img
import numpy as np
import argparse
import cv2

**Lines 2-13** import our required Python packages. As you can see, most of the packages are part of the Keras library.

Specifically, **Lines 2-6** handle importing the Keras implementations of ResNet50, Inception V3, Xception, VGG16, and VGG19, respectively.

Please note that the Xception network is compatible _only with the TensorFlow backend_ (the class will throw an error if you try to instantiate it with a Theano backend).

**Line 7** gives us access to the `imagenet_utils` sub-module, a handy set of convenience functions that will make pre-processing our input images and decoding output classifications easier.

The remainder of the imports are other helper functions, followed by NumPy for numerical processing and `cv2` for our OpenCV bindings.

Next, let’s parse our command line arguments:

\# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-i", "--image", required=True,
	help="path to the input image")
ap.add\_argument("-model", "--model", type=str, default="vgg16",
	help="name of pre-trained network to use")
args = vars(ap.parse\_args())

We’ll require only a single command line argument, `--image` , which is the path to our input image that we wish to classify.

We’ll also accept an optional command line argument, `--model` , a string that specifies which pre-trained Convolutional Neural Network we would like to use — this value defaults to `vgg16` for the VGG16 network architecture.

Given that we accept the name of our pre-trained network via a command line argument, we need to define a Python dictionary that maps the model names (strings) to their actual Keras classes:

\# define a dictionary that maps model names to their classes
# inside Keras
MODELS = {
	"vgg16": VGG16,
	"vgg19": VGG19,
	"inception": InceptionV3,
	"xception": Xception, # TensorFlow ONLY
	"resnet": ResNet50
}

# esnure a valid model name was supplied via command line argument
if args\["model"\] not in MODELS.keys():
	raise AssertionError("The --model command line argument should "
		"be a key in the \`MODELS\` dictionary")

**Lines 25-31** defines our `MODELS` dictionary which maps a model name string to the corresponding class.

If the `--model` name is not found inside `MODELS` , we’ll raise an `AssertionError` (**Lines 34-36**).

A Convolutional Neural Network takes an image as an input and then returns a set of probabilities corresponding to the class labels as output.

Typical input image sizes to a Convolutional Neural Network trained on ImageNet are _224×224_, _227×227_, _256×256_, and _299×299_; however, you may see other dimensions as well.

VGG16, VGG19, and ResNet all accept _224×224_ input images while Inception V3 and Xception require _299×299_ pixel inputs, as demonstrated by the following code block:

\# initialize the input image shape (224x224 pixels) along with
# the pre-processing function (this might need to be changed
# based on which model we use to classify our image)
inputShape = (224, 224)
preprocess = imagenet\_utils.preprocess\_input

# if we are using the InceptionV3 or Xception networks, then we
# need to set the input shape to (299x299) \[rather than (224x224)\]
# and use a different image pre-processing function
if args\["model"\] in ("inception", "xception"):
	inputShape = (299, 299)
	preprocess = preprocess\_input

Here we initialize our `inputShape` to be _224×224_ pixels. We also initialize our `preprocess` function to be the standard `preprocess_input` from Keras (which performs mean subtraction).

However, if we are using Inception or Xception, we need to set the `inputShape` to _299×299_ pixels, followed by updating `preprocess` to use a _**separate pre-processing function**_ that [performs a different type of scaling](https://github.com/fchollet/keras/blob/master/keras/applications/inception_v3.py#L389).

The next step is to load our pre-trained network architecture weights from disk and instantiate our model:

\# load our the network weights from disk (NOTE: if this is the
# first time you are running this script for a given network, the
# weights will need to be downloaded first -- depending on which
# network you are using, the weights can be 90-575MB, so be
# patient; the weights will be cached and subsequent runs of this
# script will be \*much\* faster)
print("\[INFO\] loading {}...".format(args\["model"\]))
Network = MODELS\[args\["model"\]\]
model = Network(weights="imagenet")

**Line 58** uses the `MODELS` dictionary along with the `--model` command line argument to grab the correct `Network` class.

The Convolutional Neural Network is then instantiated on **Line 59** using the pre-trained ImageNet weights;

_**Note:** Weights for VGG16 and VGG19 are > 500MB. ResNet weights are ~100MB, while Inception and Xception weights are between 90-100MB. If this is the_ **_first_** _time you are running this script for a given network, these weights will be (automatically) downloaded and cached to your local disk. Depending on your internet speed, this may take awhile. However, once the weights are downloaded, they will **not** need to be downloaded again, allowing subsequent runs of `classify_image.py` to be **much** faster._

Our network is now loaded and ready to classify an image — we just need to prepare this image for classification:

\# load the input image using the Keras helper utility while ensuring
# the image is resized to \`inputShape\`, the required input dimensions
# for the ImageNet pre-trained network
print("\[INFO\] loading and pre-processing image...")
image = load\_img(args\["image"\], target\_size=inputShape)
image = img\_to\_array(image)

# our input image is now represented as a NumPy array of shape
# (inputShape\[0\], inputShape\[1\], 3) however we need to expand the
# dimension by making the shape (1, inputShape\[0\], inputShape\[1\], 3)
# so we can pass it through the network
image = np.expand\_dims(image, axis=0)

# pre-process the image using the appropriate function based on the
# model that has been loaded (i.e., mean subtraction, scaling, etc.)
image = preprocess(image)

**Line 65** loads our input image from disk using the supplied `inputShape` to resize the width and height of the image.

**Line 66** converts the image from a PIL/Pillow instance to a NumPy array.

Our input image is now represented as a NumPy array with the shape `(inputShape[0], inputShape[1], 3)` .

However, we typically train/classify images in _batches_ with Convolutional Neural Networks, so we need to add an extra dimension to the array via `np.expand_dims` on **Line 72**.

After calling `np.expand_dims` the `image` has the shape `(1, inputShape[0], inputShape[1], 3)` . Forgetting to add this extra dimension will result in an error when you call `.predict` of the `model` .

Lastly, **Line 76** calls the appropriate pre-processing function to perform mean subtraction/scaling.

We are now ready to pass our image through the network and obtain the output classifications:

\# classify the image
print("\[INFO\] classifying image with '{}'...".format(args\["model"\]))
preds = model.predict(image)
P = imagenet\_utils.decode\_predictions(preds)

# loop over the predictions and display the rank-5 predictions +
# probabilities to our terminal
for (i, (imagenetID, label, prob)) in enumerate(P\[0\]):
	print("{}. {}: {:.2f}%".format(i + 1, label, prob \* 100))

A call to `.predict` on **Line 80** returns the predictions from the Convolutional Neural Network.

Given these predictions, we pass them into the ImageNet utility function `.decode_predictions` to give us a list of ImageNet class label IDs, “human-readable” labels, and the probability associated with the labels.

The top-5 predictions (i.e., the labels with the largest probabilities) are then printed to our terminal on **Lines 85 and 86**.

The last thing we’ll do here before we close out our example is load our input image from disk via OpenCV, draw the #1 prediction on the image, and finally display the image to our screen:

\# load the image via OpenCV, draw the top prediction on the image,
# and display the image to our screen
orig = cv2.imread(args\["image"\])
(imagenetID, label, prob) = P\[0\]\[0\]
cv2.putText(orig, "Label: {}, {:.2f}%".format(label, prob \* 100),
	(10, 30), cv2.FONT\_HERSHEY\_SIMPLEX, 0.8, (0, 0, 255), 2)
cv2.imshow("Classification", orig)
cv2.waitKey(0)

To see our pre-trained ImageNet networks in action, take a look at the next section.

### VGGNet, ResNet, Inception, and Xception classification results

All _**updated**_ examples in this blog post were gathered TensorFlow 2.2. Previously this blog post used [Keras >= 2.0](https://blog.keras.io/introducing-keras-2.html?t=1) and a [TensorFlow backend](https://www.tensorflow.org/install/) (when they were separate packages) and was also tested with the Theano backend and confirmed that the implementation will work with Theano as well.

Once you have TensorFlow/Theano and Keras installed, make sure you download the source code + example images to this blog post using the **_“Downloads”_** section at the bottom of the tutorial.

From there, let’s try classifying an image with VGG16:

$ python classify\_image.py --image images/soccer\_ball.jpg --model vgg16

![Image 9](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20364'%3E%3C/svg%3E)

**Figure 8:** Classifying a soccer ball using VGG16 pre-trained on the ImageNet database using Keras ([source](https://pl.wiktionary.org/wiki/piedpilko)).

Taking a look at the output, we can see VGG16 correctly classified the image as _“soccer ball”_ with 93.43% accuracy.

To use VGG19, we simply need to change the `--model` command line argument:

$ python classify\_image.py --image images/bmw.png --model vgg19

![Image 10](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20354'%3E%3C/svg%3E)

**Figure 9:** Classifying a vehicle as “convertible” using VGG19 and Keras ([source](https://www.pinterest.com/explore/bmw-convertible/)).

VGG19 is able to correctly classify the the input image as _“convertible”_ with a probability of 91.76%. However, take a look at the other top-5 predictions: _sports car_ with 4.98% probability (which the car is), _limousine_ at 1.06% (incorrect, but still reasonable), and _“car wheel”_ at 0.75% (also technically correct since there are car wheels in the image).

We can see similar levels of top-5 accuracy in the following example where we use the pre-trained ResNet architecture:

$ python classify\_image.py --image images/clint\_eastwood.jpg --model resnet

![Image 11](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20411'%3E%3C/svg%3E)

**Figure 10:** Using ResNet pre-trained on ImageNet with Keras + Python ([source](http://i.dailymail.co.uk/i/pix/2009/09/24/article-1215766-0009B05300000258-375_468x286.jpg)).

ResNet correctly classifies this image of Clint Eastwood holding a gun as _“revolver”_ with 69.79% accuracy. It’s also interesting to see _“rifle”_ at 7.74% and _“assault rifle”_ at 5.63% included in the top-5 predictions as well. Given the viewing angle of the revolver and the substantial length of the barrel (for a handgun) it’s easy to see how a Convolutional Neural Network would also return higher probabilities for a rifle as well.

This next example attempts to classify the species of dog using ResNet:

$ python classify\_image.py --image images/jemma.png --model resnet

![Image 12](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20559'%3E%3C/svg%3E)

**Figure 11:** Classifying dog species using ResNet, Keras, and Python.

The species of dog is correctly identified as _“beagle”_ with 94.48% confidence.

I then tried classifying the following image of Johnny Depp from the _Pirates of the Caribbean_ franchise:

$ python classify\_image.py --image images/boat.png --model inception

![Image 13](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20354'%3E%3C/svg%3E)

**Figure 12:** Classifying a ship wreck with ResNet pre-trained on ImageNet with Keras ([source](https://www.aliexpress.com/item/Pirates-Of-The-Caribbean-Boats-Ship-Boy-Nature-Tropical-Sea-Waves-Trees-Tv-Movie-Film-Poster/32607808033.html)).

While there is indeed a _“boat”_ class in ImageNet, it’s interesting to see that the Inception network was able to correctly identify the scene as a _“(ship) wreck”_ with 96.29% probability. All other predicted labels, including _“seashore”, “canoe”, “paddle”,_ and _“breakwater”_ are all relevant, and in some cases absolutely correct as well.

For another example of the Inception network in action, I took a photo of the couch sitting in my office:

$ python classify\_image.py --image images/office.png --model inception

![Image 14](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20366'%3E%3C/svg%3E)

**Figure 13:** Recognizing various objects in an image with Inception V3, Python, and Keras.

Inception correctly predicts there is a _“table lamp”_ in the image with 69.68% confidence. The other top-5 predictions are also dead-on, including a _“studio couch”_, _“window shade”_ (far right of the image, barely even noticeable), _“lampshade”_, and _“pillow”_.

In the context above, Inception wasn’t even used as an object detector, but it was still able to classify all parts of the image within its top-5 predictions. It’s no wonder that Convolutional Neural Networks make for excellent object detectors!

Moving on to Xception:

$ python classify\_image.py --image images/scotch.png --model xception

![Image 15](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20337'%3E%3C/svg%3E)

**Figure 14:** Using the Xception network architecture to classify an image ([source](http://www.slrmag.co.uk/lagavulin-rolls-out-the-barrel-to-mark-double-century/)).

Here we have an image of scotch barrels, specifically my favorite scotch, Lagavulin. Xception correctly classifies this image as _“barrels”_.

This last example was classified using VGG16:

$ python classify\_image.py --image images/tv.png --model vgg16

![Image 16](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20328'%3E%3C/svg%3E)

**Figure 15:** VGG16 pre-trained on ImageNet with Keras.

The image itself was captured a few months ago as I was finishing up _The Witcher III: The Wild Hunt_ (easily in my top-3 favorite games of all time). The first prediction by VGG16 is _“home theatre”_ — a reasonable prediction given that there is a _“television/monitor”_ in the top-5 predictions as well.

As you can see from the examples in this blog post, networks pre-trained on the ImageNet dataset are capable of recognizing a variety of common day-to-day objects. I hope that you can use this code in your own projects!

### What's next? We recommend [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend).

**Course information:**  
84 total classes • 114+ hours of on-demand code walkthrough videos • Last updated: February 2024  
★★★★★ 4.84 (128 Ratings) • 16,000+ Students Enrolled

**I strongly believe that if you had the right teacher you could _master_ computer vision and deep learning.**

Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?

That’s _not_ the case.

All you need to master computer vision and deep learning is for someone to explain things to you in _simple, intuitive_ terms. _And that’s exactly what I do_. My mission is to change education and how complex Artificial Intelligence topics are taught.

If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to _successfully_ and _confidently_ apply computer vision to your work, research, and projects. Join me in computer vision mastery.

**Inside PyImageSearch University you'll find:**

*   ✓ **84 courses** on essential computer vision, deep learning, and OpenCV topics
*   ✓ **84 Certificates** of Completion
*   ✓ **114+ hours** of on-demand video
*   ✓ **Brand new courses released _regularly_**, ensuring you can keep up with state-of-the-art techniques
*   ✓ **Pre-configured Jupyter Notebooks in Google Colab**
*   ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
*   ✓ Access to **centralized code repos for _all_ 536+ tutorials** on PyImageSearch
*   ✓ **Easy one-click downloads** for code, datasets, pre-trained models, etc.
*   ✓ **Access** on mobile, laptop, desktop, etc.

[Click here to join PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend)

Summary
-------

In today’s blog post we reviewed the five Convolutional Neural Networks pre-trained on the ImageNet dataset inside the Keras library:

1.  VGG16
2.  VGG19
3.  ResNet50
4.  Inception V3
5.  Xception

I then demonstrated how to use each of these architectures to classify your own input images using the Keras library and the Python programming language.

**If you are interested in learning more about deep learning and Convolutional Neural Networks (and how to train your own networks from scratch), be sure to take a look at my book, [_Deep Learning for Computer Vision with Python_](https://pyimagesearch.com/deep-learning-computer-vision-python-book/), available for order now.**

![Image 17](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20410%20567'%3E%3C/svg%3E)

#### Download the Source Code and FREE 17-page Resource Guide

Enter your email address below to get a .zip of the code and a **FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning.** Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!