Cómo extraer información de scikits.learn classificador para luego usar en código C
-
27-10-2019 - |
Pregunta
He entrenado un montón de SVM de RBF usando Scikits. Aprender en Python y luego en vecino los resultados. Estos son para tareas de procesamiento de imágenes y una cosa que quiero hacer para probar es ejecutar cada clasificador en cada píxel de algunas imágenes de prueba. Es decir, extraiga el vector de características desde una ventana centrada en píxel (i, j), ejecute cada clasificador en ese vector de características y luego pase al siguiente píxel y repita. Esto es demasiado lento para ver con Python.
Aclaración: Cuando digo "esto es demasiado lento ..." Quiero decir que incluso el código de bajo-de madera libsvm que Scikits.learn usa es demasiado lento. De hecho, estoy escribiendo una función de decisión manual para la GPU, por lo que la clasificación en cada píxel ocurre en paralelo.
¿Es posible que cargue los clasificadores con Pickle y luego tome algún tipo de atributo que describe cómo se calcula la decisión del vector de características y luego pasa esa información a mi propio código C? En el caso de SVM lineales, podría extraer el vector de peso y el vector de sesgo y agregarlos como entradas a una función C. Pero, ¿qué es lo equivalente para los clasificadores RBF y cómo obtengo esa información del objeto scikits.learn?
Adicional: Primeros intentos de una solución.
Parece que el objeto clasificador tiene el atributo support_vectors_
que contiene los vectores de soporte como cada fila de una matriz. También está el atributo dual_coef_
que es un 1 por len(support_vectors_)
variedad de coeficientes. De los tutoriales estándar en SVM no lineales, parece que uno debe hacer lo siguiente:
- Calcule el vector de funciones
v
Desde su punto de datos en prueba. Este será un vector que es la misma longitud que las filas desupport_vectors_
. - Por cada fila
i
ensupport_vectors_
, calcule la distancia euclidiana al cuadradod[i]
entre ese vector de soporte yv
. - Calcular
t[i]
comogamma * exp{-d[i]}
dóndegamma
es el parámetro RBF. - Resumir
dual_coef_[i] * t[i]
generali
. Agregue el valor delintercept_
atributo de scikits.care clasificador de esta suma. - Si la suma es positiva, clasifique como 1. De lo contrario, clasifique como 0.
Adicional: En la página 9 en esto enlace de documentación menciona que de hecho el intercept_
El atributo del clasificador contiene el término de sesgo. He actualizado los pasos anteriores para reflejar esto.
Solución
Sí, tu solución se ve bien. Para pasar la memoria en bruto de una matriz numpy directamente a un programa C, puede usar el Ayudantes de Ctypes de Numpy O envuelva su programa C con Cython y llámelo directamente pasando la matriz Numpy (vea el documento en http://ython.org para más detalles).
Sin embargo, no estoy seguro de que tratar de acelerar la predicción en una GPU es el enfoque más fácil: se sabe que las máquinas de vectores de soporte del núcleo son lentas en el tiempo de predicción, ya que su complejidad depende directamente de la cantidad de vectores de soporte que pueden ser altos para ser altamente no altamente no -Los problemas lineales (multimodales).
Los enfoques alternativos que son más rápidos en el momento de la predicción incluyen redes neuronales (probablemente más complicadas o más lentas para entrenar a la derecha que las SVM que solo tienen 2 hiperparametros C y gamma) o transformando sus datos con una transformación no lineal basada en distancias a prototipos + umbral + umbral + Agrupación máxima sobre áreas de imagen (solo para la clasificación de imágenes).
Para el primer método encontrará una buena documentación en el Tutorial de aprendizaje profundo
Para el segundo lee los documentos recientes de Adam Coates y eche un vistazo a esta página en Extracción de características de Kmeans
Finalmente también puede intentar usar modelos NUSVC cuyo parámetro de regularización nu
Tiene un impacto directo en el número de vectores de soporte en el modelo ajustado: menos vectores de soporte significa tiempos de predicción más rápidos (verifique la precisión, sin embargo, será una compensación entre la velocidad de predicción y la precisión al final).