# A simple neural network with Python and Keras

If you’ve been following along with this series of blog posts, then you already know what a huge fan I am of Keras.

Keras is a super powerful, easy to use Python library for building neural networks and deep learning networks.

In the remainder of this blog post, I’ll demonstrate how to build a simple neural network using Python and Keras, and then apply it to the task of image classification.

Looking for the source code to this post?

## A simple neural network with Python and Keras

To start this post, we’ll quickly review the most common neural network architecture — feedforward networks.

We’ll then discuss our project structure followed by writing some Python code to define our feedforward neural network and specifically apply it to the Kaggle Dogs vs. Cats classification challenge. The goal of this challenge is to correctly classify whether a given image contains a dog or a cat.

We’ll review the results of our simple neural network architecture and discuss methods to improve it.

Our final step will be to build a test script that will load images and classify them with OpenCV, Keras, and our trained model.

### Feedforward neural networks

While there are many, many different neural network architectures, the most common architecture is the feedforward network:

Figure 1: An example of a feedforward neural network with 3 input nodes, a hidden layer with 2 nodes, a second hidden layer with 3 nodes, and a final output layer with 2 nodes.

In this type of architecture, a connection between two nodes is only permitted from nodes in layer i to nodes in layer i + 1 (hence the term feedforward; there are no backwards or inter-layer connections allowed).

Furthermore, the nodes in layer i are fully connected to the nodes in layer i + 1. This implies that every node in layer i connects to every node in layer i + 1. For example, in the figure above, there are a total of 2 x 3 = 6 connections between layer 0 and layer 1 — this is where the term “fully connected” or “FC” for short, comes from.

We normally use a sequence of integers to quickly and concisely describe the number of nodes in each layer.

For example, the network above is a 3-2-3-2 feedforward neural network:

• Layer 0 contains 3 inputs, our $x_{i}$ values. These could be raw pixel intensities or entries from a feature vector.
• Layers 1 and 2 are hidden layers, containing 2 and 3 nodes, respectively.
• Layer 3 is the output layer or the visible layer — this is where we obtain the overall output classification from our network. The output layer normally has as many nodes as class labels; one node for each potential output. In our Kaggle Dogs vs. Cats example, we have two output nodes — one for “dog” and another for “cat”.

### Project directory structure

Figure 2: The Kaggle Dogs vs. Cats dataset is used in our simple neural network with Keras.

From within the directory, let’s run the tree  command with two command line arguments to list our project structure:

The first command line argument is important as it prevents tree  from displaying all of the image files and cluttering our terminal.

The Kaggle Dogs vs. Cats dataset is in the relevant directory ( kaggle_dogs_vs_cats). All 25,000 images are contained in the train  subdirectory. This data came from the  train.zip  dataset available on Kaggle.

I’ve also included 50 samples from the Kaggle test1.zip  available on their website.

The output  directory contains our serialized model that we’ll generate with Keras at the bottom of the first script.

We’ll review the two Python scripts, simple_neural_network.py  and test_network.py , in the next sections.

### Implementing our own neural network with Python and Keras

Now that we understand the basics of feedforward neural networks, let’s implement one for image classification using Python and Keras.

To start, you’ll want to follow the appropriate tutorial for your system to install TensorFlow and Keras:

Note: A GPU is not needed for today’s blog post — your laptop can run this very elementary network easily. That being said, in general I do not recommend using a laptop for deep learning. Laptops are for productivity rather than working with TB sized datasets required for many deep learning activities. I recommend Amazon AWS using my pre-configured AMI or Microsoft’s DSVM. Both of these environments are ready to go in less than 5 minutes.

From there, open up a new file, name it simple_neural_network.py , and we’ll get coding:

We start off by importing our required Python packages. We’ll be using a number of scikit-learn implementations along with Keras layers and activation functions. If you do not already have your development environment configured for Keras, please see this blog post.

We’ll be also using imutils, my personal library of OpenCV convenience functions. If you do not already have imutils  installed on your system, you can install it via pip :

Next, let’s define a method to accept and image and describe it. In previous tutorials, we’ve extracted color histograms from images and used these distributions to characterize the contents of an image.

This time, let’s use the raw pixel intensities instead. To accomplish this, we define the image_to_feature_vector  function which accepts an input image  and resizes it to a fixed size , ignoring the aspect ratio:

We resize our image  to fixed spatial dimensions to ensure each and every image in the input dataset has the same “feature vector” size. This is a requirement when utilizing our neural network — each image must be represented by a vector.

In this case, we resize our image to 32 x 32 pixels and then flatten the 32 x 32 x 3 image (where we have three channels, one for each Red, Green, and Blue channel, respectively) into a 3,072-d feature vector.

The next code block handles parsing our command line arguments and taking care of a few initializations:

We only need a single switch here, --dataset , which is the path to the input directory containing the Kaggle Dogs vs. Cats images. This dataset can be downloaded from the official Kaggle Dogs vs. Cats competition page.

