#matlab #machine-learning #svm #libsvm
#matlab #машинное обучение #svm #libsvm
Вопрос:
В настоящее время я работаю над классификацией изображений с помощью разных дескрипторов изображений. Поскольку у них есть свои собственные показатели, я использую предварительно вычисленные ядра. Итак, учитывая эти матрицы ядра NxN (всего N изображений), я хочу обучить и протестировать SVM. Однако я не очень опытен в использовании SVM.
Что меня смущает, так это то, как ввести входные данные для обучения. Используя подмножество MxM ядра (M — количество обучающих образов), обучает SVM с помощью M функций. Однако, если я правильно понял, это ограничивает меня в использовании тестовых данных с аналогичным количеством функций. Попытка использовать подядро размером MxN приводит к бесконечным циклам во время обучения, следовательно, использование большего количества функций при тестировании дает плохие результаты.
Это приводит к использованию обучающих и тестовых наборов одинакового размера, дающих разумные результаты. Но если я только хотел бы классифицировать, скажем, одно изображение, или обучаться с заданным количеством изображений для каждого класса и тестировать с остальными, это вообще не работает.
Как я могу удалить зависимость между количеством обучающих изображений и функций, чтобы я мог тестировать с любым количеством изображений?
Я использую libsvm для MATLAB, ядра представляют собой матрицы расстояний в диапазоне [0,1].
Комментарии:
1. решаемая проблема: учитывая Mx (M 1) ядро для обучения ( 1 — обязательные индексы), тестовое ядро должно (конечно) иметь размер Kx (M 1), где K — количество тестовых изображений.
Ответ №1:
Похоже, вы уже разобрались с проблемой… Согласно файлу README, включенному в пакет MATLAB:
Чтобы использовать предварительно вычисленное ядро, необходимо включить серийный номер образца в качестве первого столбца данных обучения и тестирования.
Позвольте мне проиллюстрировать это на примере:
%# read dataset
[dataClass, data] = libsvmread('./heart_scale');
%# split into train/test datasets
trainData = data(1:150,:);
testData = data(151:270,:);
trainClass = dataClass(1:150,:);
testClass = dataClass(151:270,:);
numTrain = size(trainData,1);
numTest = size(testData,1);
%# radial basis function: exp(-gamma*|u-v|^2)
sigma = 2e-3;
rbfKernel = @(X,Y) exp(-sigma .* pdist2(X,Y,'euclidean').^2);
%# compute kernel matrices between every pairs of (train,train) and
%# (test,train) instances and include sample serial number as first column
K = [ (1:numTrain)' , rbfKernel(trainData,trainData) ];
KK = [ (1:numTest)' , rbfKernel(testData,trainData) ];
%# train and test
model = svmtrain(trainClass, K, '-t 4');
[predClass, acc, decVals] = svmpredict(testClass, KK, model);
%# confusion matrix
C = confusionmat(testClass,predClass)
Вывод:
*
optimization finished, #iter = 70
nu = 0.933333
obj = -117.027620, rho = 0.183062
nSV = 140, nBSV = 140
Total nSV = 140
Accuracy = 85.8333% (103/120) (classification)
C =
65 5
12 38
Комментарии:
1. Да, именно так я и решил. Был немного смущен тем, какие части ядра использовать. Хороший пример кода.