Machine Learning---Backpropagation

Machine Learning---Backpropagation

引言

反向傳播法(backpropagration),是一個非常經典的監督學習方法。在前面已經介紹過LMS算法,所以對於這兩種之間的公共部分不會再做詳細介紹。

一、Backpropagation算法基本介紹

1.算法思想

反向傳播算法是監督式學習最流行的方法。

它其中的算法思想就如它的名字一樣。它順序計算了輸出值,然後反序將error(計算值和正確值的差值)往回傳,進行計算模型中的權值調整。

應用於多層感知器學習算法中,可以解決一些較複雜的問題。

2.權值調整公式

和前面介紹的LMS算法一樣,這個算法通過一些給定的訓練數據進行權值調整。

其中權值調整公式:


其中表示第i個“輸入端”的權值,是學習參數,t是正確值,Y是計算值,是第i個“輸入端”的輸入值。

我們這裏選用這個處理函數是因爲它的導數

這個結果使得導數的計算簡單化。


接下來部分是關於這個算法的一些說明:如果沒有興趣的讀者可以直接跳過這一段:

首先我們定義一個差值的比方

其中t便是目標值(正確值),y便是計算值,這裏去乘於1/2,主要爲了之後求導之後的化簡。

,這裏n便是輸入端的數量,便是第i個輸入端的權值和輸入值。

我們這裏設

按照梯度下降法


其中是一個學習參數,剩下的我們就要求


我們將右邊三個分式進行計算:


所以帶入公式便是


其實不難發現這個公式在進行一次轉換便是上面所提到的


這裏我們對這個算法的核心部分進行了簡單的數學介紹。關於其中提到的梯度下降算法的知識,筆者已經寫過一篇《Machine Learning---LMS 算法數學說明》進行了介紹。

3.算法流程

對於這個算法的流程也是比較好理解:

1.首先給權值覆上隨機初值;

2.在訓練集中隨機選擇訓練組;

3.按照當前計算模型進行計算輸出值;

4.將error反向傳播,逐步調整計算模型中的權值;

5.判斷MSE是否滿足條件,如果不滿足繼續步驟2;如果滿足就跳出算法。

 

二、算法實現

在這裏提供這個算法的實現代碼:

struct TrainningSet
{
    double inputs[NUM_INPUTS];
    double outputs[NUM_OUTPUTS];
}TrainningSet;
 
TrainningSet tests[NUM_TESTS];
 
double sigmoid(double val)
{
     return ( 1.0 /(1.0 + exp(-val)) );
}
double sigmoid_d(double val)
{
    return val*(1.0 - val);
}
//
void calculate_output()
{
    for (int i = 0 ; i< NUM_HIDDENS; ++i)
    {
        hiddens[i]= 0.0;
        for(int j = 0 ; j< NUM_HIDDENS ; ++j)
        {
            hiddens[i]+= inputs[j] * w_h_i[i][j];
        }
        hiddens[i]= sigmoid(hiddens[i]);
    }
 
    for (int i = 0 ; i< NUM_OUTPUTS ; ++i)
    {
        outputs[i]= 0.0;
        for(int j = 0 ; j< NUM_HIDDENS ; ++j)
        {
            outputs[i]+= hiddens[j] * w_o_h[i][j];
        }
        outputs[i]= sigmoid(outputs[i]);
    }
}
 
void backpropagate_error(int test)
{
    for (int i = 0 ; i< NUM_OUTPUTS ; ++i)
    {
        for (int j = 0 ; j< NUM_HIDDENS ; ++j)
        {
            w_o_h[i][j]= w_o_h[i][j] -ALPHA * (tests[test].outputs[i] - outputs[i]) *sigmoid_d(outputs[i]) * hiddens[j];
        }
    }
    //
    for (int i = 0 ; i< NUM_HIDDENS ; ++i)
    {
        for (int j = 0 ; j< NUM_INPUTS ; ++j)
        {
            w_h_i[i][j]= w_h_i[i][j] -ALPHA * (tests[test].hiddens[i] - hiddens[i]) *sigmoid_d(hiddens[i]) * inputs[j];
        }
    }
}


三、總結

由於筆者不是專門研究人工智能方面,所以在寫這些文章的時候,肯定會有一些錯誤,也請諒解,上面介紹中有什麼錯誤或者不當地方,敬請指出,不甚歡迎。

如果有興趣的可以留言,一起交流一下算法學習的心得。

聲明:本文章是筆者整理資料所得原創文章,如轉載需註明出處,謝謝。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章