Матрицы не выровнены. Ошибка: Python SciPy fmin_bfgs
Проблема Синопсис:
При попытке использовать функцию минимизации (оптимизации) scipy.optimize.fmin_bfgs функция выбрасывает
derphi0 = np.dot(gfk, pk) Матрицы ValueError: не выровнены
ошибка. Согласно моей проверке ошибок это происходит в самом конце первой итерации через fmin_bfgs - непосредственно перед возвратом любых значений или любыми вызовами обратного вызова.
Конфигурация:
Виндоус виста
Python 3.2.2
SciPy 0.10
IDE = Eclipse с PyDev
Подробное описание:
Я использую scipy.optimize.fmin_bfgs, чтобы минимизировать затраты на реализацию простой логистической регрессии (преобразование из Octave в Python/SciPy). В принципе, функция стоимости называется функцией cost_arr, а спуск градиента находится в функции gradient_descent_arr.
Я проверил вручную и полностью проверил, что * cost_arr * и * gradient_descent_arr * работают правильно и правильно возвращают все значения. Я также проверял, чтобы соответствующие параметры передавались функции * fmin_bfgs *. Тем не менее, при запуске я получаю значения ValueError: матрицы не выровнены. Согласно исходному обзору, точная ошибка возникает в
def line_search_wolfe1 функции в # Minpack Вулф линии и скалярные поиски, как поставляется scipy пакетов.
В частности, если вместо этого использовать scipy.optimize.fmin, функция fmin завершится.
Точная ошибка:
Файл "D:\Users\Shannon\Программирование\Затмение\рабочее пространство \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)
Я потратил несколько дней, пытаясь исправить это и не могу определить, что вызывает ошибку не выровнены.
ДОБАВЛЕНИЕ: 2012-01-08
Я работал с этим намного больше и, кажется, сузил проблемы (но я не мог понять, как их исправить). Во-первых, fmin (используя только fmin) работает с использованием этих функций - стоимость, градиент. Во-вторых, затраты и функции градиента точно возвращают ожидаемые значения при тестировании на одной итерации в ручном режиме (НЕ используя 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 (Actual: theta Info Size = (2, 1) Тип =)
Предположим, что X = 100x2 ndarray (Actual: X Info Size = (2, 100) Тип =)
Предположим, что y = 100x1 ndarray (Actual: y Info Size = (100, 1) Type =)
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
Ответы
Ответ 1
Если кто-то еще сталкивается с этой проблемой....
1) ОШИБКА 1: Как отмечено в комментариях, я неправильно вернул значение из моего градиента в виде многомерного массива (m, n) или (m, 1). Кажется, что fmin_bfgs требует получить 1d-массив из градиента (т.е. вы должны вернуть массив (m)) и массив NOT (m, 1). Используйте scipy.shape(myarray), чтобы проверить размеры, если вы не уверены в возвращаемое значение.
Исправление связано с добавлением:
grad = numpy.ndarray.flatten(grad)
перед возвратом градиента из вашей функции градиента. Это "выравнивает" массив от (m, 1) до (m,). fmin_bfgs может принимать это как вход.
2) ОШИБКА 2: Помните, что fmin_bfgs работает с нелинейными функциями. В моем случае образец, с которым я работал, был функцией LINEAR. По-видимому, это объясняет некоторые аномальные результаты даже после упомянутого выше исправления сглаживания. Для функций LINEAR fmin, а не fmin_bfgs, может работать лучше.
КЭД
Ответ 2
В текущей версии scipy вам не нужно передавать аргумент fprime. Он будет вычислять градиент для вас без каких-либо проблем. Вы также можете использовать "минимизировать" fn и передавать метод как "bfgs", не предоставляя градиент в качестве аргумента.