2012-03-17 19 views
5

Tengo que entrenar un modelo de máquina de vectores de soporte y me gustaría utilizar una matriz de núcleo personalizada, en lugar de las predeterminadas (como RBF, Poly, ecc.). ¿Cómo puedo hacer eso (si es posible) con la biblioteca de aprendizaje automático de opencv?Cree una matriz de kernel svm personalizada con opencv

¡Gracias!

Respuesta

6

AFAICT, kernels personalizados para SVM no son compatibles directamente en OpenCV. Parece que LIBSVM, que es la biblioteca subyacente que OpenCV usa para esto, no proporciona un medio particularmente fácil de definir núcleos personalizados. Por lo tanto, muchos de los contenedores que usan LIBSVM tampoco proporcionan esto. Parece que hay algunos, por ej. scikit para python: scikit example of SVM with custom kernel

También puede consultar una biblioteca completamente diferente, como SVMlight. Admite kernels personalizados directamente. También echa un vistazo al this SO question. Las respuestas allí incluyen un puñado de bibliotecas SVM, junto con breves reseñas.

Si tiene razones de peso para permanecer dentro de OpenCV, puede lograrlo utilizando el tipo de kernel CvSVM::LINEAR y aplicando su kernel personalizado a los datos antes de entrenar el SVM. Estoy un poco confuso acerca de si esta dirección sería fructífera, por lo que espero que alguien con más experiencia con SVM pueda intervenir y comentar. Si es es posible utilizar un "kernel precalculado" al elegir "lineal" como su núcleo, luego eche un vistazo a this answer para obtener más ideas sobre cómo proceder.

También podría considerar incluir LIBSVM y llamarlo directamente, sin utilizar OpenCV. Consulte FAQ #418 for LIBSVM, que trata brevemente sobre cómo hacer kernels personalizados:

P: Me gustaría utilizar mi propio kernel. ¿Algún ejemplo? En svm.cpp, hay dos subrutinas para las evaluaciones del kernel: k_function() y kernel_function(). ¿Cuál debería modificar?

Un ejemplo es "LIBSVM para datos de cadena" en Herramientas LIBSVM.

La razón por la que tenemos dos funciones es la siguiente. Para la exp de kernel RBF (-g | xi - xj |^2), si calculamos xi - xj primero y luego el cuadrado de norma, hay 3n operaciones. Por lo tanto, consideramos exp (-g (| xi |^2 - 2dot (xi, xj) + | xj |^2)) y al calcular todos | xi |^2 al comienzo, el número de operaciones se reduce a 2n. Esto es para el entrenamiento. Para la predicción no podemos hacer esto, por lo que se necesita una subrutina regular que use esas operaciones 3n. La forma más fácil de tener su propio kernel es poner el mismo código en estas dos subrutinas reemplazando cualquier kernel.

Sin embargo, la última opción parece un poco molesta. Yo recomendaría scikit o SVMlight. ¡La mejor de las suertes para ti!

+0

¡Muchas gracias por la respuesta completa! Por cierto, creo que usaré directamente LibSVM ... Parece que no hay forma de usar un kernel precompilado con OpenCV :( –

2

Si no está casado con OpenCV para las cosas SVM, eche un vistazo a the shogun toolbox ... un montón de SVM vudú allí.

+0

Shogun se ve bien. ¡Gracias por compartir! – justis

Cuestiones relacionadas