Remove deleted files
[ti-machine-learning/ti-machine-learning.git] / doc / timl.dox
1 /*!\r
2 \r
3 \defgroup app app\r
4 \brief Applications\r
5 \r
6 \defgroup appCNN appCNN\r
7 \ingroup app\r
8 \brief CNN applications\r
9 \r
10 \defgroup benchmark benchmark\r
11 \brief Bechmarks\r
12 \r
13 \defgroup benchmarkCNN benchmarkCNN\r
14 \brief CNN benchmarks\r
15 \ingroup benchmark\r
16 \r
17 \defgroup test test\r
18 \brief Test\r
19 \r
20 \mainpage Introduction\r
21 \r
22 \section sectionOverview Overview\r
23 \r
24 The Texas Instruments Machine Learning (TIML) library is C implementation of common machine learning functions optimized for TI embedded devices.  Initially, the library supports convolutional neural networks (CNNs), but will grow with time in scope.  The library has a minimal set of dependencies upon other libraries to simplify the installation and use.\r
25 \r
26 \section sectionInstallation Installation\r
27 \r
28 \subsection subsectionDependencies Dependencies\r
29 <B> TIML library dependencies </B><BR>\r
30 The TIML library requires a high performance C basic linear algebra subprogram (CBLAS) library and a library for reading Joint Photographic Experts Group (JPEG) images.  An optimized CBLAS implementation is included with TI embedded devices.  For pre development work on a desktop, a reference (unoptimized) CBLAS implementation can be downloaded from http://www.netlib.org/blas/blast-forum/cblas.tgz or in Ubuntu using the command\r
31 \r
32 <KBD>\r
33 sudo apt-get install libatlas-base-dev\r
34 </KBD>\r
35 \r
36 A JPEG library, libjpeg, can be downloaded from \n\r
37 http://sourceforge.net/projects/libjpeg/files/latest/download?source=files \n\r
38 or in Ubuntu using the command\r
39 \r
40 <KBD>\r
41 sudo apt-get install libjpeg-dev\r
42 </KBD>\r
43 \r
44 <B> Application dependencies </B><BR>\r
45 The ImageNet database conversion application resizes all the images to size 256*256. The resizing is done using openCV. In Ubuntu, use the following command to install openCV\r
46 \r
47 <KBD>\r
48 sudo apt-get install libopencv-dev\r
49 </KBD>\r
50 \r
51 The interop application converts a CNN model in Caffe format to TIML CNN format. The Caffe format depends on google's protocol buffer library. To install the library, use command\r
52 \r
53 <KBD>\r
54 sudo apt-get install libprotobuf-dev\r
55 </KBD>\r
56 \r
57 \r
58 \subsection subsectionDirectoryStructure Directory Structure\r
59 \r
60 Install the TIML library by unzipping the zip file to a directory referred to as <install_directory>.\r
61 At a terminal prompt, change the working directory to <KBD><install_directory>/build</KBD> and use the command <KBD>make all</KBD> to compile the library.\r
62 The library file will be placed inside the <KBD><install_directory>/bin</KBD> folder.\r
63 \r
64 The directory structure of the compiled library is shown as follows:\r
65 - <KBD><install_directory>/bin</KBD>: library binary file directory\r
66 - <KBD><install_directory>/build</KBD>: makefile directory\r
67 - <KBD><install_directory>/doc</KBD>: doxygen file directory\r
68 - <KBD><install_directory>/src/common</KBD>: common library directory\r
69         - <KBD><install_directory>/src/common/api</KBD>: library API source file\r
70         - <KBD><install_directory>/src/common/cnn</KBD>: cnn moudule source file\r
71         - <KBD><install_directory>/src/common/util</KBD>: util moudule source file\r
72 - <KBD><install_directory>/src/test</KBD>: test module directory\r
73         - <KBD><install_directory>/src/test/cnn</KBD>: cnn test source file\r
74         - <KBD><install_directory>/src/test/util</KBD>: util test source file\r
75 - <KBD><install_directory>/src/benchmark</KBD>: benchmark module directory\r
76         - <KBD><install_directory>/src/benchmark/cnn</KBD>: cnn benchmark source file\r
77            - <KBD><install_directory>/src/benchmark/cnn/class</KBD>: cnn classification benchmark source file\r
78 - <KBD><install_directory>/src/app</KBD>: application module directory\r
79         - <KBD><install_directory>/src/app/cnn</KBD>: cnn application source file\r
80       - <KBD><install_directory>/src/app/cnn/class</KBD>: cnn classification application source file\r
81          - <KBD><install_directory>/src/app/cnn/class/cifar10</KBD>: cnn CIFAR10 database classification application source file\r
82          - <KBD><install_directory>/src/app/cnn/class/imagenet</KBD>: cnn ImageNet database classification application source file\r
83          - <KBD><install_directory>/src/app/cnn/class/mnist</KBD>: cnn MNIST database classification application source file\r
84       - <KBD><install_directory>/src/app/cnn/scene</KBD>: cnn scene labeling application source file\r
85          - <KBD><install_directory>/src/app/cnn/scene/sbd</KBD>: cnn stanford background dataset scene labeling application source file\r
86       - <KBD><install_directory>/src/app/cnn/interop</KBD>: cnn interoperation application source file\r
87          - <KBD><install_directory>/src/app/cnn/interop/caffe</KBD>: cnn-caffe interoperation application source file\r
88       - <KBD><install_directory>/src/app/cnn/convert</KBD>: cnn database conversion application source file\r
89          - <KBD><install_directory>/src/app/cnn/convert/imagenet</KBD>: cnn ImageNet database conversion application source file\r
90          - <KBD><install_directory>/src/app/cnn/convert/sbd</KBD>: cnn SBD database conversion application source file\r
91 - <KBD><install_directory>/src/database</KBD>: database directory\r
92         - cifar10: Canadian Institute for Advanced Research-10 Class\r
93         - imagenet: ImageNet 2012\r
94         - mnist: Mixed National Institute of Standards and Technology\r
95         - sbd: Stanford Background Dataset\r
96         - model: pretrained models\r
97                 - cifar10\r
98                 - alexnet\r
99                 - caffenet\r
100                 - vggnet\r
101                 - mnist\r
102                 - sbd\r
103 \r
104 \subsection subsectionDoc Document Genearation\r
105 Documents of html and pdf formats can be generated using Doxygen. Make sure you have both latex and Doxygen installed. In Ubuntu, the installation commands are\r
106 \r
107 - <KBD>sudo apt-get install doxygen</KBD>\r
108 - <KBD>sudo apt-get install texlive-full</KBD>\r
109 \r
110 Use the command <KBD>doxygen <install- <KBD><install_directory>/src/app/cnn/scene</KBD>: cnn scene labeling application source file_directory>/doc/timl.Doxyfile</KBD> to generate the documents.\r
111 The html version is located at <KBD>doxygen <install_directory>/doc/html</KBD>. To generate the pdf version, change the directory\r
112 to <KBD>doxygen <install_directory>/doc/latex</KBD> and run the command <KBD>make</KBD>. A filed named refman.pdf will be generated in the currnet folder.\r
113 \r
114 \subsection subsectionImageDatabases Image Databases\r
115 \r
116 In order to run the examples provided by the library, it is required to download additional databases of test images.\r
117 \r
118 <B>MNIST</B>\r
119 \r
120 The MNIST database of handwritten digits, available from this page, has a training set of 60,000 examples, and a test set of 10,000 examples. It is a subset of a larger set available from NIST. The digits have been size-normalized and centered in a fixed-size image. \r
121 \r
122 You can download the MNIST database from http://yann.lecun.com/exdb/mnist/ or simpliy change the directory to <KBD><install_directory>/src/database/mnist</KBD> and run the script <KBD>./databaseMNISTDownload.sh</KBD>.\r
123 After the download, there should be 4 files in the folder:\r
124 - <KBD>t10k-images.idx3-ubyte</KBD>\r
125 - <KBD>t10k-labels.idx1-ubyte</KBD>\r
126 - <KBD>train-images.idx3-ubyte</KBD>\r
127 - <KBD>train-labels.idx1-ubyte</KBD>.\r
128 \r
129 <B>CIFAR10</B>\r
130 \r
131 The CIFAR-10 dataset consists of 60000 32x32 colour images in 10 classes, with 6000 images per class.\r
132 The dataset is divided into five training batches and one test batch, each with 10000 images. The test batch contains exactly 1000 randomly-selected images from each class.\r
133 The training batches contain the remaining images in random order, but some training batches may contain more images from one class than another.\r
134 Between them, the training batches contain exactly 5000 images from each class. \r
135 \r
136 You can download the CIFAR10 database from http://www.cs.toronto.edu/~kriz/cifar.html or simpliy change the directory to <KBD><install_directory>/src/database/cifar10</KBD> and run the script <KBD>./databaseCIFAR10Download.sh</KBD>.\r
137 After the download, there should be 6 files in the folder:\r
138 - <KBD>data_batch_1.bin</KBD>\r
139 - <KBD>data_batch_2.bin</KBD>\r
140 - <KBD>data_batch_3.bin</KBD>\r
141 - <KBD>data_batch_4.bin</KBD>\r
142 - <KBD>data_batch_5.bin</KBD>\r
143 - <KBD>test_batch_6.bin</KBD>\r
144 \r
145 <B>ImageNet</B>\r
146 \r
147 ImageNet is an image dataset organized according to the WordNet hierarchy.Each meaningful concept in WordNet, possibly described by multiple words or word phrases, is called a "synonym set" or "synset".\r
148 There are more than 100,000 synsets in WordNet, majority of them are nouns (80,000+).\r
149 ImageNet aims to provide on average 1000 images to illustrate each synset. Images of each concept are quality-controlled and human-annotated.\r
150 \r
151 Download the database from http://www.image-net.org/challenges/LSVRC/2012/nonpub-downloads to <install_directory>/database/imagnet.\r
152 You need to register before you can download the database.http://dags.stanford.edu/projects/scenedataset.html\r
153 - Download the training images of size 138GB and MD5: 1d675b47d978889d74fa0da5fadfb00e\r
154 - Download the validation images of size 6.3GB and MD5: 29b22e2961454d5413ddabcf34fc5622\r
155 - Download the auxiliary  files by changing the working directory to <KBD><install_directory>/src/database/imagnet</KBD> and runing the script <KBD> ./databaseImageNetDownload.sh </KBD>\r
156 - Extract all the files to the <install_directory>/src/database/imagnet\r
157 - Change run the script ./databaseImageNetConvert.sh to convert the raw database to a format that is ready to be processed by TIML. You may need to change the path variables in this script if you choose to store the database \r
158   in other directories. You can also specify the number of images to be converted in the script.\r
159 \r
160 After the conversion, there should be two folders, test and train, in <install_directory>/src/database/imagnet.\r
161 There will be a single labels.txt file in each of the folder. All the images will be resized to 256*256.\r
162 \r
163 <B>Stanford Background Dataset</B>\r
164 \r
165 The Stanford Background Dataset is a new dataset introduced in Gould et al. (ICCV 2009) for evaluating methods for geometric and semantic scene understanding.\r
166 The dataset contains 715 images chosen from existing public datasets: LabelMe, MSRC, PASCAL VOC and Geometric Context.\r
167 The selection criteria were for the images to be of outdoor scenes, have approximately 320-by-240 pixels, contain at least one foreground object, and have the horizon position within the image.\r
168 \r
169 You can download the database from http://dags.stanford.edu/data/iccv09Data.tar.gz \r
170 or simply change the working directory to <KBD><install_directory>/src/database/sbd</KBD> and run the script <KBD>databaseSBDDownload.sh</KBD>\r
171 To convert the database to TIML compatible format, run the script ./databaseSBDConvert.sh. You can specify the number of images used for training and testing by changing the corresponding variables in the script. After running the script, there should be two folders named "train"  and "test" in the current folder.\r
172 \r
173 \subsection subsectionCNNPretrainedModels CNN Pretrained Models\r
174 TIML can convert models pretrained by Caffe\cite Caffe to a format that is compatible with TIML.\r
175 Caffe is a deep learning framework developed by the Berkeley Vision and Learning Center (BVLC).\r
176 You can train your CNN on Caffe on CPU or GPU, save the parameters and then convert it to a format supported by TIML.\r
177 \r
178 <B> AlexNet </B>\cite AlexNet\r
179 \r
180 AlexNet is a deep convolutional neural network to classify the 1.3 million high-resolution images in the LSVRC-2010 ImageNet training set into the 1000 different classes.\r
181 On the test data, AlexNet achieved top-1 and top-5 error rates of 39.7\% and 18.9\% which is considerably better than the previous state-of-the-art results.\r
182 The neural network, which has 60 million parameters and 500,000 neurons, consists of five convolutional layers, some of which are followed by max-pooling layers, and two globally connected layers with a final 1000-way softmax. \r
183 - Download the Caffe AlexNet binary file from http://dl.caffe.berkeleyvision.org/bvlc_alexnet.caffemodel to <install_directory>/src/database/model/alexnet\r
184 - Download the Caffe AlexNet depoly file from https://github.com/BVLC/caffe/blob/master/models/bvlc_alexnet/deploy.prototxt to <install_directory>/src/database/model/alexnet\r
185 - Run the script ./databaseModelAlexNetInterop.sh to perform the conversion\r
186 \r
187 After the conversion, there should two files in <install_directory>/database/model/alexnet:\r
188 - databaseModelAlexNet.m                        <I>A text file that defines the structure of the CNN</I>\r
189 - databaseModelAlexNet.m.params <I>A binary file that stores the parameters of the CNN</I>\r
190 \r
191 <B> CaffeNet </B>\r
192 \r
193 The CaffeNet is a replication of the model described in the AlexNet publication with some differences:\r
194 - not training with the relighting data-augmentation;\r
195 - the order of pooling and normalization layers is switched (in CaffeNet, pooling is done before normalization).\r
196 \r
197 This model obtains a top-1 accuracy 57.4% and a top-5 accuracy 80.4% on the validation set, using just the center crop.\r
198 \r
199 - Download the Caffe CaffeNet binary file from http://dl.caffe.berkeleyvision.org/bvlc_reference_caffenet.caffemodel to <install_directory>/database/model/caffenet\r
200 - Download the Caffe CaffeNet depoly file from https://github.com/BVLC/caffe/blob/master/models/bvlc_reference_caffenet/deploy.prototxt to <install_directory>/src/database/model/caffenet\r
201 - Run the script ./databaseModelCaffeNetInterop.sh to perform the conversion\r
202 \r
203 After the conversion, there should two files in <install_directory>/src/database/model/caffenet:\r
204 - databaseModelCaffeNet.m\r
205 - databaseModelCaffeNet.m.params\r
206 \r
207 <B> VGGNet </B> \cite VGG\r
208 \r
209 VGGNet shows that a significant improvement on the prior-art configurations can be achieved by increasing the depth to 16-19 weight layers, which is substantially deeper than what has been used in the prior art.\r
210 To reduce the number of parameters in such very deep networks, the researchers use very small 3×3 filters in all convolutional layers.\r
211  \r
212 - Download the VGGNet binary file from http://www.robots.ox.ac.uk/~vgg/software/very_deep/caffe/VGG_ILSVRC_16_layers.caffemodel to <install_directory>/src/database/model/vggnet\r
213 - Download the VGGNet depoly file from https://gist.githubusercontent.com/ksimonyan/211839e770f7b538e2d8/raw/0067c9b32f60362c74f4c445a080beed06b07eb3/VGG_ILSVRC_16_layers_deploy.prototxt to <install_directory>/src/database/model/vggnet\r
214 - Run the script ./databaseModelVGGNetInterop.sh to perform the conversion\r
215 \r
216 After the conversion, there should two files in <install_directory>/src/database/model/caffenet:\r
217 - databaseModelVGGNet.m\r
218 - databaseModelVGGNet.m.params\r
219 \r
220 <B> MNIST </B>\r
221 A pretrained CNN for MNIST database is located at <install_directory>/src/database/model/mnist:\r
222 - databaseModelMNIST.m\r
223 - databaseModelMNIST.m.params\r
224 \r
225 <B> CIFAR10 </B>\r
226 A pretrained CNN for CIFAR10 database is located at <install_directory>/src/database/model/cifar10:\r
227 - databaseModelCIFAR10.m\r
228 - databaseModelCIFAR10.m.params\r
229 \r
230 \r
231 \section sectionCNNs Convolutional Neural Networks (CNNs)\r
232 \r
233 The TIML library provides a set of APIs that allow a user to implement a CNN architecture and perform training and testing.  Common CNN layer types are supported in the current version and more will be added in future versions.  Both image classification and scene labeling examples are provided.\r
234 \r
235 This section briefly describes the use of CNN library APIs.  For complete examples, refer to the folder <KBD><install_directory>/src/app/cnn</KBD>\r
236 \r
237 \subsection subsectionTrainingParameters Training Parameters\r
238 \r
239 The default training parameters structure is obtained by calling `timlCNNTrainingParamsDefault()`.  Default parameters can be overridden by setting specific field values (refer to `timlCNNTrainingParams` for details).\r
240 \r
241 \subsection subsectionLayers Layers\r
242 \r
243 This section describes the different CNN layers supported by the TIML library.  To create a CNN, call `timlCNNCreateConvNeuralNetwork()`.  Here is an example code block in `timlTestCNNSimpleTraining()` that generates a simple CNN with 8 layer types:\r
244 \r
245 ~~~~~~~~~~~~~~~{.c}\r
246    trainingParams              = timlCNNTrainingParamsDefault();\r
247    trainingParams.batchSize    = BATCH_SIZE;\r
248    trainingParams.learningRate = 0.1;\r
249    cnn = timlCNNCreateConvNeuralNetwork(trainingParams, 0);\r
250    inputParams       = timlCNNInputParamsDefault();\r
251    inputParams.scale = 1.0/256.0;\r
252    timlCNNAddInputLayer(cnn, IMAGE_ROW, IMAGE_COL, IMAGE_CHANNEL, inputParams);            // input layer\r
253    timlCNNAddConvLayer(cnn, 5, 5, 1, 1, 6, timlCNNConvParamsDefault());                    // conv layer\r
254    timlCNNAddNonlinearLayer(cnn, Util_Relu);                                               // relu layer\r
255    timlCNNAddPoolingLayer(cnn, 4, 4, 4, 4, CNN_MaxPooling, timlCNNPoolingParamsDefault()); // max pooling layer\r
256    timlCNNAddNormLayer(cnn, timlCNNNormParamsDefault());                                   // norm layer\r
257    timlCNNAddDropoutLayer(cnn, 0.5);                                                       // dropout layer\r
258    timlCNNAddLinearLayer(cnn, 10, timlCNNLinearParamsDefault());                           // linear layer\r
259    timlCNNAddNonlinearLayer(cnn, Util_Softmax);                                            // softmax layer\r
260    timlCNNInitialize(cnn);\r
261    timlCNNReset(cnn);\r
262 ~~~~~~~~~~~~~~~\r
263 \r
264 \subsubsection subsubsectionInputLayer Input\r
265 \r
266 The input layer is responsible for preprocessing the raw input data. The user can choose to crop, scale, mirror, or subtract the mean form the raw image. The required parameters are the dimensions (row, column, channel) of the feature maps in the input layer.  Refer to `timlCNNAddInputLayer()` for more details.\r
267 \r
268 \subsubsection subsubsectionConvolutionalLayer Convolutional\r
269 \r
270 The convolutional layer performs 2D convolution or correlation between feature maps and kernels.  The required parameters are the 2D kernel dimension (row, column), kernel strides along row and column and the output feature map channel.  For each feature map in the previous layer, there will be a corresponding 2D kernel applied to it and links to each feature map in the next layer.  Refer to `timlCNNAddConvLayer()` for more detail.\r
271 \r
272 \subsubsection subsubsectionNonlinearLayer Nonlinear\r
273 \r
274 The nonlinear layer implements 1 nonlinearity, supported types are:\r
275 \r
276 - rectified linear unit\n\r
277 \f$ f(z) = \max(0, z) \f$\r
278 - sigmoid\n\r
279 \f$ f(z) = \frac{1}{1+e^{-z}} \f$\r
280 - softmax\n\r
281 \f$ f(z)_j = \frac{e^{-z_j}}{\sum_{i=0}^{K}e^{-z_i}} \f$\r
282 - tanh\n\r
283 \f$ f(z) = \frac{e^{z}-e^{-z}}{e^{z}+e^{-z}} \f$\r
284 .\r
285 \r
286 To add a nonlinear layer to the cnn structure, call the function `timlCNNAddNonlinearLayer()`.  Note that for image classification applications, the last layer is most commonly chosen to be a softmax nonlinear layer that output an array of class probabilities that sum up to 1. \r
287 \r
288 \subsubsection subsubsectionPoolingLayer Pooling\r
289 \r
290 The pooling layer performs a local maxing or averaging operation on the feature maps.  The required parameters are the pooling kernel dimension (row, col), kernel strides along column and row and the pooling method.  Refer to `timlCNNAddPoolingLayer()` for more details.\r
291 \r
292 \subsubsection subsubsectionNormalizationLayer Normalization\r
293 \r
294 The normalization layer performs local contrast normalization across channels:\n\r
295 \f$\r
296 y^i = \frac{x^i}{(1+\frac{\alpha}{N}\sum^{\min(N-1, i+N/2)}_{j=\max(0, i-N/2)}x^j)^\beta}\r
297 \f$\r
298 ,where \f$x^i\f$ stands for the feature map in the i-th channel.  The channel span N defaults to 5.  \f$\alpha\f$ and \f$\beta\f$ default to 0.001 and 0.75, respectively.  Refer to `timlCNNAddNormLayer()` for more details.\r
299 \r
300 \subsubsection subsubsectionDropoutLayer Dropout\r
301 \r
302 The dropout layer is used during training to help prevent overfitting.  Each element in the feature map is set to 0 (deactivated) according to a preset probability in the training phase.  Note the dropout layer is simply a pass through in the testing phase.  Refer to `timlCNNAddDropoutLayer()` for more details.\r
303 \r
304 \subsubsection subsubsectionLinearLayer Linear\r
305 \r
306 The linear layer is also referred to as the inner product layer or fully connected layer.  A traditional neural network layer, the feature map in the previous layer is first vectorized and then multiplied by a weight matrix to obtain the feature map of next layer.  The required parameter is the dimension of the output feature map.  Refer to `timlCNNAddLinearLayer()` for more details.\r
307 \r
308 \subsection subsectionMemory Memory\r
309 \r
310 Once the setup of the cnn structure is complete, `timlCNNInitialize()` is called to allocate the memory.  There are 3 levels of memory allocation specified inside `timlCNNTrainingParams`.\r
311 - Level 1 can be used both for training and testing and requires the most memory.\r
312 - Level 2 requires less memory but can only be used for testing.\r
313 - Level 3 uses even less memory by operating on a memory pool and can also only be used for testing. \r
314 \r
315 Note that this function does not initialize the kernels or weights in the convolutional and linear layers.  To perform that initialization the function `timlCNNReset()` is used.\r
316 \r
317 The exact memory allocated in bytes can be obtained by calling `timlCNNMemory()`. \r
318 \r
319 `timlCNNResize()` is used to resize the dimension of a CNN. Once the input layer dimension is changed, the dimension of the following layers will be re-calcualted and re-allocated. \r
320 \r
321 `timlCNNClone()` creates a independent copy of a CNN. The function `timlCNNShareParams()` differs from `timlCNNClone()` in that the CNN structure returned by this function allocates its own feature map memory but points to the parameter memory of its target.\r
322 Therefore, `timlCNNShareParams()` returns a structure that takes less memory compared with the structure returned by `timlCNNClone()`, which allocates its own parameter memory.\r
323 The user should be careful when manipulating the shared copy of a CNN as it may write to the parameters of its target.\r
324 `timlCNNShareParams()` is used primarily to accelerate the training and testing of a CNN. Multiple shared copies of a CNN can work in parallel by using OpenMP.\r
325 \r
326 To free the space allocated by the CNN, call the function `timlCNNDelete()`.\r
327 \r
328 \subsection subsectionUtilityFunctions Utility Functions\r
329 \r
330 Utility functions aim to perform miscellaneous functions that related to IO.\r
331 \r
332 The phase of a CNN can be set to training or testing by calling `timlCNNSetMode()`. A CNN allocated with level 2 or 3 is not allowed to be set to the training mode as no memory is allocated to run the back propagation algorithm.\r
333 In the testing mode, only forward propagation will be performed.\r
334 \r
335 CNN structure information can be printed to the console by using `timlCNNPrint()`. `timlCNNGetLayerNum()` returns the number of layers of the CNN.\r
336 `timlCNNGetParamsNum()` returns the total number of parameters in the CNN.\r
337 \r
338 `timlCNNWriteToFile()` writes the cnn structure into a combination of text and binary files.  The key parameter of this function is the `timlUtilParamsLevel`, which specifies the level of details of the writing.\r
339 - Level 1 only writes the network structure to a text file without specifying the parameters or feature maps of the cnn.\r
340 The text file is formatted in a syntax that is compatible with Matlab script.\r
341 - Level 2 writes both the network structure text file and the binary parameter file.\r
342 - Level 3 writes one more state binary files.  Level 3 is only used for debugging purpose.\r
343 Note that the path of the binary files to read is written into the text file. \r
344 \r
345 Similarly, `timlCNNReadFromFile()` can be used to read a CNN from text or binary files.\r
346 \r
347 One example of the generated text file is shown below:\r
348 ~~~~~~~~~~~~~~~~~~\r
349 paramsBinaryFileName = './database/test/cnn/timl_cnn_simple_config.m.params';\r
350 stateBinaryFileName  = './database/test/cnn/timl_cnn_simple_config.m.state';\r
351 \r
352 cnn.params.count          = 0;\r
353 cnn.params.batchSize      = 100;\r
354 cnn.params.epoch          = 1;\r
355 cnn.params.learningRate   = 0.1000;\r
356 cnn.params.momentum       = 0.0000;\r
357 cnn.params.phase          = 0;\r
358 cnn.params.allocatorLevel = 0;\r
359 cnn.params.costType       = 0;\r
360 \r
361 layerNum                                    = 8;\r
362 cnn.layer(1).id                             = 1;\r
363 cnn.layer(1).type                           = 0;\r
364 cnn.layer(1).row                            = 28;\r
365 cnn.layer(1).col                            = 28;\r
366 cnn.layer(1).channel                        = 1;\r
367 cnn.layer(1).inputParams.row                = 28;\r
368 cnn.layer(1).inputParams.col                = 28;\r
369 cnn.layer(1).inputParams.channel            = 1;\r
370 cnn.layer(1).inputParams.scale              = 1.0000;\r
371 cnn.layer(1).inputParams.trainingCropType   = 0;\r
372 cnn.layer(1).inputParams.trainingMirrorType = 1;\r
373 cnn.layer(1).inputParams.testingCropType    = 0;\r
374 cnn.layer(1).inputParams.testingMirrorType  = 1;\r
375 \r
376 cnn.layer(2).id                                 = 2;\r
377 cnn.layer(2).type                               = 1;\r
378 cnn.layer(2).row                                = 24;\r
379 cnn.layer(2).col                                = 24;\r
380 cnn.layer(2).channel                            = 6;\r
381 cnn.layer(2).convParams.kernelRow               = 5;\r
382 cnn.layer(2).convParams.kernelCol               = 5;\r
383 cnn.layer(2).convParams.padUp                   = 0;\r
384 cnn.layer(2).convParams.padDown                 = 0;\r
385 cnn.layer(2).convParams.padLeft                 = 0;\r
386 cnn.layer(2).convParams.padRight                = 0;\r
387 cnn.layer(2).convParams.strideX                 = 1;\r
388 cnn.layer(2).convParams.strideY                 = 1;\r
389 cnn.layer(2).convParams.inputFeatureMapChannel  = 1;\r
390 cnn.layer(2).convParams.outputFeatureMapChannel = 6;\r
391 cnn.layer(2).convParams.type                    = 0;\r
392 cnn.layer(2).convParams.kernelDecayFactor       = 1.0000;\r
393 cnn.layer(2).convParams.kernelInit.type         = 3;\r
394 cnn.layer(2).convParams.kernelLearningFactor    = 1.0000;\r
395 cnn.layer(2).convParams.biasInit.type           = 0;\r
396 cnn.layer(2).convParams.biasLearningFactor      = 1.0000;\r
397 \r
398 cnn.layer(3).id                   = 3;\r
399 cnn.layer(3).type                 = 3;\r
400 cnn.layer(3).row                  = 24;\r
401 cnn.layer(3).col                  = 24;\r
402 cnn.layer(3).channel              = 6;\r
403 cnn.layer(3).nonlinearParams.type = 0;\r
404 \r
405 cnn.layer(4).id                     = 4;\r
406 cnn.layer(4).type                   = 2;\r
407 cnn.layer(4).row                    = 12;\r
408 cnn.layer(4).col                    = 12;\r
409 cnn.layer(4).channel                = 6;\r
410 cnn.layer(4).poolingParams.type     = 0;\r
411 cnn.layer(4).poolingParams.scaleRow = 2;\r
412 cnn.layer(4).poolingParams.scaleCol = 2;\r
413 cnn.layer(4).poolingParams.padUp    = 0;\r
414 cnn.layer(4).poolingParams.padDown  = 0;\r
415 cnn.layer(4).poolingParams.padLeft  = 0;\r
416 cnn.layer(4).poolingParams.padRight = 0;\r
417 cnn.layer(4).poolingParams.strideX  = 2;\r
418 cnn.layer(4).poolingParams.strideY  = 2;\r
419 \r
420 cnn.layer(5).id                 = 5;\r
421 cnn.layer(5).type               = 6;\r
422 cnn.layer(5).row                = 12;\r
423 cnn.layer(5).col                = 12;\r
424 cnn.layer(5).channel            = 6;\r
425 cnn.layer(5).dropoutParams.prob = 0.5000\r
426 \r
427 cnn.layer(6).id               = 6;\r
428 cnn.layer(6).type             = 5;\r
429 cnn.layer(6).row              = 12;\r
430 cnn.layer(6).col              = 12;\r
431 cnn.layer(6).channel          = 6;\r
432 cnn.layer(6).normParams.type  = 0;\r
433 cnn.layer(6).normParams.N     = 5;\r
434 cnn.layer(6).normParams.alpha = 0.0010;\r
435 cnn.layer(6).normParams.beta  = 0.7500;\r
436 \r
437 cnn.layer(7).id                                = 7;\r
438 cnn.layer(7).type                              = 4;\r
439 cnn.layer(7).row                               = 1;\r
440 cnn.layer(7).col                               = 1;\r
441 cnn.layer(7).channel                           = 10;\r
442 cnn.layer(7).linearParams.dim                  = 10;\r
443 cnn.layer(7).linearParams.prevDim              = 864;\r
444 cnn.layer(7).linearParams.weightDecayFactor    = 1.0000;\r
445 cnn.layer(7).linearParams.weightInit.type      = 3;\r
446 cnn.layer(7).linearParams.weightLearningFactor = 1.0000;\r
447 cnn.layer(7).linearParams.biasInit.type        = 0;\r
448 cnn.layer(7).linearParams.biasLearningFactor   = 1.0000;\r
449 \r
450 cnn.layer(8).id                   = 8;\r
451 cnn.layer(8).type                 = 3;\r
452 cnn.layer(8).row                  = 1;\r
453 cnn.layer(8).col                  = 1;\r
454 cnn.layer(8).channel              = 10;\r
455 cnn.layer(8).nonlinearParams.type = 1;\r
456 ~~~~~~~~~~~~~~~~~~\r
457 \r
458 Note that the text file is formatted using Matlab syntax such that the text file can be used as a script to obtain a cnn structure object.\r
459 \r
460 \subsection cnnTraining Training\r
461 \r
462 The following code block in `testCNNSimpleTraining()` performs training:\r
463 \r
464 ~~~~~~~~~~~~~~~{.c}\r
465   // read MNIST database\r
466    printf("2. Read the MNIST database\n");\r
467    timlUtilReadMNIST(DATABASE_PATH, &training, &testing);\r
468 \r
469    // training\r
470    printf("3. Start training\n");\r
471    clock_gettime(CLOCK_REALTIME, &startTime);\r
472    for (i = 0; i < batchNum; i++) {\r
473       timlCNNSupervisedTrainingWithLabelBatchMode(cnn, training.data + i*batchSize*dim, training.label + i*batchSize, dim, batchSize);\r
474    }\r
475    clock_gettime(CLOCK_REALTIME, &endTime);\r
476    trainingTime = timlUtilDiffTime(startTime, endTime);\r
477    printf("Training time = %.2f s.\n", trainingTime/1000000.0);\r
478 ~~~~~~~~~~~~~~~ \r
479 \r
480 In this example, the training and testing image data set structures are read from the MNIST database and then passed into `timlCNNSupervisedTrainingWithLabelBatchMode()`.\r
481 Note that there is also a multi-thread version of this function that called `timlCNNSupervisedTrainingWithLabelBatchMode()`.\r
482 The training time is returned by `timlUtilDiffTime()` in microsecond precision. \r
483 \r
484 \subsection subsectionTesting Testing\r
485 \r
486 The following code block in `testCNNSimpleTesting()` performs testing:\r
487 \r
488 ~~~~~~~~~~~~~~~{.c}\r
489         for(i = 0; i < testing.num; i++)\r
490         {\r
491                 label = timlCNNClassifyTop1SingleMode(cnn, testing.data + i*dim, dim);\r
492                 if (label != testing.label[i]) misClassifyNum++;\r
493         }\r
494 ~~~~~~~~~~~~~~~ \r
495 \r
496 `timlCNNClassifyTop1SingleMode()` returns the top 1 label generated by the CNN.\r
497 A similar function `timlCNNClassifyTopNBatchMode()` that returns the top N labels together with their corresponding probabilities for a batch of data.\r
498 Note that there is also a multi-thread version of this function called `timlCNNClassifyTopNBatchModeOpenMP()` that classifies a batch of images using OpenMP.\r
499  \r
500 \section sectionApplications Applications\r
501 \r
502 Application source code is located at <KBD><install_directory>/src/app</KBD>. To run the applications, change the directory to the corresponding binary files and run the applications.<BR>\r
503 There are 1 application example for Caffe to TIML CNN model interoperation:\r
504 - `appCNNInteropCaffe`: Caffe interoperation\r
505 \r
506 There are 2 application example for Caffe to TIML CNN database conversion:\r
507 - `appCNNConvertImageNet`: ImagNet conversion\r
508 - `appCNNConvertSBD`: SBD conversion\r
509 \r
510 There are 8 application examples for CNN classification:\r
511 - `appCNNClassMNISTTraining()`: MNIST database training\r
512 - `appCNNClassMNISTTesting()`: MNIST database testing\r
513 - `appCNNClassCIFAR10Training()`: CIFAR10 database training\r
514 - `appCNNClassCIFAR10Testing()`: CIFAR10 database testing\r
515 - `appCNNClassCaffeNetTraining()`: CaffeNet database training\r
516 - `appCNNClassCaffeNetTesting()`: CaffeNet database testing\r
517 - `appCNNClassAlexNetTesting()`: AlexNet database training\r
518 - `appCNNClassVGGNetTesting()`: VGGNet database testing\r
519 \r
520 There are 2 application examples for CNN scene labeling:\r
521 - `appCNNSceneSBDTraining()`: scene labeling database training\r
522 - `appCNNSceneSBDTesting()`: scene labeling database testing\r
523 \r
524 \subsection subsectionClassification Classification\r
525 \r
526 Training and testing a CNN for image classification is very straightforward to implement using the TIML library. Let's take the MNIST database for example. \r
527 Here is one code block in `appCNNClassMNISTTraining()`. There are 3 major steps. First, build up the CNN structure using the library API. Next, read the database.\r
528 Third, apply the training function on the database. After the training, you can write the trained network to file(s) using `timlCNNWriteToFile()`.\r
529 ~~~~~~~~~~~~~~~{.c}\r
530    // setup CNN\r
531    printf("1. Build up the CNN\n");\r
532    timlConvNeuralNetwork *cnn = timlCNNCreateConvNeuralNetwork(timlCNNTrainingParamsDefault(), 0);\r
533    cnn->params.learningRate = LEARN_RATE;\r
534    cnn->params.batchSize    = BATCH_SIZE;\r
535    inputParams = timlCNNInputParamsDefault();\r
536    inputParams.scale = 1.0/256.0;\r
537    timlCNNAddInputLayer(cnn, IMAGE_ROW, IMAGE_COL, IMAGE_CHANNEL, inputParams);             // input layer\r
538    convParams = timlCNNConvParamsDefault();\r
539    convParams.kernelInit.type = Util_Xavier;\r
540    timlCNNAddConvLayer(cnn, 5, 5, 1, 1, 20, convParams);                                    // conv layer\r
541    poolingParams = timlCNNPoolingParamsDefault();\r
542    timlCNNAddPoolingLayer(cnn, 2, 2, 2, 2, CNN_MaxPooling, poolingParams);                  // max pooling layer\r
543    convParams = timlCNNConvParamsDefault();\r
544    convParams.kernelInit.type = Util_Xavier;\r
545    timlCNNAddConvLayer(cnn, 5, 5, 1, 1, 50, convParams);                                    // conv layer\r
546    timlCNNAddPoolingLayer(cnn, 2, 2, 2, 2, CNN_MaxPooling, timlCNNPoolingParamsDefault());  // max pooling layer\r
547    timlCNNAddLinearLayer(cnn, 500, timlCNNLinearParamsDefault());                           // linear layer\r
548    timlCNNAddNonlinearLayer(cnn, Util_Relu);                                                // relu layer\r
549    timlCNNAddLinearLayer(cnn, 10, timlCNNLinearParamsDefault());                            // linear layer\r
550    timlCNNAddNonlinearLayer(cnn, Util_Softmax);                                             // softmax layer\r
551    timlCNNInitialize(cnn);\r
552    timlCNNReset(cnn);\r
553    mem = timlCNNMemory(cnn);\r
554    timlCNNPrint(cnn);\r
555    printf("CNN memory allocation = %.10f MB.\n", (float) mem/1024.0/1024.0);\r
556    printf("CNN parameter #       = %ld.\n", timlCNNGetParamsNum(cnn));\r
557 \r
558    // read MNIST database\r
559    printf("2. Read the MNIST database\n");\r
560    timlUtilReadMNIST(DATABASE_PATH, &training, &testing);\r
561 \r
562    // training\r
563    printf("3. Start training\n");\r
564    clock_gettime(CLOCK_REALTIME, &startTime);\r
565    for (i = 0; i < batchNum; i++) {\r
566       timlCNNSupervisedTrainingWithLabelBatchMode(cnn, training.data + i*batchSize*dim, training.label + i*batchSize, dim, batchSize);\r
567    }\r
568    clock_gettime(CLOCK_REALTIME, &endTime);\r
569    trainingTime = timlUtilDiffTime(startTime, endTime);\r
570    printf("Training time = %.2f s.\n", trainingTime/1000000.0);\r
571 ~~~~~~~~~~~~~~~\r
572 Deploying or testing the CNN is even simpler. Here is one code block in `appCNNClassMNISTTesting()`. Again, there are 3 major steps.\r
573 First, read the CNN structure from file(s). Next, read the testing database. Third, apply the testing function to produced the labels generated by the CNN.\r
574 ~~~~~~~~~~~~~~~{.c}\r
575    // read CNN config\r
576    printf("1. Read CNN config\n");\r
577    timlConvNeuralNetwork *cnn = timlCNNReadFromFile(MODEL_PATH, 0);\r
578    timlCNNSetMode(cnn, Util_Tes\subsection subsectionSceneLabeling Scene Labelingt);\r
579    mem = timlCNNMemory(cnn);\r
580    timlCNNPrint(cnn);\r
581    printf("CNN memory allocation = %.10f MB.\n", (float)mem/1024.0/1024.0);\r
582    printf("CNN parameter #       = %lu.\n", timlCNNGetParamsNum(cnn));\r
583 \r
584    // read MNIST database\r
585    printf("2. Read MNIST database\n");\r
586    timlUtilReadMNIST(DATABASE_PATH, &training, &testing);\r
587 \r
588    // testing\r
589    printf("3. Start testing\n");\r
590    clock_gettime(CLOCK_REALTIME, &startTime);\r
591    timlCNNClassifyTopNBatchMode(cnn, testing.data, dim, testing.num, label, NULL, topN);\r
592    clock_gettime(CLOCK_REALTIME, &endTime);\r
593    testingTime = timlUtilDiffTime(startTime, endTime);\r
594    classifyNum = timlUtilClassifyAccuracy(label, topN, testing.num, testing.label);\r
595    classifyPercent = (float)classifyNum/(float)testing.num;\r
596    printf("Testing time      = %.3f s\n", testingTime/1000000.0);\r
597    printf("Classify accuracy = %.3f %%\n", classifyPercent*100.00);\r
598 ~~~~~~~~~~~~~~~\r
599 \r
600 \subsection subsectionSceneLabeling Scene Labeling\r
601 \r
602 Scene labeling consists in labeling each pixel in an image with the category of the object it belongs to. Instread of producing one lable for the entire image,\r
603 scene labeling produces one label for each pixel in the image. Therefore, training a CNN for scene labeling is slightly different from training a CNN for classification purpose.\r
604 The setup of the CNN follows the same procedure:\r
605 \r
606 ~~~~~~~~~~~~~~~{.c}\r
607    // build up the CNN\r
608    printf("1. Build up the CNN\n");\r
609    cnn = timlCNNCreateConvNeuralNetwork(timlCNNTrainingParamsDefault(), 0);\r
610    timlCNNAddInputLayer(cnn, PATCH_SIZE, PATCH_SIZE, IMAGE_CHANNEL, timlCNNInputParamsDefault());\r
611    timlCNNAddConvLayer(cnn, 6, 6, 1, 1, 25, timlCNNConvParamsDefault());                    // conv layer\r
612    timlCNNAddNonlinearLayer(cnn, Util_Tanh);                                                // tanh layer\r
613    timlCNNAddPoolingLayer(cnn, 8, 8, 8, 8, CNN_MaxPooling, timlCNNPoolingParamsDefault());  // max pooling layer\r
614    timlCNNAddConvLayer(cnn, 3, 3, 1, 1, 50, timlCNNConvParamsDefault());                    // conv layer\r
615    timlCNNAddNonlinearLayer(cnn, Util_Tanh);                                                // tanh layer\r
616    timlCNNAddPoolingLayer(cnn, 2, 2, 2, 2, CNN_MaxPooling, timlCNNPoolingParamsDefault());  // max pooling layer\r
617    timlCNNAddLinearLayer(cnn, 8, timlCNNLinearParamsDefault());                             // linear layer\r
618    timlCNNAddNonlinearLayer(cnn, Util_Softmax);                                             // softmax layer\r
619 ~~~~~~~~~~~~~~~ \r
620 \r
621 The second step is to setup the training database:\r
622 ~~~~~~~~~~~~~~~{.c}\r
623    slTraining.num              = TRAIN_IMAGE_NUM;\r
624    slTraining.row              = IMAGE_ROW;\r
625    slTraining.col              = IMAGE_COL;\r
626    slTraining.channel          = IMAGE_CHANNEL;\r
627    slTraining.patchSize        = PATCH_SIZE;\r
628    slTraining.imageFileNameStr = TRAIN_IMAGE_PATH;\r
629    slTraining.labelFileNameStr = TRAIN_LABEL_PATH;\r
630 ~~~~~~~~~~~~~~~ \r
631 \r
632 In this example, 450 images are used for training and 143 images are used for testing.\r
633 The dimension of the images are 240*320*3.  There are 450 text file labels in the training database, each with a 240*320 label matrix.\r
634 The label integer ranges from -1 to 7 (8 classes) with -1 indicating an unlabeled pixel.\r
635 The image and label text file name must follow the format as indicated in the imageFileNameStr and labelFileNameStr.\r
636 For each pixel in the image, a 133*133 patch centered at the pixel is passed into the CNN to output a label.\r
637 \r
638 To train the database, the CNN first randomly selects an image and then randomly selects a pixel.\r
639 Next, a patch centered at that pixel is passed to the CNN for training.\r
640 The pixels are randomly selected without replacement, with 240*320*450 iterations needed to sweep through the entire database 1x.\r
641 There is a specialized training function:\r
642 ~~~~~~~~~~~~~~~{.c}\r
643 appCNNSceneSupervisedTraining(cnn, &slTraining);\r
644 ~~~~~~~~~~~~~~~ \r
645 \r
646 To test one image, a natural way is to generate a patch for each pixel which requires 240*320 forward passes through the CNN.\r
647 However, there is more efficient way to do this which exploits the convolutional structure.\r
648 First, pad zeros on the test image and shift the image in all four directions.\r
649 The number of shifted and zero padded images is proportional to the number of pooling layers in the CNN.\r
650 Next, pass the shifted and zero padded image to the trained CNN.\r
651 Finally, merge the output feature maps into a label matrix for the image.\r
652 Using this approach, the input feature map size is no longer the patch size which is 133*133 in the above example.\r
653 We need to re-calculate the input feature map dimensions and use function `timlCNNResize()` to resize the CNN.\r
654 Note that the above cnn has gone through 2 max pooling layers which scales down the feature map by a factor of 2*8 in the row and column dimensions.\r
655 The formula to calculate the resized row and col for the input layer is:\r
656 ~~~~~~~~~~~~~~~{.c}\r
657    printf("3. Resize the feature maps\n");\r
658    resolutionLossRow = 8*2; // resolution loss due to max pooling\r
659    resolutionLossCol = 8*2; // resolution loss due to max pooling\r
660    resizeRow = slTraining.row + (slTraining.patchSize/2)*2 - (resolutionLossRow - 1);\r
661    resizeCol = slTraining.col + (slTraining.patchSize/2)*2 - (resolutionLossCol - 1);\r
662    timlCNNResize(cnn, resizeRow, resizeCol, slTraining.channel);\r
663 ~~~~~~~~~~~~~~~ \r
664 \r
665 Multiple forward passes through the same CNN can be performed in parallel.\r
666 First, create multilple shared copies of the CNN to form a team called cnnTeam. Then we can call the function `appCNNSceneClassifyOpenMP()` to perform the labeling operation.\r
667 A single-thread version of the function also exists as `appCNNSceneClassify()`;\r
668 The parameter scale in `appCNNSceneClassifyOpenMP()` stands for the scale down factor of the generated label matrix.\r
669 When scale == 1, no downscaling is performed.\r
670 When scale == 4, the generated label matrix would be of size 60*80 and then upscaled to 240*320 to match the size of the image.\r
671 Downscaling can effectively reduce the labeling time.\r
672 \r
673 ~~~~~~~~~~~~~~~{.c}\r
674    // create cnnTeam\r
675    cnnTeam[0] = cnn;\r
676    for (i = 1; i < thread; i++) {\r
677       cnnTeam[i] = timlCNNShareParams(cnn, 0);\r
678    }\r
679 \r
680    // testing\r
681    printf("2. Start testing\n");\r
682    for (i = 0; i < slTesting.num; i++) {\r
683       printf("Read image %03d.jpg\n", i);\r
684       sprintf(str, slTesting.imageFileNameStr, i);\r
685       timlUtilReadFixedSizeJPEG(str, image, slTesting.row, slTesting.col, slTesting.channel);\r
686       clock_gettime(CLOCK_REALTIME, &startTime);\r
687       appCNNSceneClassifyOpenMP(cnnTeam, thread, image, slTesting.row, slTesting.col, slTesting.channel, labelMatrix, scale);\r
688       clock_gettime(CLOCK_REALTIME, &endTime);\r
689       testingTime = timlUtilDiffTime(startTime, endTime);\r
690 \r
691       // read true label\r
692       sprintf(str, slTesting.labelFileNameStr, i);\r
693       fp = fopen(str, "rt");\r
694       for (n = 0; n < slTesting.row; n++) {\r
695          for (m = 0; m < slTesting.col; m++) {\r
696             fscanf(fp, "%d", trueLabelMatrix + n*slTesting.col + m);\r
697          }\r
698          fscanf(fp, "\n");\r
699       }\r
700       fclose(fp);\r
701 \r
702       // calculate accuracy\r
703       labelAccuracy = appCNNSceneAccuracy(labelMatrix, trueLabelMatrix, slTesting.row*slTesting.col);\r
704       printf("Test image %03d label accuracy = %.2f %%\n", i, 100.0*labelAccuracy);\r
705       printf("Test image %03d time           = %.3f s\n", i, testingTime/1000000.0);\r
706    }\r
707 ~~~~~~~~~~~~~~~ \r
708 \r
709 \section sectionBenchmarks Benchmarks\r
710 \r
711 The benchmark source code is located at <KBD><install_directory>/src/benchmark</KBD>.\r
712 \r
713 There are 2 examples for CNN classification benchmark:\r
714 - `benchmarkCNNClassCaffeNetTesting()` : CaffeNet benchmark\r
715 - `benchmarkCNNClassVGGNetTesting()` : VGGNet benchmark\r
716 \r
717 These two functions will benchmark the memory usage and processing time for each individual layers in the network.\r
718 \r
719 */\r