2012-01-06 9 views
12

Problema Sinopsis: Al intentar utilizar la scipy.optimize.fmin_bfgs función (optimización) minimización, la función emite un errormatrices no están alineados Error: Python SciPy fmin_bfgs

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

. De acuerdo con mi comprobación de errores, esto ocurre al final de la primera iteración a través de fmin_bfgs, justo antes de que se devuelvan los valores o cualquier llamada a la devolución de llamada.

Configuración: Windows Vista Python 3.2.2 SciPy 0,10 IDE = Eclipse con PyDev

Descripción detallada: estoy usando los scipy.optimize.fmin_bfgs para minimizar el coste de una implementación simple de regresión logística (conversión de Octave a Python/SciPy). Básicamente, la función de costo se denomina función cost_arr y el descenso del gradiente está en la función gradient_descent_arr.

He probado y verificado completamente que * cost_arr * y * gradient_descent_arr * funcionan correctamente y devuelven todos los valores correctamente. También probé para verificar que los parámetros correctos pasen a la función * fmin_bfgs *. Sin embargo, cuando se ejecuta, obtengo el ValueError: las matrices no están alineadas. De acuerdo con la opinión de origen, el error exacto se produce en el

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

Cabe destacar que, si uso scipy.optimize.fmin lugar, la función fmin ejecuta hasta el final.

error exacto:

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

que llamo la función de optimización con: optcost = scipy.optimize.fmin_bfgs (self.cost_arr, initialtheta, fprime = self.gradient_descent_arr, args = myargs, maxiter = maxnumit, devolución de llamada = self.callback_fmin_bfgs, retall = True)

he pasado unos días tratando de solucionar este problema y parece que no puede determinar qué está causando el matrices no están alineados error.

ADDENDUM: 2012-01-08 He trabajado con esto mucho más y parece que se han reducido los problemas (pero estoy desconcertado sobre cómo solucionarlos). Primero, fmin (usando solo fmin) funciona usando estas funciones: costo, gradiente. En segundo lugar, el costo y las funciones de gradiente devuelven con precisión los valores esperados cuando se prueban en una única iteración en una implementación manual (NO usando fmin_bfgs). En tercer lugar, agregué un código de error para optimizar .linsearch y el error parece ser lanzado en def line_search_wolfe1 en línea: derphi0 = np.dot (gfk, pk). Aquí, de acuerdo con mis pruebas, scipy.optimize.optimize pk = [[12.00921659] [11.26284221]] pk type = y scipy.optimize.optimizegfk = [[-12.00921659] [-11.26284221]] gfk type = Nota: de acuerdo con mis pruebas, el error se genera en la primera iteración a través de fmin_bfgs (es decir, fmin_bfgs nunca completa una sola iteración o actualización).

Agradezco CUALQUIER orientación o información.

Mi código de abajo (registro, documentación eliminado): Supongamos theta = 2x1 ndarray (Actual: theta Información Tamaño = (2, 1) Tipo =) Supongamos X = 100x2 ndarray (Actual: Tamaño X Info = (2 , 100) type =) Supóngase y = (100x1 real ndarray: y = Información de talla (100, 1) Tipo =)

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

¿Puedes publicar un caso simple y conciso que alguien más podría ejecutar y reproducir el error? Es probable que un argumento que esté suministrando esté en forma incorrecta, pero sin ver qué es lo que hace su código, será imposible ayudarlo. – talonmies

+0

'def gradient_descent_arr (self, theta, X, y): theta = scipy.resize (theta, (2,1)) # da el tamaño Octave de la matriz m = scipy.shape (X) m = 1/m [1] # Use m [1] porque esta es la longitud de X x = scipy.dot (theta.T, X) # Debe transponer el vector theta sig = self.sigmoid (x) sig = sig.T - y grad = scipy.dot (X, SIG) grad = m * grad return grad' – SaB

+0

talonmies - Gracias. Agregué el código a la publicación original. Cualquier idea sería apreciada. – SaB

Respuesta

16

En caso de que alguien lo demás encuentros este problema ....

1) ERROR 1: Como se señaló en los comentarios, devolví incorrectamente el valor de mi degradado como una matriz multidimensional (m, n) o (m, 1). fmin_bfgs parece requerir una salida de matriz 1d del degradado (es decir, debe devolver una matriz (m) y NO una matriz (m, 1). Use scipy.shape (myarray) para verificar las dimensiones si no está seguro de el valor de retorno

la solución implicaba añadir:...

grad = numpy.ndarray.flatten(grad) 

justo antes de devolver el gradiente de la función de su gradiente Esta "aplana" la matriz a partir de (m, 1) a (m,) fmin_bfgs puede toma esto como entrada.

2) ERROR 2: Recuerda, el fmin_bfgs parece funcionar con funciones no lineales. En mi caso, la muestra con la que estaba trabajando inicialmente era una función LINEAL. Esto parece explicar algunos de los resultados anómalos incluso después de la corrección de aplanar mencionada anteriormente. Para funciones LINEALES, fmin, en lugar de fmin_bfgs, puede funcionar mejor.

QED

+0

Parece que 'fmin_ncg' también necesita retornos de gradiente aplanados, (m, 1) debe cambiarse a (m,) – dashesy

0

partir de la versión actual scipy Usted no tiene que pasar el argumento fprime. Calculará el gradiente por usted sin ningún problema. También puede usar 'minimize' fn y pasar el método como 'bfgs' en lugar de proporcionar gradiente como argumento.

Cuestiones relacionadas