对“视觉机器学习20讲配套仿真代码”的研究心得---Adaboost(一)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%功能:演示Adaboost算法在计算机视觉中的应用
%基于Adaboost实现目标分类;
%环境:Win7,Matlab2012b
%Modi: NUDT-VAP
%时间:2013-09-23
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% Step1: reading Data from the file

file_data = load('Ionosphere.txt');%%这里是调入一个TXT文件的数据。


Data = file_data(:,1:end-1)'; %%把上面的TXT文件的数据的第一列到倒数最后的一列,直接给DATA这个变量。
Labels = file_data(:, end)';
Labels = Labels*2 - 1; %%%这里是一些标签数据,这里的LABELS做了变化的,我们可以在MATLAB中的内存变量里面看到信息值的改变。


% boosting iterations
MaxIter = 100; %%%这个参数是一个迭代次数,或者说是一个级联分类器的个数。因为我们知道,这一算法的核心就是用弱分类器构成强分类器。


% Step2: splitting data to training and control set    将数据分为训练和控制集
TrainData   = Data(:,1:2:end);
TrainLabels = Labels(1:2:end);


ControlData   = Data(:,2:2:end);
ControlLabels = Labels(2:2:end);


% Step3: constructing weak learner        构建弱分类器
weak_learner = tree_node_w(3); % pass the number of tree splits to the constructor 弱分类器是由一些分裂树构造出来的。


% Step4: training with Gentle AdaBoost                              训练通用分类器,这里面有很多形式参数 ,在我们上面的代码中可以找到对就的参量。
[RLearners RWeights] = RealAdaBoost(weak_learner, TrainData, TrainLabels, MaxIter);  RealAdaBoost这是一个函数,它在工程中是有给出的,如果大家想要用这个工程,在我上传CSDN的文件中是有所以的工程文件的。


% Step5: evaluating on control set   控制集的评价,下面的函数就是对CLASSIFY这个弱分类器里面控制集的评价,我们要知道我们构造的级联弱分类器是不是满足我们的需要的,是不是有效的,所以我们要有一个评价机制。评价的结果请看下面的SIGN的这段英文解释。SIGN这是这个分类算法的一个流程,在经过T次迭代之后,得到T个弱分类器,最后通过加权投票,得到强分类器。这里会有一个公式。请大家自行参照相关理论。H(X)=SIGN{......}

ResultR = sign(Classify(RLearners, RWeights, ControlData));


sign   Signum function.
    For each element of X, sign(X) returns 1 if the element
    is greater than zero, 0 if it equals zero and -1 if it is
    less than zero.  For the nonzero elements of complex X,
    sign(X) = X ./ ABS(X).

 

http://blog.csdn.net/xiaowei_cqu/article/details/26746353   (参考网页)





http://blog.csdn.net/u014114990/article/details/50293495     分类器之Adaboost学习

% Step6: calculating error    计算误差

ErrorR  = sum(ControlLabels ~= ResultR) / length(ControlLabels)


&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

这里,弱分类器作为类使用,而分类器都作为全局函数进行使用。

1function [Learners, Weights, {final_hyp}] = RealAdaBoost(WeakLrn, Data, Labels, Max_Iter, {OldW, OldLrn, final_hyp})

说明:Real Adaboot分类算法,以WeakLrn为弱分类器,最大迭代次数:Max_Iter,数据集为DataLabels

输入:

• WeakLrn – 弱分类器;

• Data – 训练数据集,D*N维矩阵,D表示特征的维数,N表示样本个数;

• Labels – 训练标签,1*N维矩阵,N表示训练样本个数,label取值为:-1或者+1

• Max_Iter – 迭代次数;

• OldW – 已经建立单元的权重,用于更深层的训练,是可选参数;

• OldLrn – 已经建立单元的learners,用于更深层的训练,是可选参数;

• final_hyp – 已经建立单元的训练数据输出,用于加速更深层的训练,可选参数;

输出:

• Learners – 建立learner的单元阵列,每个learner都代表CART决策树的一个节点,用对象:tree_node_w class来表示;

• Weights – learners的权重. 该矢量与Learners大小相同,并且代表最终单元的每个learner的权重;

• final_hyp – 训练数据的输出。

