Creating an imdb structure

Hi,
I have written a new createIMDB function following an online tutorial on Deep Learning by German Ros. The original imdb was written for a binary classification problem. I attempted to change it for a three class problem. Each of my class 'cat', 'dog' and 'rat' contain say, three images, for simplicity. My function goes like this:
function imdb = createIMDB_RAM1(folder)
% imdb is a matlab struct with several fields, such as:
% - images: contains data, labels, ids dataset mean, etc.
% - meta: contains meta info useful for statistics and visualization
% - any other you want to add
imdb = struct();
% let's assume we have a folder with three
% subfolders "cat" "dog" and "rat" containing images
% for a multi-class problem
positives = dir([folder '/cat/*.jpg']);
negatives = dir([folder '/dog/*.jpg']);
neutral = dir([folder '/rat/*.jpg']);
imref = imread([folder '/cat/', positives(1).name]);
[H, W, CH] = size(imref);
% number of images
NPos = numel(positives);
NNeg = numel(negatives);
NNeu = numel(neutral);
N = NPos + NNeg + NNeu;
% we can initialize part of the structures already
meta.sets = {'train', 'val'};
meta.classes = {'cat', 'dog', 'rat'};
% images go here
images.data = zeros(H, W, CH, N, 'single');
% this will contain the mean of the training set
images.data_mean = zeros(H, W, CH, 'single');
% a label per image
images.labels = zeros(1, N);
% vector indicating to which set an image belong, i.e.,
% training, validation, etc.
images.set = zeros(1, N);
numImgsTrain = 0;
% loading positive samples
for i=1:numel(positives)
im = single(imread([folder '/cat/', positives(i).name]));
images.data(:,:,:, i) = im;
images.labels(i) = 2;
% in this case we select the set (train/val) randomly
if(randi(10, 1) > 6) % 60% for training and 40% for validation
images.set(i) = 1;
images.data_mean = images.data_mean + im;
numImgsTrain = numImgsTrain + 1;
else
images.set(i) = 2;
end
end
% loading negative samples
for i=1:numel(negatives)
im = single(imread([folder '/dog/', negatives(i).name]));
images.data(:,:,:, NPos+NNeu+i) = im;
images.labels(NPos+NNeu+i) = 1;
% in this case we select the set (train/val) randomly
if(randi(10, 1) > 6)
images.set(NPos+NNeu+i) = 1;
images.data_mean = images.data_mean + im;
numImgsTrain = numImgsTrain + 1;
else
images.set(NPos+NNeu+i) = 2;
end
end
% loading neutral samples
for i=1:numel(neutral)
im = single(imread([folder '/rat/', neutral(i).name]));
images.data(:,:,:, NPos+NNeg+i) = im;
images.labels(NPos+NNeu+i) = 3;
% in this case we select the set (train/val) randomly
if(randi(10, 1) > 6)
images.set(NPos+NNeg+i) = 1;
images.data_mean = images.data_mean + im;
numImgsTrain = numImgsTrain + 1;
else
images.set(NPos+NNeu+i) = 2;
end
end
% let's finish to compute the mean
images.data_mean = images.data_mean ./ numImgsTrain;
% now let's add some randomization
indices = randperm(N);
images.data(:,:,:,:) = images.data(:,:,:,indices);
images.labels(:) = images.labels(indices);
images.set(:) = images.set(indices);
imdb.meta = meta;
imdb.images = images;
end
I'm trying to give labels '1', '2', '3' for 'cat', 'dog' and 'rat' respectively. When i run the function, all the other meta-parameters including the number of sets (train, val), labels ('cat', 'dog', 'rat') are declared properly however the 'labels' and 'sets' are improperly assigned to the images. I'm pretty sure I am committing mistake in assigning the labels and sets inside the 'for' loop.
This is an issue with creating a structure and I'm sure the experts out here can solve my problem in no time. Kindly help rectifying the same with the modified peice of code. Thanks for your assistance.

9 Comments

