2017-10-05 100 views
0

我在x64电脑上使用MATLAB R2016a上的LIBSvm 3.22(但我已经测试过R2017a),并且执行了我的代码,我有奇怪的行为。LibSVM for Matlab - 不稳定的结果

我正在使用预计算机内核(对角线上的68x68,对称,全零)。

这里是我的代码:

% 
    clear all 

    % 
    % 
    E1=load('..\sani_bi.mat'); 
    addpath('..\libsvm-3.22\windows\'); 
D=E1.Error_fro_sym 
D=D+D' 
labels=[zeros(34,1);ones(size(D,1)-34,1)]'; 
results = []; 
GACC=[]; 
dec_values_p = []; 
models=[]; 
rbfKernel = @(Gamma) exp(-Gamma .* D); 
for C = 25:27%21:30 
    for Gamma = -1.75:.01:1%-50:.01:25 
     eC= 2^C; 
     eG=2^Gamma; 
     K = [rbfKernel(eG)]; 
     szK=size(K,1); 
     u_param = ['-c ' num2str(eC) ' -t 4 -q']; 
     for i = 1: szK 
      % 
      ind=[1:i-1, i+1:szK]; 
      model = svmtrain(labels(ind)',[(1:szK-1)', K(ind,ind)],u_param); 
      [predict_label, accuracy, dec_values] = svmpredict(labels(i),K(i,ind), model); 
      dec_values_p=[dec_values_p; dec_values]; 
      results = [results; accuracy(1)/100]; 
      %disp([i accuracy(1)/100]); 
     end 
     value=sum(results)/szK; 
     disp(value); 
     GACC=[GACC; value, C, Gamma,sum(dec_values_p)/szK]; 
     results = []; 
     dec_values_p = []; 
    end 
end 
E=sortrows(GACC,[1]); 
save('GACC') 
%% 
clear all 

E1=load('..\sani_bi.mat'); 
E2=load('.\GACC.mat'); 
GACC=E2.GACC; 
addpath('..\libsvm-3.22\windows\'); 
D=E1.Error_fro_sym 
D=D+D' 
labels=[zeros(34,1);ones(size(D,1)-34,1)]'; 
results = []; 
GACC1=[]; 
dec_values_p = []; 
models=[]; 
rbfKernel = @(Gamma) exp(-Gamma .* D); 
for C = 25:27%21:30 
    for Gamma = -1.75:.01:1%-50:.01:25 
     eC= 2^C; 
     eG=2^Gamma; 
     K = [rbfKernel(eG)]; 
     szK=size(K,1); 
     u_param = ['-c ' num2str(eC) ' -t 4 -q']; 
     for i = 1: szK 
      % 
      ind=[1:i-1, i+1:szK]; 
      model = svmtrain(labels(ind)',[(1:szK-1)', K(ind,ind)],u_param); 
      [predict_label, accuracy, dec_values] = svmpredict(labels(i),K(i,ind), model); 
      dec_values_p=[dec_values_p; dec_values]; 
      results = [results; accuracy(1)/100]; 
      %disp([i accuracy(1)/100]); 
     end 
     value=sum(results)/szK; 
     disp(value); 
     GACC1=[GACC1; value, C, Gamma,sum(dec_values_p)/szK]; 
     results = []; 
     dec_values_p = []; 
    end 
end 


GACC(GACC(:,4) ~= GACC1(:,4),:) 

正如你所看到的,我做同样的事情两次。然而,并不总是最后的命令返回相同的东西。 有时是确定:海关总署== GACC1广告它返回

ans = 

Empty matrix: 0-by-4 

,但有时它返回的东西,看这两个矩阵,我可以看到(例如):

GACC= 
0,500000000000000 27 0,970000000000000 -0,418026223801469 
0,500000000000000 27 0,980000000000000 -0,418081551411518 
0,500000000000000 27 0,990000000000000 -0,418132655182850 
0,500000000000000 27 1 -0,418184269051726 

GACC1= 
0,500000000000000 27 0,970000000000000 -0,233717714208454 
0,500000000000000 27 0,980000000000000 -0,233752196783965 
0,500000000000000 27 0,990000000000000 -0,233784292330333 
0,500000000000000 27 1 -0,233816355641198 

,只是打重新运行,我收获:

GACC= 
0,500000000000000 27 0,970000000000000 159857,292875661 
0,500000000000000 27 0,980000000000000 159875,372503753 
0,500000000000000 27 0,990000000000000 159891,859001955 
0,500000000000000 27 1 159908,815885524  

GACC1= 
0,220588235294118 27 0,970000000000000 -0,0149253624535754 
0,220588235294118 27 0,980000000000000 -0,0149350999202524 
0,205882352941176 27 0,990000000000000 -0,0149446308316416 
0,205882352941176 27 1 -0,0149534857047891 

而一些运行后,转回到第一个结果(无差异斑点)

我不明白为什么会发生这种情况。在我的调试过程中,我发现问题可能出现在“预测”方法中,看起来有时dec_value可能会发散并且有时会收敛,但在LIBSvm源代码中查找我无法找到任何种子\随机初始化,并且代码看起来是确定性的(即没有随机启动或其他优化)。

可能是关于核心矩阵的问题(可能是精度问题?)? ķ看起来是这样的(对角线都是1显然是因为已经幂):

1       2,54073447948936e-11 4,23480527542159e-12 
2,54073447948936e-11  1      8,81718110217103e-12 
4,23480527542159e-12  8,81718110217103e-12 1 

谢谢支持!

+0

[tag:kernel]标记用于** Operating System **内核(请参阅标记的说明)。但是你的问题是关于“内核”这个词的其他含义。请为你的问题使用更合适的标签。 [我不熟悉你的问题的主题,所以不能建议替换标记。] – Tsyvarev

回答

0

libSVM在svm_binary_svc_probability和svm_cross_validation函数中使用'C'随机数生成器(rand()函数)进行数据移植。

见svm.cpp:

Line 1906:  int j = i+rand()%(prob->l-i); 
Line 2371:    int j = i+rand()%(count[c]-i); 
Line 2408:   int j = i+rand()%(l-i); 

所以,你需要修改源并重新编译LIBSVM获得稳定的结果。

你也可以试试我的libSVM 3.2.1 fork与-rnd选项(https://github.com/agdavydov81/antennaarray/tree/master/voice-noise-music/matlab/thirdpart/libsvm/src)。在这种情况下,请将lib前缀用于任何libSVM功能:例如libsvmtrain而不是svmtrain

+0

rand()出现在svm_binary_svc_probability和svm_cross_validation中。但是: - 仅当您设置发起SVM的概率时,才能访问该函数的第一个点:并且我没有(概率参数的默认值为0,因此跳过if) - 对于第二个,我不't使用svm_cross_validation 我需要专门使用LibSVM,而不是任何其他工具 – RicMarVr

+0

嗯......似乎你是对的。 GACC也可能会更好地保存训练有素的模型。如果模型相同(isequal),那么svmpredict中的问题。 –