Hand input data to custom loss function in a regression neural network

7 views (last 30 days)
I'm building an LSTM deep neural network for sequence-to-one regression and need to implement a custom loss function for training. The issue is that my loss function depends on the input data X that I feed to the network. I'm running out of ideas how to properly hand the input data to the output layer. For custom regression output layers there seems to be no way to use the NN input data X as an input to the loss function. Also, I tried adding the input data to the target data array T, but then the size of T doesn't match the expected format compared to the NN output. Does anyone know how I can properly implement this?
  2 Comments
Rebecca Plant
Rebecca Plant on 8 Nov 2021
In case someone else is struggling with this in the future:
I found a workaround by using
X = evalin('base','nnDataIn');
to import the input data (nnDataIn) from the base workspace to the loss function. For what I know the evalin function is not the best coding style, but it worked fine for me.
Marcos
Marcos on 25 Jan 2024
Hi Rebecca, do you remember how you did this? Where did you use evalin?
Thank you!

Sign in to comment.

Answers (1)

Maksym Tymchenko
Maksym Tymchenko on 2 May 2025
Edited: Maksym Tymchenko on 6 May 2025
It sounds like you want to define a custom loss function that depends on the input data X that you feed to the network. As you noticed, this is tricky because the custom loss function passed to trainnet can only receive the outputs Y and the targets T to the network but does not directly receive the inputs X. In other words, the signature of the custom loss function must be @(Y,T)myCustomLossFunction(Y,T).
To be able to use the inputs X in your custom loss function, as a workaround, you can incorporate X in the targets T and then unpack them in the custom loss function. For example you could define the targets T as follows:
X = myInputData;
actualTargets = myTargetData;
T = [actualTargets; X];
you can then unpack them in your custom loss function as follows:
function loss = myCustomLossFunction(Y, T)
actualTargets = T(1,:);
X = T(2,:);
[...]
end
Here is a full example of how you can train a simple multi-layer perceptron to predict a value that minimizes the deviation from a target T = 2*X+0.5 and the input X itself. You can see that if the inputWeight value is equal to 0.5, then the network will learn to predict a line that is exactly in between the input and the target. If you increase the value of inputWeight to 0.9 you will see that the predicted line will be much closer to the input X.
% Generate training data
numSamples = 1000;
X = dlarray(rand(1,numSamples),"CB");
actualTargets = 2 * X + 0.5;
inputs = X;
targets = [actualTargets; X];
inputSize = 1;
outputSize = 1;
numHiddenUnits = 100;
% Define a multi layer perceptron architecture
layers = [
featureInputLayer(inputSize)
fullyConnectedLayer(numHiddenUnits)
reluLayer
fullyConnectedLayer(outputSize)
];
% Define a custom loss function that aims to minimize the deviation of the output Y both
% from the actual target and the input to the network X.
function loss = customLossFcn(Y, T)
actualTarget = T(1,:);
inputX = T(2,:);
deviationFromTarget = mean((Y - actualTarget).^2, "all");
deviationFromInput = mean((Y - inputX).^2, "all");
inputWeight = 0.5;
loss = (1-inputWeight) * deviationFromTarget + inputWeight * deviationFromInput;
end
% Train
opts = trainingOptions('adam', MiniBatchSize = 50, MaxEpochs=20, Verbose=false);
net = trainnet(inputs, targets, layers, @(Y, T) customLossFcn(Y,T), opts);
% Predict & Plot
XSorted = sort(X,2);
TSorted = sort(actualTargets,2);
Y = predict(net, XSorted);
hold on
plot(XSorted);
plot(TSorted);
plot(Y)
hold off
legend('Input', 'Target', 'Predicted');
xlabel('Sample');
ylabel('Value');

Categories

Find more on Deep Learning Toolbox 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!