用于线性回归的 mxnet 梯度下降,变量类型错误

mxnet gradient descent for linear regression, variable types error

我正在尝试为线性回归实现简单的梯度下降。

如果我手动计算梯度(通过使用解析表达式),它可以正常工作,但现在我试图用 mxnet 模块的 autograd 来实现它。

这是代码


from mxnet import autograd, np, npx
npx.set_np()

def main():
    # learning algorithm parameters
    nr_epochs = 1000
    alpha = 0.01

    # read data, insert column of ones (to include bias with other parameters)
    data = pd.read_csv("dataset.txt", header=0, index_col=None, sep="\s+")
    data.insert(0, "x_0", 1, True)  # insert column of "1"s as x_0
    m = data.shape[0]  # number of samples
    n = data.shape[1] - 1  # number of features
    X = data.iloc[:, 0:n].values  # array with x values
    Y = data.iloc[:, -1].values  # array with y values

    theta = np.zeros(n)  # initial parameters array
    theta.attach_grad()

    theta, J = GradientDescent(X, Y, theta, alpha, nr_epochs)



#-------------------#
#   loss function   #
#-------------------#
def LossFunction(X, Y, theta):
    m = X.shape[0]                  # number of training samples
    loss = 0

    for i in range(X.shape[0]):
        loss = loss + (1 / (2 * m)) * (H(X[i, :], theta) - Y[i]) ** 2
    return loss


#----------------#
#   hypothesis   #
#----------------#
def H(x, theta):
    return np.dot(x, theta)


#----------------------#
#   gradient descent   #
#----------------------#
def GradientDescent(X, Y, theta, alpha, nr_epochs):

    m = X.shape[0]
    n = X.shape[1]
    grad = np.zeros(n)   

    Loss = np.zeros(nr_epochs)          


    for epoch in range(nr_epochs):
        with autograd.record():
            Loss[epoch] = LossFunction(X, Y, theta)

        Loss[epoch].backward()

        for j in range(n):
            theta[j] = theta[j] - alpha * theta.grad[j]
        return theta, Loss


if __name__ == "__main__":
    main()

问题是当代码在 X 和 theta 之间的点积中计算假设时我得到一个错误

return np.dot(x, theta)

错误消息说: 参数 a 必须具有 NDArray 类型,但得到 [ 1. -5.05358]

所以,我假设 x 和 theta 的类型之间一定存在某种不兼容。 我检查了它们,我得到了:

X -> <class 'numpy.ndarray'>
theta -> <class 'mxnet.numpy.ndarray'>

theta 是用 np.zeros 创建的,所以它是一个 mxnet 数组,而 X 是使用 .values 方法从数据集转换而来的...这是问题的根源吗? 谢谢!

MXNet 不使用 Numpy NDArray,但 mxnet NDArray, which has very similar functionality and API but a different backend; mxnet NDArray is written in C++, uses asynchronous execution, is GPU-compatible and supports automatic differentiation。它也适用于 CPU,它通常比默认的(OpenBLAS 支持的)Numpy 更快。

因此,为了解决您的错误,我建议您确保不要在代码中使用 numpy,而是到处使用 mxnet NDArray。因为the API is super similar to numpy所以其实很容易改。如果需要,您可以与 numpy 相互转换,例如:

from mxnet import nd

# Assuming A is an numpy ndarray and B an mxnet ndarray

# from numpy to mxnet
mxnet_array = nd.array(A)


# from mxnet to numpy
np_array = B.asnumpy()

关于您对线性回归的具体兴趣,请参阅此处 python 中的 2 个 mxnet 演示:

使用这些 NDArrays 是 MXNet 如此之快的原因之一,因为它使您的代码完全异步并让引擎找到优化。 那些 NDArrays 是让 MXNet 如此棒的东西之一,尝试它们你会爱上它们:)