How can I train multi-input deep network without DataStore

171 views (last 30 days)
Y. K.
Y. K. on 30 Apr 2020
Commented: 鑫 陈 on 25 May 2022
I want to build two inputs, one output network.
But the first input is an image and the second input is a vector.
When I try to train the network with cell array including two sub arrays (one for images, one for vector), I got an error.
"Invalid training data for multiple-input network. For multiple-input training, use a single datastore."
I created 4D image array, a vector array for each input and labels array for training.
How can I combine these data to a DataStore.
Matlab Datastore couldn't get the data from defined variable from workspace.
  2 Comments
Srivardhan Gadila
Srivardhan Gadila on 5 Oct 2021
From R2020b onwards we can directly use arrayDatastore function instead of saving the data to disk and loading it, as mentioned in the answer. For versions less than R2020b the answer would be the workaround.

Sign in to comment.

Accepted Answer

Srivardhan Gadila
Srivardhan Gadila on 3 May 2020
To define and train a deep learning network with multiple inputs, specify the network architecture using a layerGraph object and train using the trainNetwork function by specifying the multiple inputs using a combinedDatastore or transformedDatastore object.
For networks with multiple inputs, the datastore must be a combined or transformed datastore that returns a cell array with (numInputs+1) columns containing the predictors and the responses, where numInputs is the number of network inputs and numResponses is the number of responses. For i less than or equal to numInputs, the ith element of the cell array corresponds to the input layers.InputNames(i), where layers is the layer graph defining the network architecture. The last column of the cell array corresponds to the responses.
data = read(ds)
data =
4×3 cell array
{28×28 double} {128×128 double} {[7]}
{28×28 double} {128×128 double} {[7]}
{28×28 double} {128×128 double} {[9]}
{28×28 double} {128×128 double} {[9]}
Hence in order to train Multiple input networks you have to use a datastore. Refer to Input Arguments & ds of trainNetwork and Multiple-Input and Multiple-Output Networks, Input Datastore for Training, Validation, and Inference for more information.
You can make use of the following code as workaround if your training data is saved in a .mat file:
%% Generate random training data for muliple input network
imgDat = randn([28 28 3 200]);
vectorData = randn([10 1 200]);
trainLabels = categorical(randi([0 1], 200,1));
%% Convert trianing data into cell arrays
imgCells = mat2cell(imgDat,28,28,3,ones(200,1));
vectorCells = mat2cell(vectorData,10,1,ones(200,1));
imgCells = reshape(imgCells,[200 1 1]);
vectorCells = reshape(vectorCells,[200 1 1]);
labelCells = arrayfun(@(x)x,trainLabels,'UniformOutput',false);
combinedCells = [imgCells vectorCells labelCells];
%% Save the converted data so that it can be loaded by filedatastore
save('traingData.mat','combinedCells');
filedatastore = fileDatastore('traingdata.mat','ReadFcn',@load);
trainingDatastore = transform(filedatastore,@rearrangeData);
%% Define muliple input network
layers1 = [
imageInputLayer([28 28 3],'Name','input')
convolution2dLayer(3,16,'Padding','same','Name','conv_1')
batchNormalizationLayer('Name','BN_1')
reluLayer('Name','relu_1')
fullyConnectedLayer(10,'Name','fc11')
additionLayer(2,'Name','add')
fullyConnectedLayer(2,'Name','fc12')
softmaxLayer('Name','softmax')
classificationLayer('Name','classOutput')];
lgraph = layerGraph(layers1);
layers2 = [imageInputLayer([10 1],'Name','vinput')
fullyConnectedLayer(10,'Name','fc21')];
lgraph = addLayers(lgraph,layers2);
lgraph = connectLayers(lgraph,'fc21','add/in2');
plot(lgraph)
%% Define trainingOptions and also set 'Shuffle' to 'never' for this workaround to work
options = trainingOptions('adam', ...
'InitialLearnRate',0.005, ...
'LearnRateSchedule','piecewise',...
'MaxEpochs',300, ...
'MiniBatchSize',1024, ...
'Verbose',1, ...
'Plots','training-progress',...
'Shuffle','never');
net = trainNetwork(trainingDatastore,lgraph,options);
%% function to be used to transform the filedatastore
%to ensure the read(datastore) returns M-by-3 cell array ie., (numInputs+1) columns
function out = rearrangeData(ds)
out = ds.combinedCells;
end
  7 Comments
san su
san su on 17 Mar 2022
If the multi-input data can be oganized as [input1, input2, ..., inputN], it would be an easier way.

Sign in to comment.

More Answers (1)

David Willingham
David Willingham on 11 Mar 2022
Please see this example, released in R2022a that shows how train a multi-input network. It still uses datastores, but shows how they can be combined easily.
  3 Comments
鑫 陈
鑫 陈 on 25 May 2022
For unsupervised multi-input neural networks, without labels,I do not know how to define the labels in the third column and how to generate training data with combine, such as the image regression problem of two image inputs?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!

Translated by