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 de support_vectors_.
  • Por cada fila i en support_vectors_, calcule la distancia euclidiana al cuadrado d[i] entre ese vector de soporte y v.
  • Calcular t[i] como gamma * exp{-d[i]} dónde gamma es el parámetro RBF.
  • Resumir dual_coef_[i] * t[i] general i. Agregue el valor del intercept_ 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.

¿Fue útil?

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).

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).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top