Line 30 grabs the paths to our --dataset  of images residing on disk. We then initialize the data  and labels  lists, respectively, on Lines 33 and 34.

Now that we have our imagePaths , we can loop over them individually, load them from disk, convert the images to feature vectors, and the update the data  and labels  lists:

The data  list now contains the flattened 32 x 32 x 3 = 3,072-d representations of every image in our dataset. However, before we can train our neural network, we first need to perform a bit of preprocessing:

Lines 61 and 62 handle scaling the input data to the range [0, 1], followed by converting the labels  from a set of integers to a set of vectors (a requirement for the cross-entropy loss function we will apply when training our neural network).

We then construct our training and testing splits on Lines 67 and 68, using 75% of the data for training and the remaining 25% for testing.

For a more detailed review of the data preprocessing stage, please see this blog post.

We are now ready to define our neural network using Keras:

On Lines 71-76 we construct our neural network architecture — a 3072-768-384-2 feedforward neural network.

Our input layer has 3,072 nodes, one for each of the 32 x 32 x 3 = 3,072 raw pixel intensities in our flattened input images.

We then have two hidden layers, each with 768 and 384 nodes, respectively. These node counts were determined via a cross-validation and hyperparameter tuning experiment performed offline.

The output layer has 2 nodes — one for each of the “dog” and “cat” labels.

We then apply a softmax  activation function on top of the network — this will give us our actual output class label probabilities.

The next step is to train our model using Stochastic Gradient Descent (SGD):

To train our model, we’ll set the learning rate parameter of SGD to 0.01. We’ll use the binary_crossentropy  loss function for the network as well.

In most cases, you’ll want to use just crossentropy , but since there are only two class labels, we use binary_crossentropy . For > 2 class labels, make sure you use crossentropy .

The network is then allowed to train for a total of 50 epochs, meaning that the model “sees” each individual training example 50 times in an attempt to learn an underlying pattern.

The final code block evaluates our Keras neural network on the testing data:

### Classifying images using neural networks with Python and Keras

To execute our simple_neural_network.py  script, make sure you have already downloaded the source code and data for this post by using the “Downloads” section at the bottom of this tutorial.

The following command can be used to train our neural network using Python and Keras:

The output of our script can be seen in the screenshot below:

Figure 3: Training a simple neural network using the Keras deep learning library and the Python programming language.

On my Titan X GPU, the entire process of feature extraction, training the neural network, and evaluation took a total of 1m 15s with each epoch taking less than 0 seconds to complete.

At the end of the 50th epoch, we see that we are getting ~76% accuracy on the training data and 67% accuracy on the testing data.

This ~9% difference in accuracy implies that our network is overfitting a bit; however, it is very common to see ~10% gaps in training versus testing accuracy, especially if you have limited training data.

You should start to become very worried regarding overfitting when your training accuracy reaches 90%+ and your testing accuracy is substantially lower than that.

In either case, this 67.376% is the highest accuracy we’ve obtained thus far in this series of tutorials. As we’ll find out later on, we can easily obtain > 95% accuracy by utilizing Convolutional Neural Networks.

### Classifying images using our Keras model

We’re going to build a test script to verify our results visually.

So let’s go ahead and create a new file named test_network.py  in your favorite editor and enter the following code:

On Lines 2-8, we load necessary packages. These should be familiar as we used each of them above, with the exception of load_model  from keras.models . The load_model  module simply loads the serialized Keras model from disk so that we can send images through the network and acquire predictions.

The image_to_feature_vector  function is identical and we include it in the test script because we want to preprocess our images in the same way as training.

Our script has three command line arguments which can be provided at runtime (Lines 16-23):

• --model : The path to our serialized model file.
• --test-images : The path to the directory of test images.
• --batch-size : Optionally, the size of mini-batches can be specified with the default being 32 .

You do not need to modify Lines 16-23 — if you are unfamiliar with argparse  and command line arguments, just give this blog post a read.

Moving on, let’s define our classes and load our serialized model from disk:

Line 26 creates a list of the classes we’re working with today — a cat and a dog.

From there we load the model into memory so that we can easily classify images as needed (Line 30).

Let’s begin looping over the test images and predicting whether each image is a feline or canine:

We begin looping over all images in the testing directory on Line 34.

First, we load the image and preprocess it (Lines 39-41).

From there, let’s send the image through the neural network:

A prediction is made on Lines 45 and 46.

The remaining lines build a display label containing the class name and probability score and overlay it on the image (Lines 50-54). Each iteration of the loop, we wait for a keypress so that we can check images one at a time (Line 55).

### Testing our neural network with Keras

Now that we’re finished implementing our test script, let’s run it and see our hard work in action. To grab the code and images, be sure to scroll down to the “Downloads” section of this blog post.

When you have the files extracted, to run our test_network.py  we simply execute it in the terminal and provide two command line arguments:

Did you see the following error message?

This message describes how to use the script with command line arguments.

Are you unfamiliar with command line arguments and argparse? No worries — just give this blog post on command line arguments a quick read.

