⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ihlf_svr_rfntrain_normal.m

📁 这是一个师兄编的程序
💻 M
字号:
function [alpha,b,sv] = ihlf_svr_rfntrain_normal(samples,targets,param)
% recursive finite Newton algorithm for support vector regression
% precompute the n*nsv kernel matrix and the space complexity is O(n*nsv)
%
% input parameters
% samples: n*d matrix vector
% targets: n vector
% param:   aus parameters
%   param.kernel:       kernel type
%   param.kernelparam:  kernel parameter
%   param.lamda:        regular constant
%   param.epsilon:      insensitive parameter
%   param.delta:        Huber parameter
%
% output parameters
% alpha:  weight vector
% b:      threshold 
% sv:     support vector
%
% written by Liefeng Bo on 12/12/2005
% version 1.0

st = cputime;
itmax = 100;
[n,d] = size(samples);

% rearrange the samples
perm = randperm(n);
samples = samples(perm,:);
targets = targets(perm,1);

% recursively partition the samples
tempn = n;
nvec(1) = n;
i = 1;
while tempn > 1000
    i = i+1;
    tempn = round(tempn/2);
    nvec(i) = tempn;
end
nvec = fliplr(nvec);

% initialize the parameters
oldsv = 1:nvec(1);
oldsv1 = oldsv;
oldsv2 = oldsv;
H = evalkernel(samples(oldsv,:),samples(oldsv,:),param.kernel,param.kernelparam) + param.lamda*eye(length(oldsv));
oldalpha = H\targets(1:nvec(1));
fprintf('\n');

% train the sub-problem
for i = 1:length(nvec)
    
    ksamples = evalkernel(samples(1:nvec(i),:),samples(oldsv,:),param.kernel,param.kernelparam);
    y = ksamples*oldalpha(oldsv);
    it = 1;
    
    while 1
        
        % find the support vectors
        r = y - targets(1:nvec(i));
        sv1 = find(abs(r) > param.epsilon & abs(r) < param.delta);
        sv2 = find(abs(r) >= param.delta);
        nonsv = find(abs(r) <= param.epsilon);
        sv = [sv1;sv2];
        
        % print the related information
        obj = param.lamda*oldalpha'*y + sum((abs(r(sv1))-param.epsilon).^2)...
            + 2*(param.delta - param.epsilon)*sum(abs(r(sv2))) - length(sv2)*(param.delta.^2 - param.epsilon.^2);
        fprintf('n = %d, iter = %d, obj = %f, nb of sv = %d     \r',[nvec(i) it obj length(sv)]);
        
        % stop
        if isempty(setxor(sv1,oldsv1)) & isempty(setxor(sv2,oldsv2)) | it >itmax
            b = 0;
            break;
        end
        
        % update the kernel matrix and targets
        ksamples = updateksamples(ksamples,samples,nvec(i),oldsv,sv,length(sv1),param);
        H = ksamples(sv1,1:length(sv1)) + param.lamda*eye(length(sv1));
        term = (param.delta - param.epsilon)*sign(r(sv2))/param.lamda;
        ttargets = targets(sv1) + param.epsilon*sign(r(sv1)) + ksamples(sv1,length(sv1)+1:end)*term;
        
        % compute the step
        tempalpha = zeros(nvec(i),1);
        tempalpha(sv) = [H\ttargets; -term];
        tempy = ksamples*tempalpha(sv);
        h = tempalpha - oldalpha;
        
        % line search
        u = tempy - y;
        coff(1,1) = 2*(u(sv1)'*r(sv1) - param.epsilon*u(sv1)'*sign(r(sv1))...
            + (param.delta - param.epsilon)*u(sv2)'*sign(r(sv2)) + param.lamda*h'*y);
        coff(1,2) = 2*(u(sv1)'*u(sv1) + param.lamda*h'*u);
        t = linesearch(coff,r,u,param,nonsv,sv1,sv2);
        alpha = oldalpha + t*h;      
        
        % update y and support vector
        y = t*tempy + (1 - t)*y;
        oldsv = sv;
        oldsv1 = sv1;
        oldsv2 = sv2;
        oldalpha = alpha;
        it = it + 1;
        
    end
    
    if i < length(nvec)
        oldalpha = [oldalpha;zeros(nvec(i+1) - nvec(i),1)];
    end
    fprintf('\n');
    
