Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Ubuntu committed Jun 19, 2015
2 parents 4928cd9 + 3827be2 commit b77c463
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 113 deletions.
2 changes: 2 additions & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@ In general, cxxnet configuration file contains four kinds of configurations in a
- This page includes all the four tasks you could try by cxxnet.
* [Other Setting](other.md)
- Set other parameters for neural network, related to device selection, running control.
* [Caffe Converter](caffe_converter.md)
- Convert the pretrained model in Caffe to cxxnet.
* [Advanced Usages](advanced.md)
- Some advanced usages of cxxnet can he found here.
1 change: 1 addition & 0 deletions doc/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This page will introduce some advanced usages in cxxnet, including:

#### Multi-label Training
* To use multi-label training, you need the following three steps in additional to the case of single label training:
- For multi-label training, in ```imgrec```, you need to specify ```image_list``` field to indicate the list file that contains the labels.
- First, you need to specify the number of labels in the network by setting ```label_width``` variable in global settings. The following setting denotes that we have 5 labels in the network.
```bash
label_width = 5
Expand Down
25 changes: 25 additions & 0 deletions doc/caffe_converter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#### Introduction
This page will introduce the usage of Caffe converter. It can convert a pretrained model in Caffe to cxxnet format.

#### Preparation
* To begin with the convert, a latest version of Caffe should be built.
* Currently, no automatic configuration file converter is provided. You need to convert the Caffe config file in prototxt to cxxnet configuration format by yourself. **Please make sure that all the layers in original Caffe model has corresponding layer in cxxnet!**
* Converters are provided in both C++ and Python.
- To use the C++ converter, you need to specify the following paths in the config.mk. For example,

```bash
# whether to build caffe converter
USE_CAFFE_CONVERTER = 1
CAFFE_ROOT = ~/caffe
CAFFE_INCLUDE = ~/caffe/include/
CAFFE_LIB = ~/caffe/build/lib/
```

Then, run ```make all``` in the root of cxxnet. if everything is correct, you could find ```caffe_converter``` and ```caffe_mean_converter``` in the ```bin``` folder.

- To use the Python converter, you should first make sure the Python wrapper of Caffe is successfully built. Then you need to specify the paths of Caffe and cxxnet in ```tools/caffe_converter/convert.py```.

#### Convert
* Simply run '''bin/caffe_converter''' and '''tools/caffe_converter/convert.py''', and then follow the instructions.
* To convert the mean file of Caffe, please use the C++ converter: ```caffe_mean_converter```. But we strongly recommend you to recompute the mean file in cxxnet due to the different data augmentation methods in Caffe and cxxnet.

11 changes: 6 additions & 5 deletions doc/io.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ options 2 =
...
iter = end
```
* The basic iterator type is **mnist** , **image** , **imgbin**, **csv**
* The basic iterator type is **mnist** , **image** , **imgrec**, **csv**
* To use thread buffer, declare in this form
```bash
iter = iterator_type
Expand All @@ -36,7 +36,7 @@ iter = end
```bash
shuffle = 1
```
* **shuffle** set 1 to shuffle the **training data**. Note that this option **does not** apply to **imgbin** and **csv**.
* **shuffle** set 1 to shuffle the **training data**. Note that this option **does not** apply to **csv**.

=
### MNIST Iterator
Expand Down Expand Up @@ -83,12 +83,13 @@ A valid image list file is like the following (NO header):
Image binary iterator aims to reduce to IO cost in random seek. It is especially useful when deal with large amount for data like in ImageNet.
* Required field
```bash
image_rec = path to the image binary file
# The image list file can be removed, if only single label exists. It is a must in the multi-label case.
image_list = path to the image list file
image_bin = path to the image binary file
```
* The **image_list** file is described [above](#image-list-file)
* To generate **image_bin** file, you need to use the tool [im2bin](https://github.com/antinucleon/cxxnet/blob/master/tools/im2bin.cpp) in the tools folder.
* You may check an example [here](https://github.com/antinucleon/cxxnet/blob/master/example/ImageNet/ImageNet.conf)
* To generate **image_rec** file, you need to use the tool [im2rec](../tools/im2rec.cc) in the tools folder.
* You may check examples [here](../example/ImageNet/)

#### Realtime Preprocessing Option for Image/Image Binary
```bash
Expand Down
16 changes: 8 additions & 8 deletions example/ImageNet/ImageNet.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
# The scheduling parameters is adapted from Caffe(http:https://caffe.berkeleyvision.org/)