If everything worked correctly, after the model loads and runs the first inference, we’re presented with a picture of a dog:

Figure 4: A dog from the Kaggle Dogs vs. Cats competition test dataset is correctly classified using our simple neural network with Keras script.

The network classified the dog with 71% prediction accuracy. So far so good!

When you’re ready, press a key to cycle to the next image (the window must be active).

Figure 5: Even a simple neural network with Keras can achieve relatively good accuracy and distinguish between dogs and cats.

Our cute and cuddly cat with white chest hair passed the test with 77% accuracy!

Onto Lois, a dog:

Figure 6: Lois likes the snow. He also likes when a simple deep learning neural network correctly classifies him as a dog!

Lois is definitely a dog — our model is 97% sure of it.

Let’s try another cat:

Figure 7: Deep learning classification allows us to do just that — to classify the image contents. Using the Kaggle Dogs vs. Cats dataset, we have built an elementary model to classify dog and cat images.

Yahoo! This ball of fur is correctly predicted to be a cat.

Let’s try a yet another dog:

Figure 8: This is an example of a misclassification. Our elementary neural network built with Keras has room for improvement as it is only 67% accurate. To learn how to improve the model, check out DL4CV.

DOH! Our network thinks this dog is a cat with 61% confidence. Clearly this is a misclassification.

How could that be? Well, our network is only 67% accurate as we demonstrated above. It will be common to see a number of misclassifications.

Our last image is of one of the most adorable kittens in the test_images folder. I’ve named this kitten Simba. But is Simba a cat according to our model?

Figure 9: Our simple neural network built with Keras (TensorFlow backend), misclassifies a number of images such as of this cat (it predicted the image contains a dog). Deep learning requires experimentation and iterative development to improve accuracy.

Alas, our network has failed us, but only by 3.29 percent. I was almost sure that our network would classify Simba correctly, but I was wrong.

Not to worry — there are improvements we can make to rank on the Top-25 leaderboard of the Kaggle Dogs vs. Cats challenge.

In my new book, Deep Learning for Computer Vision with Python, I demonstrate how to do just that. In fact, I’ll go so far to say that you’ll probably achieve a Top-5 position with what you’ll learn in the book.

To pick up your copy, just use this link: Deep Learning for Computer Vision with Python.

## Summary

In today’s blog post, I demonstrated how to train a simple neural network using Python and Keras.

We then applied our neural network to the Kaggle Dogs vs. Cats dataset and obtained 67.376% accuracy utilizing only the raw pixel intensities of the images.

Starting next week, I’ll begin discussing optimization methods such as gradient descent and Stochastic Gradient Descent (SGD). I’ll also include a tutorial on backpropagation to help you understand the inner-workings of this important algorithm.

Before you go, be sure to enter your email address in the form below to be notified when future blog posts are published — you won’t want to miss them!

### 103 Responses to A simple neural network with Python and Keras

1. Stan September 26, 2016 at 9:48 pm #

That is awesome. Thanks. Please keep posting that stuff.

• Adrian Rosebrock September 27, 2016 at 6:36 am #

Thanks Stan! I’ll certainly be doing more neural network and deep learning tutorials in the future.

2. Bogomil September 27, 2016 at 4:01 pm #

I used the default engine for keras – tensorflow and got the following:

Epoch 50/50
18750/18750 [==============================] – 12s – loss: 0.4859 – acc: 0.7707
[INFO] evaluating on testing set…
6250/6250 [==============================] – 1s
[INFO] loss=0.6020, accuracy: 68.0960%

is this difference normal ?

• Adrian Rosebrock September 28, 2016 at 10:42 am #

Absolutely. Keep in mind that neural networks are stochastic algorithms meaning there is a level of randomness involved with them (specifically the weight initializations). It’s totally normal to see a bit of variance between training runs.

3. Gilad September 28, 2016 at 1:06 am #

Hi,
wonderful post!
I have a question – how did you manage to pick your parameters (including the NN scheme)?
No matter what I did (and I did a lot – including adding 2 more NN levels, adding dropout, changeling the SGD parameters and all other parameters), I didn’t manage to get more than your 67%.
Especially I wonder why adding more levels and increasing the depth of each, didn’t contribute to my score (but as expected contribute to my run time ;-))
Only when I increased the resolution to 64×64, and the depth of the 2 NN levels, I manage to get 68%, and I wonder why it is so low.

• Adrian Rosebrock September 28, 2016 at 10:37 am #

Hey Gilad — as the blog post states, I determined the parameters to the network using hyperparameter tuning.

Regarding the accuracy, keep in mind that this is a simple feedforward neural network. 68% accuracy is actually quite good for only considering the raw pixel intensities. And again, as the blog post states, we require a more powerful network architecture (i.e., Convolutional Neural Networks) to obtain higher accuracy. I’ll be covering how to apply CNNs to the Dogs vs. Cats dataset in a future blog post. In the meantime, I would suggest reading this blog post on MNIST + LeNet to help you get started with CNNs.

4. Max Kostka September 28, 2016 at 2:10 pm #

