sequenceInputLayer() Dimensions of arrays being concatenated are not consistent - matlab

I try to create an LSTM model. I get following error:
Error using vertcat Dimensions of arrays being concatenated are not
consistent. Error in source (line 9)
sequenceInputLayer(33)
What should be the input of sequenceInputLayer and its size?
Data = csvread('newData.csv');
num_timesteps = size(Data,1)
num_features = size(Data,2)
Data = normalize(Data);
numHiddenUnits = 200;
size(Data)
layers = [
sequenceInputLayer(33)
lstmLayer(numHiddenUnits,'OutputMode','sequence')
fullyConnectedLayer(50)
dropoutLayer(0.5)
fullyConnectedLayer(num_features),regressionLayer];
maxEpochs = 60;
miniBatchSize = 20;
options = trainingOptions('adam', ...
'MaxEpochs',maxEpochs, ...
'MiniBatchSize',miniBatchSize, ...
'InitialLearnRate',0.001, ...
'GradientThreshold',1, ...
'Shuffle','never', ...
'Plots','training-progress',...
'Verbose',0);
% net = trainNetwork(Data,Data,layers,options);

The problem is not in sequenceInputLayer, the problem is in the way you are creating the layers array.
Replace:
layers = [
sequenceInputLayer(33)
lstmLayer(numHiddenUnits,'OutputMode','sequence')
fullyConnectedLayer(50)
dropoutLayer(0.5)
fullyConnectedLayer(num_features),regressionLayer];
With:
layers = [
sequenceInputLayer(33)
lstmLayer(numHiddenUnits,'OutputMode','sequence')
fullyConnectedLayer(50)
dropoutLayer(0.5)
fullyConnectedLayer(num_features),
regressionLayer];
Explanation: In an array declaration, when adding elements in new lines (or separating by ;) you are crating a columns vector, when separating by ,, you are crating a row vector. Somehow you mixed them up.

Related

How do I load multiple files in MatLab?

I have the following code to load a single matrix file in matlab
filename='1';
filetype='.txt';
filepath='D:\20170913\';
fidi = fopen(strcat(filepath,filename,filetype));
Datac = textscan(fidi, repmat('%f', 1, 640), 'HeaderLines',1,
'CollectOutput',1);
f1 = Datac{1};
sum(sum(f1))
how can I load many files, say 1-100.
Thanks in advance.
Just include everything in a for loop that loops from 1 up to N_files, which is the number of files that you have. I used the function num2str() to convert the index i to a string. I also included the matrix sum in an array file_sums and a loaded_matrices cell array that stores all the loaded matrices. If all the loaded matrices have a known and same dimensions, you could use a 2D array (ex. loaded_matrices = zeros(N_rows, N_columns, N_files); and then load the data as loaded_matrices(:,:,i) = Datac{1};).
% N_files - the number of files that you have
N_files = 100;
file_sums = zeros(1,N_files);
loaded_matrices = cell(1,N_files);
for i=1:1:N_files
filename=num2str(i);
filetype='.txt';
filepath='';
fidi = fopen(strcat(filepath,filename,filetype));
Datac = textscan(fidi, repmat('%f', 1, 640), 'HeaderLines',1,...
'CollectOutput',1);
loaded_matrices{i} = Datac{1};
file_sums(i) = sum(sum(loaded_matrices{i}));
end

how to get rid of exceed matrix dimension (binning data)?

bet{j,3} = react{j};
numBins = {};
edges = linspace(min(bet{j,3}), max(bet{j,3}), numBins(bet{j,3}));
[N, whichBin] = histc(bet{j,3}, edges);
binsize = NaN*zeros(size(bins));
for k = 1:numBins
bin = find(whichBin == k);
binMembers = bet{j,3}(bin);
if (~isempty(bin))
mu(k) = mean(y(bin));
end
end
error on
edges = linspace(min(bet{j,3}), max(bet{j,3}), numBins(bet{j,3})); that says it exceeds matrix dimensions
Any suggestions to what could be the problem, as well as suggestions if this is code might work for binning data (e.g., reaction time)?
Your line numBins = {}; creates an empty cell array. But in numBins(bet{j,3})); you are trying to access an element. As there is none it fails on index exceeds matrix dimension.

Sorting several functions in one function