data = train
iter = imgbin
image_list = "../../NameList.train"
image_bin = "../../TRAIN.BIN"
image_root = "../../data/resize256/"
iter = imgrec
# image_list = "../../NameList.train"
image_rec = "../../TRAIN.BIN"
# image_root = "../../data/resize256/"
image_mean = "models/image_net_mean.bin"
rand_crop=1
rand_mirror=1
iter = threadbuffer
iter = end

eval = test
iter = imgbin
image_list = "../../NameList.test"
image_bin = "../../TEST.BIN"
image_root = "../../data/resize256/"
iter = imgrec
# image_list = "../../NameList.test"
image_rec = "../../TEST.BIN"
# image_root = "../../data/resize256/"
image_mean = "models/image_net_mean.bin"
# no random crop and mirror in test
iter = end
Expand Down
12 changes: 6 additions & 6 deletions example/ImageNet/Inception-BN.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
# 10.07% for top 5) from single crop.
#
data = train
iter = imgbin
image_list = "imagenet/train.lst"
image_bin = "imagenet/train.bin"
iter = imgrec
# image_list = "imagenet/train.lst"
image_rec = "imagenet/train.bin"
image_mean = "models/mean_224.bin"
rand_crop=1
rand_mirror=1
Expand All @@ -32,9 +32,9 @@ iter = threadbuffer
iter = end

eval = val
iter = imgbin
image_list = "imagenet/val.lst"
image_bin = "imagenet/val.bin"
iter = imgrec
# image_list = "imagenet/val.lst"
image_rec = "imagenet/val.bin"
image_mean = "models/mean_224.bin"
#no random crop and mirror in test
iter = end
Expand Down
10 changes: 6 additions & 4 deletions example/ImageNet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This tutorial will guide you train your own super vision model. The default conf
* If you want to still use a large batch with not enough RAM, You can set ```update_period=2``` and ```batch_size=128```, this means the parameter update is done every 2 batches, which is equivalent to ```batch_size=256```

### 0.Before you start
Make sure you have downloaded the ImageNet training data. Resize the picture into size 256 * 256 *3 for later we will crop random 227 * 227 * 3 image while training.
Make sure you have downloaded the ImageNet training data. You don't need to resize the images by yourself, currently ```im2rec``` could resize it automatically. You could check the promoting message of ```im2rec``` for details.