Yes, absolutely awesome Adrian, i am already totally eager for a simple convolutional neural network. I love your blog 🙂 Been following it for a year now. Keep up the great work.
Btw, i did this simple neural network on a raspberry Pi 2 and FYI it took almost 5 hours 😀

• Adrian Rosebrock September 30, 2016 at 6:51 am #

Thanks for the kind words Max, I’m happy the tutorial helped you (and that you’ve been a long time reader)!

If you would like a simple CNN, take a look at this blog post on LeNet to help you get started. Future posts will discuss each of the layer types in detail, etc.

• Max Kostka September 30, 2016 at 1:29 pm #

i did that right away, another awesome post:D and fyi, the training there on a raspi 2 took almost about 19 hours.

5. Marios September 29, 2016 at 11:09 pm #

You could also do an implementation of your NN using TensorFlow!

• Adrian Rosebrock September 30, 2016 at 6:40 am #

Keras can use either Theano or TensorFlow as a backend — it’s really your choice. I personally like using Keras because it adds a layer of abstraction over what would otherwise be a lot more code to accomplish the same task. In future blog posts I’m planning on continuing using Keras, but I’ll also consider the “nitty-gritty” with TensorFlow as well!

6. roberto October 1, 2016 at 7:52 am #

I run the code, but i would like to use it to classify some images, but i dont want to run it every time. How can i save the model and use it to classify?

ps: I’ll be waiting for next post to improve the accuracy!

Regards!!!

• Adrian Rosebrock October 2, 2016 at 9:02 am #

Once your model is saved you can actually serialize it to disk using `model.save` and then load it again via `load_model`. Take a look at the Keras documentation for more information and a code example.

7. Atti November 29, 2016 at 10:53 am #

great article thanks for all the insights

8. Alberto Franzaroli December 1, 2016 at 6:06 am #

Now there is also a opensource library The Microsoft Cognitive Toolkit
would you like to try it and compare with Keras ?

• Adrian Rosebrock December 1, 2016 at 7:20 am #

I haven’t used the Microsoft Cognitive Toolkit before, but I’ll look into it. I don’t normally use Microsoft products.

9. Dharma KC December 11, 2016 at 9:06 am #

Please can you provide the link to the tutorial with convolutional neural network to solve this problem with 95% accuracy. Thank you.

• Adrian Rosebrock December 11, 2016 at 10:46 am #

I will be covering how to obtain 95%+ accuracy in the Dogs vs. Cats challenge in my upcoming deep learning book. Stay tuned!

10. UDAY December 12, 2016 at 7:25 am #

How much it will take to train without a GPU
and how we can get a GPU for trail.

11. Tajj kasem December 14, 2016 at 4:57 pm #

How I can use model.predict() after training my neural network .
I have this error :

Exception: Error when checking : expected dense_input_1 to have 2 dimensions, but got array with shape (303, 400, 3)
How i fixed it ?

• Adrian Rosebrock December 18, 2016 at 9:10 am #

You need to call `image_to_feature_vector` on your image before passing it into `model.predict`.

12. azhng December 26, 2016 at 10:23 pm #

Thank you so much for this awesome tutorial. However, when I run the code on my laptop, the process with terminated with exit code of 137.
Any idea what does that mean?

13. Yunhwan Kim January 10, 2017 at 11:06 pm #

Thank you for awesome tutorial.
I just wonder how you could use Titan X GPU on your (seemingly) OSX machine. I see “ssh” in the top of the terminal window figure, and I guess that you access other (probably linux) machine with GPU from your OSX machine via ssh.
Then, do you have any plan to post about that process? It would be much helpful if I (and other readers) could use GPU in other machine from OSX machine.
Thank you again.

Yunhwan

• Adrian Rosebrock January 11, 2017 at 10:35 am #

You are correct, Yunhwan — I am ssh’ing into my Ubuntu GPU box and then running any scripts over the SSH session. Does that help clarify your question? If you are looking to learn more about SSH and how to SSH into machines I would suggest reading up on SSH basics.

14. Vincent FOUCAULT January 15, 2017 at 1:48 pm #

didn’t you forget, in picture1, connection from first node in layer2 to second in layer3 ?

I’m impatient to see your next books.

CU.
Vincent

15. Foobar March 10, 2017 at 11:07 pm #

Hi i am training an an ARM based device 4 cores 1GB RAM but i am getting a memory error when running the script it gets up to processing 24,000 images and crashes on a memory error but there is still 100MB of free space what am I doing wrong and how do I fix this?

• Adrian Rosebrock March 13, 2017 at 12:20 pm #

It’s hard to say without knowing which device you are using. I would confirm that the script will run on your desktop/laptop before moving on to other devices.

• Foobar March 17, 2017 at 7:21 pm #

It works on my laptop but I have been trying to run it on an Odroid C1. My Odroid is running a headless debian jessie for the odroid.

• Adrian Rosebrock March 21, 2017 at 7:40 am #

