Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Create CaffeDB training data for siamese networks out of image directory

I need some help to create a CaffeDB for siamese CNN out of a plain directory with images and label-text-file. Best would be a python-way to do it.
The problem is not to walk through the directory and making pairs of images. My problem is more of making a CaffeDB out of those pairs.
So far I only used convert_imageset to create a CaffeDB out of an image directory.
Thanks for help!

like image 364
Feuerteufel Avatar asked Jan 20 '16 15:01

Feuerteufel


People also ask

What is the final output of the Siamese network?

The objective of the Siamese network is to discriminate between the two inputs X1 and X2 . The output of the network is a probability between 0 and 1 , where a value closer to 0 indicates a prediction that the images are dissimilar, and a value closer to 1 that the images are similar.

What is the output of each twin network inside a Siamese network architecture?

For same class input pairs, target output is 1 and for different classes input pairs, the output is 0. Remember, both networks have same the parameters and weights. If not, then they are not Siamese.


1 Answers

Why don't you simply make two datasets using good old convert_imagest?

layer {
  name: "data_a"
  top: "data_a"
  top: "label_a"
  type: "Data"
  data_param { source: "/path/to/first/data_lmdb" }
  ...
}
layer {
  name: "data_b"
  top: "data_b"
  top: "label_b"
  type: "Data"
  data_param { source: "/path/to/second/data_lmdb" }
  ...
}

As for the loss, since every example has a class label you need to convert label_a and label_b into a same_not_same_label. I suggest you do this "on-the-fly" using a python layer. In the prototxt add the call to python layer:

layer {
  name: "a_b_to_same_not_same_label"
  type: "Python"
  bottom: "label_a"
  bottom: "label_b"
  top: "same_not_same_label"
  python_param { 
    # the module name -- usually the filename -- that needs to be in $PYTHONPATH
    module: "siamese"
    # the layer name -- the class name in the module
    layer: "SiameseLabels"
  }
  propagate_down: false
}

Create siamese.py (make sure it is in your $PYTHONPATH). In siamese.py you should have the layer class:

import sys, os
sys.path.insert(0,os.environ['CAFFE_ROOT'] + '/python')
import caffe
class SiameseLabels(caffe.Layer):
  def setup(self, bottom, top):
    if len(bottom) != 2:
       raise Exception('must have exactly two inputs')
    if len(top) != 1:
       raise Exception('must have exactly one output')
  def reshape(self,bottom,top):
    top[0].reshape( *bottom[0].shape )
  def forward(self,bottom,top):
    top[0].data[...] = (bottom[0].data == bottom[1].data).astype('f4')
  def backward(self,top,propagate_down,bottom):
      # no back prop
      pass

Make sure you shuffle the examples in the two sets in a different manner, so you get non-trivial pairs. Moreover, if you construct the first and second data sets with different number of examples, then you will see different pairs at each epoch ;)


Make sure you construct the network to share the weights of the duplicated layers, see this tutorial for more information.

like image 73
Shai Avatar answered Sep 28 '22 05:09

Shai