gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 18:16:40 38 4
gpt4 key购买 nike

我想将 caffe 与矢量标签一起使用,而不是整数。我检查了一些答案,HDF5 似乎是更好的方法。但后来我遇到了这样的错误:

accuracy_layer.cpp:34] Check failed: outer_num_ * inner_num_ == bottom[1]->count() (50 vs. 200) Number of labels must match number of predictions; e.g., if label axis == 1 and prediction shape is (N, C, H, W), label count (number of labels) must be N*H*W, with integer values in {0, 1, ..., C-1}.

HDF5 创建为:

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

我的网络是由:

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

看来我应该增加标签数量并将东西放在整数而不是数组中,但如果我这样做,caffe 会提示数据数量和标签不相等,然后存在。

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

另外,我很想知道为什么没有人只是简单地写下 HDF5 如何映射到 caffe blob 的数据格式?

最佳答案

回答这个问题的标题:

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

使用 h5py 创建训练集的示例代码是:

import h5py, osimport numpy as npf = h5py.File('train.h5', 'w')# 1200 data, each is a 128-dim vectorf.create_dataset('data', (1200, 128), dtype='f8')# Data's labels, each is a 4-dim vectorf.create_dataset('label', (1200, 4), dtype='f4')# Fill in something with fixed pattern# Regularize values to between 0 and 1, or SigmoidCrossEntropyLoss will not workfor i in range(1200):    a = np.empty(128)    if i % 4 == 0:        for j in range(128):            a[j] = j / 128.0;        l = [1,0,0,0]    elif i % 4 == 1:        for j in range(128):            a[j] = (128 - j) / 128.0;        l = [1,0,1,0]    elif i % 4 == 2:        for j in range(128):            a[j] = (j % 6) / 128.0;        l = [0,1,1,0]    elif i % 4 == 3:        for j in range(128):            a[j] = (j % 4) * 4 / 128.0;        l = [1,0,1,1]    f['data'][i] = a    f['label'][i] = lf.close()

Also, the accuracy layer is not needed, simply removing it is fine. Next problem is the loss layer. Since SoftmaxWithLoss has only one output (index of the dimension with max value), it can't be used for multi-label problem. Thank to Adian and Shai, I find SigmoidCrossEntropyLoss is good in this case.

Below is the full code, from data creation, training network, and getting test result:

main.py (modified from caffe lanet example)

import os, sysPROJECT_HOME = '.../project/'CAFFE_HOME = '.../caffe/'os.chdir(PROJECT_HOME)sys.path.insert(0, CAFFE_HOME + 'caffe/python')import caffe, h5pyfrom pylab import *from caffe import layers as Ldef 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)    return n.to_proto()with open(PROJECT_HOME + 'auto_train.prototxt', 'w') as f:    f.write(str(net(PROJECT_HOME + 'train.h5list', 50)))with open(PROJECT_HOME + 'auto_test.prototxt', 'w') as 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)niter = 200test_interval = 10train_loss = zeros(niter)test_acc = zeros(int(np.ceil(niter * 1.0 / test_interval)))print len(test_acc)output = zeros((niter, 8, 4))# The main solver loopfor it in range(niter):    solver.step(1)  # SGD by Caffe    train_loss[it] = solver.net.blobs['loss'].data    solver.test_nets[0].forward(start='data')    output[it] = solver.test_nets[0].blobs['ip3'].data[:8]    if it % test_interval == 0:        print 'Iteration', it, 'testing...'        correct = 0        data = solver.test_nets[0].blobs['ip3'].data        label = solver.test_nets[0].blobs['label'].data        for test_it in range(100):            solver.test_nets[0].forward()            # Positive values map to label 1, while negative values map to label 0            for i in range(len(data)):                for j in range(len(data[i])):                    if data[i][j] > 0 and label[i][j] == 1:                        correct += 1                    elif data[i][j] %lt;= 0 and label[i][j] == 0:                        correct += 1        test_acc[int(it / test_interval)] = correct * 1.0 / (len(data) * len(data[0]) * 100)# Train and test done, outputing convege graph_, 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('iteration')ax1.set_ylabel('train loss')ax2.set_ylabel('test accuracy')_.savefig('converge.png')# Check the result of last batchprint solver.test_nets[0].blobs['ip3'].dataprint solver.test_nets[0].blobs['label'].data

h5list files simply contain paths of h5 files in each line:

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: 10test_interval: 20base_lr: 0.01momentum: 0.9weight_decay: 0.0005lr_policy: "inv"gamma: 0.0001power: 0.75display: 100max_iter: 10000snapshot: 5000snapshot_prefix: "sed"solver_mode: GPU

收敛图: Converge graph

最后一批结果:

[[ 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.]]

我认为这段代码还有很多地方需要改进。任何建议表示赞赏。

关于python - 如何以HDF5格式提供caffe多标签数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33140000/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com