版權聲明:
本文由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大牛的
好了,就寫到這里。
(end)