我想使用库LIBSVM对5个测试图像的列表进行分类,并使用策略'一个针对所有'为了获得每个班级的概率。使用过的代码如下:
load('D:\xapp.mat');
load('D:\xtest.mat');
load('D:\yapp.mat');%% matrix contains true class of images yapp=[641;645;1001;1010;1100]
load('D:\ytest.mat');%% matrix contains unlabeled class of test set ytest=[1;2;3;4;5]
numLabels=max(yapp);
numTest=size(ytest,1);
%# train one-against-all models
model = cell(numLabels,1);
for k=1:numLabels
model{k} = svmtrain(double(yapp==k),xapp, ['-c 1000 -g 10 -b 1 ']);
end
%# get probability estimates of test instances using each model
prob = zeros(numTest,numLabels);
for k=1:numLabels
[~,~,p] = svmpredict(double(ytest==k), xtest, model{k}, '-b 1');
prob(:,k) = p(:,model{k}.Label==1); %# probability of class==k
end
%# predict the class with the highest probability
[~,pred] = max(prob,[],2);
acc = sum(pred == ytest) ./ numel(ytest) %# accuracy
我收到此错误:
模型不支持概率估算 订阅分配维度不匹配 comp中的错误(第98行)
prob(:,k)= p(:,model {k} .Label == 1); %#class of probability == k
请帮助我解决此错误,并提前致谢
答案 0 :(得分:0)
您要做的是使用评估SVM分类器性能的代码片段,而您的目标是正确估计测试集的标签。
我假设您的五个标签为[641;645;1001;1010;1100]
(如yapp
中所示)。您要做的第一件事是删除ytest
,因为您不知道测试集的任何标签。用ytest
填充一些虚拟值是没有意义的:SVM将返回我们预测的标签。
第一个错误,正如评论中已经指出的那样是
numLabels=max(yapp);
您必须使用max()
更改length()
才能收集课程数量。
训练阶段几乎是正确的
鉴于k
从1变为5,而yapp
具有上述范围,您应该考虑将double(yapp==k)
更改为double(yapp==yapp(k))
:以这种方式我们将k标记为正yapp
中的第 - 个值。鉴于k
从1到5的事实,yapp(k)
将从641变为1100.
现在是预测阶段
svmpredict()
的第一个输入应该是测试标签,但现在我们不知道它们,所以我们可以用零向量填充它(测试集中的模式会有很多零)。这是因为如果已知测试标签,svmpredict()
也会自动返回准确性,但事实并非如此。所以你必须将第二个for循环更改为
for k=1:numLabels
[~,~,p] = svmpredict(zeros(size(xtest,1),1), xtest, model{k}, '-b 1');
prob(:,k) = p(:,model{k}.Label==1); %# probability of class==k
end
最后用
预测标签[~,pred] = max(prob,[],2);
和pred
包含预测的标签。
注1 :但是,在这种方法中,您无法测量精度和/或其他参数,因为我们称之为测试集的实际上不是测试集。测试集是标记集,我们假装我们不知道它的标签,以便让SVM预测它们,然后将预测标签与实际标签相匹配,以便测量其准确性。
注2 :pred
中的预测标签很可能由于第二个for循环而具有范围1到5的值。但是,由于您的标签具有不同的值,因此可以考虑到1为641,2为645,3为1001,4为1010,5为1100。