这个使用 Octave\MatLab 的 ML 梯度下降成本函数的简单计算到底是如何工作的?

How exactly works this simple calculus of a ML gradient descent cost function using Octave\MatLab?

我正在学习 Coursera 上的 机器学习 课程,我正在使用 Octave 进行以下练习(MatLab 应该是相同的) .

练习与计算梯度下降算法的成本函数有关。

在课程幻灯片中,我知道这是我必须使用 Octave 实现的成本函数:

这是课程幻灯片中的公式:

因此J是由THETA矩阵表示的一些THETA变量的函数(在前面的第二个等式中)。

这是 J(THETA) 计算的正确 MatLab\Octave 实现:

function J = computeCost(X, y, theta)
%COMPUTECOST Compute cost for linear regression
%   J = COMPUTECOST(X, y, theta) computes the cost of using theta as the
%   parameter for linear regression to fit the data points in X and y

% Initialize some useful values
m = length(y); % number of training examples

% You need to return the following variables correctly 
J = 0;

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta
%               You should set J to the cost.

J = (1/(2*m))*sum(((X*theta) - y).^2)

% =========================================================================

end

其中:

Xm 行的 2 列矩阵,第一列的所有元素都设置为值 1:

X =

1.0000    6.1101
1.0000    5.5277
1.0000    8.5186
......    ......
......    ......
......    ......

ym 个元素的向量(如 X):

y =

   17.59200
    9.13020
   13.66200
   ........
   ........
   ........

最后 theta 是一个具有 0 个值的 2 列向量,如下所示:

theta = zeros(2, 1); % initialize fitting parameters
theta
theta =

   0
   0

好的,回到我的工作解决方案:

J = (1/(2*m))*sum(((X*theta) - y).^2)

具体到这个矩阵乘法(矩阵X和向量theta之间的乘法):我知道它是一个有效矩阵乘法因为 X 的列数(2 列)等于 theta 的行数(2 行)所以它是一个完美的有效的矩阵乘法。

让我发疯的疑惑(可能是一个微不足道的疑惑)与之前的课程幻灯片上下文有关:

正如您在用于计算当前 h_theta(x) 值的第二个方程中所见,它使用 转置 theta 向量 而不是代码中的 theta 向量。

为什么?!?!

我怀疑这仅取决于 theta 向量的创建方式。它是这样构建的:

theta = zeros(2, 1); % initialize fitting parameters

生成一个 2 行 1 列向量而不是经典的 1 行 2 列向量。所以也许我不必转置它。但我完全不确定这个说法。

我的直觉是正确的还是我错过了什么?

您的直觉是正确的。实际上,无论您是按 theta.' * X 还是 X.' * theta 执行乘法都没有关系,因为这会生成代表所有观察结果的假设的水平向量或垂直向量,以及您期望做的事情接下来是在每次观察时从假设向量中减去 y 向量,并对结果求和。因此,只要 y 与您的假设具有相同的方向并且您在每个等效点进行减法,那么求和的标量最终结果将是相同的。

通常,您会看到 X.' * theta 版本优于 theta.' * X 纯粹是为了方便,避免为了与数学符号保持一致而一遍又一遍地转置。但这很好,因为底层数学并没有真正改变,只是等效操作的顺序。

我同意这很令人困惑,这既是因为当代码实际上看起来像是在做其他事情时,它使遵循公式变得更加困难,也是因为它与垂直向量代表 'coordinates',水平向量表示观察结果。在这种情况下,尤其是在像 matlab / octave 这样的语言中,向量的方向没有在变量的类型中明确定义,记录你期望输入代表什么是非常重要的,最好应该有 assert 代码中的语句确认输入已以正确的方向传递。很明显,他们在这里觉得没有必要,因为无论如何,这段代码都是在预定义的练习环境中的受控条件下运行的,但从软件工程的角度来看,这样做是一种很好的做法。