end

%output the weights and support vectors
alpha = alpha(sv);
sv = perm(sv);
[sv,index] = sort(sv);
alpha = alpha(index);
fprintf('Execution time : %4.1f seconds\n',cputime - st);

function ksamples = updateksamples(ksamples,samples,n,oldsv,sv,leng,param)

% update the kernel matrix
[diff,ioldsv,isv] = setxor(oldsv,sv);
oldsv(ioldsv) = [];
index = [oldsv; sv(isv)];
if ~isempty(ioldsv)
    ksamples(:,ioldsv) = [];
end
if ~isempty(isv)
    ksamples = [ksamples evalkernel(samples(1:n,:),samples(sv(isv),:),param.kernel,param.kernelparam)];
end

% rearrange the kernel matrix
[temp,inda] = sort(index);
[temp,indb] = sort(sv);
indb1 = find( indb <= leng);
indb2 = find( indb > leng);
ksamples = ksamples(:,inda([indb1; indb2]));

function t = linesearch(coff,r,u,param,nonsv,sv1,sv2)

% from zero loss to the quadratic loss, the linear loss
kv = [(sign(u(nonsv))*param.epsilon - r(nonsv))./u(nonsv) nonsv]; % enter the quadratic loss
kv = [kv; [(sign(u(nonsv))*param.delta - r(nonsv))./u(nonsv) -nonsv]]; % leave the quadratic loss

% from quadratic loss to the other loss
index1 = find(r(sv1).* u(sv1) > 0);
index1 = sv1(index1);
kv = [kv; [(sign(u(index1))*param.delta - r(index1))./u(index1) -index1]]; % enter the linear loss
index2 = find(r(sv1).* u(sv1) < 0);
index2 = sv1(index2);
kv = [kv; [(-sign(u(index2))*param.epsilon - r(index2))./u(index2) -index2]]; % enter the zero loss
kv = [kv; [(sign(u(index2))*param.epsilon - r(index2))./u(index2) index2]]; % enter the quadratic loss
kv = [kv; [(sign(u(index2))*param.delta - r(index2))./u(index2) -index2]]; % enter the linear loss

% from linear loss to the other loss
index = find(r(sv2).* u(sv2) < 0);
index = sv2(index);
kv = [kv; [(-sign(u(index))*param.delta - r(index))./u(index) index]]; % enters the quadratic loss
kv = [kv; [(-sign(u(index))*param.epsilon - r(index))./u(index) -index]]; % enters the zero loss
kv = [kv; [(sign(u(index))*param.epsilon - r(index))./u(index) index]]; % again enters the quadratic loss
kv = [kv; [(sign(u(index))*param.delta - r(index))./u(index) -index]]; % enters the linear loss

% sort the kink values
[temp ind] = sort(kv(:,1));
kv = kv(ind,:);

% compute the step length
kv = [kv; [Inf,0]];
leng = size(kv,1);
for i = 1:leng
    if  coff(1,1) + kv(i,1)*coff(1,2) > 0
        t = -coff(1,1)/coff(1,2); 
        break;
    else  % update coefficients
        if kv(i,2) > 0
            ind = abs(kv(i,2));
            coff(1,1) = coff(1,1) - 2*kv(i,1)*u(ind)^2;
            coff(1,2) = coff(1,2) + 2*u(ind)^2;
        else
            ind = abs(kv(i,2));
            coff(1,1) = coff(1,1) + 2*kv(i,1)*u(ind)^2;;
            coff(1,2) = coff(1,2) - 2*u(ind)^2;
        end
    end
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -