Error using trainNetwork. Invalid training data. Responses must be a vector, a matrix, or a 4-D array of real numeric responses. Responses must not contain NaNs.

Hello, I'm getting a size-related error in the TTrain data, but according to MATLAB, TTrain is an N-by-1 cell array, where each cell contains a 2x1 matrix. Additionally, TTrain has the same dimensions as XTrain. The documentation states that I can provide input in this format. How can I fix this error?
Note error code is:
Error using trainNetwork (line 191)
Invalid training data. For regression tasks, responses must be a vector, a matrix, or a 4-D array of real numeric responses. Responses must not contain NaNs.
% Load the dataset
clc;
clear;
data = readtable('DataDoubleLineChange.xlsx');
% Extract inputs and outputs
inputs = data{:, {'Time','side_slip_angle', 'Lateral_Acceleration', 'Yaw_Rate','LongitudinalVelocity','steering_wheel_angle_front'}};
outputs = data{:, {'steering_wheel_angle_front','LongitudinalVelocity'}};
% Decide input and output
inputVars = {'Time','side_slip_angle', 'Lateral_Acceleration', 'Yaw_Rate','LongitudinalVelocity','steering_wheel_angle_front'};
outputVars = {'steering_wheel_angle_front','LongitudinalVelocity'};
% Take labels
input_headers = data(:, inputVars).Properties.VariableNames;
output_headers = data(:, outputVars).Properties.VariableNames;
% Take num of obs
numObservations = size(data, 1);
% Seperate dataset
numTrain = round(0.7 * numObservations);
numVal = round(0.15 * numObservations);
numTest = numObservations - numTrain - numVal;
% Decied index
idxTrain = 1:numTrain;
idxVal = numTrain + 1:numTrain + numVal;
idxTest = numTrain + numVal + 1:numObservations;
% Create Training, Validation and Test set
dataTrain = data(idxTrain, :);
dataVal = data(idxVal, :);
dataTest = data(idxTest, :);
numObservationsTrain = numel(dataTrain.Time); % Number of observations in training set
XTrain = cell(numObservationsTrain, 1);
TTrain = cell(numObservationsTrain, 1);
% Prepare training data (X and T)
for n = 1:numObservationsTrain-1 % Adjust the loop to avoid out-of-bounds errors
XTrain{n} = dataTrain{n,input_headers}; % Features (exclude the last value for each feature)
TTrain{n} = dataTrain{n+1,output_headers}; % Targets (use the next value for each feature)
end
% Normalize features and targets
% Calculate mean and std dev for each feature
XAll = vertcat(XTrain{:}); % Concatenate all feature data into one matrix
TAll = vertcat(TTrain{:}); % Concatenate all target data into one matrix
% Calculate mean and standard deviation for each feature (column-wise)
muX = mean(XAll,1); % Mean for each feature (column-wise)
sigmaX = std(XAll, 0, 1); % Standard deviation for each feature (column-wise)
muT = mean(TAll, 1); % Mean for each target (column-wise)
sigmaT = std(TAll, 0, 1); % Standard deviation for each target (column-wise)
% Prepare data for normalization
dataPredictorTrain=data(idxTrain,inputVars);
dataTargetTrain=data(idxTrain, outputVars );
% Generate cell
XTrain = cell(height(dataPredictorTrain), 1);
TTrain = cell(height(dataPredictorTrain), 1);
% Normalization
for n = 1:height(dataPredictorTrain)
timeValue = dataPredictorTrain{n, "Time"};
XFeatures = dataPredictorTrain{n, 2:end};
% Normalization without time
XTrain{n} = [(timeValue), ((XFeatures - muX(2:end)) ./ sigmaX(2:end))];
% Target normalization
TTrain{n} = (dataTargetTrain{n, :} - muT) ./ sigmaT;
% Reverses column
XTrain{n} = XTrain{n}(:);
TTrain{n} = TTrain{n}(:);
end
dataPredictorVal = dataVal(:, inputVars);
dataTargetVal = dataVal(:,outputVars);
% Generate cell
XVal = cell(height(dataPredictorVal), 1);
TVal = cell(height(dataPredictorVal), 1);
% Normalization
for n = 1:height(dataPredictorVal)
timeValue = dataPredictorVal{n, "Time"};
XFeatures = dataPredictorVal{n, 2:end};
% Normalization without time
XVal{n} = [(timeValue), ((XFeatures - muX(2:end)) ./ sigmaX(2:end))];
% Target normalization
TVal{n} = (dataTargetVal{n,:} - muT) ./ sigmaT;
% Reverses colum
XVal{n} = XVal{n}(:);
TVal{n} = TVal{n}(:);
end
% Define LSTM network
inputSize = size(XTrain{1},1); % Number of features (should be 5)
numHiddenUnits = 50;
numResponses = 1;
layers = [
sequenceInputLayer(inputSize)
lstmLayer(numHiddenUnits, 'OutputMode', 'last')
fullyConnectedLayer(numResponses)
regressionLayer
];
% Training options
options = trainingOptions('adam', ...
'MaxEpochs', 50, ...
'MiniBatchSize', 32, ...
'InitialLearnRate', 0.01, ...
'GradientThreshold', 1, ...
'Verbose', 0, ...
'Plots', 'training-progress', ...
'ValidationData', {XVal, TVal}, ...
'ValidationFrequency', 5, ...
'ValidationPatience', 5);
% Train the network
net = trainNetwork(XTrain, TTrain, layers, options);
Error using trainNetwork (line 191)
Invalid training data. For regression tasks, responses must be a vector, a matrix, or a 4-D array of real numeric responses. Responses must not contain NaNs.

