матрицы не выровнены Ошибка: Python SciPy fmin_bfgs - PullRequest
14 голосов
/ 06 января 2012

Краткое описание проблемы: При попытке использовать функцию минимизации (оптимизации) scipy.optimize.fmin_bfgs, функция выдает

derphi0 = np.dot (gfk, pk) ValueError: матрицы не выровнены

ошибка.Согласно моей проверке ошибок, это происходит в самом конце первой итерации через fmin_bfgs - перед тем, как будут возвращены какие-либо значения или любые вызовы обратного вызова.

Конфигурация: Windows Vista Python 3.2.2 SciPy 0.10 IDE = Eclipse с PyDev

Подробное описание: Я использую scipy.optimize.fmin_bfgs, чтобы минимизировать затраты на реализацию простой логистической регрессии (преобразование из Octave в Python / SciPy).По сути, функция стоимости называется функцией cost_arr, а градиентный спуск - функцией градиента_descent_arr.

Я вручную проверил и полностью проверил, что * cost_arr * и * градиент_descent_arr * работают правильно и возвращают все значения должным образом.Я также проверил, чтобы убедиться, что правильные параметры передаются в функцию * fmin_bfgs *.Тем не менее, при запуске я получаю ValueError: матрицы не выровнены.Согласно обзору источника, точная ошибка возникает в функции

def line_search_wolfe1 в строке # Minpack Wolfe и скалярных поисках, предоставляемых пакетами scipy.

Примечательно,если вместо этого я использую scipy.optimize.fmin , функция fmin завершается.

Точная ошибка:

Файл "D: \ Users \ Shannon \ Programming \ Eclipse \ workspace \ SBML \ sbml \ LogisticRegression.py", строка 395, в fminunc_opt

optcost = scipy.optimize.fmin_bfgs(self.cost_arr, initialtheta, fprime=self.gradient_descent_arr, args=myargs, maxiter=maxnumit, callback=self.callback_fmin_bfgs, retall=True)   

Файл "C: \ Python32x32 \ lib \site-packages \ scipy \ optimize \ optimize.py ", строка 533, в fmin_bfgs old_fval, old_old_fval)
Файл" C: \ Python32x32 \ lib \ site-packages \ scipy \ optimize \ linesearch.py ​​", строка 76,в line_search_wolfe1 derphi0 = np.dot (gfk, pk) ValueError: матрицы не выровнены

Я вызываю функцию оптимизации с помощью: optcost = scipy.optimize.fmin_bfgs (self.cost_arr, initialtheta, fprime =)self.gradient_descent_arr, args = myargs, maxiter = maxnumit, callback = self.callback_fmin_bfgs, retall = True)

Я потратил несколько дней, пытаясь это исправить, и не могу определить, что является причиной того, что матрицы не выровнены ошибка.

ADDENDUM: 2012-01-08 Я работал с этим гораздо больше и, похоже, сузил проблемы (но сбит с толку, как их исправить).Во-первых, fmin (используя просто fmin) работает с использованием этих функций - cost, градиента.Во-вторых, функции стоимости и градиента точно возвращают ожидаемые значения при тестировании за одну итерацию в ручной реализации (НЕ используя fmin_bfgs).В-третьих, я добавил код ошибки в optimize.linsearch и, похоже, ошибка выдается в def line_search_wolfe1 в строке: derphi0 = np.dot (gfk, pk).Здесь, согласно моим тестам, scipy.optimize.optimize pk = [[12.00921659] [11.26284221]] pk type = и scipy.optimize.optimizegfk = [[-12.00921659] [-11.26284221]] gfk type = Примечание: согласно моемуВ тестах ошибка выдается на самой первой итерации с помощью fmin_bfgs (т. е. fmin_bfgs даже не завершает ни одной итерации или обновления).

Я ценю ЛЮБЫЕ указания или идеи.

Мой код ниже (ведение журнала, документация удалена): Предположим, theta = 2x1 ndarray (Фактически: размер theta Info Size = (2, 1) Тип =) Предположим, X = 100x2 ndarray (Фактически: X Info Size = (2, 100) Тип =) Предположим, y = 100x1 ndarray (Фактически: y Размер информации = (100, 1) Тип =)

def cost_arr(self, theta, X, y):

    theta = scipy.resize(theta,(2,1))         

    m = scipy.shape(X)

    m = 1 / m[1] # Use m[1] because this is the length of X
    logging.info(__name__ + "cost_arr reports m = " + str(m))         

    z = scipy.dot(theta.T, X) # Must transpose the vector theta               

    hypthetax = self.sigmoid(z)

    yones = scipy.ones(scipy.shape(y))

    hypthetaxones = scipy.ones(scipy.shape(hypthetax))

    costright = scipy.dot((yones - y).T, ((scipy.log(hypthetaxones - hypthetax)).T))

    costleft = scipy.dot((-1 * y).T, ((scipy.log(hypthetax)).T))


def gradient_descent_arr(self, theta, X, y):

    theta = scipy.resize(theta,(2,1)) 

    m = scipy.shape(X)

    m = 1 / m[1] # Use m[1] because this is the length of X

    x = scipy.dot(theta.T, X) # Must transpose the vector theta

    sig = self.sigmoid(x)

    sig = sig.T - y

    grad = scipy.dot(X,sig)

    grad = m * grad

    return grad

def fminunc_opt_bfgs(self, initialtheta, X, y, maxnumit):
    myargs= (X,y)

    optcost = scipy.optimize.fmin_bfgs(self.cost_arr, initialtheta, fprime=self.gradient_descent_arr, args=myargs, maxiter=maxnumit, retall=True, full_output=True)

    return optcost

Ответы [ 2 ]

17 голосов
/ 27 января 2012

В случае, если кто-то еще столкнется с этой проблемой ....

1) ОШИБКА 1: Как отмечено в комментариях, я неверно возвратил значение из моего градиента в виде многомерного массива (m, n) или (м, 1).fmin_bfgs, кажется, требует вывода массива 1d из градиента (то есть вы должны вернуть массив (m,), а НЕ массив (m, 1). Используйте scipy.shape (myarray), чтобы проверить размеры, если вы не уверены ввозвращаемое значение.

Исправление включало добавление:

grad = numpy.ndarray.flatten(grad)

непосредственно перед возвратом градиента из функции градиента. Это "выравнивает" массив от (m, 1) до (m,). fmin_bfgs может принимать это как входные данные.

2) ОШИБКА 2: Помните, что fmin_bfgs, кажется, работает с НЕЛИНЕЙНЫМИ функциями.В моем случае образец, с которым я первоначально работал, был ЛИНЕЙНОЙ функцией.Это, кажется, объясняет некоторые из аномальных результатов даже после упомянутого выше исправления.Для ЛИНЕЙНЫХ функций, fmin, а не fmin_bfgs, может работать лучше.

QED

0 голосов
/ 08 декабря 2016

Начиная с текущей версии scipy вам не нужно передавать аргумент fprime.Он вычислит градиент для вас без каких-либо проблем.Вы также можете использовать метод «минимизации» fn и pass как «bfgs», не указывая градиент в качестве аргумента.

...