I have a function where I'm receiving input data and other data from four random sources. This function must be repeated for 12 times and 12 should be set so that. This function should also be repeated 10 times. Is there a more compact way to perform what I'm doing below?
for ii=1:10
Percent=0.7;
num_points1 = size(X_1,1);
split_point1 = round(num_points1*Percent);
sequence1 = randperm(num_points1);
X1_train{ii} = X_1(sequence1(1:split_point1),:);
Y1_train{ii} = Y_1(sequence1(1:split_point1));
X1_test{ii} = X_1(sequence1(split_point1+1:end),:);
Y1_test{ii}= Y_1(sequence1(split_point1+1:end));
num_points2 = size(X_2,1);
split_point2 = round(num_points2*Percent);
sequence2 = randperm(num_points2);
X2_train{ii} = X_2(sequence2(1:split_point2),:);
Y2_train{ii} = Y_2(sequence2(1:split_point2));
X2_test{ii} = X_2(sequence2(split_point2+1:end),:);
Y2_test{ii}= Y_2(sequence2(split_point2+1:end));
.
.
.
.
num_points12 = size(X_12,1);
split_point12 = round(num_points12*Percent);
sequence12 = randperm(num_points12);
X12_train{ii} = X_12(sequence12(1:split_point12),:);
Y12_train{ii} = Y_12(sequence12(1:split_point12));
X12_test{ii} = X_12(sequence12(split_point12+1:end),:);
Y12_test{ii}= Y_12(sequence12(split_point12+1:end));
end
The biggest problem you have currently is that you have 12 separate variables to do 12 related operations. Don't do that. Consolidate all of the variables into one container then iterate over the container.
I have the following suggestions for you:
Combine X_1, X_2, ... X_12 into one container. A cell array or structure may be prudent to use here. I'm going to use cell arrays in this case as your code currently employs them and it's probably the easiest thing for you to transition to.
Create four master cell arrays for the training and test set data and labels and within each cell array are nested cell arrays that contain each trial.
Loop over the cell array created in step #1 and assign the results to each of the four master cell arrays.
Therefore, something like this comes to mind:
X = {X_1, X_2, X_3, X_4, X_5, X_6, X_7, X_8, X_9, X_10, X_11, X_12};
Y = {Y_1, Y_2, Y_3, Y_4, Y_5, Y_6, Y_7, Y_8, Y_9, Y_10, Y_11, Y_12};
N = numel(X);
num_iterations = 10;
X_train = cell(1, num_iterations);
Y_train = cell(1, num_iterations);
X_test = cell(1, num_iterations);
Y_test = cell(1, num_iterations);
Percent = 0.7;
for ii = 1 : num_iterations
for jj = 1 : N
vals = X{jj};
labels = Y{jj};
num_points = size(vals,1);
split_point = round(num_points*Percent);
sequence = randperm(num_points);
X_train{ii}{jj} = vals(sequence(1:split_point),:);
Y_train{ii}{jj} = labels(sequence(1:split_point));
X_test{ii}{jj} = vals(sequence(split_point+1:end),:);
Y_test{ii}{jj} = labels(sequence(split_point+1:end));
end
end
As such, to access the training data for a particular iteration, you would do:
data = X_train{ii};
ii is the iteration you want to access. data would now be a cell array, so if you want to access the training data for a particular group, you would now do:
group = data{jj};
jj is the group you want to access. However, you can combine this into one step by:
group = X_train{ii}{jj};
You'll see this syntax in various parts of the code I wrote above. You'd do the same for the other data in your code (X_test, Y_train, Y_test).
I think you'll agree that this is more compact and to the point.

How do I get the Matlab data point labels correct?

I've created some Matlab code which anyone helping can run and see the problem.
When I run the following code, for each data point on my plot I seem to get all 15 labels instead of only 1 specific label.
So how do I get the Matlab data point labels correct for the following code?
Based on the the suggestions, I did the following:
I replaced these two lines of code:
labels = num2str(test_vector_label,'F%d');
labels_cell = cellstr(labels);
With this line of code as suggested:
labels_cell = strread(num2str(test_vector_label),'%s');
Now there are two follow-up questions:
1) A warning appears stating that I should use textscan instead of strread:
labels_cell = textscan(num2str(test_vector_label),'%s');
Then when I use textscan as in the above line of code above, I get an error?
"Error using text
Cell array of strings may only contain string and numeric
matrices"
"Error in Code_Test (line 46)
text(x_val,y_val,labels_cell,'horizontal','left',
'vertical','bottom')"
2) How do I put a letter in front of the number labels? For example, in the original code I had put letter F followed by a number?
%--------------Randomly select training and testing data.-----------
num_data = 35;
data_idx = 1:35;
train_data_idx_tmp = randsample(num_data,20)
train_dataRand_idx = sort(train_data_idx_tmp)
% Lia = ismember(A,B) returns an array the same size as A, containing 1 (true)
% where the elements of A are found in B, and 0 (false) elsewhere.
test_data_idx_tmp = ismember(data_idx,train_dataRand_idx)
test_dataRand_idx = data_idx(~test_data_idx_tmp)'
% Check to see if training and test data index are exclusive.
check_train_test_idx = ismember(train_dataRand_idx,test_dataRand_idx)
%--------------------------------------------------------------------------
% Testing stage.
test_vector = test_dataRand_idx; %Select randomly obtained testing data.
% Training stage.
train_vector = train_dataRand_idx; %Select randomly obtained training
x_val = [1:15];
y_val = 2*[1:15];
plot(x_val,y_val,'or','MarkerFaceColor','r')
grid on
%Put specific data point labels on plots.
test_vector_label = test_vector';
labels = num2str(test_vector_label,'F%d');
labels_cell = cellstr(labels);
text(x_val,y_val,labels_cell,'horizontal','left', 'vertical','bottom')
Your variable labels_cell is a 1x1 string cell not an array of strings. Replace
labels = num2str(test_vector_label,'F%d');
labels_cell = cellstr(labels);
with
labels_cell = strread(num2str(test_vector_label),'%s');

