关于Adaboost强分类器的训练

来源:互联网 发布:mac版本炒股软件 编辑:程序博客网 时间:2024/06/04 20:06


function [H w flag] = AdaBoost(A, T, T0, haar, r, m, w, flag)
% 训练强分类器
% A:样本积分图信息
% T:训练次数
% T0:中断训练时的次数
% haar: haar结构特征,包括(1,2), (2,1), (1,3), (3,1), (2,2)
% r:人脸样本个数
% m:非人脸样本个数
% H:训练后的强分类器 H = [haar, P, Theta, Alpha]
% w:样本权重
% flag: 程序中断标志(首次计算flag=0,其余情况flag=1)

N = size(haar,1); % harr特征个数
yr = ones(r,1); % 人脸样本标识y=1
ym = zeros(m,1); % 非人脸样本标识y=0
y = [yr;ym]; % 人脸样本在前,非人脸样本在后
if flag == 0
    w = ones(r+m,1); % 权重初始化
    w(1:r) = w(1:r)/(2*r); % 人脸样本在前
    w(r+1:r+m) = w(r+1:r+m)/(2*m); % 非人脸样本在后
end
H = zeros(1,9); % 训练得到的T组最优弱分类器(初始化)
for t = T0:T
    w = w/sum(w); % 权重归一化计算
    Error = zeros(N,1); % 弱分类器的分类误差统计
    for  j= 1:N
        F = AdaBoost_f(haar(j,:), A); % 调用函数AdaBoost_f计算特征值fj
        [Theta P] = AdaBoost_Theta_P(F, y, w, r, m); % 调用函数AdaBoost_Theta_P计算最优阈值θj和Pj
        hx = P*F < P*Theta; % 弱分类器对人脸和非人人脸进行判断
        Error(j) = sum(w.*abs(hx-y)); % 弱分类器的分类误差统计
    end
   
    [E_t I_t] = min(Error); % 寻找具有最小错误Et的弱分类器Ht
    haar_t = haar(I_t,:); % 第t次训练得到的最优弱分类器的haar结构
    F_t = AdaBoost_f(haar_t, A); % 调用函数AdaBoost_f计算最优弱分类器的haar结构的特征值ft
    [Theta_t P_t] = AdaBoost_Theta_P(F_t, y, w, r, m); % 调用函数AdaBoost_Theta_P计算最优弱分类器的haar结构的最优阈值θt和Pt
    hx_t = P_t*F_t < P_t*Theta_t; % 第t次训练得到的最优弱分类器对人脸和非人人脸进行判断
    H_t = (hx_t == y); % 第t次训练得到的最优弱分类器Ht的分类结果判定(若一致H_t=1,反之H_t=0)
    Beta_t = E_t/(1-E_t); % 样本权重更改(正确分类的权重减小,未被正确分类的权重增加)
    w = w.*Beta_t.^H_t; % 更新权重
    Alpha_t = log(1/Beta_t); % 第t次训练得到的最优弱分类器的权重
    H(t,:) = [haar_t, P_t, Theta_t, Alpha_t]; % 第t次训练得到的最优弱分类器
    save(['Data\H',num2str(t),'.mat'],'H'); % 保存强分类器(含有t个弱分类器)
    save(['Data\w',num2str(t),'.mat'],'w'); % 保存样本权重信息,以便在中断计算后重新加载运算。
    flag = 1; % 计算运行状态标识
    if sum(H_t) == r+m % 如果强分类器能正确区分所有的人脸和非人脸样本
        file = fopen('Data\结束信息.txt','wt'); % 打开文件
        info =['当强分类器含有',num2str(t),'个弱分类器时,该强分类器能区分所有的人脸样本和非人脸样本,计算结束!'];
        fprintf(file,'%s',info);
        fclose(file);
        break; % 跳出循环
    end
    file = fopen('Data\中断信息.txt','wt'); % 打开文件
    info = ['在t=',num2str(t),'时中断,重新加载时请将T0置为:',num2str(t+1),';重新加载时请将flag置为:',num2str(flag),...
        ';人脸样本为:',num2str(r),'个;非人脸样本为:',num2str(r),'个;人脸和非人脸样本的序列起始值均为0!'];
    fprintf(file,'%s',info);
    fclose(file);
end

0 0