python - How to feed caffe multi label data in HDF5 format? -


i want use caffe vector label, not integer. have checked answers, , seems hdf5 better way. i'm stucked error like:

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 , prediction shape (n, c, h, w), label count (number of labels) must n*h*w, integer values in {0, 1, ..., c-1}.

with hdf5 created as:

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

my network generated by:

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()  open(project_home + 'auto_train.prototxt', 'w') f: f.write(str(net('/home/romulus/code/project/train.h5list', 50)))  open(project_home + 'auto_test.prototxt', 'w') f: f.write(str(net('/home/romulus/code/project/test.h5list', 20))) 

it seems should increase label number , put things in integer rather array, if this, caffe complains number of data , label not equal, exists.

so, correct format feed multi label data?

also, i'm wondering why no 1 write data format how hdf5 maps caffe blobs?

answer question's title:

the hdf5 file should have 2 dataset in root, named "data" , "label", respectively. shape (data amount, dimension). i'm using one-dimension data, i'm not sure what's order of channel, width, , height. maybe not matter. dtype should float or double.

a sample code creating train set h5py is:

 import h5py, os import numpy np  f = h5py.file('train.h5', 'w') # 1200 data, each 128-dim vector f.create_dataset('data', (1200, 128), dtype='f8') # data's labels, each 4-dim vector f.create_dataset('label', (1200, 4), dtype='f4')  # fill in fixed pattern # regularize values between 0 , 1, or sigmoidcrossentropyloss not work in range(1200):     = np.empty(128)     if % 4 == 0:         j in range(128):             a[j] = j / 128.0;         l = [1,0,0,0]     elif % 4 == 1:         j in range(128):             a[j] = (128 - j) / 128.0;         l = [1,0,1,0]     elif % 4 == 2:         j in range(128):             a[j] = (j % 6) / 128.0;         l = [0,1,1,0]     elif % 4 == 3:         j in range(128):             a[j] = (j % 4) * 4 / 128.0;         l = [1,0,1,1]     f['data'][i] =     f['label'][i] = l  f.close() 

also, accuracy layer not needed, removing fine. next problem loss layer. since softmaxwithloss has 1 output (index of dimension max value), can't used multi-label problem. thank adian , shai, find sigmoidcrossentropyloss in case.

below full code, data creation, training network, , getting test result:

main.py (modified caffe lanet example)

 import os, sys  project_home = '.../project/' caffe_home = '.../caffe/' os.chdir(project_home)  sys.path.insert(0, caffe_home + 'caffe/python') import caffe, h5py  pylab import * caffe import layers 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)     return n.to_proto()  open(project_home + 'auto_train.prototxt', 'w') f:     f.write(str(net(project_home + 'train.h5list', 50))) open(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)  niter = 200 test_interval = 10 train_loss = zeros(niter) test_acc = zeros(int(np.ceil(niter * 1.0 / test_interval))) print len(test_acc) output = zeros((niter, 8, 4))  # main solver loop in range(niter):     solver.step(1)  # sgd 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 % 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         test_it in range(100):             solver.test_nets[0].forward()             # positive values map label 1, while negative values map label 0             in range(len(data)):                 j in range(len(data[i])):                     if data[i][j] > 0 , label[i][j] == 1:                         correct += 1                     elif data[i][j] %lt;= 0 , label[i][j] == 0:                         correct += 1         test_acc[int(it / test_interval)] = correct * 1.0 / (len(data) * len(data[0]) * 100)  # train , 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 result of last batch print solver.test_nets[0].blobs['ip3'].data print solver.test_nets[0].blobs['label'].data 

h5list files contain paths of h5 files in each line:

train.h5list

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

test.h5list

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

and solver:

auto_solver.prototxt

train_net: "auto_train.prototxt" test_net: "auto_test.prototxt" test_iter: 10 test_interval: 20 base_lr: 0.01 momentum: 0.9 weight_decay: 0.0005 lr_policy: "inv" gamma: 0.0001 power: 0.75 display: 100 max_iter: 10000 snapshot: 5000 snapshot_prefix: "sed" solver_mode: gpu 

converge graph: converge graph

last batch result:

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

i think code still has many things improve. suggestion appreciated.


Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -