Integrate 1-D maxpoolinglayer neuronal Network convolution1dLayer

1 visualizzazione (ultimi 30 giorni)
I want to replicate the following network (see picture for the final idea). In- and outputs are timeseries of equal length.
in the code below i only build only a fraction of the final network to test the syntax.
without the maxPooling1dLayer it works fine. Integrating the maxPooling1dLayer i get the following mistake:
  • Error using trainNetwork (line 184)
  • Arrays have incompatible sizes for this operation.
  • Caused by: Error using - Arrays have incompatible sizes for this operation.
It must have something todo with the stride i tried. With the stride i want to reduce the information. If i choose a stride different from 1, i receive the error listed above.
Why can't i integrate the maxpoolingLayer? At the moment my workaround is working with imageinputLayer and 2d-Layers-CNNs. That is a very untidy solution.
here the Code producing the error:
layers =[];
layers = [
sequenceInputLayer(1,"Name","sequenceinput","Normalization","zscore") convolution1dLayer(10,50,"Padding","same","Name","conv_1")
reluLayer("Name","relu_1")
maxPooling1dLayer(2,"Stride",2,"Name","pool1","Padding","same")
flattenLayer
fullyConnectedLayer(1,"Name","fc")
regressionLayer("Name","out")];
X=[];Y=[];
for i=1:100
X{i,1}(1,:)=i*ones(1,200);
Y{i,1}(1,:)=i*ones(1,200);
end
trainingOptions('adam');
options = trainingOptions('adam', ...
'MiniBatchSize',256,...
'Shuffle','every-epoch',...
'MaxEpochs',2, ...
'ValidationFrequency',200,...
'Plots','none');
[net scores] = trainNetwork(X,Y,layers,options);
Ypred=predict(net,X)

Risposte (1)

Antoni Woss
Antoni Woss il 24 Feb 2022
The maxPooling1dLayer can change the length of the sequences owing to the stride and padding. This means that when training, your input sequences that pass through this layer can change in length so when it then regresses with the Y-sequences, the differences in sequence lengths can throw errors. This is why you observe that without this layer, i.e. maintaining sequence length, it works as expected.
You can change the stride/padding options of the maxPooling1dLayer in a few ways as highlighted on the documentation page - https://www.mathworks.com/help/deeplearning/ref/nnet.cnn.layer.maxpooling1dlayer.html. In this instance, reducing the Stride to 1 while maintaining the name-value pair Padding as same will not change the length of your sequences so you can regress.
maxPooling1dLayer(2,"Stride",1,"Name","pool1","Padding","same")
I suspect in the snippet of the network above, the concatenation layer with the auxillary input that you have not yet incorporated in your tester demo would recover the sequence length when combined with the differential input sequence that shrinks in the length with the many max pooling operations of strides length 2. I would assume then that the output of the network is a sequence with length equal to the input, ready for regression.
  2 Commenti
