【问题标题】:Create lmdb for multi label classification为多标签分类创建 lmdb
【发布时间】:2017-03-07 07:33:06
【问题描述】:

我正在尝试创建 2 个 lmdb。一个用于我的图像,一个用于我的标签。我想确定图片的角度,为此我试图估计水平和垂直角度。我有这样的课程:0-10 度水平 10-20 度水平等等。垂直角度也是如此。现在我不知道如何创建标签数据库,因为标签必须在 lmdb 中格式化。 我有一个.txt 列表文件,其中包含:/path/pic.png 1 32 条目,其中1 表示 10-20 度,32 表示 320-330 度。 我的代码如下所示:

for line in fileinput.input(data):
    entries = re.split(' ', line.strip())
    images.append(entries[0])
    labels.append(entries[1:])
.... 
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)
    print im_dat

    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())

但这似乎不正确,因为我在尝试训练网络时遇到了以下错误:

检查失败:outer_num_ * inner_num_ == bottom[1]->count() (10 vs. 20) 标签数必须与预测数匹配;例如,如果 softmax axis == 1 并且预测形状为 (N, C, H, W),则标签计数(标签数量)必须为 NHW,整数值在 {0, 1 , ..., C-1}。

我的数据层如下所示:

name: "LearnAngle"
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/train2_images_lmdb"
    batch_size: 10
    backend: LMDB
  }
}
layer {
  name: "data_label"
  type: "Data"
  top: "labels"
  include {
    phase: TRAIN
  }
  data_param {
    source: "path/train2_labels_lmdb"
    batch_size: 10
    backend: LMDB
  }
}

我的最后一层看起来像

layer {
  name: "fc8"
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc8"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 36
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}

layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "fc8"
  bottom: "labels"
  top: "loss"
}

【问题讨论】:

  • 数据层也可以上传吗?
  • 完成! @DaleSong

标签: deep-learning caffe multilabel-classification


【解决方案1】:

问题是:您在第二个data 层中的top: "labels" 包含2 种水平和垂直角度的标签,而您只使用了1 个SoftmaxWithLoss 层作为标签。

实际上,要在一个网络中训练 2 个分类任务,可以分别为 2 个任务的标签创建 2 个lmdb 数据库,并使用 2 个data 层将它们解析为 2 个SoftmaxWithLoss 层。如下所示:

为 2 任务分类创建 lmdb 的代码:

for line in fileinput.input(data):
    entries = re.split(' ', line.strip())
    images.append(entries[0])
    horizontal_labels.append(entries[1])
    vertical_labels.append(entries[2])

...
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)
    print im_dat

    images_txn.put('{:0>10d}'.format(in_idx), im_dat.SerializeToString())
    horizontal_label = [label[0]]
    vertical_label = [label[1]]

    horizontal_label = np.array(horizontal_label).astype(int).reshape(1, 1, 1)
    vertical_label = np.array(vertical_label).astype(int).reshape(1, 1, 1)

    horizontal_label_dat = caffe.io.array_to_datum(horizontal_label)
    vertical_label_dat = caffe.io.array_to_datum(vertical_label)

    horizontal_labels_txn.put('{:0>10d}'.format(in_idx), horizontal_label_dat.SerializeToString())
    vertical_labels_txn.put('{:0>10d}'.format(in_idx), vertical_label_dat.SerializeToString())

train_val.prototxt:

name: "LearnAngle"
layer {
  name: "data"
  type: "Data"
  top: "images"
  include {
    phase: TRAIN
  }
  ...
}
layer {
  name: "horizontal_label"
  type: "Data"
  top: "horizontal_label"
  include {
    phase: TRAIN
  }
  data_param {
    source: "path/horizontal_labels_lmdb" #created using above python code
    ...
  }
}
layer {
  name: "vertical_label"
  type: "Data"
  top: "vertical_label"
  include {
    phase: TRAIN
  }
  data_param {
    source: "path/vertical_labels_lmdb" #created using above python code
    ...
  }
}
... #follow layers
# branch for horizontal label classification
layer {
  name: "fc_horizon"
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc_horizon"
  ...
  inner_product_param {
    num_output: 36
    ...
  }
}

layer {
  name: "loss_horizon"
  type: "SoftmaxWithLoss"
  bottom: "fc_horizon"
  bottom: "horizontal_label"
  top: "loss_horizon"
}
# branch for vertical label classification
layer {
  name: "fc_vertical"
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc_vertical"
  ...
  inner_product_param {
    num_output: 36
    ...
  }
}

layer {
  name: "loss_vertical"
  type: "SoftmaxWithLoss"
  bottom: "fc_vertical"
  bottom: "vertical_label"
  top: "loss_vertical"
}

【讨论】:

  • 你的python代码有问题! label[0] 和 label[1] 是从哪里来的?因为你之前已经重命名了?
  • label 不是列表吗?看到这条线for in_idx, (image, label) in enumerate(inputs):@thigi
  • 是的,但您已将标签名称更改为水平和垂直标签。我假设您可以压缩(图像、垂直标签、水平)标签来输入?
  • @thigi 也可以。
  • 你会建议添加一个准确层吗?还是不需要?
猜你喜欢
  • 2017-11-08
  • 1970-01-01
  • 2018-10-31
  • 2019-11-17
  • 2018-06-25
  • 1970-01-01
  • 2019-10-13
  • 1970-01-01
  • 2014-10-19
相关资源
最近更新 更多