人工神經網絡(從原理到代碼) Step 01 感知器 梯度下降


 版權聲明:

   本文由SimonLiang所有,發布於http://www.cnblogs.com/idignew/。如果轉載,請注明出處,在未經作者同意下將本文用於商業用途,將追究其法律責任。

 

感知器

1.問題

人工神經網絡(ANN)是機器學習的一重要分支,在沒介紹神經網絡之前,有必要先介紹感知器,感知器是人工神經網絡的前身。

有這么一個問題,我們知道某人的體重及身高可否估計出人體脂肪的含量比例(就是肥瘦問題了)?

而實際的

在這之前,我們隨機在街上找了幾百人做測量,測量下面的數據:

1。年齡(歲)
2。體重(公斤)
3。身高(厘米)
4。頸圍(厘米)
5。胸圍(厘米)
6。腹部(厘米)
7。臀圍(厘米)
8。大腿圍(厘米)
9。膝圍(厘米)
10。踝周長(厘米)
11。肱二頭肌(擴展)腰圍(cm)
12。前臂圍(厘米)
13。腕圍(厘米)

最后是測量這個人的脂肪比例(百分比)

看看是上面的13個因素和身體的脂肪比例有沒關系?

為了方便理解,這里只選取測量的體重(X1)及身高(X2)中30組數據為說明對象,數據如下:

編號 x1 體重(kg) x2 身高(cm) y 脂肪含量(%)
1 70 172 12
2 79 184 6
3 70 168 25
4 84 184 10
5 84 181 29
6 95 190 21
7 82 177 19
8 80 184 12
9 87 188 4
10 90 187 12
11 84 189 7
12 98 193 8
13 82 177 21
14 93 181 21
15 85 177 22
16 74 168 21
17 89 180 29
18 95 180 23
19 83 172 16
20 96 187 17
21 81 173 19
22 91 177 15
23 64 173 16
24 67 178 18
25 69 172 14
26 72 182 4
27 60 171 8
28 67 171 23
29 60 164 4
30 73 175 9

 -----

2.思路

思路是這樣的,能否找到w1,w2,w0,使得y~=w1*x1+w2*x2+w0*x0(其中定義xo=1),這樣只要求出w1,w2,wo就可以解決一開始的問題。

於是,我們把上面的模型簡化為:

然后讓h盡可能接近y的。

 

---

3.模型

於是每一組數據(一行為一組數據)輸入到模型中有了(例子中共30組數據):

上面的其中一組數據可以簡化寫成:

 

定義一個函數J,通過函數J來衡量w1,w2,w0是否合適:

J=1/2*(([h(1)-y(1)])2+([h(2)-y(2)])2+...([h(30)-y(30)]) 2)

 簡寫成:

-----

4.求導

下面的工作就是如何求w1,w2,w0了,

由於上面的式子中未知的只有w1,w2,w0(每一組的x1,x2,y都是知道的),

那么函數J實際上就是關於變量(w1,w2,w0)的函數。

為了方便理解,我們暫時把w0=0,這樣

J=f(w1,w2)了

對應一個二元方程來說,可以通過一個立體圖來直觀的描述:

 

 現在就是如何求出最低的位置。

這里用到的是一種稱為梯度下降的方法,

首先,隨意給定一個點A,然后求出其所在位置的最陡峭的方向(用偏導的方式),再給定一定長度,往下走一點,

停下來再求最陡峭的方向,然后往下走一點,循環直到到達最低的位置。

如下圖,

 

 

上面的是一個比較好理解的情形,實際上這個J(w1,w2,w0)是一個難以用圖表示的,但道理是一樣的。

 

下面給出w1求偏導的具體過程,真的的很詳細。。。(可憐的電腦編輯公式實在慢)。

同理求出w2,及w0的偏導(注意x0=1);

 

---

5.梯度下降求答案

求出偏導后,可以設定一個固定的步長α,向低窪的地方出發了。

下面的公式中的“:=”為編程中的更新公式

代入上面的求導結果后

為了形象的說明為什么減去“α*偏導”,下圖形象的說明,其中w’為更新后的w值

 

 ---

6.代碼實現

 %數據

bodyData =

     1    70   172    12
     1    79   184     6
     1    70   168    25
     1    84   184    10
     1    84   181    29
     1    95   190    21
     1    82   177    19
     1    80   184    12
     1    87   188     4
     1    90   187    12
     1    84   189     7
     1    98   193     8
     1    82   177    21
     1    93   181    21
     1    85   177    22
     1    74   168    21
     1    89   180    29
     1    95   180    23
     1    83   172    16
     1    96   187    17
     1    81   173    19
     1    91   177    15
     1    64   173    16
     1    67   178    18
     1    69   172    14
     1    72   182     4
     1    60   171     8
     1    67   171    23
     1    60   164     4
     1    73   175     9

 %% matlab 代碼

 

%加載數據
x=bodyData(:,1:3);%注意x(:,1)=1;
y=bodyData(:,4);


%初始化
step=0.000001;%設定步長,就是
stepn=1;%步驟數
w=[-0.5;0.5;-0.5];%初始化w值,注意w(1)對應的是上面的x0;


while  stepn<500;
    h=x*w; %計算出h
    e=(h-y); %計算出差值e
    e1=e.*x(:,1); 
    e2=e.*x(:,2);
    e3=e.*x(:,3);
    w(1)=w(1)-step*sum(e1);%計算出w1,就是上面講的w0;
    w(2)=w(2)-step*sum(e2);%計算出w1,就是上面講的w1;
    w(3)=w(3)-step*sum(e3);%計算出w1,就是上面講的w2;
    J(stepn)=1/2*sum(power(e,2)); %計算出代價函數J;
    if stepn>1
        J_gradient=J(stepn-1)-J(stepn); %計算梯度值
    end
    
    %繪制圖形
    plot(stepn,J(stepn),'o');
    hold on;
    title(['步數=',num2str(stepn),'  梯度=',num2str(J_gradient)]);
    
    pause(0.1); %暫停0.5秒
    stepn=stepn+1;
end

 

運行結果:

最后的w值:

w =

   -0.4979
    0.6018
   -0.1820

 

----

7 后話

1.關於數據擴充

對於上面的例子,可以很容易把上面的3個x變為m個x,數據從30個變為m個。

 

2.關於BGD與SGD,還有Mini-BGD。

還記得上面的

留意一下,這個是需要對整個數據集都要求和計算的。

而對整體求出梯度的下降方式是叫批量梯度下降(Batch Gradient Descent,簡稱BGD);

如果數據的維度少(所謂維度就是x1,x2,x3,...,xn,如果上面的例子就是體重,身高,腰圍等)的數據沒問題。

但對於大數據,如圖形那樣過萬的維度數據,效率就很低了。

所以就有了隨機梯度下降,Stochastic Gradient Descent(簡稱SGD),

及常用的小批量梯度下降 Mini Batch Gradient Descent。

這里不展開,有興趣可以Search一下區別。

 

3.關於編程

對應上面的數據,或者類似這樣的數據,要做線性回歸,

可以自己不寫代碼,而matlab有一個簡單的方式可以實現:

% 把上面的數據用regress 函數就可以解決

w = regress(y,x)

ans:

w =

  116.0441
    0.5502
   -0.8103

 

參考:

NG大牛的

UFLDL教程

斯坦福機器學習網上教程

 

 

好了,就寫到這里。

(end)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM