This code helps quickly set up and run a deep CNN project for image classification.
Before you can run this code, you need to have all of the following Python modules installed:
- Keras
- Theano
- Pillow
- h5py
- sklearn
Here is how to do this with Anaconda 2 (for Python 2):
- Download Anaconda 2 here: https://www.continuum.io/downloads#_unix
- Run the installer bash script:
$ bash Anaconda2-2.5.0-Linux-x86_64.sh
- Reload bashrc:
$ . ~/.bashrc
- Create a new anaconda environment:
$ conda create -n py27x python=2.7
. "py27x" is the name of the environment. You can name it whatever you want. -
$ source activate py27x
. -
$ pip install --upgrade pip
-
$ pip install keras
- If this fails due to an error installing scipy, run
$ conda install scipy
first. - This is a general fix for any packages it fails to install with pip.
- If this fails due to an error installing scipy, run
-
$ pip install git+git://github.com/Theano/Theano.git
-
$ pip install Pillow
-
$ pip install h5py
. -
$ pip install sklearn
.- This will get an error along the way, but don't worry - it fixes itself.
- If it doesn't work at all,
$ conda install h5py
instead.
Whenever you want to use this environment (which includes all of the things you just installed), simply run $ source activate py27x
. Then run source deactivate
when you're finished.
If you want to use the GPU (which is pretty much necessary if you want to train a deep CNN model), you need to install CUDA. You can download it here: https://developer.nvidia.com/cuda-downloads. If you download the runfile version, you can install it by running the provided bash script. If the appropriate Nvidea drivers are already installed, this will give you the option to install CUDA in a directory of your choosing (without root access).
This code must be run in a Python 2 environment with all of the required modules listed above installed. The run.py
script is what allows you to train or test a model.
Run on CPU: python run.py <config-file> [options]
Run on GPU (requires CUDA): ./run_gpu <config-file> [options]
The config file must be provided (see below). Other options are as follows:
-
-load-model _file_
Loads an existing model architecture from the given file (_file_
). The saved architecture must match the input image size (specified by the config file). If this parameter is not provided, a new model will be built as defined inmodel.py
. -
-save-model _file_
Saves the model architecture used for training to the given file (training mode only). You may want to save the model after training to test it later. -
-load-weights _file_
Loads existing weights from this file. The weights must match the architecture of the model being used. You can load weights for a training run to fine-tune the model's parameters. -
-save-weights _file_
Saves the trained weights to this file (training mode only). You should save weights if you wish to test the trained model later. -
--explicit-labels
Uses an explicitly-provided label distribution over the classes (i.e. soft labels) instead of just a 1-hot vector for labels. To use this option, the data files must be formatted appropriately (see "Preparing Your Data" below). -
--test
Runs a test on a model with existing weights instead of training. This option requires the-load-weights
to be set. You may also want to explicity load the model (-load-model
) that you used for training. -
-confusion-matrix _file_
Saves a confusion matrix of the test results to the given file (test mode only). -
-report-misclassified _file_
Saves a list of misclassified images to the given file (test mode only). Each line of this file will contain the path of a misclassified image, followed by its correct (ground truth) class, and then the class that was incorrectly predicted by the model. -
-report-scores _file_
For each test image, writes the path of the image file followed by the prediction probabilities for each possible class to the file, one image per line (test mode only). The format is /path/to/image prob0 prob1 ....
The data itself can consist of any RGB or Grayscale images saved on your computer. You need to specify three files that will tell the code where your data is and how it is organized:
- A file containing a list of class names. Each line of this file should be a string indicating a classname (e.g. "cat", "dog", "building", etc.
- A file containing a list of training images. Each line of this file should specify the full path of an image, followed by a space and their numerical class number (e.g. 0, 1, 2, ..., N-1) where N is the total number of classes.
- A file containing a list of test images. As for the training images, each line must specify the full path of an image followed by the class number.
In all of the above files, empty lines will be ignored. Also, lines starting with a "#" will be ignored (so you can add comments).
Example Files:
# classnames.txt
cat
dog
# train_images.txt
# 5 cat training images
/home/users/You/data/cats/img1.jpg 0
/home/users/You/data/cats/img2.jpg 0
/home/users/You/data/cats/img3.jpg 0
/home/users/You/data/cats/img4.jpg 0
/home/users/You/data/cats/img5.jpg 0
# 5 dog training images
/home/users/You/data/dogs/img1.jpg 1
/home/users/You/data/dogs/img2.jpg 1
/home/users/You/data/dogs/img3.jpg 1
/home/users/You/data/dogs/img4.jpg 1
/home/users/You/data/dogs/img5.jpg 1
# test_images.txt
# 2 cat and 3 dog test images
/home/users/You/data/cats/img6.jpg 0
/home/users/You/data/dogs/img6.jpg 1
/home/users/You/data/cats/img7.jpg 0
/home/users/You/data/dogs/img7.jpg 1
/home/users/You/data/dogs/img8.jpg 1
Using Soft Labels:
If you want to explicity provide label values for each image (instead of just using 1-hot label vectors for the model), you can add the soft label values (floats) on each line of the train and test data files, after the class ID. For each image, you have to specify a weight for each possible class. For example, we can augment the above data with soft labels:
# train_images.txt
# 5 cat training images
/home/users/You/data/cats/img1.jpg 0 0.9 0.1
/home/users/You/data/cats/img2.jpg 0 0.8 0.2
/home/users/You/data/cats/img3.jpg 0 0.5 0.5
/home/users/You/data/cats/img4.jpg 0 1 0
/home/users/You/data/cats/img5.jpg 0 0.7 0.3
# 5 dog training images
/home/users/You/data/dogs/img1.jpg 1 0.1 0.9
/home/users/You/data/dogs/img2.jpg 1 0 1
/home/users/You/data/dogs/img3.jpg 1 0.3 0.7
/home/users/You/data/dogs/img4.jpg 1 0.25 0.75
/home/users/You/data/dogs/img5.jpg 1 0.4 0.6
# test_images.txt
# 2 cat and 3 dog test images
/home/users/You/data/cats/img6.jpg 0 0.9 0.1
/home/users/You/data/dogs/img6.jpg 1 0.2 0.8
/home/users/You/data/cats/img7.jpg 0 0.5 0.5
/home/users/You/data/dogs/img7.jpg 1 0.0 1.0
/home/users/You/data/dogs/img8.jpg 1 0.1 0.9
Note that there are 2 classes, so we provide 2 weights for each image. If there were N classes, you have to specify N weights per line.
An example use case for this is if the images have some visual similarities to images of other classes, then you can provide a better distribution to model this similarity better.
Edit the params.config
file (or write your own) with your specific data information. This file is formatted as key: value
pairs on each line. All of the values must be defined, otherwise the configuration file will not be accepted. The values must be explicity defined as valid Python 2 types (e.g. a string must be in quotes, a tuple must be of the form (val1, val2, val3)
, etc. Here is what you need to add:
- Point to the data files you defined above. Specifically, set up the appropriate
classnames_file
,train_img_paths_file
, andtest_img_paths_file
. Note that these file paths must be in quotes (i.e. they will be interpreted as Python strings). - Set the number of classes parameter:
number_of_classes
. Following the example files above, this values would be 2. - Set the image dimensions (
img_dimensions
). All images will be resized to these dimensions (width, height, number of channels) before being fed into the CNN. Currently, only 1 channel is supported (grayscale). This is a TODO. - Optionally, set the training hyperparameters as desired (
batch_size
,num_epochs
,learning_rate
,decay
, andmomentum
).
TODO