如何以HDF5格式提供caffe多标签数据?

我想用一个向量标签的咖啡,而不是整数。 我查了一些答案,看来HDF5是一个更好的方法。 但是,然后我陷入了像这样的错误:

outer_num_ * inner_num_ == bottom[1]->count() :34]检查失败: outer_num_ * inner_num_ == bottom[1]->count() (50与200)标签数量必须匹配预测数量; 例如,如果标签轴== 1且预测形状是(N,C,H,W),则标签计数(标签数量)必须是N*H*W ,其中整数值在{0,1,…, C-1}。

与HDF5创build为:

 f = h5py.File('train.h5', 'w') f.create_dataset('data', (1200, 128), dtype='f8') f.create_dataset('label', (1200, 4), dtype='f4') 

我的networking是由以下产生的:

 def net(hdf5, batch_size): n = caffe.NetSpec() n.data, n.label = L.HDF5Data(batch_size=batch_size, source=hdf5, ntop=2) n.ip1 = L.InnerProduct(n.data, num_output=50, weight_filler=dict(type='xavier')) n.relu1 = L.ReLU(n.ip1, in_place=True) n.ip2 = L.InnerProduct(n.relu1, num_output=50, weight_filler=dict(type='xavier')) n.relu2 = L.ReLU(n.ip2, in_place=True) n.ip3 = L.InnerProduct(n.relu1, num_output=4, weight_filler=dict(type='xavier')) n.accuracy = L.Accuracy(n.ip3, n.label) n.loss = L.SoftmaxWithLoss(n.ip3, n.label) return n.to_proto() with open(PROJECT_HOME + 'auto_train.prototxt', 'w') as f: f.write(str(net('/home/romulus/code/project/train.h5list', 50))) with open(PROJECT_HOME + 'auto_test.prototxt', 'w') as f: f.write(str(net('/home/romulus/code/project/test.h5list', 20))) 

看起来我应该增加标签号码,把整数而不是数组中的东西,但如果我这样做,咖啡抱怨数据的数量和标签是不相等的,然后存在。

那么,提供多标签数据的正确格式是什么?

此外,我很想知道为什么没有人只是写数据格式如何HDF5映射到咖啡斑点?

回答这个问题的标题:

HDF5文件应该有两个根数据集,分别命名为“data”和“label”。 形状是( data amountdimension )。 我只使用一维数据,所以我不确定channelwidthheight的顺序是什么。 也许没关系。 dtype应该是float或者double。

h5py创build的示例代码创buildh5py是:

导入h5py,os
将numpy导入np

 f = h5py.File('train.h5','w')
 #1200数据,每个数据是一个128-dimvector
 f.create_dataset('data',(1200,128),dtype ='f8')
 #数据标签,每个标签都是一个4-dim向量
 f.create_dataset('label',(1200,4),dtype ='f4')

 #填写固定模式的东西
 #将值调整到0到1之间,否则SigmoidCrossEntropyLoss将不起作用
我在范围内(1200):
     a = np.empty(128)
    如果我%4 == 0:
        对于范围内的j(128):
             a [j] = j / 128.0;
         l = [1,0,0,0]
     elif i%4 == 1:
        对于范围内的j(128):
             a [j] =(128-j)/128.0;
         l = [1,0,1,0]
     elif i%4 == 2:
        对于范围内的j(128):
             a [j] =(j%6)/128.0;
         l = [0,1,1,0]
     elif i%4 == 3:
        对于范围内的j(128):
             a [j] =(j%4)* 4 / 128.0;
         l = [1,0,1,1]
     f ['data'] [i] = a
     f ['label'] [i] = 1

 f.close()

另外,不需要准确的图层,简单的删除就可以了。 下一个问题是损失层。 由于SoftmaxWithLoss只有一个输出(具有最大值的维度的索引),因此不能用于多标签问题。 感谢Adian和Shai,我发现SigmoidCrossEntropyLoss在这种情况下是很好的。

下面是完整的代码,从数据创build,培训networking,并获得testing结果:

main.py(从caffe lanet例子中修改)

import操作系统,系统

 PROJECT_HOME ='... / project /'
 CAFFE_HOME ='... / caffe /'
 os.chdir(PROJECT_HOME)

 sys.path.insert(0,CAFFE_HOME +'caffe / python')
import咖啡,h5py

从pylab导入*
从咖啡import层作为L.

 def net(hdf5,batch_size):
     n = caffe.NetSpec()
     n.data,n.label = L.HDF5Data(batch_size = batch_size,source = hdf5,ntop = 2)
     n.ip1 = L.InnerProduct(n.data,num_output = 50,weight_filler = dict(type ='xavier'))
     n.relu1 = L.ReLU(n.ip1,in_place = True)
     n.ip2 = L.InnerProduct(n.relu1,num_output = 50,weight_filler = dict(type ='xavier'))
     n.relu2 = L.ReLU(n.ip2,in_place = True)
     n.ip3 = L.InnerProduct(n.relu2,num_output = 4,weight_filler = dict(type ='xavier'))
     n.loss = L.SigmoidCrossEntropyLoss(n.ip3,n.label)
    返回n.to_proto()

