I am trying to preprocess an Image Datastore using 'transform' function which will be input for training a CNN. I think I lose the labels in the transformation, how can I fix?
10 views (last 30 days)
Show older comments
Ali Bora Aydin
on 23 Jan 2023
Commented: Ali Bora Aydin
on 24 Jan 2023
train_imds = imageDatastore("train_dataset","IncludeSubfolders",true,"LabelSource","foldernames");
dsTrain = transform(train_imds,@preprocessing1);
net = trainNetwork(dsTrain,layers,options);
TransformedDataStore produces an error so that the network cannot be trained.
For context, the training dataset consists of images of different sizes and I also do some other operations, hence preprocessing is mandatory. The images are all .bmp and there are two classes ("pos" , "neg") or "labels" (with datastore terminology).
train_imds works well. It has 8436 images with "pos" label and 8436 "neg" label. I ran all kinds of tests and train_imds is correct. However, when I input transformed datastore into trainNetwork, I get the following error: "Invalid training data. For a network with 1 inputs and 1 output, the datastore read function must return a cell array with 2 columns, but it returns an cell array with 1 columns."
I suppose this is because labels are lost in the process but I don't know. Even if it is, I couldn't figure out how to solve this.This is the first time I will be training a CNN and I never created a datastore before. I have been reading documentations and even trying with ChatGPT for 10 hours but I am stuck very hard. I will appreciate a lot for any help, I can't solve with any information on the internet. I really want to start training the network, please help!
Note: The function I have written preproceessing1(image) works as I expect on a single image correctly. For completeness it is below:
function preprocessed_image = preprocessing1(image)
% CONVERT THEM ALL TO GRAYSCALE
gray_image = image(:,:,1); % get only the first channel as all R,G,B channels are equal
% RESIZING ALL IMAGES
target_size = [48,48];
resized_image = imresize(gray_image,target_size);
% APPLY THE NORMALISATION FUNCTION - my function but works well, creates
% 48x48 double
preprocessed_image = normalise_image1(resized_image);
end
0 Comments
Accepted Answer
Richard
on 24 Jan 2023
Ali, you are correct that the issue is that the TransformedDatastore does not have a Labels property and is no longer trivially recognised as returning the underlying ImageDatatore info, so trainNetwork does not automatically pull labels from it.
To fix this you need to explicitly add the labels to the output data of your transform function, using a cell array to combine it with the image data. This output will then have two columns which will match the requirements listed for datastores in https://www.mathworks.com/help/deeplearning/ref/trainnetwork.html#bu6sn4c-2. In order to do that you will also need to specify that the TransformedDatastore should pass in a second argument that contains the info for each read image:
...
dsTrain = transform(train_imds, @preprocessing1, 'IncludeInfo', true);
...
function [labelled_image, info] = preprocessing1(image, info)
% CONVERT THEM ALL TO GRAYSCALE
gray_image = image(:,:,1); % get only the first channel as all R,G,B channels are equal
% RESIZING ALL IMAGES
target_size = [48,48];
resized_image = imresize(gray_image,target_size);
% APPLY THE NORMALISATION FUNCTION - my function but works well, creates
% 48x48 double
preprocessed_image = normalise_image1(resized_image);
labelled_image = {preprocessed_image, info.Label};
end
More Answers (0)
See Also
Categories
Find more on Image Data Workflows 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!