1. 程式人生 > >關於Adaboost強分類器的訓練

關於Adaboost強分類器的訓練



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