web-dev-qa-db-ja.com

libsvmで事前計算されたカーネルを使用する

私は現在、さまざまな画像記述子を使用して画像を分類する作業を行っています。それらには独自のメトリックがあるため、事前に計算されたカーネルを使用しています。したがって、これらのNxNカーネル行列(合計N個のイメージ)を前提として、SVMをトレーニングしてテストしたいと思います。ただし、SVMの使用経験はあまりありません。

しかし、私を混乱させるのは、トレーニングの入力を入力する方法です。カーネルMxMのサブセット(Mはトレーニングイメージの数)を使用して、M個の機能でSVMをトレーニングします。ただし、正しく理解していれば、同じような量の機能を備えたテストデータを使用することが制限されます。サイズMxNのサブカーネルを使用しようとすると、トレーニング中に無限ループが発生するため、テスト時に多くの機能を使用すると結果が悪くなります。

これにより、同じサイズのトレーニングとテストセットを使用して、妥当な結果が得られます。しかし、1つの画像を分類したり、クラスごとに特定の量の画像でトレーニングしたり、残りの画像でテストしたりするだけの場合、これはまったく機能しません。

トレーニング画像と機能の数の依存関係を削除して、任意の数の画像でテストできるようにするにはどうすればよいですか?

私はMATLABにlibsvmを使用していますが、カーネルは[0,1]の範囲の距離行列です。

20
Henrik

あなたはすでに問題を理解しているようです... MATLABパッケージに含まれているREADMEファイルによると:

事前に計算されたカーネルを使用するには、トレーニングおよびテストデータの最初の列としてサンプルのシリアル番号を含める必要があります。

例を挙げて説明しましょう。

%# 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
41
Amro