I haven’t used Odroid before, so I’m not sure about the specifics. Debian Jessie seems like it would work just fine; however, I don’t have any experience with the Odroid so I’m not sure what the exact problem would be. Again, we typically don’t train networks on such small devices — only deploy them if memory allows.

16. DL March 25, 2017 at 11:51 am #

Getting this error while using Keras 1.0.7 in Anaconda

Any idea?

Thanks!

• Adrian Rosebrock March 28, 2017 at 1:12 pm #

Your class labels are not getting encoding properly. 99% of the time this is due to invalid paths to your training images. Double-check the path to the training images and ensure it’s correct. Also make sure you are not also using the paths to the Kaggle testing data as these filenames do not have “dog” or “cat” in them.

17. naitik March 26, 2017 at 6:59 am #

It’s really informative article you posted , but just curious that instead of having accuracy can i have detailed result of each image classified as wrong or right ?

• Adrian Rosebrock March 28, 2017 at 1:07 pm #

Can you clarify what you mean by “detailed result of each image classified as wrong or right”? I’m not sure what you mean.

18. Werner April 19, 2017 at 1:31 pm #

Nice post really love the work! I just have a question regarding the feedforward idea. From my understanding, feedforward network uses delta rule to learn, and does not backpropagate. How is this specified using Keras? If you were to write this feedforward Keras code using backpropagation, how would it be different?

Thanks!

• Adrian Rosebrock April 21, 2017 at 11:03 am #

I think you might be confusing the standard Perceptron algorithm with multi-layer feedforward networks. The Perceptron uses the delta rule to learn while multi-layer feedforward networks use backpropagation. If you’re interested in learning more about these algorithms, how to train neural networks, and even build Convolutional Neural Networks that can understand the contents of an image, be sure to take a look at Deep Learning for Computer Vision with Python.

19. maxtri April 20, 2017 at 4:53 am #

20. chris May 11, 2017 at 2:05 am #

Simple question…got it to work but lets say I want to load in the test data (the pictures with just numbers) any trick to doing that?

• Adrian Rosebrock May 11, 2017 at 8:44 am #

Hi Chris — can you elaborate more on what you mean by “the pictures with just numbers”? I’m not sure I understand.

• chris May 11, 2017 at 11:58 am #

Sure 🙂 so in the data set of dogs and cats there is the training data that is labeled either a cat or a dog and its corresponding image number. Using this data we train and test our model (correct me if i’m wrong anywhere). Once this is done, model is trained and tested for accuracy, we could use it to predict if an image is a cat or a dog. So at kaggles site there is a set of images that you can download that is a mix of cats and dogs but minus the label of a cat or a dog. Its simply just numbered images. So how do we take that data and feed it into our model to predict if those images are cats or dogs. I want to use the model now to do actual predictions. Thanks for the prompt response.

• Adrian Rosebrock May 15, 2017 at 8:57 am #

Thank you for the clarification on the question. Basically, you would like to know how take a test set and then pass it through the network to obtain the output classifications.

All you need to do is (1) pre-process your input data in the same way as your training data and (2) call the `.predict` method of the network.

I would suggest taking a look at this blog post on LeNet where I demonstrate how to classify individual images.

21. Richard May 19, 2017 at 7:00 am #

Hi, fantastic posts – I love your blog.

I have a question, though!

In ‘SGD(lr=0.01)’, where does the 0.01 come from? You don’t say how you chose that value. Was it pie-in-the-sky, or was there some secret to your choice?

Thanks!

• Adrian Rosebrock May 21, 2017 at 5:19 am #

Hi Richard — typical initial learning rates include 0.1, 0.01, and 0.001. It really depends on the specific architecture and your dataset, but those are typical starting points.

22. Will May 25, 2017 at 5:47 pm #

I am having trouble getting the SGD algorithm to converge. The algorithm generally does well and decreases the loss, but sometimes (generally after a few epochs) the loss explodes in a few steps (by a factor of 10 or so) and does not recover. It does not simply seem to be fluctuations from navigating local minima of the objective function, it seems that there is something pathological going on. Which is bizzare because I am using the same code and hyperparameters.

• Adrian Rosebrock May 28, 2017 at 1:17 am #

It sounds like you’re overfitting. Are you using the dataset in this blog post or your own custom dataset?

23. Shrinidhi Rao June 7, 2017 at 12:30 am #

Hi, Thanks for the tutorial. but for some reason I am not able to enter the for loop, which is giving me the error

• Adrian Rosebrock June 9, 2017 at 1:53 pm #

What is the error you are getting, Shrinidhi?

24. Foobar June 20, 2017 at 6:41 am #

I have managed to use the .predict function with this but I don’t know how to understand the data given by .predict

• Adrian Rosebrock June 20, 2017 at 10:43 am #

The `.predict` method will return a NumPy with shape `(N, M)` where N is the total number of data points passed into `.predict` and M is your total number of class labels. You can use the `np.argmax` function to find the index with the largest class label probability for each row.

• Foobar June 20, 2017 at 4:49 pm #

Thanks