### 1.Make the image list
After you get the data, you need to make a [image list file](../../doc/io.md#image-list-file) first. The format is
Expand All @@ -35,14 +35,16 @@ A sample file is provided here
```

### 2.Make the binary file
Although you can use image iterator now. the disk random seek will make the training process extremely slow. So **you'd better generate binary file for training and use imgbin iterator** .
Although you can use image iterator now. the disk random seek will make the training process extremely slow. So **you'd better generate binary file for training and use imgrec iterator** .

To generate binary image, you need to use *im2bin* in the tool folder. The im2bin will take the path of _image list file_ you generated just now, _root path_ of the images and the _output file path_ as input. These processes usually take several hours, so be patient. :)
To generate binary image, you need to use *im2rec* in the tool folder. The im2rec will take the path of _image list file_ you generated just now, _root path_ of the images and the _output file path_ as input. These processes usually take several hours, so be patient. :)

A sample command:
```bash
im2bin ./train.lst ./resized256_images/ TRAIN.BIN
./bin/im2rec image.lst image_root_dir output.bin resize=256
```
More details can be found by running ```./bin/im2rec```.

### 3.Set correct configuration file
Change the iterator path in the [ImageNet.conf](ImageNet.conf) or [kaiming.conf](kaiming.conf) to point to your _image list file_ and _image binary file_ correctly, then just run as MNIST example. After about 20 round, you can see some reasonable result. We strongly recommend to use [kaiming.conf](kaiming.conf), since it could provide much better results than Alexnet, while keeping the time cost unchanged.
By calling
Expand Down
12 changes: 6 additions & 6 deletions example/ImageNet/kaiming.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
# J' model in the paper above

data = train
iter = imginst
image_list = "train.lst"
image_bin = "train.bin"
iter = imgrec
# image_list = "train.lst"
image_rec = "train.bin"
image_mean = "mean_224.bin"
rand_crop=1
rand_mirror=1
Expand All @@ -17,9 +17,9 @@ iter = threadbuffer
iter = end

eval = val
iter = imginst
image_list = "val.lst"
image_bin = "val.bin"
iter = imgrec
# image_list = "val.lst"
image_rec = "val.bin"
image_mean = "mean_224.bin"
# no random crop and mirror in test
iter = end
Expand Down
34 changes: 19 additions & 15 deletions src/cxxnet_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class CXXNetLearnTask {
if (!strcmp(name,"model_dir")) name_model_dir= val;
if (!strcmp(name,"num_round" )) num_round = atoi(val);
if (!strcmp(name,"max_round")) max_round = atoi(val);
if (!strcmp(name, "silent")) silent = atoi(val);
if (!strcmp(name, "silent")) silent = atoi(val);
if (!strcmp(name, "task")) task = val;
if (!strcmp(name, "dev")) {
device = val;
Expand Down Expand Up @@ -431,8 +431,8 @@ class CXXNetLearnTask {
#if MSHADOW_RABIT_PS
is_root = rabit::GetRank() == 0;
print_tracker = rabit::IsDistributed();
#endif
silent = !is_root;
#endif
time_t start = time(NULL);
unsigned long elapsed = 0;
if (continue_training == 0 && name_model_in == "NULL") {
Expand Down Expand Up @@ -470,22 +470,26 @@ class CXXNetLearnTask {
if (++ sample_counter % print_step == 0) {
elapsed = (long)(time(NULL) - start);
if (!silent) {
std::ostringstream os;
os << "round " << std::setw(8) << start_counter - 1
<< ":[" << std::setw(8) << sample_counter << "] " << elapsed << " sec elapsed";
if (print_tracker) {
utils::TrackerPrint(os.str().c_str());
} else {
printf("\r \r");
printf("%s", os.str().c_str());
fflush(stdout);
}
std::ostringstream os;
os << "round " << std::setw(8) << start_counter - 1
<< ":[" << std::setw(8) << sample_counter << "] " << elapsed << " sec elapsed";
if (print_tracker) {
utils::TrackerPrint(os.str().c_str());
} else {
printf("\r \r");
printf("%s", os.str().c_str());
fflush(stdout);
}
}
}
}

if (test_io == 0) {
std::ostringstream os;
if (silent) {
os << "Finish " << sample_counter << " epochs in "
<< (long)(time(NULL) - start) << " sec. ";
}
os << '[' << start_counter << ']';
// handle only with eval_train = 1, but not val data
if (itr_evals.size() == 0) {
Expand All @@ -498,9 +502,9 @@ class CXXNetLearnTask {
utils::TrackerPrint(os.str());
}
elapsed = (unsigned long)(time(NULL) - start);
if (is_root) {
this->SaveModel();
}
if (is_root) {
this->SaveModel();
}
}

if (!silent) {
Expand Down
68 changes: 0 additions & 68 deletions tools/im2bin.cpp

This file was deleted.

2 changes: 1 addition & 1 deletion tools/network_maker/config_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def ConvFactory(nchannel, kernel_size=1, pad=0, stride = 1, bn = True, act = "re

def DFS(layer, table, seq):
out_layers = graph[layer]
for l in out_layers:
for l in out_layers - table:
DFS(l, table, seq)
if layer not in table:
table.add(layer)
Expand Down

0 comments on commit b77c463

Please sign in to comment.