2012-01-06 12 views
12

Problem Synopsis: Podczas próby użycia minimalizację scipy.optimize.fmin_bfgs function (optymalizacja), funkcja zgłasza błądmacierze nie są wyrównane błąd: Python scipy fmin_bfgs

derphi0 = np.dot(gfk, pk) ValueError: matrices are not aligned

. Zgodnie z moim sprawdzaniem błędów występuje to na samym końcu pierwszej iteracji poprzez fmin_bfgs - tuż przed zwróceniem jakichkolwiek wartości lub wywołaniami wywołania zwrotnego.

Konfiguracja: Windows Vista Python 3.2.2 scipy 0,10 IDE = Eclipse z PyDev

Szczegółowy opis: Używam scipy.optimize.fmin_bfgs aby zminimalizować koszt prosta implementacja regresji logistycznej (konwersja z Octave na Python/SciPy). Zasadniczo, funkcja kosztu nazywa się funkcja cost_arr, a pochylenie gradientu jest w funkcji gradient_descent_arr.

Mam ręcznie przetestowane i w pełni zweryfikowane, czy * cost_arr * i * gradient_descent_arr * działają poprawnie i zwracają wszystkie wartości poprawnie. Przetestowałem również, aby sprawdzić, czy odpowiednie parametry są przekazywane do funkcji * fmin_bfgs *. Niemniej jednak, po uruchomieniu otrzymuję ValueError: macierze nie są wyrównane. Według przeglądu źródłowego, występuje dokładna błąd w

def line_search_wolfe1 function in # Minpack's Wolfe line and scalar searches as supplied by the scipy packages.

Warto zauważyć, że jeśli używam scipy.optimize.fmin zamiast tego fmin funkcja działa do końca.

Dokładna błędu:

File "D:\Users\Shannon\Programming\Eclipse\workspace\SBML\sbml\LogisticRegression.py", line 395, in 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) 

File "C:\Python32x32\lib\site-packages\scipy\optimize\optimize.py", line 533, in fmin_bfgs old_fval,old_old_fval)
File "C:\Python32x32\lib\site-packages\scipy\optimize\linesearch.py", line 76, in line_search_wolfe1 derphi0 = np.dot(gfk, pk) ValueError: matrices are not aligned

zadzwonić do funkcji optymalizacji z: optcost = scipy.optimize.fmin_bfgs (self.cost_arr, initialtheta, fprime = self.gradient_descent_arr, arg = myargs, maxiter = maxnumit, callback = self.callback_fmin_bfgs, retall = True)

spędziłem kilka dni próbuje rozwiązać ten problem i nie potrafię określić, co jest przyczyną macierze nie są wyrównane błąd.

ADDENDUM: 2012-01-08 Pracowałem z tym dużo więcej i wydaje się, że zawęziłem problemy (ale jestem zdumiony, jak je naprawić). Po pierwsze, fmin (używając tylko fmin) działa za pomocą tych funkcji - koszt, gradient. Po drugie, funkcje kosztu i gradientu zarówno zwracają dokładnie oczekiwane wartości podczas testowania w jednej iteracji w ręcznej implementacji (NIE używając fmin_bfgs). Po trzecie, dodałem kod błędu do optimize.linsearch, a błąd wydaje się być generowany w linii def line_search_wolfe1 w linii: derphi0 = np.dot (gfk, pk). Tutaj, zgodnie z moimi testami, scipy.optimize.optimize pk = [[12.00921659] [11.26284221]] pk type = i scipy.optimize.optimizegfk = [[-12.00921659] [-11.26284221]] gfk type = Uwaga: zgodnie z moimi testami błąd jest zgłaszany przy pierwszej iteracji za pomocą fmin_bfgs (tzn. fmin_bfgs nigdy nie wykonuje nawet jednej iteracji lub aktualizacji).

Doceniam WSZYSTKIE wytyczne lub spostrzeżenia.

mojego kodu poniżej (rejestrowanie, usunięto dokumentacja): Załóżmy teta = 2x1 ndarray (rzeczywista: theta informacji Rozmiar = (2, 1) type =) Przyjmijmy X = 100x2 ndarray (rzeczywista: X Informacje Rozmiar = (2 100) type =) Załóżmy y = 100x1 ndarray (rzeczywista: 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 
+0

Czy umieścisz prosty, zwięzły przypadek, który może uruchomić ktoś inny, który powiela błąd? Jest prawdopodobne, że argument, który dostarczasz, jest w niewłaściwej formie, ale nie widząc, jaki jest twój kod, nie będzie można pomóc. – talonmies

+0

'def gradient_descent_arr (samo theta, x, y) teta = scipy.resize (theta (2,1)) # podaje rozmiar oktawy matrycy m = scipy.shape (X) m = 1/m [1] # Użyj m [1], ponieważ jest to długość X x = scipy.dot (theta.T, X) # Musi przetransponować wektor theta sig = self.sigmoid (x) porządek = sig.T - Y grad = scipy.dot (x, sIG) grad = m * grad powrót grad'' – SaB

+0

talonmies - dziękuję. Dodałem kod do oryginalnego wpisu. Wszelkie dociekania byłyby doceniane. – SaB

Odpowiedz

16

W przypadku, ktoś inny napotyka ten problem ....

1) BŁĄD 1: Jak zauważono w komentarzach, niepoprawnie zwróciłem wartość z mojego gradientu jako tablicę wielowymiarową (m, n) lub (m, 1). fmin_bfgs wydaje się wymagać wyjścia tablicy 1d z gradientu (to znaczy, że musisz zwrócić tablicę (m,), a NIE tablicę (m, 1). Użyj scipy.shape (myarray), aby sprawdzić wymiary, jeśli nie jesteś pewien wartość zwracana

Rozwiązaniem zaangażowany dodając:...

grad = numpy.ndarray.flatten(grad) 

tuż przed powrotem gradientu z funkcją gradientu Ten "spłaszcza" tablicę z (m, 1) do (m,) fmin_bfgs puszka weź to jako dane wejściowe:

2) BŁĄD 2: Pamiętaj, że fmin_bfgs wydaje się działać z funkcjami NONlinear. W moim przypadku próbka, z którą początkowo pracowałem była funkcją LINEAR. Wydaje się to tłumaczyć niektóre anomalne wyniki nawet po wspomnianym wyżej rozwiązaniu spłaszczenia. W przypadku funkcji LINEAR fmin, a nie fmin_bfgs, może działać lepiej.

QED

+0

Wygląda na to, że 'fmin_ncg' również potrzebuje spłaszczonych gradientów, (m, 1) trzeba zmienić na (m,) – dashesy

0

Począwszy od aktualnej wersji scipy nie trzeba przechodzić argumentu fprime. Oblicza gradient dla Ciebie bez żadnych problemów. Możesz również użyć metody "zminimalizuj" fn and pass jako "bfgs" zamiast podawać gradient jako argument.

Powiązane problemy