打开(PROJECT_HOME +'auto_train.prototxt','w')为f:
     f.write(str(net(PROJECT_HOME +'train.h5list',50)))
打开(PROJECT_HOME +'auto_test.prototxt','w')为f:
     f.write(str(net(PROJECT_HOME +'test.h5list',20)))

 caffe.set_device(0)
 caffe.set_mode_gpu()
 solver = caffe.SGDSolver(PROJECT_HOME +'auto_solver.prototxt')

 solver.net.forward()
 solver.test_nets [0]的.forward()
 solver.step(1)

硝基= 200
 test_interval = 10
 train_loss =零(硝酸)
 test_acc = zeros(int(np.ceil(niter * 1.0 / test_interval)))
打印len(test_acc)
输出=零((niter,8,4))

 #主要求解器循环
在范围内(硝酸):
     solver.step(1)#Caffe
     train_loss [it] = solver.net.blobs ['loss']。data
     solver.test_nets [0]的.forward(开始= '数据')
    输出[it] = solver.test_nets [0] .blobs ['ip3']。data [:8]

    如果它%test_interval == 0:
        打印“迭代”,它,“testing...”
        正确= 0
         data = solver.test_nets [0] .blobs ['ip3']。data
         label = solver.test_nets [0] .blobs ['label']。data
        对于范围(100)中的test_it:
             solver.test_nets [0]的.forward()
             #正值映射到标签1,负值映射到标签0
            我在范围内(len(数据)):
                对于范围内的j(len(data [i])):
                    如果data [i] [j]> 0和label [i] [j] == 1:
                        正确+ = 1
                     elif data [i] [j]%lt; = 0和label [i] [j] == 0:
                        正确+ = 1
         test_acc [int(it / test_interval)] = correct * 1.0 /(len(data)* len(data [0])* 100)

 #完成训练和testing,输出stream行图
 _,ax1 = subplots()
 ax2 = ax1.twinx()
 ax1.plot(arange(niter),train_loss)
 ax2.plot(test_interval * arange(len(test_acc)),test_acc,'r')
 ax1.set_xlabel( '迭代')
 ax1.set_ylabel('火车丢失')
 ax2.set_ylabel('test accuracy')
 _.savefig( 'converge.png')

 #检查最后一批的结果
打印solver.test_nets [0] .blobs ['ip3']。data
打印solver.test_nets [0] .blobs ['label']。data

h5list文件在每行中只包含h5文件的path:

train.h5list

 /home/foo/bar/project/train.h5 

test.h5list

 /home/foo/bar/project/test.h5 

和解决者:

auto_solver.prototxt

  train_net:“auto_train.prototxt”
 test_net:“auto_test.prototxt”
 test_iter:10
 test_interval:20
 base_lr:0.01
动力:0.9
 weight_decay:0.0005
 lr_policy:“inv”
 γ:0.0001
功率:0.75
显示:100
 max_iter:10000
快照:5000
 snapshot_prefix:“sed”
 solver_mode:GPU

收敛图: 收敛图

最后一批结果:

 [[35.91593933 -37.46276474 -6.2579031 -6.30313492]
 [42.69248581 -43.00864792 13.19664764 -3.35134125]
 [-1.36403108 1.38531208 2.77786589 -0.34310576]
 [2.91686511 -2.88944006 4.34043217 0.32656598]
 ...
 [35.91593933 -37.46276474 -6.2579031 -6.30313492]
 [42.69248581 -43.00864792 13.19664764 -3.35134125]
 [-1.36403108 1.38531208 2.77786589 -0.34310576]
 [2.91686511 -2.88944006 4.34043217 0.32656598]]

 [[1.0.0.0]
 [1.0.1.0]
 [0.1.1.0]
 [1. 0. 1. 1]
 ...
 [1.0.0.0]
 [1.0.1.0]
 [0.1.1.0]
 [1. 0. 1. 1.]]

我认为这个代码还有很多东西需要改进。 任何build议表示赞赏。

您的准确性层没有意义。

准确性层的工作方式 : caffe准确性层期望两个input
(i)预测的概率向量
(ii)地面实况相应的标量整数标签。
准确性层比检查预测标签的概率是否确实是最大(或在top_k内)。
因此,如果您必须对C不同的类进行分类,那么您的input将是属于每个C类的N样本的input预测概率Ninput(其中N是批量大小),以及N标签。

在networking中定义的方式 :您input准确性层数的N比4预测和N比4的标签 – 这对caffe毫无意义。