2016-10-25 49 views
0

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

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_ ==底部[1 ] - > count()(10对20)标签数量必须与预测数量相匹配;例如,如果softmax轴== 1且预测形状为(N,C,H,W),则标签计数(标签数量)必须为N,其中整数值在{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" 
} 
+0

你能还上载了数据层? – Dale

+0

完成! @DaleSong – thigi

回答

1

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

事实上,训练2个分类任务在一个网络,可以为2个任务标签respectivly创建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" 
} 
+0

你的python代码有问题!标签[0]和标签[1]来自哪里?既然你已经更早更名了? – thigi

+0

是不是'标签'列表?在in_idx(image,label)中查看这一行'in enumerate(inputs):'@thigi – Dale

+0

是的,但是您已经将标签名称更改为水平和垂直标签。我假设你可以压缩(图像,veritcal标签,水平)标签输入? – thigi