Title: Visualizing network architectures using Keras and TensorFlow - PyImageSearch

URL Source: https://pyimagesearch.com/2021/05/22/visualizing-network-architectures-using-keras-and-tensorflow/

Published Time: 2021-05-22T14:00:00+00:00

Markdown Content:
One concept we have not discussed yet is _architecture visualization_, the process of constructing a _graph_ of nodes and associated connections in a network and saving the graph to disk as an image (i.e., PNG, JPG, etc.). Nodes in the graphs represent layers, while connections between nodes represent the flow of data through the network.

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

These graphs typically include the following components for each layer:

1.  The _input_ volume size.
2.  The _output_ volume size.
3.  And optionally the _name_ of the layer.

We typically use network architecture visualization when (1) debugging our own custom network architectures and (2) publication, where a visualization of the architecture is easier to understand than including the actual source code or trying to construct a table to convey the same information. In the remainder of this tutorial, you will learn how to construct network architecture visualization graphs using Keras, followed by serializing the graph to disk as an actual image.

**To learn how to **visualize network architectures using Keras and TensorFlow**, _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)

**The Importance of Architecture Visualization**
------------------------------------------------

Visualizing the architecture of a model is a critical debugging tool, _especially_ if you are:

1.  Implementing an architecture in a publication, but are unfamiliar with it.
2.  Implementing your own custom network architecture.

In short, network visualization _validates our assumptions_ that our code is correctly building the model we are intending to construct. By examining the output graph image, you can see if there is a flaw in your logic. The most common flaws include:

1.  Incorrectly ordering layers in the network.
2.  Assuming an (incorrect) output volume size after a `CONV` or `POOL` layer.

Whenever implementing a network architecture, I suggest you visualize the network architecture after every block of `CONV` and `POOL` layers, which will enable you to validate your assumptions (and more importantly, catch “bugs” in the network early on).

Bugs in Convolutional Neural Networks are not like other logic bugs in applications resulting from edge cases. Instead, a CNN very well may train and obtain reasonable results even with an incorrect layer ordering, but if you don’t _realize_ that this bug has happened, you might report your results thinking you did one thing, but in reality did another.

In the remainder of this tutorial, I’ll help you visualize your own network architectures to avoid these types of problematic situations.

### **Configuring your development environment**

To follow this guide, you need to have the OpenCV library installed on your system.

Luckily, OpenCV is pip-installable:

$ pip install opencv-contrib-python

