我的实现(见下文)给出了标量值3.18,这不是正确的答案。正确的值应该是0.693。我的代码在哪里偏离了公式?
以下是使用Octave运行成本函数方法的数据解决方案说明:
data = load('ex2data1.txt');X = data(:, [1, 2]); y = data(:, 3);[m, n] = size(X);X = [ones(m, 1) X];initial_theta = zeros(n + 1, 1);[cost, grad] = costFunction(initial_theta, X, y);
这里是ex2data
的链接,在这个包中有数据:数据链接。
这是我使用的代码:
function [J, grad] = costFunction(theta, X, y)m = length(y); % 训练样本的数量% 你需要正确返回以下变量 J = 0; %#ok<NASGU>grad = zeros(size(theta)); %#ok<NASGU>hx = sigmoid(X * theta)';m = length(X);J = sum(-y' * log(hx) - (1 - y')*log(1 - hx)) / m;grad = X' * (hx - y) / m;end
这是Sigmoid函数:
function g = sigmoid(z)g = 1/(1+exp(-z));end
回答:
你的sigmoid
函数是错误的。输入的数据类型是向量,但你使用的操作是在进行矩阵除法。这需要按元素进行操作。
function g = sigmoid(z) g = 1.0 ./ (1.0 + exp(-z));end
通过1 / A
,其中A
是一个表达式,你实际上是在计算A
的逆。由于逆仅存在于方阵中,这将计算伪逆,这绝对不是你想要的。
你可以保留大多数的costFunction
代码,因为你使用了点积。我建议去掉sum
,因为点积已经隐含了这个操作。我将用注释标出我的修改:
function [J, grad] = costFunction(theta, X, y)m = length(y); % 训练样本的数量% 你需要正确返回以下变量 %J = 0; %#ok<NASGU> <-- 不需要声明,因为你稍后会创建这些变量%grad = zeros(size(theta)); %#ok<NASGU>hx = sigmoid(X * theta); % <-- 移除转置m = length(X);J = (-y' * log(hx) - (1 - y')*log(1 - hx)) / m; % <-- 移除sumgrad = X' * (hx - y) / m;end