Supplied objective function must return a scalar value

65 visualizaciones (últimos 30 días)
reza
reza el 20 de En. de 2019
Comentada: Jay Guwalani el 19 de Nov. de 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 comentarios
Walter Roberson
Walter Roberson el 20 de En. de 2019
what are the sizes of the inputs?
Jay Guwalani
Jay Guwalani el 19 de Nov. de 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));

Iniciar sesión para comentar.

Respuesta aceptada

reza
reza el 20 de En. de 2019
Editada: reza el 20 de En. de 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 comentario
Rik
Rik el 20 de En. de 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.

Iniciar sesión para comentar.

Más respuestas (1)

Rik
Rik el 20 de En. de 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 comentarios
Rik
Rik el 16 de Jul. de 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 el 16 de Jul. de 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.

Iniciar sesión para comentar.

Categorías

Más información sobre Solver Outputs and Iterative Display en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by