如何以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 amount , dimension )。 我只使用一维数据,所以我不确定channel , width和height的顺序是什么。 也许没关系。  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毫无意义。