градиентный спуск mxnet для линейной регрессии, ошибка типов переменных - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь реализовать простой градиентный спуск для линейной регрессии.

Это работает нормально, если я вычисляю градиент вручную (используя аналитическое выражение), но теперь я пытался реализовать его с помощью autogradиз модуля mxnet.

Это код


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 и тета

return np.dot(x, theta)

Сообщение об ошибке гласит: Аргумент a должен иметь тип NDArray, но получил [1. -5.05358]

Итак, я предполагаю, что между типами x и должно быть некоторая несовместимостьтета.Я проверил их и получил:

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

тета создается с помощью np.zeros, поэтому это массив mxnet, а X преобразуется из набора данных с помощью метода .values ​​...источник проблемы?Спасибо!

1 Ответ

1 голос
/ 21 сентября 2019

MXNet не использует Numpy NDArray, но mxnet NDArray , который имеет очень похожую функциональность и API, но другой бэкэнд;mxnet NDArray написан на C ++, использует асинхронное выполнение и совместим с GPU.Он также работает на процессоре, где он обычно быстрее, чем по умолчанию (с поддержкой OpenBLAS) Numpy.

Поэтому, чтобы исправить ошибку, я рекомендую убедиться, что вы не используете numpy в своем коде, но везде применяете mxnet NDArray.Это на самом деле очень легко изменить, потому что API очень похож на 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()

Что касается вашего особого интереса к линейной регрессии, см. Здесь 2 демонстрации mxnet в python:

Использование этих NDArrays - одна из причин, по которой MXNet работает так быстро, потому что он делает ваш код полностью асинхронным и позволяет движку находить оптимизации.Эти NDArrays - одна из вещей, которые делают MXNet таким классным, попробуйте их, и вы полюбите их:)

...