python代码

时间:2017-08-10 06:13:50

标签: python gradient-descent

def computeCost(X, y, theta):
    inner = np.power(((X * theta.T) - y), 2)
    return np.sum(inner) / (2 * len(X))

def gradientDescent(X, y, theta, alpha, iters):
    temp = np.matrix(np.zeros(theta.shape))
    params = int(theta.ravel().shape[1]) #flattens
    cost = np.zeros(iters)

    for i in range(iters):
        err = (X * theta.T) - y

        for j in range(params):
            term = np.multiply(err, X[:,j])
            temp[0, j] = theta[0, j] - ((alpha / len(X)) * np.sum(term))

        theta = temp
        cost[i] = computeCost(X, y, theta)

    return theta, cost

以下是我在教程中找到的线性回归成本函数和梯度下降的代码,但我不太清楚它是如何工作的。

首先,我了解computeCost代码的工作原理,因为它只是(1 / 2M),其中M是数据的数量。

对于gradientDescent代码,我只是不明白它是如何工作的。我知道更新theta的公式类似于

theta = theta - (learningRate) * derivative of J(cost function)。但我不确定更新alpha / len(X)) * np.sum(term的行是temp[0,j])的来源。

请帮我理解!

2 个答案:

答案 0 :(得分:1)

我会为你解决这个问题。所以在你的gradientDescent函数中,你要接受预测变量(X),目标变量(y), 权重矩阵(theta)和另外两个参数(alphaiters),它们是训练参数。该功能的工作是弄清楚应该多少 预测变量(X)集中的每一列应在加之前乘以得到目标变量(y)的预测值。 在函数的第一行中,您将启动称为temp的权重矩阵为零。这基本上是起点 函数最终输出的最终权重矩阵(theta)。 params变量基本上是权重数或预测变量数。 在创建特征抽象的神经网络环境中,这条线更有意义。

在线性回归中,权重矩阵主要是一维数组。在典型的前馈神经网络中,我们假设有5个特征, 通过使用权重矩阵等将其转换为4或6或n个特征。在线性回归中,我们只需提取所有输入 功能集成一个输出功能。因此theta基本上等同于行向量(行temp[0,j]=...明显),params将是要素的数量。我们cost数组只是存储 每次迭代时的那个数组。现在进入两个循环。在第一个err = (X * theta.T) - y循环下的行for中,我们正在计算预测 每个训练样例的错误。 err变量的形状为number of examples,1。在第二个for循环中,我们正在训练模型, 那就是我们正在逐步更新我们的term矩阵。我们运行第二个for循环iters 次数。在神经网络环境中,我们通常将其称为时代。它基本上是您想要训练模型的次数。

现在行term = np.multiply(err, X[:,j]):这里我们正在计算应该对temp矩阵中的每个权重进行的个别调整。 我们将成本定义为(y_predicted-y_actual)** 2 / number_of_training_points,其中y_predicted = X_1 * w_1 + X_2 * w_2 + X_3 * w_3 + ...如果我们将此成本v区分为 我们得到一个特定的权重(比如W_i)(y_predicted-y_actual)*(X_i)/ number_of_training_points,其中X_i是W_i乘以的列。那么term =行 基本上计算差异化部分。我们可以将term变量乘以学习率并从W_i中减去。 但是您可能会注意到term变量是一个数组。但是下一行就是这个问题。 在下一行中,我们采用term的平均值(通过将其相加然后除以len(X)) 并从temp矩阵中的相应权重中减去它。权重更新并存储后,temp矩阵, 我们将theta替换为temp。我们重复此过程iters

答案 1 :(得分:0)

如果你,而不是像((alpha / len(X)) * np.sum(term))那样写,那就像(alpha * (np.sum(term) / len(X)))那样写,你可以这么做,因为乘法和除法是可交换的(如果我记得正确的话)那么你就是将alpha乘以平均误差,因为无论如何,术语长度为X.

这意味着你减去学习率(alpha)乘以平均误差,就像X [j] * tetha(实际) - y(理想)一样,顺便提一下也足够接近(X *的导数) tetha - y)^ 2