1

I have the following structure in a .txt file:

/path/to/image x y
/path/to/image x y

where x and y are integers.

What I want to do now is: Create a hdf5 file to use in Caffe ('train.prototxt')

My Python code looks like this:

import h5py, os
import caffe
import numpy as np

SIZE = 256
with open( 'train.txt', 'r' ) as T :
    lines = T.readlines()


count_files = 0
split_after = 1000
count = -1

# If you do not have enough memory split data into
# multiple batches and generate multiple separate h5 files
X = np.zeros( (split_after, 3, SIZE, SIZE), dtype='f4' )
y1 = np.zeros( (split_after, 1), dtype='f4' )
y2 = np.zeros( (split_after, 1), dtype='f4' )

for i,l in enumerate(lines):
    count += 1
    sp = l.split(' ')
    img = caffe.io.load_image( sp[0] )
    img = caffe.io.resize( img, (3, SIZE, SIZE) )

    X[count] = img
    y1[count] = float(sp[1])
    y2[count] = float(sp[2])

    if (count+1) == split_after:
        with h5py.File('train_' + str(count_files) +  '.h5','w') as H:
            H.create_dataset( 'X', data=X ) # note the name X given to the dataset!
            H.create_dataset( 'y1', data=y1 )
            H.create_dataset( 'y2', data=y2 )

            X = np.zeros( (split_after, 3, SIZE, SIZE), dtype='f4' )
            y1 = np.zeros( (split_after, 1), dtype='f4' )
            y2 = np.zeros( (split_after, 1), dtype='f4' )
        with open('train_h5_list.txt','a') as L:
            L.write( 'train_' + str(count_files) + '.h5') # list all h5 files you are going to use
        count_files += 1
        count = 0

In fact I want to estimate angles. That means I have two classes one for vertical angles one for horizontal angles. The first class ranges from 0-10 degrees the second from 10-20 and so on (for both horizontal and vertical angles).

How would the .prototxt look like? Here are my last layers

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: "y"
  top: "loss"
}
  • are you writing `train` or `val` files? it's a bit confusing what you are doing... – Shai Oct 25 '16 at 13:14
  • In thtat case I am trying to do both. That should be easy with an include? But I thought for both cases the last layers are similiar? –  Oct 25 '16 at 13:19
  • I was referring to the first part: the python code for creating the h5 files. – Shai Oct 25 '16 at 13:20
  • Oh I am doing both! I will just change the the filenames and will do the same operations! –  Oct 25 '16 at 13:22

1 Answers1

0

You also need to modify the input layer: now you have three tops:

layer {
  type: "HDF5Data"
  name: "data"
  top: "X"
  top: "y1"
  top: "y2"
  # ... params and phase
}

Now, the top of your fc7 serves as a "high level descriptor" of your data, from which you wish to predict y1 and y2. Thus, after layer fc7 you should have:

layer {
  type: "InnerProduct"
  name: "class_y1" 
  bottom: "fc7"
  top: "class_y1"
  #... params num_output: 36 
}
layer {
  type: "SoftmaxWithLoss" # to be replaced with "Softmax" in deploy
  name: "loss_y1"
  bottom: "class_y1"
  bottom: "y1"
  top: "loss_y1"
  # optionally, loss_weight
}

And:

layer {
  type: "InnerProduct"
  name: "class_y2" 
  bottom: "fc7"
  top: "class_y2"
  #... params num_output: 36 
}
layer {
  type: "SoftmaxWithLoss" # to be replaced with "Softmax" in deploy
  name: "loss_y2"
  bottom: "class_y2"
  bottom: "y2"
  top: "loss_y2"
  # optionally, loss_weight
}
Shai
  • 111,146
  • 38
  • 238
  • 371
  • Ok thank you! How do you call such a classification task? Is that multilabel classification or multi class classification? –  Oct 25 '16 at 13:15
  • @thigi does it matter? more importantly, can you make it work? – Shai Oct 25 '16 at 13:16
  • Yeah I am trying to. Problem is my hdf5 files are too big. –  Oct 25 '16 at 13:17
  • @thigi. no problem. you can have many `.h5` files, list all their paths in `val_h5_list.txt` or `train_h5_list.txt` and caffe will read all of them one after the other. – Shai Oct 25 '16 at 13:19
  • Problem is, how do i split the files? I have only one big hdf5 file as you can see. I know that it is possible to list many of them but the question is how to split them? –  Oct 25 '16 at 13:20
  • @thigi in the python code. after `N` iterations write to `h5` and start over to fill `X`, `y1` and `y2`. – Shai Oct 25 '16 at 13:24
  • Isnt the problem that I woud have to change the dimensions? Cause I have to clear X and y1 and y2? Or can I just leave them as they are? –  Oct 25 '16 at 13:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126628/discussion-between-thigi-and-shai). –  Oct 25 '16 at 13:38
  • @thigi that's the general idea. you should consider the case where you have less than `split_after` examples for the last file. – Shai Oct 25 '16 at 13:53
  • Would you recommend to add a accuracy layer? –  Oct 25 '16 at 16:33