Title: Keras - Save and Load Your Deep Learning Models - PyImageSearch

URL Source: https://pyimagesearch.com/2018/12/10/keras-save-and-load-your-deep-learning-models/

Published Time: 2018-12-10T15:00:03+00:00

Markdown Content:
[![Image 1](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20373'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2018/12/keras_save_load_header.png)

In this tutorial, you will learn how to save and load your Keras deep learning models.

This blog post was inspired by PyImageSearch reader, Mason, who emailed in last week and asked:

> Adrian, I’ve been going through your blog and reading your deep learning tutorials. Thanks for them.
> 
> I have a question though:
> 
> After training, how do you save your Keras model?
> 
> And once you have it saved, how do you load it again so you can classify new images?
> 
> I know this is a basic question but I don’t know how to save and load my Keras models.

Mason asks an excellent question — **and it’s actually not as “basic” of a concept as he (and maybe even you) may think.**

On the surface, saving your Keras models is as simple as calling the `model.save` and `load_model` function. **But there’s actually _more to consider_ than just the load and save model functions!**

**What’s _even more important_, and sometimes overlooked by new deep learning practitioners, is the _preprocessing stage_** — your preprocessing steps for training and validation must be _identical_ to the training steps when loading your model and classifying new images.

**In the remainder of today’s tutorial we’ll be exploring:**

1.  How to properly save and load your Keras deep learning models.
2.  The proper steps to preprocess your images after loading your model.

**To learn how to save and load your deep learning models with Keras, _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-03 Update:** This blog post is now TensorFlow 2+ compatible!_

In the first part of this tutorial, we’ll briefly review both (1) our example dataset we’ll be training a Keras model on, along with (2) our project directory structure. From there I will show you how to:

1.  Train a deep learning model with Keras
2.  Serialize and save your Keras model to disk
3.  Load your saved Keras model from disk
4.  Make predictions on new image data using your saved Keras model

Let’s go ahead and get started!

### Configuring your development environment

To configure your system for this tutorial, I first 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/).

### Our example dataset

[![Image 3](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20264'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2018/12/dl_medical_imaging_malaria_dataset.jpg)

**Figure 1:** A subset of the [Malaria Dataset provided by the National Institute of Health](https://ceb.nlm.nih.gov/repositories/malaria-datasets/) (NIH). We will use this dataset to develop a deep learning medical imaging classification model saved to disk with Python, OpenCV, and Keras.

The dataset we’ll be utilizing for today’s tutorial is a subset of the malaria detection and classification dataset we covered in last week’s _[Deep learning and Medical Image Analysis with Keras](https://pyimagesearch.com/2018/12/03/deep-learning-and-medical-image-analysis-with-keras/)_ blog post.

The original dataset consists of 27,588 images belonging to two classes:

1.  **Parasitized:** Implying that the image contains malaria
2.  **Uninfected:** Meaning there is no evidence of malaria in the image

Since the goal of this tutorial is not medical image analysis, but rather how to save and load your Keras models, **I have sampled the dataset down to 100 images.**

I have reduced the dataset size mainly because:

1.  You should be able to run this example on your CPU (if you do not own/have access to a GPU).
2.  Our goal here is to teach the basic concept of saving and loading Keras models, not train a state-of-the-art malaria detector.
3.  And because of that, it’s better to work with a smaller example dataset

If you would like to read my full blog post on how to build a (near) state-of-the-art malaria classifier with the full dataset, please be sure to refer to [this blog post](https://pyimagesearch.com/2018/12/03/deep-learning-and-medical-image-analysis-with-keras/).

### Project structure

Be sure to grab today’s _**“Downloads”**_ consisting of the reduced dataset, ResNet model, and Python scripts.

Once you’ve unzipped the files you’ll be presented with this directory structure:

$ tree --filelimit 10 --dirsfirst
.
├── malaria
│   ├── testing
│   │   ├── Parasitized \[50 entries\]
│   │   └── Uninfected \[50 entries\]
│   ├── training
│   │   ├── Parasitized \[175 entries\]
│   │   └── Uninfected \[185 entries\]
│   └── validation
│       ├── Parasitized \[18 entries\]
│       └── Uninfected \[22 entries\]
├── pyimagesearch
│   ├── \_\_init\_\_.py
│   └── resnet.py
├── save\_model.py
└── load\_model.py

11 directories, 4 files

Our project consists of two folders in the root directory:

*   `malaria/` : Our reduced Malaria dataset. It is organized into training, validation, and testing sets via the “build dataset” script from last week.
*   `pyimagesearch/` : A package included with the downloads which contains our ResNet model class.

Today, we’ll review two Python scripts as well:

*   `save_model.py` : A demo script which will save our Keras model to disk after it has been trained.
*   `load_model.py` : Our script that loads the saved model from disk and classifies a small selection of testing images.

By reviewing these files, you’ll quickly see how easy Keras makes saving and loading deep learning model files.

### Saving a model with Keras and TensorFlow

[![Image 4](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20400%20419'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2018/12/keras_save_load_diagram01.png)

**Figure 2:** The steps for training and saving a Keras deep learning model to disk.

Before we can load a Keras model from disk we first need to:

1.  Train the Keras model
2.  Save the Keras model

The `save_model.py` script we’re about to review will cover both of these concepts.

Go ahead and open up your `save_model.py` file and let’s get started:

\# set the matplotlib backend so figures can be saved in the background
import matplotlib
matplotlib.use("Agg")

# import the necessary packages
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import SGD
from pyimagesearch.resnet import ResNet
from sklearn.metrics import classification\_report
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import os

We begin on **Lines 2-14** by importing required packages.

On **Line 3** the `"Agg"` matplotlib backend is specified as we’ll be saving our plot to disk (in addition to our model).

Our `ResNet` CNN is imported on **Line 8**. In order to use this CNN, be sure to grab the _**“Downloads”**_ for today’s blog post.

Using the `argparse` import, let’s [parse our command line arguments](https://pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/):

\# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-d", "--dataset", type=str, required=True,
	help="path dataset of input images")
ap.add\_argument("-m", "--model", type=str, required=True,
	help="path to trained model")
ap.add\_argument("-p", "--plot", type=str, default="plot.png",
	help="path to output loss/accuracy plot")
args = vars(ap.parse\_args())

Our script requires that three arguments be provided with the command string in your terminal:

*   `--dataset` : The path to our dataset. We’re using a subset of the [Malaria dataset that we built last week](https://pyimagesearch.com/2018/12/03/deep-learning-and-medical-image-analysis-with-keras/).
*   `--model` : You need to specify the path to the trained output model (i.e., where the Keras model is going to be saved). _This is key for what we are covering today._
*   `--plot` : The path to the training plot. By default, the figure will be named `plot.png` .

No modifications are needed for these lines of code. Again, you will need to type the values for the arguments in the terminal and let `argparse` do the rest. If you are unfamiliar with the concept of command line arguments, [see this post](https://pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/).

Let’s initialize our training variables and paths:

\# initialize the number of training epochs and batch size
NUM\_EPOCHS = 25
BS = 32

# derive the path to the directories containing the training,
# validation, and testing splits, respectively
TRAIN\_PATH = os.path.sep.join(\[args\["dataset"\], "training"\])
VAL\_PATH = os.path.sep.join(\[args\["dataset"\], "validation"\])
TEST\_PATH = os.path.sep.join(\[args\["dataset"\], "testing"\])

# determine the total number of image paths in training, validation,
# and testing directories
totalTrain = len(list(paths.list\_images(TRAIN\_PATH)))
totalVal = len(list(paths.list\_images(VAL\_PATH)))
totalTest = len(list(paths.list\_images(TEST\_PATH)))

We’ll be training for `25` epochs with a batch size of `32` .

Last week, we split the NIH Malaria Dataset into three sets, creating a corresponding directory for each:

*   Training
*   Validation
*   Testing

Be sure to review the `build_dataset.py` script [in the tutorial](https://pyimagesearch.com/2018/12/03/deep-learning-and-medical-image-analysis-with-keras/) if you’re curious how the data split process works. For today, I’ve taken the resulting dataset that has been split (as well as made is significantly smaller for the purposes of this blog post).

The images paths are built on **Lines 32-34**, and the number of images in each split is grabbed on **Lines 38-40**.

Let’s initialize our data augmentation objects:

\# initialize the training training data augmentation object
trainAug = ImageDataGenerator(
	rescale=1 / 255.0,
	rotation\_range=20,
	zoom\_range=0.05,
	width\_shift\_range=0.05,
	height\_shift\_range=0.05,
	shear\_range=0.05,
	horizontal\_flip=True,
	fill\_mode="nearest")

# initialize the validation (and testing) data augmentation object
valAug = ImageDataGenerator(rescale=1 / 255.0)

Data augmentation is the process of generating new images from a dataset with random modifications. It results in a better deep learning model and I almost always recommend it (it is especially important for small datasets).

Data augmentation is briefly covered in my [_Keras Tutorial_](https://pyimagesearch.com/2018/09/10/keras-tutorial-how-to-get-started-with-keras-deep-learning-and-python/) blog post. For a full dive into data augmentation be sure to read my deep learning book, **[_Deep Learning for Computer Vision with Python_](https://pyimagesearch.com/deep-learning-computer-vision-python-book/)**.

_**Note:**_ _The `valAug` object simply performs scaling — no augmentation is actually performed. We’ll be using this object twice: once for validation rescaling and once for testing rescaling._

Now that the training and validation augmentation objects are created, let’s initialize the generators:

\# initialize the training generator
trainGen = trainAug.flow\_from\_directory(
	TRAIN\_PATH,
	class\_mode="categorical",
	target\_size=(64, 64),
	color\_mode="rgb",
	shuffle=True,
	batch\_size=32)

# initialize the validation generator
valGen = valAug.flow\_from\_directory(
	VAL\_PATH,
	class\_mode="categorical",
	target\_size=(64, 64),
	color\_mode="rgb",
	shuffle=False,
	batch\_size=BS)

# initialize the testing generator
testGen = valAug.flow\_from\_directory(
	TEST\_PATH,
	class\_mode="categorical",
	target\_size=(64, 64),
	color\_mode="rgb",
	shuffle=False,
	batch\_size=BS)

The three generators above actually produce images on demand during training/validation/testing per our augmentation objects and the parameters given here.

Now we’re going to build, compile, and train our model. We’ll also evaluate our model and print a classification report:

\# initialize our Keras implementation of ResNet model and compile it
model = ResNet.build(64, 64, 3, 2, (2, 2, 3),
	(32, 64, 128, 256), reg=0.0005)
opt = SGD(lr=1e-1, momentum=0.9, decay=1e-1 / NUM\_EPOCHS)
model.compile(loss="binary\_crossentropy", optimizer=opt,
	metrics=\["accuracy"\])

# train our Keras model
H = model.fit(
	x=trainGen,
	steps\_per\_epoch=totalTrain // BS,
	validation\_data=valGen,
	validation\_steps=totalVal // BS,
	epochs=NUM\_EPOCHS)

# reset the testing generator and then use our trained model to
# make predictions on the data
print("\[INFO\] evaluating network...")
testGen.reset()
predIdxs = model.predict(x=testGen, steps=(totalTest // BS) + 1)

# for each image in the testing set we need to find the index of the
# label with corresponding largest predicted probability
predIdxs = np.argmax(predIdxs, axis=1)

# show a nicely formatted classification report
print(classification\_report(testGen.classes, predIdxs,
	target\_names=testGen.class\_indices.keys()))

_**2020-06-03 Update:** Formerly, TensorFlow/Keras required use of a method called `.fit_generator` in order to accomplish data augmentation. Now, the `.fit` method can handle data augmentation as well, making for more-consistent code. This also applies to the migration from `.predict_generator` to `.predict`. Be sure to check out my articles about [fit and fit generator](https://pyimagesearch.com/2018/12/24/how-to-use-keras-fit-and-fit_generator-a-hands-on-tutorial/) as well as [data augmentation](https://pyimagesearch.com/2019/07/08/keras-imagedatagenerator-and-data-augmentation/)._

In the code block above, we:

*   Initialize our implementation of `ResNet` on **Lines 84-88** (from [_Deep Learning for Computer Vision with Python_](https://pyimagesearch.com/deep-learning-computer-vision-python-book/)). Notice how we’ve specified `"binary_crossentropy"` because our model has two classes. You should change it to `"categorical_crossentropy"` if you are working with > 2 classes.
*   Train the ResNet `model` on the augmented Malaria dataset (**Lines 91-96**).
*   Make predictions on test set (**Line 102**) and extract the highest probability class index for each prediction (**Line 106**).
*   Display a `classification_report` in our terminal (**Lines 109-110**).

Now that our model is trained let’s **save our Keras model to disk:**

\# save the network to disk
print("\[INFO\] serializing network to '{}'...".format(args\["model"\]))
model.save(args\["model"\], save\_format="h5")

To save our Keras model to disk, we simply call `.save` on the `model` (**Line 114**).

_**2020-06-03 Update:** Note that for TensorFlow 2.0+ we recommend explicitly setting the `save_format="h5"` (HDF5 format)._

Simple right?

Yes, it is a simple function call, but the hard work before it made the process possible.

In our next script, we’ll be able to load the model from disk and make predictions.

Let’s plot the training results and save the training plot as well:

\# plot the training loss and accuracy
N = NUM\_EPOCHS
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, N), H.history\["loss"\], label="train\_loss")
plt.plot(np.arange(0, N), H.history\["val\_loss"\], label="val\_loss")
plt.plot(np.arange(0, N), H.history\["accuracy"\], label="train\_acc")
plt.plot(np.arange(0, N), H.history\["val\_accuracy"\], label="val\_acc")
plt.title("Training Loss and Accuracy on Dataset")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.savefig(args\["plot"\])

_**2020-06-03 Update:** In order for this plotting snippet to be TensorFlow 2+ compatible the `H.history` dictionary keys are updated to fully spell out “accuracy” sans “acc” (i.e., `H.history["val_accuracy"]` and `H.history["accuracy"]`). It is semi-confusing that “val” is not spelled out as “validation”; we have to learn to love and live with the API and always remember that it is a work in progress that many developers around the world contribute to._

At this point our script is complete. Let’s go ahead and train our Keras model!

* * *

To train your Keras model on our example dataset, make sure you use the _**“Downloads”**_ section of the blog post to download the source code and images themselves.

From there, open up a terminal and execute the following command:

$ python save\_model.py --dataset malaria --model saved\_model.model
Found 360 images belonging to 2 classes.
Found 40 images belonging to 2 classes.
Found 100 images belonging to 2 classes.
Epoch 1/25
11/11 \[==============================\] - 10s 880ms/step - loss: 0.9204 - accuracy: 0.5686 - val\_loss: 7.0116 - val\_accuracy: 0.5625
Epoch 2/25
11/11 \[==============================\] - 7s 624ms/step - loss: 0.8821 - accuracy: 0.5899 - val\_loss: 1.4123 - val\_accuracy: 0.4375
Epoch 3/25
11/11 \[==============================\] - 7s 624ms/step - loss: 0.9426 - accuracy: 0.5878 - val\_loss: 0.8156 - val\_accuracy: 0.6562
...
Epoch 23/25
11/11 \[==============================\] - 7s 664ms/step - loss: 0.3372 - accuracy: 0.9659 - val\_loss: 0.2396 - val\_accuracy: 0.9688
Epoch 24/25
11/11 \[==============================\] - 7s 622ms/step - loss: 0.3035 - accuracy: 0.9514 - val\_loss: 0.3389 - val\_accuracy: 0.9375
Epoch 25/25
11/11 \[==============================\] - 7s 624ms/step - loss: 0.2934 - accuracy: 0.9543 - val\_loss: 0.2876 - val\_accuracy: 0.9375
\[INFO\] evaluating network...
              precision    recall  f1-score   support

 Parasitized       0.98      1.00      0.99        50
  Uninfected       1.00      0.98      0.99        50

    accuracy                           0.99       100
   macro avg       0.99      0.99      0.99       100
weighted avg       0.99      0.99      0.99       100

\[INFO\] serializing network to 'saved\_model.model'...

Notice the command line arguments. I’ve specified the path to the Malaria dataset directory (`--dataset malaria` ) and the path to our destination model (`--model saved_model.model` ). These command line arguments are key to the operation of this script. You can name your model whatever you’d like _without changing a line of code!_

Here you can see that our model is obtaining **~99% accuracy** on the test set.

Each epoch is taking **~7 seconds** on my CPU. On my GPU each epoch takes **~1 second**. Keep in mind that training is faster than last week because we’re pushing less data through the network for each epoch due to the fact that I reduced today’s dataset.

After training you can list the contents of your directory and see the saved Keras model:

$ ls -l
total 5216
-rw-r--r--@ 1 adrian  staff     2415 Nov 28 10:09 load\_model.py
drwxr-xr-x@ 5 adrian  staff      160 Nov 28 08:12 malaria
-rw-r--r--@ 1 adrian  staff    38345 Nov 28 10:13 plot.png
drwxr-xr-x@ 6 adrian  staff      192 Nov 28 08:12 pyimagesearch
-rw-r--r--@ 1 adrian  staff     4114 Nov 28 10:09 save\_model.py
-rw-r--r--@ 1 adrian  staff  2614136 Nov 28 10:13 saved\_model.model

[![Image 5](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20345'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2018/12/keras_save_load_model.png)

**Figure 3:** Our Keras model is now residing on disk. Saving Keras models is quite easy via the Keras API.

The `saved_model.model` file is your actual saved Keras model.

You will learn how to load your saved Keras model from disk in the next section.

### Loading a model with Keras and TensorFlow

[![Image 6](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20500%20137'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2018/12/keras_save_load_diagram02.png)

**Figure 4:** The process of loading a Keras model from disk and putting it to use to make predictions. Don’t forget to preprocess your data in the same manner as during training!

Now that we’ve learned how to save a Keras model to disk, the next step is to load the Keras model so we can use it for making classifications. Open up your `load_model.py` script and let’s get started:

\# import the necessary packages
from tensorflow.keras.preprocessing.image import img\_to\_array
from tensorflow.keras.models import load\_model
from imutils import build\_montages
from imutils import paths
import numpy as np
import argparse
import random
import cv2

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-i", "--images", required=True,
	help="path to out input directory of images")
ap.add\_argument("-m", "--model", required=True,
	help="path to pre-trained model")
args = vars(ap.parse\_args())

We import our required packages on **Lines 2-10**. Most notably we need `load_model` in order to load our model from disk and put it to use.

Our two command line arguments are parsed on **Lines 12-17**:

*   `--images` : The path to the images we’d like to make predictions with.
*   `--model` : The path to the model we just saved previously.

Again, these lines don’t need to change. When you enter the command in your terminal you’ll provide values for both `--images` and `--model` .

**The next step is to load our Keras model from disk:**

\# load the pre-trained network
print("\[INFO\] loading pre-trained network...")
model = load\_model(args\["model"\])

On **Line 21**, to load our Keras `model` , we call `load_model` , providing the path to the model itself (contained within our parsed `args` dictionary).

Given the `model` , we can now make predictions with it. But first we’ll need some images to work with and a place to put our results:

\# grab all image paths in the input directory and randomly sample them
imagePaths = list(paths.list\_images(args\["images"\]))
random.shuffle(imagePaths)
imagePaths = imagePaths\[:16\]

# initialize our list of results
results = \[\]

On **Lines 24-26**, we grab a random selection of testing image paths.

**Line 29** initializes an empty list to hold the `results` .

Let’s loop over each of our `imagePaths` :

\# loop over our sampled image paths
for p in imagePaths:
	# load our original input image
	orig = cv2.imread(p)

	# pre-process our image by converting it from BGR to RGB channel
	# ordering (since our Keras mdoel was trained on RGB ordering),
	# resize it to 64x64 pixels, and then scale the pixel intensities
	# to the range \[0, 1\]
	image = cv2.cvtColor(orig, cv2.COLOR\_BGR2RGB)
	image = cv2.resize(image, (64, 64))
	image = image.astype("float") / 255.0

On **Line 32** we begin looping over our `imagePaths` .

We begin the loop by loading our image from disk (**Line 34**) and preprocessing it (**Lines 40-42**). These preprocessing steps should be _**identical**_ to those taken in our training script. As you can see, we’ve converted the images from BGR to RGB channel ordering, resized to 64×64 pixels, and scaled to the range _\[0, 1\]_.

**A _common mistake_ I see new deep learning practitioners make is _failing to preprocess new images_ in the same manner as their training images.**

Moving on, let’s make a prediction an `image` each iteration of the loop:

	# order channel dimensions (channels-first or channels-last)
	# depending on our Keras backend, then add a batch dimension to
	# the image
	image = img\_to\_array(image)
	image = np.expand\_dims(image, axis=0)

	# make predictions on the input image
	pred = model.predict(image)
	pred = pred.argmax(axis=1)\[0\]

	# an index of zero is the 'parasitized' label while an index of
	# one is the 'uninfected' label
	label = "Parasitized" if pred == 0 else "Uninfected"
	color = (0, 0, 255) if pred == 0 else (0, 255, 0)

	# resize our original input (so we can better visualize it) and
	# then draw the label on the image
	orig = cv2.resize(orig, (128, 128))
	cv2.putText(orig, label, (3, 20), cv2.FONT\_HERSHEY\_SIMPLEX, 0.5,
		color, 2)

	# add the output image to our list of results
	results.append(orig)

In this block we:

*   Handle channel ordering (**Line 47**). The TensorFlow backend default is `"channels_first"` , but don’t forget that Keras supports alternative backends as well.
*   Create a batch to send through the network by adding a dimension to the volume (**Line 48**). We’re just sending one image through the network at a time, but the additional dimension is critical.
*   Pass image through ResNet `model` (**Line 51**), obtaining a prediction. We take the index of the max prediction (either `"Parasitized"` or `"Uninfected"` ) on **Line 52**.
*   Then we create a colored label and draw it on the original image (**Lines 56-63**).
*   Finally, we append the annotated `orig` image to `results` .

To visualize our results let’s create a montage and display it on the screen:

\# create a montage using 128x128 "tiles" with 4 rows and 4 columns
montage = build\_montages(results, (128, 128), (4, 4))\[0\]

# show the output montage
cv2.imshow("Results", montage)
cv2.waitKey(0)

A `montage` of results is built on **Line 69**. Our `montage` is a 4×4 grid of images to accommodate the 16 random testing images we grabbed earlier on. Learn how this function works in my blog post, [_Montages with OpenCV_](https://pyimagesearch.com/2017/05/29/montages-with-opencv/).

The `montage` will be displayed until any key is pressed (**Lines 72 and 73**).

* * *

To see our script in action make sure you use the _**“Downloads”**_ section of the tutorial to download the source code and dataset of images.

From there, open up a terminal and execute the following command:

$ python load\_model.py --images malaria/testing --model saved\_model.model
Using TensorFlow backend.
\[INFO\] loading pre-trained network...

[![Image 7](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20625'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2018/12/keras_save_load_results.jpg)

**Figure 5:** A montage of cells either “Parasitized” or “Uninfected” with Malaria. In today’s blog post we saved a ResNet deep learning model to disk and then loaded it with a separate script to make these predictions.

Here you can see that we have:

1.  Provided the path to our testing images (`--images malaria/testing` ) as well as the model already residing on disk (`--model saved_model.model` ) via command line argument
2.  Loaded our Keras model from disk
3.  Preprocessed our input images
4.  Classified each of the example images
5.  Constructed an output visualization of our classifications (**Figure 5**)

This process was made possible due to the fact we were able to save our Keras model from disk in the training script and then load the Keras model from disk in a separate script.

### 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 tutorial you learned:**

1.  How to train a Keras model on a dataset
2.  How to serialize and save your Keras model to disk
3.  How to load your saved Keras model from a separate Python script
4.  How to classify new input images using your loaded Keras model

You can use the Python scripts covered in today’s tutorial as templates when training, saving, and loading your own Keras models.

I hope you enjoyed today’s blog post!

**To download the source code to today’s tutorial, and be notified when future blog posts are published here on PyImageSearch, _just enter your email address in the form below!_**

![Image 8](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!