Как извлечь информацию из классификатора scikits.learn для последующего использования в коде C - PullRequest
8 голосов
/ 02 декабря 2011

Я обучил кучу SVF RBF с использованием scikits.learn в Python, а затем замаскировал результаты.Они предназначены для задач обработки изображений, и одну вещь, которую я хочу сделать для тестирования, - запустить каждый классификатор для каждого пикселя некоторых тестовых изображений.То есть, извлеките вектор объекта из окна с центром в пикселе (i, j), запустите каждый классификатор для этого вектора объекта, а затем перейдите к следующему пикселю и повторите.Это слишком медленно, чтобы делать с Python.

Пояснение: Когда я говорю «это слишком медленно ...», я имею в виду, что даже внутренний код Libsvm, которыйscikits.learn использует слишком медленно.На самом деле я пишу функцию ручного принятия решения для графического процессора, поэтому классификация для каждого пикселя происходит параллельно.

Могу ли я загрузить классификаторы с помощью Pickle, а затем получить какой-то атрибут, который описывает, какрешение вычисляется из вектора признаков, а затем передать эту информацию в мой собственный код C?В случае линейных SVM я мог бы просто извлечь вектор весов и вектор смещения и добавить их в качестве входных данных для функции C.Но что эквивалентно сделать для классификаторов RBF, и как я могу получить эту информацию из объекта scikits.learn?

Добавлено: Первые попытки решения.

Похоже, у объекта классификатора есть атрибут support_vectors_, который содержит векторы поддержки в качестве каждой строки массива.Существует также атрибут dual_coef_, который представляет собой массив коэффициентов 1 на len(support_vectors_).Из стандартных руководств по нелинейным SVM следует, что нужно сделать следующее:

  • Вычислить вектор признаков v из тестируемой точки данных.Это будет вектор, длина которого равна строкам support_vectors_.
  • . Для каждой строки i в support_vectors_ вычислите квадрат евклидова расстояния d[i] между этим опорным вектором и * 1026.*.
  • Вычислить t[i] как gamma * exp{-d[i]}, где gamma - параметр RBF.
  • Суммировать dual_coef_[i] * t[i] по всем i.Добавьте к этой сумме значение атрибута intercept_ классификатора scikits.learn.
  • Если сумма положительная, классифицировать как 1. В противном случае классифицировать как 0.

Добавлено: На пронумерованной странице 9 по этой ссылке на документацию упоминается, что действительно атрибут intercept_ классификатора содержит термин смещения.Я обновил шаги выше, чтобы отразить это.

1 Ответ

9 голосов
/ 03 декабря 2011

Да, ваше решение выглядит хорошо.Чтобы передать необработанную память массива numpy непосредственно в программу на C, вы можете использовать помощники ctypes из numpy или обернуть вашу C-программу в cython и вызывать ее напрямую, передавая массив numpy (см. Документ в http://cython.org для более подробной информации).

Однако я не уверен, что попытка ускорить прогнозирование на графическом процессоре - самый простой подход: известно, что векторные машины поддержки ядра работают медленно во время прогнозирования, поскольку ихсложность напрямую зависит от количества векторов поддержки, которые могут быть высокими для весьма нелинейных (многомодальных) задач.

Альтернативные подходы, которые быстрее во время прогнозирования, включают нейронные сети (возможно, более сложные или медленнее обучаемые)Право, чем SVM, которые имеют только 2 гиперпараметра C и гамма) или преобразовывают ваши данные с помощью нелинейного преобразования на основе расстояний до прототипов + пороговое значение + максимальное объединение по областям изображения (только для классификации изображений).

Наконец, вы также можете попробовать использовать модели NuSVC, параметр регуляризации которых nu напрямую влияет на число опорных векторов в подобранной модели: меньшее количество опорных векторов означает меньшее время прогнозирования(проверьте точность, хотя, это будет компромисс между скоростью предсказания и точностью в конце).

...