MATLAB convert from struct to table and ouput as csv

As part of an image processing pipeline using 'regionprops' in Matlab I generate the struct:
vWFfeatures =
1631x1 struct array with fields:
Area
Centroid
MajorAxisLength
MinorAxisLength
Eccentricity
EquivDiameter
Where 'Centroid' is a Vector containing [x, y] for example [12.4, 26.2]. I would like to convert this struct to a table and save as a CSV file. The objective is to separate the 'Centroid' vector into two columns in the table labelled Centroid_X and Centroid_Y for example. I am not sure how to achieve this.
So far I have investigated using the 'struct2table' function. This ouputs the 'Centroid' as one column. In addition when I try to assign the output to a variable I get an error:
table = struct2table(vWFfeatures)
Error using struct2table
Too many output arguments.
I cannot understand this, any help please?
Since the original struct2table isn't available to you, you might want to implement specifically the behavior you're trying to achieve yourself.
In this case, this means extracting the values you want to save, (split the array,) then save the data:
data_Centroid = vertcat(vWFfeatures.Centroid); %// contains the centroid data
Centroid_X = data_Centroid(:,1); %// The first column is X
Centroid_Y = data_Centroid(:,2); %// the second column is Y
csvwrite('centroid.csv',data_Centroid); %// writes values into csv
If you want column headers in your csv, it gets complicated because csvwrite can only handle numeric arrays:
celldata = num2cell(num2str(data_Centroid)); %// create cell array
celldata(:,3) = celldata(:,4); %// copy col 4 (y data) into col 3 (spaces)
for i=1:length(celldata)
celldata{i,2} = ','; %// col 2 has commas
celldata{i,4} = '\n'; %// col 4 has newlines
end
celldata = celldata'; %'// transpose to make the entries come columnwise
strdata = ['Centroid_X,Centroid_Y\n',celldata{:}]; %// contains all as string
fid = fopen('centroid.csv','w'); % writing the string into the csv
fprintf(fid,strdata);
fclose(fid);
This is how I solved it in the end: extracted each field from struct used horzcat to join into a new array then defined headers and used csvwrite_with_headers, to ouput to csv.
wpbFeatures = regionprops(vWFlabelled, 'Area','Centroid', 'MajorAxisLength', 'MinorAxisLength', 'Eccentricity', 'EquivDiameter');
wpbArea = vertcat(wpbFeatures.Area);
wpbCentroid = vertcat(wpbFeatures.Centroid);
wpbCentroidX = wpbCentroid(:,1);
wpbCentroidY = wpbCentroid(:,2);
wpbFeret = max(imFeretDiameter(vWFlabelled, linspace(0,180,201)), [], 2);
wpbMajorAxisLength = vertcat(wpbFeatures.MajorAxisLength);
wpbMinorAxisLength = vertcat(wpbFeatures.MinorAxisLength);
wpbEccentricity = vertcat(wpbFeatures.Eccentricity);
wpbEquivDiameter = vertcat(wpbFeatures.EquivDiameter);
wpbFeatures = horzcat(wpbArea, wpbCentroidX, wpbCentroidY, wpbFeret, wpbMajorAxisLength, wpbMinorAxisLength, wpbEccentricity, wpbEquivDiameter);
headers = {'Area','CentroidX','CentroidY', 'Feret', 'MajorAxisLength', 'MinorAxisLength', 'Eccentricity', 'EquivDiameter'};
csvwrite_with_headers(strcat(PlateName, '_ResultsFeatures.csv'),wpbFeatures,headers);