用于线性回归的 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 演示:
- Linear regression in MXNet from scratch
- Linear regression in MXNet with gluon(gluon是python命令式前端的名字,有点像keras之于TF)
使用这些 NDArrays 是 MXNet 如此之快的原因之一,因为它使您的代码完全异步并让引擎找到优化。
那些 NDArrays 是让 MXNet 如此棒的东西之一,尝试它们你会爱上它们:)
我正在尝试为线性回归实现简单的梯度下降。
如果我手动计算梯度(通过使用解析表达式),它可以正常工作,但现在我试图用 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 演示:
- Linear regression in MXNet from scratch
- Linear regression in MXNet with gluon(gluon是python命令式前端的名字,有点像keras之于TF)
使用这些 NDArrays 是 MXNet 如此之快的原因之一,因为它使您的代码完全异步并让引擎找到优化。 那些 NDArrays 是让 MXNet 如此棒的东西之一,尝试它们你会爱上它们:)