【问题标题】:LibSVM for Matlab - Unstable resultsMatlab 的 LibSVM - 不稳定的结果
【发布时间】:2018-03-17 00:32:51
【问题描述】:

我在 x64 PC 上的 MATLAB R2016a 上使用 LIBSvm 3.22(但我已经用 R2017a 进行了测试),并且我的代码出现了奇怪的行为。

我使用的是预计算机内核(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),:)

如你所见,我做了两次同样的事情。然而,最后一个命令并不总是返回相同的东西。 有时还可以:GACC == 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 源代码中我找不到任何种子\随机初始化,并且代码看起来是确定性的(即没有随机启动或其他优化)。

可能是核矩阵的问题(可能是精度问题?)? K 看起来像这样(对角线显然都是 1,因为已经取幂了):

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

感谢支持!

【问题讨论】:

  • kernel 标签适用于 操作系统 内核(参见标签说明)。但是您的问题是关于“内核”一词的其他含义。请为您的问题使用更合适的标签。 [我不熟悉您的问题的主题,因此无法建议替换标签。]

标签: matlab svm libsvm


【解决方案1】:

libSVM 使用“C”随机数生成器(rand() 函数)在 svm_binary_svc_probability 和 svm_cross_validation 函数中进行数据混洗。

参见 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)。在这种情况下,请为任何 libSVM 函数使用 lib 前缀:例如libsvmtrain 而不是 svmtrain

【讨论】:

  • rand() 出现在 svm_binary_svc_probability 和 svm_cross_validation 中。但是: - 对于第一点,只有当你设置了 SVM 午餐的概率时,你才能访问该函数:而我没有(概率参数的默认值为 0,所以跳过 if) - 第二点,我没有使用 svm_cross_validation 我需要专门使用 LibSVM,而不是任何其他工具
  • 嗯...看来你是对的。使用 GACC 保存训练有素的模型可能会更好。如果模型相同(相等),那么 svmpredict 中的问题。
猜你喜欢
  • 2013-12-07
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
  • 2014-10-19
  • 2018-06-13
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多