25. Rolando June 29, 2017 at 2:11 pm #

One question, I want to make a neural network probabilistica in python, you that you recommend me?

• Adrian Rosebrock June 30, 2017 at 8:08 am #

Do Do you mean a neural network that predicts probabilities? This implementation can do that as well. Just use the `model.predict_proba` function.

• Rolando June 30, 2017 at 2:50 pm #

Thanks, I mean a PNN type neural network

• Muhammad Wahid January 25, 2019 at 4:43 am #

Hi Rolando,

Do you have an implementation of PNN in python/Keras?

26. Niki July 14, 2017 at 2:57 pm #

Nice work! I used your code with the exact same data, but I could never reach an accuracy better than 50% on both training and test data. I tried to increase the resolution of the images, but it didn’t work. No matter what I tried I kept seeing the same pattern in the results; at the first few epochs the accuracy improved and the loss decreased, but then all of the sudden the loss became 8 or 9 times large. I thought this might be the result of overfitting, so finally I reduced both learning rate as well as the number of epochs. The best result that I got was 65.7% on training and 64.59% on the test data and this was achieved by setting learning rate = .005 and number of epochs = 25. I understand that using raw pixels as the input features does not make a strong feature vector, so I shouldn’t expect a high accuracy, but I was wondering why using exact same data and exact same code could result in such a big difference in the final result (in particular, my first results that couldn’t get any better than 50%, and this happened when I ran the code at least 7 or 8 times before making any changes)?

• Adrian Rosebrock July 18, 2017 at 10:13 am #

It depends on (1) what version of Keras you are using and (2) whether you are using Theano or TensorFlow as your backend. Both of these can have different impacts on your accuracy. However, without physical access to your machine I can’t be 100% sure what the issue is.

• Niki July 19, 2017 at 10:15 am #

Thank you for your response! These are the python, Keras, and Tensorflow (my keras backend engine) versions that I use:

Python 2.7.13 (anaconda 1.6.3), Tensorflow 1.2.1, Keras 2.0.5

• Adrian Rosebrock July 21, 2017 at 8:57 am #

Hi Niki — thank you for sharing your Python and library versions. Unfortunately, I’m not sure what the exact issue is here. I wish I could be of more help, but like I said, without physical access to your machine, I can’t diagnose why there are such big discrepancies between the accuracies.

27. Diego November 14, 2017 at 7:48 pm #

Hello Adrian, I am making a project where I need to classify gender using SIFT descriptor. I used those descriptors in this simple neural network but I am getting low accuracy in my train and test. What kind of neural network do you recommend me to train sift descriptors for gender classification?

Thanks!

• Adrian Rosebrock November 15, 2017 at 12:57 pm #

Hey Diego — I don’t recommend keypoint detectors and local invariant descriptors for this type of problem. An end-to-end Convolutional Neural network will work much better. In fact, I cover age + gender recognition inside my book, Deep Learning for Computer Vision with Python. Be sure to take a look!

28. Fraol November 16, 2017 at 3:12 am #

Hello Adrian, I downloaded the code and run it without a problem on the training data. but when i try to run in for the “test” directory it gives me this warning after some time

index 2 is out of bound for axis 1 with size 2

i am just beginning computer vision and machine learning and thank you for your work.

• Adrian Rosebrock November 18, 2017 at 8:24 am #

The reason is because the testing data does not include the class label information (i.e., dog or cat) in the filename. To evaluate our model we need the class labels and since the training data only includes the class label we need to take a portion of the training data to compute our accuracy. If you wanted to submit your predictions to the Kaggle servers for evaluation you would need to serialize your model to disk and then run it on each of the testing images.

If you’re interested in studying computer vision and deep learning in more depth, be sure to take a look at my book, Deep Learning for Computer Vision with Python. Regardless if you’re a beginner or an advanced user you’ll find the book extremely helpful.

29. Katya November 17, 2017 at 4:52 pm #

Thank you very much! It’s very good and clear tutorial

• Adrian Rosebrock November 18, 2017 at 8:08 am #

Thanks Katya! 🙂

30. Maryam December 2, 2017 at 4:01 pm #

awesome work!
In fact I am a beginner in learning deep learning for a bout 1 week. Thank you in advanced to publish a tutorial for teaching other neural network functions such as Recurrent network, Auto encoder networks , … .
Waiting for the mentioned tutorial as I know nothing about writing code on RNN, Auto encoders and other NNs.

• Adrian Rosebrock December 5, 2017 at 7:50 am #

Hi Maryam — I actually have a number of tutorials on neural networks and deep learning. Take a look at them here. If you’re interested in taking a deeper dive into deep learning, I would suggest reading through my book, Deep Learning for Computer Vision with Python.

• Maryam December 8, 2017 at 6:22 am #

I am not interested in either computer vision or Image processing.
I want to start text processing especially text classification in Keras through different kinds of functions such as RNN, CNN, Auto encoders,…
would you mind please give us a tutorial about text classification by the mentioned functions???

• Adrian Rosebrock December 8, 2017 at 4:38 pm #

