- Description
- Installation
- Setup
- Detailed explanation
- Additional notes on Caffe installation
- Citation
- License
This module is a basic YARP wrapper for Caffe, which receives as input a stream of images (of type yarp::sig::Image
), feeds them to a Convolutional Neural Network (CNN) model and produces as output a corresponding stream of vectors (of type yarp::sig::Vector
), which can be extracted from any CNN layer.
The libraries that are needed to compile this module are:
- YARP
- iCub
- OpenCV
- Caffe
- CUDA: this is an optional dependency of Caffe and also of this module. However, we strongly recommend to rely on a powerful enough NVIDIA CUDA-enabled GPU (with Compute Capability >= 3.0) in order to achieve a good frame rate.
Provided that the dependencies are satified, you can compile this module just by setting the BUILD_caffeCoder
flag to ON
as explained here.
When you run the ccmake
command, ensure also that:
- the
Caffe_DIR
flag is correctly pointing to a valid Caffe installation - the flag
CUDA_USE_STATIC_CUDA_RUNTIME
is set toOFF
This module can use arbitrary Caffe models: the only contraint is that the model must have an input data layer of kind MemoryData. However, this can be easily achieved for most models just by replacing the input data layer in the model definition file. In the following, we report istructions on how to setup the module to use either one of two well-known models, ResNet-50
and CaffeNet
.
The setup procedure basically follows the Extracting Features example provided with Caffe. If you are not interested in the details, you can execute the following instructions and use one of these two models with the default module parameters. We provide a little more explanataion hereafter for those who want to try different or custom Caffe models and settings.
If you don't have setted it already, for convenience, set the Caffe_ROOT
env variable pointing to your caffe
source code directory.
For CaffeNet
we can follow the instructions on caffe website:
$ cd $Caffe_ROOT
$ scripts/download_model_binary.py models/bvlc_reference_caffenet
# for this model we need also to get the mean image of the training set of ILSVRC
$ ./data/ilsvrc12/get_ilsvrc_aux.sh
For ResNet-50
we can get the weights as indicated here:
$ cd $Caffe_ROOT/models
$ mkdir ResNet50
$ cd ResNet50
by downloading, in this folder, the ResNet-50-model.caffemodel
file from the OneDrive link specified at the webpage.
We have now to customize two files in order to use the downloaded Caffe model.
These are provided for some Caffe models (the two considered here plus GoogLeNet
) with the source code of the module (inside app/conf
) and are:
- a
.ini
file for thecaffeCoder
module, specifying some parameters and pointing to the Caffe model's binary and definition files - the
.prototxt
Caffe model's definition file, where we have replaced the input data layer with one of kindMemoryData
Import the .prototxt
files from himrep
for the CaffeNet
and ResNet-50
architectures in order to customize them for your system:
$ yarp-config context --import himrep bvlc_reference_caffenet_val.prototxt
$ yarp-config context --import himrep resnet_val.prototxt
For CaffeNet
we need to do:
$ cd ~/.local/share/yarp/contexts/himrep
$ gedit bvlc_reference_caffenet_val.prototxt
At line 10, replace the following:
mean_file: "/path/to/train_mean.binaryproto"
with the correct absolute path to this file on your system (without using env variables). This is the binary file containing the mean image of the training set of ILSVRC we just downloaded. In this case this is:
mean_file: "$Caffe_ROOT/data/ilsvrc12/imagenet_mean.binaryproto"
where you must replace the $Caffe_ROOT
env variable with its full value.
For ResNet-50
we do not need to modify anything.
Import the .ini
files from himrep
for the CaffeNet
and ResNet-50
in order to customize them on your system:
# CaffeNet
$ yarp-config context --import himrep caffeCoder_caffenet.ini
$ yarp-config context --import himrep caffeCoder_resnet.ini
For each of them we must set the following variables to the correct paths: caffemodel_file
and prototxt_file
.
For CaffeNet
do:
$ cd ~/.local/share/yarp/contexts/himrep
$ gedit caffeCoder_caffenet.ini
And then set:
caffemodel_file $Caffe_ROOT/models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel
prototxt_file ~/.local/share/yarp/contexts/himrep/bvlc_reference_caffenet_val.prototxt
replacing the $Caffe_ROOT
env variable and ~/
with their full values.
For ResNet-50
do:
gedit caffeCoder_resnet.ini
And then set:
caffemodel_file $Caffe_ROOT/models/ResNet50/ResNet-50-model.caffemodel
prototxt_file ~/.local/share/yarp/contexts/himrep/resnet_val.prototxt
replacing the $Caffe_ROOT
env variable and ~/
with their full values.
For other parameters and input and output ports we refer to the module documentation here.
In Caffe, the weights of network models are stored in a .caffemodel
file, whose absolute path must be provided to the caffeCoder
in the caffemodel_file
parameter. The network definition file to be used in inference mode instead is usually called deploy.prototxt
and must be provided to the caffeCoder
in the prototxt_file
parameter.
In Caffe's Model Zoo there are many models available with related descriptions and usage instructions. You can use them with caffeCoder
, by copying their deploy.prototxt
and replacing their input layer with a corresponding MemoryData
layer.
In order to correctly use a network in inference mode, the mean image (or pixel) of the training set that has been used to learn the model parameters must be subtracted from any image that is fed to the model. The mean image is usully stored in Caffe with a .binaryproto
file. You will to specify this in the MemoryData
layer and:
- if the mean image is subtracted, the
.binaryproto
file must be downloaded and correctly pointed by the.prototxt
in your system (mean_file
field of theMemoryData
layer); - if the mean pixel is subtracted, you will need to specify, in the
.ini
file, two additional parameters (as, e.g., we do incaffeCoder_googlenet.ini
) related to the width and height (resizeWidth
andresizeHeight
) to which the input image will be resized before being fed to theMemoryData
layer.
Another important parameter to be set in the .ini
file is the tag/name of the output of the layer we want to read. This can be specified by setting the blob_name
parameter.
For a complete and continuously updated guide to how to install Caffe in any configuration you should go to Caffe - Installation. We do not cover here exhaustively the procedure. We just report the procedure we followed at present (07/2017) to use Caffe from this module on Ubuntu 16.04 LTS.
Download and install CUDA drivers and toolkit by following CUDA Installation Guide for Linux.
Download the cuDNN version you need (depending on the toolkit version) from NVIDIA cuDNN library (you have to sign up as CUDA Registered Developer, it's for free), and install it by following the instructions.
We chose the OpenBLAS implementation but also ATLAS or Intel MKL are supported by Caffe. You can either download the source code from OpenBLAS page and follow instructions to compile and install it, or install the package. In the latter case, you can just do:
sudo apt-get install libopenblas-dev
In case you compile the source code, we recommend to install in a separate and specified location of your choice instead of the default /usr/local
by doing:
tar -xzvf <downloaded-openblas-archive-name>.tar.gz
cd <downloaded-openblas-archive-name>
make PREFIX=/path/to/install/dir install
and setting the OpenBLAS_HOME
environment variable to the installation path to allow Caffe finding it.
As for BLAS, you can either download the source code from Boost C++ Libraries and follow instructions to compile and install it, or install the package. In any case, check the supported versions on Caffe website. For convenience, again we report the followed instructions (that can be found on Boost page) to compile from source:
tar --bzip2 -xf <downloaded-boost-archive>.tar.bz2
cd <downloaded-boost-archive>
./bootstrap.sh --prefix=path/to/install/dir
./b2 install
and set the Boost_DIR
environment variable to the installation path to allow Caffe finding it, or to download the package:
sudo apt-get install libboost-all-dev
OpenCV comes with the icub-common
package. In case you need to compile it from source, you can download the source code from OpenCV - Downloads and compile it through the usual:
unzip <downloaded-opencv-archive-name>.zip
cd <downloaded-opencv-archive-name>
mkdir build && cd build
ccmake ../
make
make install
Where in the CMake configuration you should have set the installation path (CMAKE\_INSTALL\_PREFIX
) to one of your choice. In this case, set the OpenCV_DIR
environment variable to the installation path to allow Caffe finding it.
Refer to Caffe - Ubuntu Installation for updated instructions or manual installation. On Ubunutu 16.04 LTS at the time being we have done:
Google Protobuf Buffers C++:
sudo apt-get install libprotobuf-dev protobuf-compiler
Google Logging:
sudo apt-get install libgoogle-glog-dev
Google Flags:
sudo apt-get install libgflags-dev
LevelDB:
sudo apt-get install libleveldb-dev
HDF5:
sudo apt-get install libhdf5-serial-dev
LMDB:
sudo apt-get install liblmdb-dev
snappy:
sudo apt-get install libsnappy-dev
Since Caffe is under active development, we try to be compatible with the changes progressively introduced in the framework and periodically check the compatibility of caffeCoder
against its master
branch. Therefore you can refer to it and clone it:
git clone https://www.github.com/BVLC/caffe.git
Note that at present Caffe RC3 is not compatible anymore with caffeCoder
.
In order to be able to link Caffe from an external project via CMake (as this application does) you should compile Caffe via CMake and not manually editing the Makefile.config.
Related instructions can be found at Caffe - Installation or here. Generally you can do:
cd caffe
mkdir build
cd build
ccmake ../ (NOTE *)
make all
make runtest
make install
NOTE In the configuration step:
-
you should be able to link to all installed dependencies, if you have set correctly the environment variables
-
set BLAS to
open
orOpen
if you installed OpenBLAS as we did: if you still see that the Atlas implementation is not found, this might be an issue with Caffe: in any case, if you check by toggling the advanced mode, you should see that OpenBLAS has been found in your installation directory -
there is no need to build the Matlab wrapper for Caffe
-
use the cuDNN library if possible (set USE_CUDNN to ON)
-
important if you are on Ubuntu 16.04 and use GCC 5.3 with CUDA 7.5: as noted here, in this case you need to modify the
CMAKE_CXX_FLAGS
CMake variable by appending to it the-D_FORCE_INLINES
flag. You can do it during the interactive configuration step withccmake
or by modifying the following line in theCMakeLists.txt
:set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -D_FORCE_INLINES -Wall")
Finally, set the Caffe_DIR
environment variable to the installation path to allow finding Caffe via find_package
.
This module has been presented and benchmarked in the iCub scenario in the following paper:
Teaching iCub to recognize objects using deep Convolutional Neural Networks Giulia Pasquale, Carlo Ciliberto, Francesca Odone, Lorenzo Rosasco and Lorenzo Natale, Proceedings of The 4th Workshop on Machine Learning for Interactive Systems, pp. 21–25, 2015
@inproceedings{pasquale15,
author = {Giulia Pasquale and Carlo Ciliberto and Francesca Odone and Lorenzo Rosasco and Lorenzo Natale},
title = {Teaching iCub to recognize objects using deep Convolutional Neural Networks},
journal = {Proceedings of the 4th Workshop on Machine Learning for Interactive Systems, 32nd International Conference on Machine Learning},
year = {2015},
volume = {43},
pages = {21--25},
url = {http://www.jmlr.org/proceedings/papers/v43/pasquale15}
}
Material included here is Copyright of iCub Facility - Istituto Italiano di Tecnologia and is released under the terms of the GPL v2.0 or later. See the file LICENSE for details.