回答(1 个)

I was able to get that particular error to go away by removing the 'OutputMode','last' option from your lstmLayer. However, you will then get a new error:
Error using trainNetwork (line 191)
Invalid training data. For cell array input, responses must be an N-by-1 cell array of sequences, where N is the number of sequences. The spatial and channel dimensions of the sequences must be the same as the output size of the last layer (1).
It looks like you are trying to perform refression on a time-series sequence. In that case, your syntax is
If so, when your inputs are Nx1 cell arrays, where the cells must be c-by-s matrices, where c is the number of features of the sequences and s is the sequence length.
Your inputs appear to be 1xc, where the row corresponds to a single time step, and the columns are the features.
It also looks like your data set has 5 observations, each with 6 channels of data (features). Given that, I tried to follow the process in this example: Time Series Forecasting Using Deep Learning.
Here's my attempt. I have removed Time and LongitudinalVelocity as features (so final dataset has 4 features) because the lstm already assumes each row is a timestep, and LongitudinalVelocity is constant in an observation, giving it no predictive power. It also turns into NaN when you normalize since it's standard deviation is 0.
With the data formatted as described, I was still getting the error about invalid training data. Based on the layers used in the example, I cahnged the intput to the fullyConnectedLayer to be the input size (I called it numChannels).
Finally, I am not an expert in this space, so no promises this is correct. This is adapting your data to work with a doc example. The main weakness I see, then, is that your data really only has 5 observations while the doc example has 900. You will need many more observations to make this approach meaningful.
% Load the data
data = readtable('DataDoubleLineChange.xlsx')
data = 154x6 table
Time side_slip_angle Lateral_Acceleration Yaw_Rate LongitudinalVelocity steering_wheel_angle_front ____ _______________ ____________________ __________ ____________________ __________________________ 0 -0.055305 2.5641e-10 0 65 -0.6069 0.5 -0.055305 -7.0711e-09 2.9564e-07 65 -0.6069 1 -0.051536 0.0026558 -0.082727 65 -0.90856 1.5 -0.099562 -0.031203 0.97483 65 2.9467 2 0.4382 0.33212 -10.475 65 -39.663 2.5 -0.51492 -0.31245 9.9374 65 35.925 3 0.90396 0.56716 -18.045 65 -70.539 3.5 4.9486 1.0056 -42.656 65 -186.06 4 8.4384 1.0028 -36.537 65 -121.95 4.5 8.8666 0.98904 -30.274 65 -109.68 5 5.4364 0.96006 -20.939 65 -100.42 5.5 1.52 0.75215 -21.359 65 -99.602 6 1.1496 0.65134 -20.159 65 -82.938 6.5 0.98178 0.57294 -17.311 65 -68.64 7 0.81913 0.49502 -14.792 65 -57.068 7.5 0.63309 0.40249 -11.953 65 -45.174
% organzize data into numObsx1 cell array, where each cell is an array
% with size numFeatures x numTimeSteps
G = findgroups(data.LongitudinalVelocity)
G = 154×1
1 1 1 1 1 1 1 1 1 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
data = removevars(data,{'LongitudinalVelocity','Time'});
data = splitapply(@(x1,x2,x3,x4) {[x1,x2,x3,x4].'},data,G);
% remove observations with less time steps than features
L = cellfun(@(x)size(x,2),data);
data(L<6)=[]
data = 5x1 cell array
{4x35 double} {4x32 double} {4x30 double} {4x28 double} {4x29 double}
% Create Training, Validation and Test set
c = cvpartition(height(data),"Holdout",0.2);
idxTest = test(c);
dataTest = data(idxTest);
idxRemain = training(c);
remain = data(idxRemain);
c = cvpartition(height(remain),"Holdout",0.25);
idxVal = test(c);
dataVal = remain(idxVal);
idxTrain = training(c);
dataTrain = remain(idxTrain)
dataTrain = 3x1 cell array
{4x35 double} {4x28 double} {4x29 double}
% Prepare data for training.
% he LSTM neural network learns to predict the value of the next time step.
% The predictors are the training sequences without the final time step.
for n = 1:numel(dataTrain)
X = dataTrain{n};
XTrain{n} = X(:,1:end-1);
TTrain{n} = X(:,2:end);
end
% Compute normalization values
muX = mean(cat(2,XTrain{:}),2);
sigmaX = std(cat(2,XTrain{:}),0,2);
muT = mean(cat(2,TTrain{:}),2);
sigmaT = std(cat(2,TTrain{:}),0,2);
% Normalization
for n = 1:numel(XTrain)
XTrain{n} = (XTrain{n} - muX) ./ sigmaX;
TTrain{n} = (TTrain{n} - muT) ./ sigmaT;
end
% Prepare validation data for training.
% he LSTM neural network learns to predict the value of the next time step.
% The predictors are the training sequences without the final time step.
for n = 1:numel(dataVal)
X = dataVal{n};
XVal{n} = X(:,1:end-1);
TVal{n} = X(:,2:end);
end
% Compute normalization values
muX = mean(cat(2,XVal{:}),2);
sigmaX = std(cat(2,XVal{:}),0,2);
muT = mean(cat(2,TVal{:}),2);
sigmaT = std(cat(2,TVal{:}),0,2);
% Normalization
for n = 1:numel(XVal)
XVal{n} = (XVal{n} - muX) ./ sigmaX;
TVal{n} = (TVal{n} - muT) ./ sigmaT;
end
% Define LSTM network
numChannels = size(XTrain{1},1); % Number of features (should be 5)
numHiddenUnits = 50;
numResponses = 1;
layers = [
sequenceInputLayer(numChannels)
lstmLayer(numHiddenUnits)
fullyConnectedLayer(numChannels)
regressionLayer
];
% Training options
options = trainingOptions('adam', ...
'MaxEpochs', 50, ...
'MiniBatchSize', 32, ...
'InitialLearnRate', 0.01, ...
'GradientThreshold', 1, ...
'Verbose', 0, ...
'Plots', 'none', ...
'ValidationData', {XVal, TVal}, ...
'ValidationFrequency', 5, ...
'ValidationPatience', 5);
% Train the network
net = trainNetwork(XTrain, TTrain, layers, options)
net =
SeriesNetwork with properties: Layers: [4x1 nnet.cnn.layer.Layer] InputNames: {'sequenceinput'} OutputNames: {'regressionoutput'}
Note that I changed the Plots options so that I could run the code here.
Now that you have a trained network, you can test it. This code is adapted from the same example.
% Test
for n = 1:size(dataTest,1)
X = dataTest{n};
XTest{n} = (X(:,1:end-1) - muX) ./ sigmaX;
TTest{n} = (X(:,2:end) - muT) ./ sigmaT;
end
YTest = predict(net,XTest,SequencePaddingDirection="left");
for i = 1:size(YTest,1)
rmse(i) = sqrt(mean((YTest{i} - TTest{i}).^2,"all"));
end
mean(rmse)
ans = single 0.8980
% Forecast Future Time Steps
idx = 1;
X = XTest{idx};
T = TTest{idx};
figure
stackedplot(X',DisplayLabels="Channel " + (1:numChannels))
xlabel("Time Step")
title("Test Observation " + idx)
% Open Loop Forecasting
net = resetState(net);
offset = 15;
[net,~] = predictAndUpdateState(net,X(:,1:offset));
numTimeSteps = size(X,2);
numPredictionTimeSteps = numTimeSteps - offset;
Y = zeros(numChannels,numPredictionTimeSteps);
for t = 1:numPredictionTimeSteps
Xt = X(:,offset+t);
[net,Y(:,t)] = predictAndUpdateState(net,Xt);
end
figure
t = tiledlayout(numChannels,1);
title(t,"Open Loop Forecasting")
for i = 1:numChannels
nexttile
plot(T(i,:))
hold on
plot(offset:numTimeSteps,[T(i,offset) Y(i,:)],'--')
ylabel("Channel " + i)
end
xlabel("Time Step")
nexttile(1)
legend(["Input" "Forecasted"])

产品

版本

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by