I don’t cover text or audio classification here on PyImageSearch.com. Take a look at MachineLearningMastery. My friend Jason runs it and does a good job.

31. Adi February 28, 2018 at 5:32 am #

hello, Thank you for the tutorial. but for some reason I am not able run the code.can you please help me out.

Thanks.

errors :

Using TensorFlow backend.
usage: simple_neural_network.py [-h] -d DATASET
simple_neural_network.py: error: the following arguments are required: -d/–dataset

Process finished with exit code 2

• Adrian Rosebrock March 2, 2018 at 11:01 am #

Hey Adi — make sure you are passing the command line arguments to the script when you execute it via the terminal (exactly as I do in the post). If you are new to command line arguments, that’s okay, but you’ll need to read up on them before continuing.

32. Daniel Saadia June 1, 2018 at 9:49 am #

For my part, it freezes when I want to test on the images from the directory test_images. It stays at the image 48.jpg..

Any ideas ?

33. fedup July 1, 2018 at 5:41 am #

This must just be a joke because after the 4th attempt at clicking the pictures , just gave up

• Adrian Rosebrock July 1, 2018 at 6:37 am #

I’m not sure what you mean by “4th attempt at clicking the pictures”? Could you clarify?

34. saka July 1, 2018 at 9:33 pm #

Hello, Thank you for the tutorial. but for some reason I am not able run the code.can you please help me out.

Thanks.

errors :

ValueError: Error when checking input: expected dense_1_input to have shape (3072,) but got array with shape (1,)

• Adrian Rosebrock July 3, 2018 at 8:32 am #

Double-check your input paths to your dataset directory — I’m willing to bet the class labels are not getting parsed properly.

35. Josh July 16, 2018 at 4:42 am #

Hey, a huge fan of the stuff that you do here. Quick question regarding your output: The output of your network is a .hdf5 file and I was wondering what that content of that file actually is an how to view? I have been doing some work with CNNs and the I was wanting to output the pixel information to .csv files. Are you outputting pixel values? And if so, how to output as .csv?

• Adrian Rosebrock July 17, 2018 at 7:20 am #

The contents of the file are the weights for each layer in the network along with the optimizer state (if you ever wanted to restart training). These weights are not “viewable” in the classical sense.

• Josh July 18, 2018 at 4:01 am #

Oh, that makes perfect sense. I have one more question: at any point do you randomize the data? When the images are split 75% training and 25% testing, is the data also randomized at that point?

• Josh July 18, 2018 at 4:23 am #

Actually, I just noticed the random_state, but why 42? Sorry. I over-looked it the first time.

• Adrian Rosebrock July 20, 2018 at 6:48 am #

It’s a Hitchhikers Gide to the Galaxy reference. I could include an explanation on how 42 is the answer to life, the universe, and everything, but perhaps that would be an entire blog post 😉 I kid, of course. We manually specify random seed values here so we can reproduce the experiment. If you’re new to working with random values you should read up on pseudorandom number generators.

• Adrian Rosebrock July 20, 2018 at 6:46 am #

The data is shuffled/randomized when we create the training and testing splits.

36. Harish Kumar T August 13, 2018 at 4:34 am #

I am getting this error How to Solve This:

usage: simple_neural_network.py [-h] -d DATASET -m MODEL
simple_neural_network.py: error: the following arguments are required: -m/–model

• Adrian Rosebrock August 15, 2018 at 8:52 am #

You need to supply the command line arguments to the script.

• popandpeek September 18, 2018 at 12:12 pm #

The confusion is due to the –model flag missing in the terminal entry you posted within the article –

1 \$ python simple_neural_network.py –dataset kaggle_dogs_vs_cats

It’s not complete – just need to add –model model (or the path to the hd5 file in the output folder to overwrite it) to give it a place to dump the model, but the confusion is because readers are not sure if they are missing a file and the walk-through doesn’t explicitly mention this (probably because you’ve provided the model with the download and are expecting everyone to read everything and look through the folder contents, ha).

• Adrian Rosebrock September 18, 2018 at 12:24 pm #

Ah, I see. Thanks for catching that 🙂 I’ve updated the post.

37. emir August 17, 2018 at 9:24 am #

Thank you for the tutorial,

im havin’ this problem

data.append(features)
NameError: name ‘data’ is not defined

• Adrian Rosebrock August 17, 2018 at 11:08 am #

38. Neelesh September 17, 2018 at 6:27 pm #

Hi @Adrian, thanks so much for the blogs and all your help for the community. I benefitted from the blog post a lot.

A few things I learnt along the way that may help others.

I got this error on my MacBookPro:

“Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA”

The article on stack overflow on this error was the most informative:
https://stackoverflow.com/questions/47068709/your-cpu-supports-instructions-that-this-tensorflow-binary-was-not-compiled-to-u

The high-level gist is that the version of TensorFlow I installed is not compiled with support for the instruction set that supports matrix computations for better performance. This is true only if you are running on CPU’s. If you use GPU’s on your machine, you can ignore this warning.

