0

I am trying to do multi label classification based on the lmdb database. I create two different databases. One for the images itself and one for the labels. My intention is to have 2 different labels for angles in horizontal and vertical direction. That means label1 [0-360] label2 [0-360].

To do so my code is the following:

data_name = "val"
data = data_name + '.txt'
lmdb_data_name = data_name + '_images_lmdb'
lmdb_label_name = data_name + '_labels_lmdb'

images = []
labels = []

for line in fileinput.input(data):
    entries = re.split(' ', line.strip())
    # append image
    images.append(entries[0])
    labels.append(entries[1:])

images_db = lmdb.open(lmdb_data_name, map_size=int(1e12))
labels_db = lmdb.open(lmdb_label_name, map_size=int(1e12))

images_txn = images_db.begin(write=True)
labels_txn = labels_db.begin(write=True)

inputs = zip(images, labels)
for in_idx, (image, label) in enumerate(inputs):
    im = cv2.imread(image)
    im = im[:,:,::-1]
    im = im.transpose((2,0,1))

    im_dat = caffe.io.array_to_datum(im)

    images_txn.put('{:0>10d}'.format(in_idx), im_dat.SerializeToString())

    label = np.array(label).astype(int).reshape(1, 1, len(label))
    label_dat = caffe.io.array_to_datum(label)
    labels_txn.put('{:0>10d}'.format(in_idx),label_dat.SerializeToString())

images_txn.commit()
labels_txn.commit()

images_db.close()
labels_db.close()

My train.txt looks like: /path/to/image label1 label2 where label1 and label2 are integers.

My train_val.prototxt looks like this:

layer {
  name: "data"
  type: "Data"
  top: "images"
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: true
    crop_size: 256
    mean_file: "/path/mean_train.binaryproto"
  }
  data_param {
    source: "/path/train_images_lmdb"
    batch_size: 10
    backend: LMDB
  }
}
layer {
  name: "data_label"
  type: "Data"
  top: "labels"
  include {
    phase: TRAIN
  }
  data_param {
    source: "/train_labels_lmdb"
    batch_size: 10
    backend: LMDB
  }
}

The part for the TEST phase is identical

My loss layer looks like this:

layer {
  name: "loss"
  type: "SigmoidCrossEntropyLoss"
  bottom: "fc8"
  bottom: "labels"
  top: "loss"
}
  • You should make sure `fc8`'s values are in the range [0, 1]. To do so you'd better use `sigmoid` activation function or softmax before `fc8`. – Dale Oct 24 '16 at 13:11
  • Yeah I have fixed that problem. But the problem is, the lables are not created properly for the lmdb. Can you help me with that? I thought you can have a label like [label1, label2] ->[40, 90] but i feel like you have to have somethin like [0, 0, 0, 0, 0, 1, 0, ] --> length of this = number labels @DaleSong –  Oct 25 '16 at 08:48
  • I mean label values should be in the range from 0 to 1, not 0 or 1. Can you modify your questions to provide more information about your new problem? – Dale Oct 25 '16 at 08:55
  • Yeah just edited it. The problem I have is how to do multi label classification. Can we have a private chat? @DaleSong –  Oct 25 '16 at 09:05
  • Why do you use `SigmoidCrossEntropyLoss` for multi label classification? You'd better use multi losses for each label. – Dale Oct 25 '16 at 09:09
  • Ok, I cannot follow. Can you give me an answer for my question how to specifiy the labels and which loss function to use and that stuff? –  Oct 25 '16 at 09:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126591/discussion-between-thigi-and-dale-song). –  Oct 25 '16 at 09:13
  • Yeah I know there might be not only one mistake. That is why I need an more general answer in a way how to do it as in how to specifiy the labels and what activation or loss functions to use. –  Oct 25 '16 at 09:16

0 Answers0