**If you need help configuring your development environment for OpenCV, I _highly recommend_ that you read my** [**_pip install OpenCV_ guide**](https://pyimagesearch.com/2018/09/19/pip-install-opencv/) — it will have you up and running in a matter of minutes.

### **Having problems configuring your development environment?**

[![Image 3](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20500%20334'%3E%3C/svg%3E)](https://pyimagesearch.com/pyimagesearch-university/)

**Figure 1:** Having trouble configuring your dev environment? Want access to pre-configured Jupyter Notebooks running on Google Colab? Be sure to join [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/) — you’ll be up and running with this tutorial in a matter of minutes.

All that said, are you:

*   Short on time?
*   Learning on your employer’s administratively locked system?
*   Wanting to skip the hassle of fighting with the command line, package managers, and virtual environments?
*   **Ready to run the code** **_right now_** **on your Windows, macOS, or Linux system?**

Then join [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/) today!

**Gain access to Jupyter Notebooks for this tutorial and other PyImageSearch guides that are** **_pre-configured_** **to run on Google Colab’s ecosystem right in your web browser!** No installation required.

And best of all, these Jupyter Notebooks will run on Windows, macOS, and Linux!

### **Installing graphviz and pydot**

To construct a graph of our network and save it to disk using Keras, we need to install the `graphviz` prerequisite:

On Ubuntu, this is as simple as:

$ sudo apt-get install graphviz

While on macOS, we can install `graphviz` via Homebrew:

$ brew install graphviz

Once the `graphviz` library is installed, we need to install two Python packages:

$ pip install graphviz
$ pip install pydot

### **Visualizing Keras Networks**

Visualizing network architectures with Keras is incredibly simple. To see how easy it is, open a new file, name it `visualize_architecture.py` and insert the following code:

\# import the necessary packages
from pyimagesearch.nn.conv import LeNet
from tensorflow.keras.utils import plot\_model

# initialize LeNet and then write the network architecture
# visualization graph to disk
model = LeNet.build(28, 28, 1, 10)
plot\_model(model, to\_file="lenet.png", show\_shapes=True)

**Line 2** imports our implementation of LeNet (**[earlier tutorial](https://pyimagesearch.com/2021/05/22/lenet-recognizing-handwritten-digits/)**) — this is the network architecture that we’ll be visualizing. **Line 3** imports the `plot_model` function from Keras. As this function name suggests, `plot_model` is responsible for constructing a graph based on the layers inside the input model and then writing the graph to disk an image.

On **Line 7**, we instantiate the LeNet architecture as if we were going to apply it to MNIST for digit classification. The parameters include the width of the input volume (28 pixels), the height (28 pixels), the depth (1 channel), and the total number of class labels (10).

Finally, **Line 8** plots our `model` saves it to disk under the name `lenet.png`.

To execute our script, just open a terminal and issue the following command:

$ python visualize\_architecture.py

Once the command successfully exists, check your current working directory:

$ ls
lenet.png  visualize\_architecture.py

As you’ll see, there is a file named `lenet.png` — this file is our actual network visualization graph. Open it up and examine it **(Figures 2 and 3**).

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

**Figure 2:** Part I of a graphical depiction of the LeNet network architecture generated by Keras. Each node in the graph represents a specific layer function (i.e., convolution, pooling, activation, flattening, fully connected, etc.). Arrows represent the flow of data through the network. Each node also includes the volume input size and output size after a given operation.

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

**Figure 3:** Part II of the LeNet architecture visualization, including the fully connected layers and softmax classifier. In this case, we assume our instantiation of LeNet will be used with the MNIST dataset so we have ten total output nodes in our final softmax layer.

Here, we can see a visualization of the data flow through our network. Each layer is represented as a node in the architecture which are then connected to other layers, ultimately terminating after the softmax classifier is applied. Notice how each layer in the network includes an `input` and `output` attribute — these values are the size of the respective volume’s spatial dimensions when it _enters_ the layer and after it _exits_ the layer.

Walking through the LeNet architecture, we see the first layer is our `InputLayer` which accepts a 28_×_28_×_1 input image. The spatial dimensions for the input and output of the layer are the same as this is simply a “placeholder” for the input data.

You might be wondering what the `None` represents in the data shape `(None, 28, 28, 1)`. The `None` is actually our batch size. When visualizing the network architecture, Keras does not know our intended batch size so it leaves the value as `None`. When training this value would change to 32, 64, 128, etc., or whatever batch size we deemed appropriate.

Next, our data flows to the first `CONV` layer, where we learn 20 kernels on the 28_×_28_×_1 input. The output of this first `CONV` layer is 28_×_28_×_20\. We have retained our original spatial dimensions due to zero padding, but by learning 20 filters we have changed the volume size.

An activation layer follows the `CONV` layer, which by definition cannot change the input volume size. However, a `POOL` operation _can_ reduce the volume size — here our input volume is reduced from 28_×_28_×_20 down to 14_×_14_×_20.

The second `CONV` accepts the 14_×_14_×_20 volume as input, but then learns 50 filters, changing the output volume size to 14_×_14_×_50 (again, zero padding is leveraged to ensure the convolution itself does not reduce the width and height of the input). An activation is applied prior to another `POOL` operation which again halves the width and height from 14_×_14_×_50 down to 7_×_7_×_50.

At this point, we are ready to apply our `FC` layers. To accomplish this, our 7_×_7_×_50 input is flattened into a list of _2,450_ values (since 7_×_7_×_50 = 2_,_450). Now that we have flattened the output of the convolutional part of our network, we can apply an `FC` layer that accepts the 2,450 input values and learns 500 nodes. An activation follows, followed by another `FC` layer, this time reducing 500 down to 10 (the total number of class labels for the MNIST dataset).

Finally, a softmax classifier is applied to each of the 10 input nodes, giving us our final class probabilities.

### 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**
-----------

Just as we can express the LeNet architecture in code, we can also visualize the model itself as an image. As you get started on your deep learning journey, I _highly encourage_ you to use this code to visualize any networks you are working with, _especially_ if you are unfamiliar with them. Ensuring you understand the flow of data through the network and how the volume sizes change based on `CONV`, `POOL`, and `FC` layers will give you a dramatically more intimate understanding of the architecture rather than relying on code alone.

When implementing my own network architectures, I validate that I’m on the right track by visualizing the architecture every 2-3 layer blocks _as I’m actually coding the network_ — this action helps me find bugs or flaws in my logic early on.

**To download the source code to this post (and be notified when future tutorials are published here on PyImageSearch), _simply enter your email address in the form below!_**

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