2. I used Anaconda for my virtual environments and using the instructions in the blog for virtual python and simply following those along after creating an Anaconda environment worked well for me. It was great to get practical insight into why private environments are good for DL projects with the library dependencies.

3. While Simba got corrected classified as a cat, Soleil and Sapphire were categorized as dogs with about 79.48% confidence. The cats are so cute, I barely looked at the fact that the algorithm mis-classified them 🙂

4. What would be useful, perhaps as a follow up, is to see if there is mis-classficiation in the labeled data that could improve performance.

Overall, it was very useful to get my stand alone environment going on my MacBookPro. Look forward to more and the book.

Cheers,
Neelesh

• Adrian Rosebrock September 17, 2018 at 7:23 pm #

Thanks for the detailed writeup, Neelesh, I appreciate it. I’d also like to reiterate that this is not not an error message. It’s just a warning and one that does not have to be resolved. TensorFlow is just letting you know there are additional optimizations that can be leveraged if you so wish.

39. Asif October 29, 2018 at 9:16 am #

Thanks for your these simple tutorials. I tried building your code. 20 out of 50 test images giving wrong prediction, even after there are only 2 classes.

How can I can get more accuracy. Any suggestions are welcome.

• Adrian Rosebrock October 29, 2018 at 1:04 pm #

Hey Asif — I would suggest you read through Deep Learning for Computer Vision with Python where I provide my tips, best practices, and suggestions on how to improve your prediction accuracy.

40. Afiqah December 11, 2018 at 2:58 pm #

i am a beginner in programming actually . i have problem in run my code. can you please help me out.

i have 4 class label and already change to crossentropy loss function but then i get error so i change this code :
labels = np_utils.to_categorical(labels, 2) to labels = np_utils.to_categorical(labels, 4) but i still cant settle this problem. would you help me ?

• Adrian Rosebrock December 13, 2018 at 9:16 am #

What is the exact error that you are receiving? If you can let me know I can try to point you in the right direction.

41. I. Aliah December 12, 2018 at 9:55 am #

Great tutorial sir! But this is feed forward neural network right? What I need to do if I want to make the backpropagation neural network with python and keras too?

• Adrian Rosebrock December 13, 2018 at 9:04 am #

This is a feedforward neural network. It’s also been trained via backpropagation. I get the impression that you may be new to deep learning and neural networks. That’s totally okay! It’s good to start your journey and I’m happy that I can accompany you on it as you study neural networks and Keras. My suggestion would be for you to read through my book, Deep Learning for Computer Vision with Python. The book will help teach you the fundamentals of Keras and deep learning, building up to more advanced applications. It will give you a very, very strong education and will prepare you for a career in DL.

42. Ozkan February 22, 2019 at 6:16 pm #

Hi Dr. Rosenbrock,
I tried to read almost all question as it was hard to make control-F without knowing the keyword that I need. Everytime I run the simple_neural_network.py file it process the images so it takes a good deal of time with 25000 training dataset. Is there a way to avoid this repetition and just run the model on processed data? I hope I expressed my answer clearly… Thank you

• Adrian Rosebrock February 27, 2019 at 6:26 am #

Is your goal to train the model once and then save it to disk, that way you don’t have to retrain it? If so, refer to this tutorial.

43. Hermawan Mulyono March 3, 2019 at 3:12 am #

Thank you very much for this excellent tutorial. I was able to run the code for training. Unfortunately, when running testing_network.py, I had a problem related to GTK not being able to open display. I ran it on a virtual machine (Microsoft) with SSH. At the moment, I can use xterm and in the xterm window, I can run testing_network.py. However, I don’t really like explicitly typing xterm every time I want to run my code.

Do you have any better solutions?

Thank you!

• Adrian Rosebrock March 5, 2019 at 8:56 am #

Enable X11 forwarding when SSH’ing into your system:

`\$ ssh -X username@your_ip_address`

44. Anicetus March 11, 2019 at 8:36 am #

I use Windows platform but have a working implementation. However, I would like to use Ubuntu as your support is for Ubuntu. Please, how can I install Ubuntu in my Windows laptop?

Thanks very much.

• Adrian Rosebrock March 13, 2019 at 3:38 pm #

I would suggest you look into either (1) dual booting or (2) using a virtual machine. I offer a pre-configured Ubuntu VM that will run on Windows inside my book, Deep Learning for Computer Vision with Python.

45. Gaby Solano May 22, 2019 at 7:41 pm #

Hi Adrian, I would like to ask a question. When we use deep Learning, with a dataset of images, should we apply gray scale and flatten function? or can we use a descriptor like HOG or LBP? I only have seen examples without applying descriptors such as HOG or LBP. I am a little confused.

• Adrian Rosebrock May 23, 2019 at 9:30 am #

No, CNNs operate on the raw pixel intensties of the images. You don’t need to perform any additional feature extraction. I would suggest you read through Deep Learning for Computer Vision with Python so you can learn the fundamentals of Deep Learning with images.

[email]
[email]