## Supplied objective function must return a scalar value

reza

### reza (view profile)

さんによって質問されました 2019 年 1 月 20 日

### Walter Roberson (view profile)

さんによって コメントされました 2019 年 1 月 21 日
reza

### reza (view profile)

さんの 回答が採用されました
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 = (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.

Walter Roberson

### Walter Roberson (view profile)

2019 年 1 月 20 日
what are the sizes of the inputs?

サインイン to comment.

## 2 件の回答

2019 年 1 月 20 日

### reza (view profile)

2019 年 1 月 20 日
採用された回答

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!

Rik

### Rik (view profile)

2019 年 1 月 20 日
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.

サインイン to comment.

### Rik (view profile)

2019 年 1 月 20 日

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);
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
%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
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.

reza

### reza (view profile)

2019 年 1 月 20 日
I don't know how to say thank you. I could solve my problem with only one simple change as I wrote in my answer, but again I say thank you very much. I learned a lot from your answer.
Walter Roberson

### Walter Roberson (view profile)

2019 年 1 月 21 日
(User supplied the source for sigmoid in the Question.)

サインイン to comment.