Supplied objective function must return a scalar value

65 Ansichten (letzte 30 Tage)
reza
reza am 20 Jan. 2019
Kommentiert: Jay Guwalani am 19 Nov. 2021
I am trying to code a ML algorithm in Matlab. These are my different functions:
sigmoid.m:
function g = sigmoid(z)
g = zeros(size(z));
g = 1 ./ (1+exp(z));
costFunction.m
function [J, grad ] = costFunction(theta, X, y)
m = length(y); % number of training examples
z = -X * theta;
g = sigmoid(z);
J = 1/m * ((-y * log(g)') - ((1 - y) * log(1 - g)'));
grad = zeros(size(theta'));
grad = (1/m) * (X' * (g - y));
end
ex2.m (This is the main file of my project and I put the relative lines I get this error message)
options = optimset('GradObj', 'on', 'MaxIter', 400);
[theta, cost] = ...
fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);
The error message:
> Error using fminunc (line 348) Supplied objective function must return Supplied objective function must return
> a scalar value.
>
> Error in ex2 (line 97) fminunc(@(t)(costFunction(t, X, y)),
> initial_theta, options);
I don't know is there enough information above or not? If not, let me know to add extra information.
  2 Kommentare
Walter Roberson
Walter Roberson am 20 Jan. 2019
what are the sizes of the inputs?
Jay Guwalani
Jay Guwalani am 19 Nov. 2021
% Try using this in cost function || I guess the issue is with the (.)
% elementwise ops
H=sigmoid(X*theta);
J=(sum(-y.*log(H)-(1-y).*log(1-H))/m);
grad=(1/m)*(X'*(H-y));

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

reza
reza am 20 Jan. 2019
Bearbeitet: reza am 20 Jan. 2019
I changed the following line of code:
J = 1/m * ((-y * log(g)') - ((1 - y) * log(1 - g)'));
To the following line of code:
J = 1/m * (((-y)' * log(g)) - ((1 - y)' * log(1 - g)));
And problem solved!
The y and g were 100*1 matrices and with previous code I had J=100*100 matrix, but with new code I have J=1*1 matrix or scalar number and problem solved!
  1 Kommentar
Rik
Rik am 20 Jan. 2019
Since it is the conclusion of my answer that you needed to change something to achieve a scalar output, I would say this derives from my answer, but anyway, happy to help.
This also shows the value of comments: I had no way of knowing what your code does, so I could only point you in a general direction. If you want your code understandable to others, make sure to write comments and function headers. Some people go as far as saying you should have a line of comment for every line of code, but I would say that is being excessive.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Rik
Rik am 20 Jan. 2019
Depending on your input variable sizes, your code is not guaranteed to return the same size output as the input size. The documentation of fminunc states the following:
"fun is a function that accepts a vector or array x and returns a real scalar f, the objective function evaluated at x."
The initial_theta determines the size of the theta that the solver will use.
Also, I can't find a sigmoid function in the Matlab doc. Do you mean this FEX entry?
%to more easily explain what's going on, assign some names to dimensions:
[a,b]=size(X);[c,d]=size(y);
[e,f]=size(initial_theta);
And now to your function:
function [J, grad ] = costFunction(theta, X, y)
m = length(y); % number of training examples
%m is either c or d
z = -X * theta;
%z is [a,f], unless theta is a scalar, then z is [a,b]
g = sigmoid(z);
%same as z (so [a,b] or [a,f])
J = 1/m * ((-y * log(g)') - ((1 - y) * log(1 - g)'));
%1/m is a scalar
%(-y * log(g)') is [c,d]*[f,a] or [c,d]*[b,a], so [c,a], but will error if d and b (or d and f) are not equal
%((1 - y) * log(1 - g)') is the same size as the other term
%so J is [c,a], unless this line returns an error
grad = zeros(size(theta'));
%this line doesn't do anything, as grad gets overwritten
grad = (1/m) * (X' * (g - y));
%1/m is scalar
%(X' * (g - y)) is [b,a]*[c,d] so [b,d] and asserts that a==c and that [a,b] (or [a,f]) is the same as [c,d]
end
So this function places quite a lot of implicit restrictions on your inputs.
To successfully evaluate, the following must all be true:
[a,b]=size(X);[c,d]=size(y);
[e,f]=size(initial_theta);
theta_is_scalar=numel(theta)==1;
%J restrictions
assert(a==1)
assert(c==1)
if theta_is_scalar
assert(d==f)%so assert(d==1)
else
assert(b==e)
assert(b==d)
end
%grad restrictions
assert(b==1)
assert(c==1)
assert(a==c)
if theta_is_scalar
%[a,b] is [c,d]
assert(b==d)
else
%[a,f] is [c,d]
assert(f==d)
end
Concluding this:
%scalar theta:
X must be [1,1]
y must be [1,1]
%non-scalar theta:
X must be [1,1]
y must be [1,1]
initial_theta must be [1,1]
So all the inputs must be scalar.
  5 Kommentare
Rik
Rik am 16 Jul. 2020
Why are you using globals?
And if the error is the same, it is likely that the solution is also the same: make sure your objective function returns a scalar.
Walter Roberson
Walter Roberson am 16 Jul. 2020
The user posted this elsewhere, and I responded there. The syms x [1 4] is a problem and it cannot be fixed without redefining the calculation.

Melden Sie sich an, um zu kommentieren.

Community Treasure Hunt

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

Start Hunting!

Translated by