(2function [Learners, Weights, {final_hyp}] = GentleAdaBoost(WeakLrn, Data, Labels, Max_Iter, {OldW, OldLrn})

说明:Gentle Adaboot分类算法,以WeakLrn为弱分类器,最大迭代次数:Max_Iter,数据集为DataLabels,这里的参数与Real Adaboost中一致。

3function [Learners, Weights, {final_hyp}] = ModestAdaBoost(WeakLrn, Data, Labels, Max_Iter, {OldW, OldLrn})

说明:Modest Adaboot分类算法,以WeakLrn为弱分类器,最大迭代次数:Max_Iter,数据集为DataLabels,这里的参数与Real Adaboost中一致。

(4function Result = Classify(Learners, Weights, Data)

根据各自的权值,使用级联learner将数据分类。结果包含如下数据:

+1或者-1表示类别,幅值表示决策的confidence.

(5function code = TranslateToC (Learners, Weights, fid)

使用该函数,可将分类器运用到c++中。

TN – 弱分类器的数目;

W –  弱分类器权重;

D –  阈值维数;

T –  阈值的大小;

Ts –  阈值sing. 取值为 –1 或者 +1, 如果样本应该更大或者比阈值小不能分类器正样本时,就重新采样。



x应当是一维行向量,
x'共轭转置后,变成一维列向量,尤其是实数时。
length(x)是求出x的元素个数
ones(length(x),1)是构造一个矩阵,length(x)行1列。
[x' ones(length(x),1)]等效于[x',ones(length(x),1)],即中间加逗号。
也就是将两个列向量并列地放在一起。
最后形成:
[
x1 1
x2 1
x3 1
x4 1
]
一般这样弄,用来直接拟合用的。

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

function [Learners, Weights, final_hyp] = RealAdaBoost(WeakLrn, Data, Labels, Max_Iter, OldW, OldLrn, final_hyp)


if( nargin == 4)
  Learners = {}; 初始化learner以及权重矩阵
  Weights = [];
  distr = ones(1, length(Data)) / length(Data);  
  final_hyp = zeros(1, length(Data));
elseif( nargin > 5)
 ///

 Learners = OldLrn;nargin是用来判断输入变量个数的函数,这样就可以针对不同的情况执行不同的功能。通常可以用他来设定一些默认值,如你上面的函数。
当nargin=5时,options=[10^(-6) 1]
当nargin=4时,evalOps=[];

//
  Weights = OldW;
  if(nargin < 7)                               

                                 &&&&&&&&&&&

既然nargin代表输入变量的个数,根据这个输入变量的个数,我们会进入不同的算法阶段。但是这里哪一些是所谓的输入变量,而且是怎么引起权值迭代的?还有待于分析 ,请知道详情的朋友来给解答一下,我也会持续跟进???????????????????

                                                           &&&&&&&&&&&&&&&
    final_hyp = Classify(Learners, Weights, Data);
  end
  distr = exp(- (Labels .* final_hyp));  
  distr = distr / sum(distr);  
else
  error('Function takes eather 4 or 6 arguments');
end




for It = 1 : Max_Iter
  
  %chose best learner         选择最好的学习分类器


  nodes = train(WeakLrn, Data, Labels, distr);          

&&&&&&&&&&&&&&&&&

这里面我们有一些函数要详细分析:train(WeakLrn, Data, Labels, distr);  calc_output(curr_tr, Data);
&&&&&&&&&&&&&&&&&


  for i = 1:length(nodes)
    curr_tr = nodes{i};
    
    step_out = calc_output(curr_tr, Data); 
      
    s1 = sum( (Labels ==  1) .* (step_out) .* distr);
    s2 = sum( (Labels == -1) .* (step_out) .* distr);


    if(s1 == 0 && s2 == 0)
        continue;
    end
    Alpha = 0.5*log((s1 + eps) / (s2+eps));&&&&&&&&&&&不同的分类器就会有不同的ALPHA的权值迭代值。


    Weights(end+1) = Alpha;
    
    Learners{end+1} = curr_tr;
    
    final_hyp = final_hyp + step_out .* Alpha;    
  end
  
  distr = exp(- 1 * (Labels .* final_hyp));
  Z = sum(distr);
  distr = distr / Z;            这几行代码是整个算法的核心部分,它实现了权值迭代,通过加权投票得到了强分类器。这里有一些我也没有搞的太明白,希望了解的朋友也帮忙分析一下。


end

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&


TrainAndSave.m

file_data = load('Diabetes.txt');这是一个文件装载。但是我找不到'Diabetes.txt这个文件
Data = file_data(:,1:end-1)';把文件FILE_DATA的第一列至倒数第二列给DATA。
Labels = file_data(:, end)';
Labels = Labels*2 - 1;


% Data = Data';
% Labels = Labels';


weak_learner = tree_node_w(2);这里表明弱分类器为分裂层级为2的弱分裂树。


% Step1: training with Gentle AdaBoost
[RLearners RWeights] = RealAdaBoost(weak_learner, Data, Labels, 200);



http://zengkui.blog.163.com/blog/static/21230008220121110111925175/

% Step2: training with Modest AdaBoost
[MLearners MWeights] = ModestAdaBoost(weak_learner, Data, Labels, 200);


http://blog.csdn.net/chenbang110/article/details/11557527

fid = fopen('RealBoost.txt','w');
TranslateToC(RLearners, RWeights, fid);
fclose(fid);
Learners – 建立learner的单元阵列,每个learner都代表CART决策树(http://blog.csdn.net/acdreamers/article/details/44664481)的一个节点,用对象:tree_node_w class来表示;


Weights – learners的权重. 该矢量与Learners大小相同,并且代表最终单元的每个learner的权重;

那么,TranslateToC()会根据弱分类器的LEARNERS  和WEIGHTS  来生成相应的权重值。这里我的解释不一定是对的,各位朋友有好见解可以指出。

fid = fopen('ModestBoost.txt','w');
TranslateToC(MLearners, MWeights, fid);
fclose(fid);

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&



TranslateToC.m

function code = TranslateToC (Learners, Weights, fid)


Weights = Weights ./ (sum(abs(Weights)));所有WEIGHTS的绝对值之和作为分母。这意为着求权值的均值 。


fprintf(fid, ' %d\r\n ', length(Weights));打印权值向量的长度。


for i = 1 : length(Weights)
  Curr_Result = get_dim_and_tr(Learners{i});


%   This file is part of GML Matlab Toolbox
%   For conditions of distribution and use, see the accompanying License.txt file.
%
%   get_dim_and_tr is the function, that returns dimension and threshold of
%   tree node
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%
%    output = get_dim_and_tr(tree_node, output)
%    ---------------------------------------------------------------------------------
%    Arguments:
%           tree_node - a node of classification tree
%           output    - vector of dimensions and thresholds. Result fo
%                       current node would be concatinated to it
%    Return:
%           output    - a vector of thresholds and dimensions. It has the
%                       following format:
%                       [dimension threshold left/right ...]
%                       left/right is  [-1, +1] number, wich signifies if
%                       current threshold is eather left or right

%这个文件是GML MATLAB工具箱的一部分
%的分布及使用条件,见所附license.txt文件。
%
% get_dim_and_tr是函数,返回维度和阈值
为树节点

  
  fprintf(fid, ' %f ', Weights(i));
  
  fprintf(fid, ' %d ', length(Curr_Result) / 3);
  
  for j = 1 : length(Curr_Result)
    fprintf(fid, ' %f ', Curr_Result(j));
  end
  
  fprintf(fid, '\r\n');
end


code = 1;

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

function Result = Classify(Learners, Weights, Data)


Result = zeros(1, size(Data, 2));


for i = 1 : length(Weights)
  lrn_out = calc_output(Learners{i}, Data);
  Result = Result + lrn_out * Weights(i);
end

%   This file is part of GML Matlab Toolbox
%   For conditions of distribution and use, see the accompanying License.txt file.
%
%   calc_output Implements classification of input by a classification tree node
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%
%    y = calc_output(tree_node, XData)
%    ---------------------------------------------------------------------------------
%    Arguments:
%           tree_node - classification tree node
%           XData     - data, that will be classified
%    Return:
%           y         - +1, if XData belongs to tree node, -1 otherwise (y is a vector)



%这个文件是GML MATLAB工具箱的一部分
%的分布及使用条件,见所附license.txt文件。
%
% calc_output通过分类树的节点进行分类输入
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%
% y = calc_output(tree_node,XDATA)
% ---------------------------------------------------------------------------------
分论点:
% tree_node分类树的节点
% XDATA数据,将分类
回报率%:
% y + 1,如果数据属于树节点,1否则(Y是一个向量)

你可能感兴趣的:(机器学习)