Ralf Schemm
Ralf Schemm il 24 Feb 2022
Hi,
many thank for the fast replay.
Unfortunatly the reduction of the sequence length is the main purpose of the maxpooling and the anxillary variable wont reconstruct the sequence length (these are skalars).
In the following code i show you the intended network implemented with a con2-Layer system but this is only a workaround due to two unused dimension and the usage of a imageinputLayer. i want to avoid this by using a con1 and sequenceInputLayer. I know that this works in python and would be very delighted to reproduce this for my stundent in matlab.
Therefore it still would be nice to understand how the code below can transformed using conv1 und maxPool1d Layers
Many Thanks
Ralf
layers = [
imageInputLayer([zs_length 1 1],"Name","imageinput","Normalization","zscore")
convolution2dLayer([10 1],30,"Padding","same","Name","conv_1")
reluLayer("Name","relu_1")
maxPooling2dLayer([2 1],"Stride",[2 1],"Name","pool1","Padding","same")
convolution2dLayer([8 1],30,"Padding","same","Name","conv_2")
reluLayer("Name","relu_2")
maxPooling2dLayer([2 1],"Stride",[2 1],"Name","pool2","Padding","same")
convolution2dLayer([6 1],40,"Padding","same","Name","conv_3")
reluLayer("Name","relu_3")
maxPooling2dLayer([2 1],"Stride",[2 1],"Name","pool3","Padding","same")
convolution2dLayer([5 1],50,"Padding","same","Name","conv_4")
reluLayer("Name","relu_4")
maxPooling2dLayer([2 1],"Stride",[2 1],"Name","pool4","Padding","same")
convolution2dLayer([5 1],50,"Padding","same","Name","conv_5")
reluLayer("Name","relu_5")
concatenationLayer(1,3,'Name','combine')
fullyConnectedLayer(zs_length,"Name","fc")
regressionLayer("Name","out")];
lgraph = layerGraph(layers);
%Integration of the anxillary variables
layers2 = [
convolution2dLayer([1 1],50,"Padding","same","Name","conv_6")
globalMaxPooling2dLayer("Name","globalmax")];
lgraph = addLayers(lgraph,layers2);
lgraph = addLayers(lgraph,globalAveragePooling2dLayer("Name","mean"));
lgraph = connectLayers(lgraph,'imageinput','conv_6');
lgraph = connectLayers(lgraph,'conv_6','mean');
lgraph = connectLayers(lgraph,'globalmax','combine/in2');
lgraph = connectLayers(lgraph,'mean','combine/in3');
Antoni Woss
Antoni Woss il 25 Feb 2022
I see, I think there are two things happening here. First, in your 2D example above, you essentially replace "T" with "Sx1". You can see in analyzeNetwork(lgraph), that your input for 1 batch is 200x1x1 but your output is 1x1x200. My guess is that this won't train either (unless you modify your X and Y data), for example, the following code errors as expected:
zs_length = 200;
layers = [
imageInputLayer([zs_length 1 1],"Name","imageinput","Normalization","zscore")
convolution2dLayer([10 1],30,"Padding","same","Name","conv_1")
reluLayer("Name","relu_1")
maxPooling2dLayer([2 1],"Stride",[2 1],"Name","pool1","Padding","same")
convolution2dLayer([8 1],30,"Padding","same","Name","conv_2")
reluLayer("Name","relu_2")
maxPooling2dLayer([2 1],"Stride",[2 1],"Name","pool2","Padding","same")
convolution2dLayer([6 1],40,"Padding","same","Name","conv_3")
reluLayer("Name","relu_3")
maxPooling2dLayer([2 1],"Stride",[2 1],"Name","pool3","Padding","same")
convolution2dLayer([5 1],50,"Padding","same","Name","conv_4")
reluLayer("Name","relu_4")
maxPooling2dLayer([2 1],"Stride",[2 1],"Name","pool4","Padding","same")
convolution2dLayer([5 1],50,"Padding","same","Name","conv_5")
reluLayer("Name","relu_5")
concatenationLayer(1,3,'Name','combine')
fullyConnectedLayer(zs_length,"Name","fc")
regressionLayer("Name","out")];
lgraph = layerGraph(layers);
%Integration of the anxillary variables
layers2 = [
convolution2dLayer([1 1],50,"Padding","same","Name","conv_6")
globalMaxPooling2dLayer("Name","globalmax")];
lgraph = addLayers(lgraph,layers2);
lgraph = addLayers(lgraph,globalAveragePooling2dLayer("Name","mean"));
lgraph = connectLayers(lgraph,'imageinput','conv_6');
lgraph = connectLayers(lgraph,'conv_6','mean');
lgraph = connectLayers(lgraph,'globalmax','combine/in2');
lgraph = connectLayers(lgraph,'mean','combine/in3');
X=rand(200,1,1);
Y=rand(200,1,1);
trainingOptions('adam');
options = trainingOptions('adam', ...
'MiniBatchSize',256,...
'Shuffle','every-epoch',...
'MaxEpochs',2, ...
'ValidationFrequency',200,...
'Plots','none');
[net scores] = trainNetwork(X,Y,lgraph,options);
If you instead rearrange your Y-data to
Y=rand(1,1,200)
then you can train this network. Is this what you are currently doing to get this network to train?
With the 1D equivalent network, you will have sequence data with length 200 and 1 channel. With the fullyConnectedLayer specifying 200 outputs, your output has format CBT with C=200 and T=1. For a network with a sequenceInputLayer, the regressionLayer will expect a sequence of the same length which is the not the case anymore, you have effectively swapped the role of time and channel dimensions. It would appear that since you are transforming 200 timeslices to 200 channels and applying a regression layer, your setup using a 2D conv network with a singleton spatial dimension might be the most direct, as this removes the requirement for sequence data in the regression layer.

Accedi per commentare.

Prodotti


Release

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by