貝葉斯學習
貝葉斯公式
貝葉斯學習器其實是從經典的貝葉斯概率公式的來的,對於經典的貝葉斯公式:
式中P(A)表示A的先驗概率(即A發生的概率與B無關),P(A|B)表示A的後驗概率(即在已知B發生的情況下,A發生的概率)
樸素貝葉斯分類
我們都知道貝葉斯是一個經典的求取概率的公式,那麼貝葉斯又是怎麼和分類相聯繫起來的呢?
實際上,在分類的過程中,我們要判斷某樣本x是否屬於某類別A時,可以將這件事看成是個概率問題,即判斷x屬於A的可能性有多大。假設類別有n種,則只需求取x分別屬於每個樣本的概率有多大,概率值最大的,即可認爲是x的所屬類別。
樸素貝葉斯分類的正式定義如下:
1. 設
2. 有類別集合
計算
P(y1|x) ,P(y2|x) ,…,P(yn|x) 。如果
P(yk|x)=max{(y1|x),P(y2|x),...,P(yn|x)}
則x∈yk
現在從定義可以看出每步並不難理解。關鍵時第三步中的每個概率值怎麼求取。對於單個變量,求取其概率值比較好求,可是這裏的x時一個含有m個屬性的變量,這種情況下,該怎麼求取其屬於某類別
下面給出求解推導:
已知我們要求取
所以求取
對於
因此:
至此,便得到了
樸素貝葉斯分類應用實例(目標跟蹤)
對於目標跟蹤,目前用的比較多的方法都是在待跟蹤目標區域周圍獲取候選窗口,然後判斷這些候選窗口是否是目標。在判斷的過程中,往往採都是計算候選窗口屬於時目標的概率值,值越大,則其時目標的可能性就越大。這種思想和樸素貝葉斯分類的思想非常相似。
下面以壓縮感知跟蹤爲例。
在感知壓縮跟蹤,作者將貝葉斯當成了一個在線學習的分類器,此分類器在分爲分類和更新參數兩個部分。
在分類階段(第t幀)
首先在目標框(t-1幀確定的位置)周圍一定範圍內選取m個候選框。對候選框提取特徵,得到特徵向量
但是要是單純的求取這個式子並不好求,因爲我們並不知道式子中
不過,注意到既然不能求解
因此將求取
對上式左右兩邊同取log(爲了方便計算,將累乘變爲累加)
這裏假定先驗概率
則可得:
其中:
在參數更新階段(第t幀)
在分類階段時,已經確定了第t幀中目標所在的位置,接下來來便更新學習機的參數。,會在目標框周圍一定範圍
式子中的
實踐代碼
這是分類代碼
void CompressiveTracker::radioClassifier(vector<float>& _muPos, vector<float>& _sigmaPos, vector<float>& _muNeg, vector<float>& _sigmaNeg,
Mat& _sampleFeatureValue, float& _radioMax, int& _radioMaxIndex)
{
float sumRadio;
_radioMax = -FLT_MAX;
_radioMaxIndex = 0;
float pPos;
float pNeg;
int sampleBoxNum = _sampleFeatureValue.cols;
for (int j=0; j<sampleBoxNum; j++)
{
sumRadio = 0.0f;
for (int i=0; i<featureNum; i++)
{
pPos = exp( (_sampleFeatureValue.at<float>(i,j)-_muPos[i])*(_sampleFeatureValue.at<float>(i,j)-_muPos[i]) / -(2.0f*_sigmaPos[i]*_sigmaPos[i]+1e-30) ) / (_sigmaPos[i]+1e-30);
pNeg = exp( (_sampleFeatureValue.at<float>(i,j)-_muNeg[i])*(_sampleFeatureValue.at<float>(i,j)-_muNeg[i]) / -(2.0f*_sigmaNeg[i]*_sigmaNeg[i]+1e-30) ) / (_sigmaNeg[i]+1e-30);
sumRadio += log(pPos+1e-30) - log(pNeg+1e-30); // equation 4
}
if (_radioMax < sumRadio)
{
_radioMax = sumRadio;
_radioMaxIndex = j;
}
}
}
這是參數跟新代碼
void CompressiveTracker::classifierUpdate(Mat& _sampleFeatureValue, vector<float>& _mu, vector<float>& _sigma, float _learnRate)
{
Scalar muTemp;
Scalar sigmaTemp;
for (int i=0; i<featureNum; i++)
{
meanStdDev(_sampleFeatureValue.row(i), muTemp, sigmaTemp);
_sigma[i] = (float)sqrt( _learnRate*_sigma[i]*_sigma[i] + (1.0f-_learnRate)*sigmaTemp.val[0]*sigmaTemp.val[0]
+ _learnRate*(1.0f-_learnRate)*(_mu[i]-muTemp.val[0])*(_mu[i]-muTemp.val[0])); // equation 6 in paper
_mu[i] = _mu[i]*_learnRate + (1.0f-_learnRate)*muTemp.val[0]; // equation 6 in paper
}
}