You don't need to double space your code. You can higlight and click the "{}Code" button. See http://www.mathworks.com/matlabcentral/answers/13205#answer_18099
Many thanks for that suggestion. I will follow it further. Kindly help me resolve the issue with the code. Thanks once again.
Your code is hard to read because it is not indented. I recommend that you go into the MATLAB editor, use control A to select all of the code, and click on the smart indentation icon. Then copy that into a post here; then select the code and click on the {} button.
Hi Roberson,
Here is the code after the smart indentation. Kindly help with the issue.
function imdb = createIMDB_RAM1(folder)
% imdb is a matlab struct with several fields, such as:
% - images: contains data, labels, ids dataset mean, etc.
% - meta: contains meta info useful for statistics and visualization
% - any other you want to add
imdb = struct();
% let's assume we have a folder with two
% subfolders "cat" "nocat" containing images
% for a binary problem
positives = dir([folder '/cat/*.jpg']);
negatives = dir([folder '/dog/*.jpg']);
neutral = dir([folder '/rat/*.jpg']);
imref = imread([folder '/cat/', positives(1).name]);
[H, W, CH] = size(imref);
% number of images
NPos = numel(positives);
NNeg = numel(negatives);
NNeu = numel(neutral);
N = NPos + NNeg + NNeu;
% we can initialize part of the structures already
meta.sets = {'train', 'val'};
meta.classes = {'cat', 'dog', 'rat'};
% images go here
images.data = zeros(H, W, CH, N, 'single');
% this will contain the mean of the training set
images.data_mean = zeros(H, W, CH, 'single');
% a label per image
images.labels = zeros(1, N);
% vector indicating to which set an image belong, i.e.,
% training, validation, etc.
images.set = zeros(1, N);
numImgsTrain = 0;
% loading positive samples
for i=1:numel(positives)
im = single(imread([folder '/cat/', positives(i).name]));
images.data(:,:,:, i) = im;
images.labels(i) = 2;
% in this case we select the set (train/val) randomly
if(randi(10, 1) > 6)
images.set(i) = 1;
images.data_mean = images.data_mean + im;
numImgsTrain = numImgsTrain + 1;
else
images.set(i) = 2;
end
end
% loading negative samples
for i=1:numel(negatives)
im = single(imread([folder '/dog/', negatives(i).name]));
images.data(:,:,:, NPos+i) = im;
images.labels(NPos+i) = 1;
% in this case we select the set (train/val) randomly
if(randi(10, 1) > 6)
images.set(NPos+i) = 1;
images.data_mean = images.data_mean + im;
numImgsTrain = numImgsTrain + 1;
else
images.set(NPos+i) = 2;
end
end
% loading neutral samples
for i=1:numel(neutral)
im = single(imread([folder '/rat/', neutral(i).name]));
images.data(:,:,:, NPos+NNeg+i) = im;
images.labels(NPos+NNeg+i) = 3;
% in this case we select the set (train/val) randomly
if(randi(10, 1) > 6)
images.set(NPos+NNeg+i) = 1;
images.data_mean = images.data_mean + im;
numImgsTrain = numImgsTrain + 1;
else
images.set(NPos+NNeg+i) = 2;
end
end
% let's finish to compute the mean
images.data_mean = images.data_mean ./ numImgsTrain;
% now let's add some randomization
indices = randperm(N);
images.data(:,:,:,:) = images.data(:,:,:,indices);
images.labels(:) = images.labels(indices);
images.set(:) = images.set(indices);
imdb.meta = meta;
imdb.images = images;
end
Your current code assigns label 1 for negatives (dog), 2 for positive (cat) and 3 for neutral. Is that different from what you want?
Hi Roberson, It is exactly what I want. I just want to know whether the lines:
for i=1:numel(negatives)
im = single(imread([folder '/dog/', negatives(i).name]));
images.data(:,:,:, NPos+i) = im;
images.labels(NPos+i) = 1; %(for the negative examples)
and
for i=1:numel(neutral)
im = single(imread([folder '/rat/', neutral(i).name]));
images.data(:,:,:, NPos+NNeg+i) = im;
images.labels(NPos+NNeg+i) = 3; %for the neutral examples
are the right way of declaring the data for the 'negative' and 'neutral' classes. In the for loop for 'negatives', do I need to consider 'NNeg' as well, in declaring images.data(:)? Similarly, in the for loop for 'neutral', do I need to do any other modifications in images.data(:)? Am I making the declaration right for the images.data (:) in both the for loops?
Those lines look okay.
"In the for loop for 'negatives', do I need to consider 'NNeg' as well, in declaring images.data(:)"
The current code is correct for placing all of the images together into images.data() with the positive images first, then the negative images, then the neutral ones.
The classical approach to NN classification of non-overlapping classes is to use {0,1} unit vector targets.
Then the outputs can be interpreted as conditional posterior probabilities.
See any text on pattern recognition.
Hope this helps.
Greg
Hi Roberson, Many thanks for your assistance. As you mentioned, I found that the above code is working fine to create a structure of three classes with their respective labels.

Sign in to comment.

Answers (0)

Categories

Find more on Deep Learning Toolbox in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!