fine tune ImageNet Model for image classification

Since I have installed Caffe, here I will adopt it to my own application. The aim of my examples is for binary classification of images. I will exploit the trained bvlc_reference_caffenet model and then fine tune it for my application.

The whole steps are as follows:


[TOC]

Data Preparation

Prepare original data

You need to prepare four files:

  • train folder which contains the training images
  • val folder which contains the testing images
  • train.txt file which contains the labels of training images.
  • val.txt file which contains the labels of testing images.

    Note that the order of image name in *.txt file is equal to that in train folder and val folder.

The train.txt looks like:

1

That means train folder includes two subfolders cat and dog. In each subfolder, it contains the cat or dog images relatively.

What you need to do is going to caffe_master/data folder, creating a new folder named myself, then putting the four files above into it.

So now in myself folder, you can see four files: train, val, train.txt, val.txt

Transform data format

Later we will use some tools to transform the image files to the data format which ImageNet model consumes.

  1. Copy all *.sh files in caffe-master/examples/imagenet to myself folder.
  2. Change the file path in create_imagenet.sh
  3. Run it and then it will generate myself_train_lmdb and myself_val_lmdb in myself

Compute the mean value

  1. Change the file path in make_imagenet_mean.sh
  2. Run it and it will generate myself_mean.binaryproto in myself

Okay, till now, you have prepared all the data the ImageNet Model needs.

Under myself folder, you can see:

  • myself_train_lmdb folder: it contains the training data
  • myself_val_lmdb folder: it contains the testing data
  • myself_mean.binaryproto: it is the mean value

Fine Tune the trained model

Firstly, we need to download the trained model.

1
2
# the root path is "caffe-master"
./scripts/download_model_binary.py models/bvlc_reference_caffenet # it will take some time to download it

After that you need to fine tune it.

  • change the train_val.prototxt
    (1) change the input data path relatively

    (2) We change the name of last layer from “fc8” to “fc8_myself”. Because there is no layer named “fc8_myself”, it’s weights will be retrained according to random weights.

    (3) change the params of the last layer

1
2
3
4
5
6
7
8
9
10
11
12
13
param{
lr_mult: 10
decay_mult: 1
}
param{
lr_mult: 20
decay_mult: 0
}
inner_product_param{
num_output: 2
...
...
}
  • set up the solver.prototxt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  net:"models/myself_caffenet/train_val.prototxt" 
test_iter: 100
test_interval: 500
base_lr: 0.001
lr_policy: "step"
gamma: 0.1
stepsize: 10000
display: 20
max_iter: 50000 # numofTotalImg / batch_size * 10
momentum: 0.9
weight_decay: 0.0005
snapshot: 2000
snapshot_prefix: "models/myself_caffenet/caffenet_train"
solver_mode: GPU

Train the model

1
2
3
./build/tools/caffe train \
-solver models/myself_caffenet/solver.prototxt \
-weights models/myself_caffenet/bvlc_reference_caffenet.caffemodel

The results will be showed as follows:
train

Test the model

1
./build/tools/caffe test -model=models/myself_caffenet/train_val.prototxt -weights=models/myself_caffenet/caffenet_iter_1000.caffemodel

The results will be showed:
train