人工神經網絡(ANN),簡稱神經網絡,是一種模仿生物神經網絡的結構和功能的數學模型或計算模型。神經網絡由大量的人工神經元聯結進行計算。大多數狀況下人工神經網絡能在外界信息的基礎上改變內部結構,是一種自適應系統。現代神經網絡是一種非線性統計性數據建模工具,經常使用來對輸入和輸出間複雜的關係進行建模,或用來探索數據的模式。git
人工神經網絡從如下四個方面去模擬人的智能行爲:算法
- 物理結構:人工神經元將模擬生物神經元的功能
- 計算模擬:人腦的神經元有局部計算和存儲的功能,經過鏈接構成一個系統。人工神經網絡中也有大量有局部處理能力的神經元,也可以將信息進行大規模並行處理
- 存儲與操做:人腦和人工神經網絡都是經過神經元的鏈接強度來實現記憶存儲功能,同時爲歸納、類比、推廣提供有力的支持
- 訓練:同人腦同樣,人工神經網絡將根據本身的結構特性,使用不一樣的訓練、學習過程,自動從實踐中得到相關知識
神經網絡是一種運算模型,由大量的節點(或稱「神經元」,或「單元」)和之間相互聯接構成。每一個節點表明一種特定的輸出函數,稱爲激勵函數。每兩個節點間的鏈接都表明一個對於經過該鏈接信號的加權值,稱之爲權重,這至關於人工神經網絡的記憶。網絡的輸出則依網絡的鏈接方式,權重值和激勵函數的不一樣而不一樣。而網絡自身一般都是對天然界某種算法或者函數的逼近,也多是對一種邏輯策略的表達。網絡
1、感知器
感知器至關於神經網絡的一個單層,由一個線性組合器和一個二值閾值原件構成:數據結構
構成ANN系統的單層感知器:機器學習
- 感知器以一個實數值向量做爲輸入,計算這些輸入的線性組合,若是結果大於某個閾值,就輸出1,不然輸出‐1。
- 感知器函數可寫爲:sign(w*x)有時可加入偏置b,寫爲sign(w*x b)
- 學習一個感知器意味着選擇權w0,…,wn的值。因此感知器學習要考慮的候選假設空間H就是全部可能的實數值權向量的集合
算法訓練步驟:函數
一、定義變量與參數x(輸入向量),w(權值向量),b(偏置),y(實際輸出),d(指望輸出),a(學習率參數)工具
二、初始化,n=0,w=0oop
三、輸入訓練樣本,對每一個訓練樣本指定其指望輸出:A類記爲1,B類記爲-1學習
四、計算實際輸出y=sign(w*x b)測試
五、更新權值向量w(n 1)=w(n) a[d-y(n)]*x(n),0<a<1
六、判斷,若知足收斂條件,算法結束,不然返回3
注意,其中學習率a爲了權值的穩定性不該過大,爲了體現偏差對權值的修正不該太小,說到底,這是個經驗問題。
從前面的敘述來看,感知器對於線性可分的例子是必定收斂的,對於不可分問題,它無法實現正確分類。這裏與咱們前面講到的支持向量機的想法十分的相近,只是肯定分類直線的辦法有所不一樣。能夠這麼說,對於線性可分的例子,支持向量機找到了「最優的」那條分類直線,而單層感知器找到了一條可行的直線。
咱們以鳶尾花數據集爲例,因爲單層感知器是一個二分類器,因此咱們將鳶尾花數據也分爲兩類,「setosa」與「versicolor」(將後兩類均看作第2類),那麼數據按照特徵:花瓣長度與寬度作分類。
運行下面的代碼:
[plain] view plaincopyprint?
- #感知器訓練結果:
- a<-0.2
- w<-rep(0,3)
- iris1<-t(as.matrix(iris[,3:4]))
- d<-c(rep(0,50),rep(1,100))
- e<-rep(0,150)
- p<-rbind(rep(1,150),iris1)
- max<-100000
- eps<-rep(0,100000)
- i<-0
- repeat{
- v<-w%*%p;
- y<-ifelse(sign(v)>=0,1,0);
- e<-d-y;
- eps[i 1]<-sum(abs(e))/length(e)
- if(eps[i 1]<0.01){
- print(「finish:」);
- print(w);
- break;
- }
- w<-w a*(d-y)%*%t(p);
- i<-i 1;
- if(i>max){
- print(「max time loop」);
- print(eps[i])
- print(y);
- break;
- }
- }
- #繪圖程序
- plot(Petal.Length~Petal.Width,xlim=c(0,3),ylim=c(0,8),
- data=iris[iris$Species=="virginica",])
- data1<-iris[iris$Species=="versicolor",]
- points(data1$Petal.Width,data1$Petal.Length,col=2)
- data2<-iris[iris$Species=="setosa",]
- points(data2$Petal.Width,data2$Petal.Length,col=3)
- x<-seq(0,3,0.01)
- y<-x*(-w[2]/w[3])-w[1]/w[3]
- lines(x,y,col=4)
- #繪製每次迭代的平均絕對偏差
- plot(1:i,eps[1:i],type=」o」)
分類結果如圖:
這是運行了7次獲得的結果。與咱們前面的支持向量機相比,顯然神經網絡的單層感知器分類不是那麼的可信,有些弱。
咱們能夠嘗試來作交叉驗證,能夠發現交叉驗證結果並不理想。
2、線性神經網絡
儘管當訓練樣例線性可分時,感知器法則能夠成功地找到一個權向量,但若是樣例不是線性可分時它將不能收斂。所以,人們設計了另外一個訓練法則來克服這個不足,稱爲delta法則。
若是訓練樣本不是線性可分的,那麼delta法則會收斂到目標概念的最佳近似。
delta法則的關鍵思想是使用梯度降低來搜索可能權向量的假設空間,以找到最佳擬合訓練樣例的權向量。
咱們將算法描述以下:
一、定義變量與參數。x(輸入向量),w(權值向量),b(偏置),y(實際輸出),d(指望輸出),a(學習率參數)(爲敘述簡便,咱們能夠將偏置併入權值向量中)
二、初始化w=0
三、輸入樣本,計算實際輸出與偏差。e(n)=d-x*w(n)
四、調整權值向量w(n 1)=w(n) a*x*e(n)
五、判斷是否收斂,收斂結束,不然返回3
Hayjin證實,只要學習率a<2/maxeign, delta法則按方差收斂。其中maxeigen爲x’x的最大特徵值。故咱們這裏使用1/maxeign做爲a的值。
咱們仍是以上面的鳶尾花數據爲例來講這個問題。運行代碼:
[plain] view plaincopyprint?
- p<-rbind(rep(1,150),iris1)
- d<-c(rep(0,50),rep(1,100))
- w<-rep(0,3)
- a<-1/max(eigen(t(p)%*%p)$values)
- max<-1000
- e<-rep(0,150)
- eps<-rep(0,1000)
- i<-0
- for(i in 1:max){
- v<-w%*%p;
- y<-v;
- e<-d-y;
- eps[i 1]<-sum(e^2)/length(e)
- w<-w a*(d-y)%*%t(p);
- if(i==max)
- print(w)
- }
獲得分類直線:
相比感知器分類而言已經好了太多了,究其緣由不外乎傳遞函數由二值閾值函數變爲了線性函數,這也就是咱們前面提到的delta法則會收斂到目標概念的最佳近似。增量法則漸近收斂到最小偏差假設,可能須要無限的時間,但不管訓練樣例是否線性可分都會收斂。
爲了明瞭這一點咱們考慮鳶尾花數據後兩類花的分類(這裏咱們將前兩類看作一類),使用感知器:
使用線性分類器:
可是要解釋的一點是,收斂並不意味着分類效果更好,要解決線性不可分問題須要的是添加非線性輸入或者增長神經元。咱們以Minsky & Papert (1969)提出的異或例子爲例說明這一點。
使用線性神經網絡,代碼與上面徹底相同,略。
第一個神經元輸出:
權值: [,1] [,2] [,3]
[1,] 0.75 0.5 -0.5
測試: [,1] [,2] [,3] [,4]
[1,] 1 0 1 1
第二個神經元輸出:
權值: [,1] [,2] [,3]
[1,] 0.75 -0.5 0.5
測試: [,1] [,2] [,3] [,4]
[1,] 1 1 0 1
求解異或邏輯(相同取0,不一樣取1)有結果:(代碼xor(c(1,0,1,1),c(1,1,0,1)))
[1] FALSE TRUE TRUE FALSE
即0,1,1,0,分類正確。
最後再說一點,Delta規則只能訓練單層網絡,但這不會對其功能形成很大的影響。從理論上說,多層神經網絡並不比單層神經網絡更強大,他們具備一樣的能力。
3、BP神經網絡
一、SIGMOID函數分類
回顧咱們前面提到的感知器,它使用示性函數做爲分類的辦法。然而示性函數做爲分類器它的跳點讓人以爲很難處理,幸虧sigmoid函數y=1/(1 e^-x)有相似的性質,且有着光滑性這一優良性質。咱們經過下圖能夠看見sigmoid函數的圖像:
Sigmoid函數有着計算代價不高,易於理解與實現的優勢但也有着欠擬合,分類精度不高的特性,咱們在支持向量機一章中就能夠看到sigmoid函數差勁的分類結果。
二、BP神經網絡結構
BP (Back Propagation)神經網絡,即偏差反傳偏差反向傳播算法的學習過程,由信息的正向傳播和偏差的反向傳播兩個過程組成。由下圖可知,BP神經網絡是一個三層的網絡:
- 輸入層(input layer):輸入層各神經元負責接收來自外界的輸入信息,並傳遞給中間層各神經元;
- 隱藏層(Hidden Layer):中間層是內部信息處理層,負責信息變換,根據信息變化能力的需求,中間層能夠設計爲單隱層或者多隱層結構;最後一個隱層傳遞到輸出層各神經元的信息,經進一步處理後,完成一次學習的正向傳播處理過程;
- 輸出層(Output Layer):顧名思義,輸出層向外界輸出信息處理結果;
當實際輸出與指望輸出不符時,進入偏差的反向傳播階段。偏差經過輸出層,按偏差梯度降低的方式修正各層權值,向隱藏層、輸入層逐層反傳。周而復始的信息正向傳播和偏差反向傳播過程,是各層權值不斷調整的過程,也是神經網絡學習訓練的過程,此過程一直進行到網絡輸出的偏差減小到能夠接受的程度,或者預先設定的學習次數爲止。
三、反向傳播算法
反向傳播這一算法把咱們前面提到的delta規則的分析擴展到了帶有隱藏節點的神經網絡。爲了理解這個問題,設想Bob給Alice講了一個故事,而後Alice又講給了Ted,Ted檢查了這個事實真相,發現這個故事是錯誤的。如今 Ted 須要找出哪些錯誤是Bob形成的而哪些又歸咎於Alice。當輸出節點從隱藏節點得到輸入,網絡發現出現了偏差,權係數的調整須要一個算法來找出整個偏差是由多少不一樣的節點形成的,網絡須要問,「是誰讓我誤入歧途?到怎樣的程度?如何彌補?」這時,網絡該怎麼作呢?
一樣源於梯度降落原理,在權係數調整分析中的惟一不一樣是涉及到t(p,n)與y(p,n)的差分。一般來講Wi的改變在於:
alpha * s’(a(p,n)) * d(n) *X(p,i,n)
其中d(n)是隱藏節點n的函數,讓咱們來看:
- n 對任何給出的輸出節點有多大影響;
- 輸出節點自己對網絡總體的偏差有多少影響。
一方面,n 影響一個輸出節點越多,n 形成網絡總體的偏差也越多。另外一方面,若是輸出節點影響網絡總體的偏差越少,n 對輸出節點的影響也相應減小。這裏d(j)是對網絡的總體偏差的基值,W(n,j) 是 n 對 j 形成的影響,d(j) * W(n,j) 是這兩種影響的總和。可是 n 幾乎老是影響多個輸出節點,也許會影響每個輸出結點,這樣,d(n) 能夠表示爲:SUM(d(j)*W(n,j))
這裏j是一個從n得到輸入的輸出節點,聯繫起來,咱們就獲得了一個培訓規則。
- 第1部分:在隱藏節點n和輸出節點j之間權係數改變,以下所示:
alpha *s’(a(p,n))*(t(p,n) – y(p,n)) * X(p,n,j)
- 第 2 部分:在輸入節點i和輸出節點n之間權係數改變,以下所示:
alpha *s’(a(p,n)) * sum(d(j) * W(n,j)) * X(p,i,n)
這裏每一個從n接收輸入的輸出節點j都不一樣。關於反向傳播算法的基本狀況大體如此。
一般把第 1部分稱爲正向傳播,把第2部分稱爲反向傳播。反向傳播的名字由此而來。
四、最速降低法與其改進
最速降低法的基本思想是:要找到某函數的最小值,最好的辦法是沿函數的梯度方向探尋,若是梯度記爲d,那麼迭代公式可寫爲w=w-alpha*d,其中alpha可理解爲咱們前面提到的學習速率。
最速降低法有着收斂速度慢(由於每次搜索與前一次均正交,收斂是鋸齒形的),容易陷入局部最小值等缺點,因此他的改進辦法也有很多,最多見的是增長動量項與學習率可變。
增長衝量項(Momentum)
- 修改權值更新法則,使第n次迭代時的權值的更新部分地依賴於發生在第n‐1次迭代時的更新
Delta(w)(n)=-alpha*(1-mc)*Delta(w)(n) mc*Delta(w)(n-1)
- 右側第一項就是權值更新法則,第二項被稱爲衝量項
- 梯度降低的搜索軌跡就像一個球沿偏差曲面滾下,衝量使球從一次迭代到下一次迭代時以一樣的方向滾動
- 衝量有時會使這個球滾過偏差曲面的局部極小值或平坦區域
- 衝量也具備在梯度不變的區域逐漸增大搜索步長的效果,從而加快收斂。
改變學習率
- 當偏差減少趨近目標時,說明修正方向是正確的,能夠增長學習率;當偏差增長超過一個範圍時,說明修改不正確,須要下降學習率。
五、BP神經網絡的實現
(1)數據讀入,這裏咱們仍是使用R的內置數據——鳶尾花數據,因爲神經網絡本質是2分類的,因此咱們將鳶尾花數據也分爲兩類(將前兩類均看作第2類),按照特徵:花瓣長度與寬度作分類。
(2)劃分訓練數據與測試數據
(3)初始化BP網絡,採用包含一個隱含層的神經網絡,訓練方法使用包含動量的最速降低法,傳遞函數使用sigmoid函數。
(4)輸入樣本,對樣本進行歸一化,計算偏差,求解偏差平方和
(5)判斷是否收斂
(6)根據偏差調整權值。權值根據如下公式進行調整:
Delta(w)= alpha *s’(a(p,n))*(t(p,n) – y(p,n)) * X(p,n,j)
其中,alpha爲學習率,s’(a(p,n))*(t(p,n)- y(p,n))爲局部梯度。此外,因爲使用了有動量因子的最速降低法,除第一次外,後續改變量應爲:
Delta(w)(n)=-alpha*(1-mc)*Delta(w)(n) mc*Delta(w)(n-1)
(7)測試,輸出分類正確率。
完整的R代碼:
[plain] view plaincopyprint?
- iris1<-as.matrix(iris[,3:4])
- iris1<-cbind(iris1,c(rep(1,100),rep(0,50)))
- set.seed(5)
- n<-length(iris1[,1])
- samp<-sample(1:n,n/5)
- traind<-iris1[-samp,c(1,2)]
- train1<-iris1[-samp,3]
- testd<-iris1[samp,c(1,2)]
- test1<-iris1[samp,3]
-
- set.seed(1)
- ntrainnum<-120
- nsampdim<-2
-
- net.nin<-2
- net.nhidden<-3
- net.nout<-1
- w<-2*matrix(runif(net.nhidden*net.nin)-0.5,net.nhidden,net.nin)
- b<-2*(runif(net.nhidden)-0.5)
- net.w1<-cbind(w,b)
- W<-2*matrix(runif(net.nhidden*net.nout)-0.5,net.nout,net.nhidden)
- B<-2*(runif(net.nout)-0.5)
- net.w2<-cbind(W,B)
-
- traind_s<-traind
- traind_s[,1]<-traind[,1]-mean(traind[,1])
- traind_s[,2]<-traind[,2]-mean(traind[,2])
- traind_s[,1]<-traind_s[,1]/sd(traind_s[,1])
- traind_s[,2]<-traind_s[,2]/sd(traind_s[,2])
-
- sampinex<-rbind(t(traind_s),rep(1,ntrainnum))
- expectedout<-train1
-
- eps<-0.01
- a<-0.3
- mc<-0.8
- maxiter<-2000
- iter<-0
-
- errrec<-rep(0,maxiter)
- outrec<-matrix(rep(0,ntrainnum*maxiter),ntrainnum,maxiter)
-
- sigmoid<-function(x){
- y<-1/(1 exp(-x))
- return(y)
- }
-
- for(i in 1:maxiter){
- hid_input<-net.w1%*%sampinex;
- hid_out<-sigmoid(hid_input);
- out_input1<-rbind(hid_out,rep(1,ntrainnum));
- out_input2<-net.w2%*%out_input1;
- out_out<-sigmoid(out_input2);
- outrec[,i]<-t(out_out);
- err<-expectedout-out_out;
- sse<-sum(err^2);
- errrec[i]<-sse;
- iter<-iter 1;
- if(sse<=eps)
- break
-
- Delta<-err*sigmoid(out_out)*(1-sigmoid(out_out))
- delta<-(matrix(net.w2[,1:(length(net.w2[1,])-1)]))%*%Delta*sigmoid(hid_out)*(1-sigmoid(hid_out));
-
- dWex<-Delta%*%t(out_input1)
- dwex<-delta%*%t(sampinex)
-
- if(i==1){
- net.w2<-net.w2 a*dWex;
- net.w1<-net.w1 a*dwex;
- }
- else{
- net.w2<-net.w2 (1-mc)*a*dWex mc*dWexold;
- net.w1<-net.w1 (1-mc)*a*dwex mc*dwexold;
- }
-
- dWexold<-dWex;
- dwexold<-dwex;
- }
-
-
- testd_s<-testd
- testd_s[,1]<-testd[,1]-mean(testd[,1])
- testd_s[,2]<-testd[,2]-mean(testd[,2])
- testd_s[,1]<-testd_s[,1]/sd(testd_s[,1])
- testd_s[,2]<-testd_s[,2]/sd(testd_s[,2])
-
- inex<-rbind(t(testd_s),rep(1,150-ntrainnum))
- hid_input<-net.w1%*%inex
- hid_out<-sigmoid(hid_input)
- out_input1<-rbind(hid_out,rep(1,150-ntrainnum))
- out_input2<-net.w2%*%out_input1
- out_out<-sigmoid(out_input2)
- out_out1<-out_out
-
- out_out1[out_out<0.5]<-0
- out_out1[out_out>=0.5]<-1
-
- rate<-sum(out_out1==test1)/length(test1)
分類正確率爲:0.9333333,是一個不錯的學習器。這裏須要注意的是動量因子mc的選取,mc不能太小,不然容易陷入局部最小而出不去,在本例中,若是mc=0.5,分類正確率僅爲:0.5333333,學習效果很不理想。
4、R中的神經網絡函數
單層的前向神經網絡模型在包nnet中的nnet函數,其調用格式爲:
nnet(formula,data, weights, size, Wts, linout = F, entropy = F,
softmax = F, skip = F, rang = 0.7,decay = 0, maxit = 100,
trace = T)
參數說明:
size, 隱層結點數;
decay, 代表權值是遞減的(能夠防止過擬合);
linout, 線性輸出單元開關;
skip,是否容許跳過隱層;
maxit, 最大迭代次數;
Hess, 是否輸出Hessian值
適用於神經網絡的方法有predict,print和summary等,nnetHess函數用來計算在考慮了權重參數下的Hessian矩陣,而且檢驗是不是局部最小。
咱們使用nnet函數分析Vehicle數據。隨機選擇半數觀測做爲訓練集,剩下的做爲測試集,構建只有包含3個節點的一個隱藏層的神經網絡。輸入以下程序:
[plain] view plaincopyprint?
- library(nnet); #安裝nnet軟件包
- library(mlbench); #安裝mlbench軟件包
- data(Vehicle); #調入數據
- n=length(Vehicle[,1]); #樣本量
- set.seed(1); #設隨機數種子
- samp=sample(1:n,n/2); #隨機選擇半數觀測做爲訓練集
- b=class.ind(Vehicle$Class); #生成類別的示性函數
- test.cl=function(true,pred){true<-max.col(true);cres=max.col(pred);table(true,cres)};
- a=nnet(Vehicle[samp,-19],b[samp,],size=3,rang=0.1,decay=5e-4,maxit=200); #利用訓練集中前18個變量做爲輸入變量,隱藏層有3個節點,初始隨機權值在[-0.1,0.1],權值是逐漸衰減的。
- test.cl(b[samp,],predict(a,Vehicle[samp,-19]))#給出訓練集分類結果
- test.cl(b[-samp,],predict(a,Vehicle[-samp,-19]));#給出測試集分類結果
- #構建隱藏層包含15個節點的網絡。接着上面的語句輸入以下程序:
- a=nnet(Vehicle[samp,-19],b[samp,],size=15,rang=0.1,decay=5e-4,maxit=10000);
- test.cl(b[samp,],predict(a,Vehicle[samp,-19]));
- test.cl(b[-samp,],predict(a,Vehicle[-samp,-19]));
再看手寫數字案例
最後,咱們回到最開始的那個手寫數字的案例,咱們試着利用支持向量機重作這個案例。(這個案例的描述與數據參見《R語言與機器學習學習筆記(分類算法)(1)》)
因爲nnet包對輸入的維數有必定限制(我也不知道爲何,可能在權值計算的時候出現了一些bug,反正將支持向量機那一節的代碼平行的移過來是會報錯的)。咱們這裏採用手寫數字識別技術中經常使用的辦法處理這個案例:計算數字的特徵。選擇數字特徵的辦法有許多種,你隨便百度一篇論文都有敘述。咱們這裏採用結構特徵與統計特徵結合的辦法計算圖像的特徵。
咱們這裏採用的統計特徵與上圖有一點的不一樣(結構特徵一致),咱們是將圖片分爲16塊(4*4),統計每一個小方塊中點的個數,這樣咱們就有25維的特徵向量了。爲了保證結果的可比性,咱們也報告支持向量機的分類結果。
運行下列代碼:
[plain] view plaincopyprint?
- setwd(「D:/R/data/digits/trainingDigits」)
- names<-list.files(「D:/R/data/digits/trainingDigits」)
- data<-paste(「train」,1:1934,sep=」」)
- for(i in 1:length(names))
- assign(data[i],as.matrix(read.fwf(names[i],widths=rep(1,32))))
- library(nnet)
- label<-factor(rep(0:9,c(189,198,195,199,186,187,195,201,180,204)))
-
- feature<-matrix(rep(0,length(names)*25),length(names),25)
- for(i in 1:length(names)){
- feature[i,1]<-sum(get(data[i])[,16])
- feature[i,2]<-sum(get(data[i])[,8])
- feature[i,3]<-sum(get(data[i])[,24])
- feature[i,4]<-sum(get(data[i])[16,])
- feature[i,5]<-sum(get(data[i])[11,])
- feature[i,6]<-sum(get(data[i])[21,])
- feature[i,7]<-sum(diag(get(data[i])))
- feature[i,8]<-sum(diag(get(data[i])[,32:1]))
- feature[i,9]<-sum((get(data[i])[17:32,17:32]))
- feature[i,10]<-sum((get(data[i])[1:8,1:8]))
- feature[i,11]<-sum((get(data[i])[9:16,1:8]))
- feature[i,12]<-sum((get(data[i])[17:24,1:8]))
- feature[i,13]<-sum((get(data[i])[25:32,1:8]))
- feature[i,14]<-sum((get(data[i])[1:8,9:16]))
- feature[i,15]<-sum((get(data[i])[9:16,9:16]))
- feature[i,16]<-sum((get(data[i])[17:24,9:16]))
- feature[i,17]<-sum((get(data[i])[25:32,9:16]))
- feature[i,18]<-sum((get(data[i])[1:8,17:24]))
- feature[i,19]<-sum((get(data[i])[9:16,17:24]))
- feature[i,20]<-sum((get(data[i])[17:24,17:24]))
- feature[i,21]<-sum((get(data[i])[25:32,17:24]))
- feature[i,22]<-sum((get(data[i])[1:8,25:32]))
- feature[i,23]<-sum((get(data[i])[9:16,25:32]))
- feature[i,24]<-sum((get(data[i])[17:24,25:32]))
- feature[i,25]<-sum((get(data[i])[25:32,25:32]))
- }
- data1 <- data.frame(feature,label)
- m1<-nnet(label~.,data=data1,size=25,maxit = 2000,decay = 5e-6, rang = 0.1)
- pred<-predict(m1,data1,type=」class」)
- table(pred,label)
- sum(diag(table(pred,label)))/length(names)
-
- library(「e1071″)
- m <- svm(feature,label,cross=10,type=」C-classification」)
- m
- summary(m)
- pred<-fitted(m)
- table(pred,label)
-
- setwd(「D:/R/data/digits/testDigits」)
- name<-list.files(「D:/R/data/digits/testDigits」)
- data1<-paste(「train」,1:1934,sep=」」)
- for(i in 1:length(name))
- assign(data1[i],as.matrix(read.fwf(name[i],widths=rep(1,32))))
-
- feature<-matrix(rep(0,length(name)*25),length(name),25)
- for(i in 1:length(name)){
- feature[i,1]<-sum(get(data1[i])[,16])
- feature[i,2]<-sum(get(data1[i])[,8])
- feature[i,3]<-sum(get(data1[i])[,24])
- feature[i,4]<-sum(get(data1[i])[16,])
- feature[i,5]<-sum(get(data1[i])[11,])
- feature[i,6]<-sum(get(data1[i])[21,])
- feature[i,7]<-sum(diag(get(data1[i])))
- feature[i,8]<-sum(diag(get(data1[i])[,32:1]))
- feature[i,9]<-sum((get(data1[i])[17:32,17:32]))
- feature[i,10]<-sum((get(data1[i])[1:8,1:8]))
- feature[i,11]<-sum((get(data1[i])[9:16,1:8]))
- feature[i,12]<-sum((get(data1[i])[17:24,1:8]))
- feature[i,13]<-sum((get(data1[i])[25:32,1:8]))
- feature[i,14]<-sum((get(data1[i])[1:8,9:16]))
- feature[i,15]<-sum((get(data1[i])[9:16,9:16]))
- feature[i,16]<-sum((get(data1[i])[17:24,9:16]))
- feature[i,17]<-sum((get(data1[i])[25:32,9:16]))
- feature[i,18]<-sum((get(data1[i])[1:8,17:24]))
- feature[i,19]<-sum((get(data1[i])[9:16,17:24]))
- feature[i,20]<-sum((get(data1[i])[17:24,17:24]))
- feature[i,21]<-sum((get(data1[i])[25:32,17:24]))
- feature[i,22]<-sum((get(data1[i])[1:8,25:32]))
- feature[i,23]<-sum((get(data1[i])[9:16,25:32]))
- feature[i,24]<-sum((get(data1[i])[17:24,25:32]))
- feature[i,25]<-sum((get(data1[i])[25:32,25:32]))
- }
- labeltest<-factor(rep(0:9,c(87,97,92,85,114,108,87,96,91,89)))
- data2<-data.frame(feature,labeltest)
- pred1<-predict(m1,data2,type=」class」)
- table(pred1,labeltest)
- sum(diag(table(pred1,labeltest)))/length(name)
-
- pred<-predict(m,feature)
- table(pred,labeltest)
- sum(diag(table(pred,labeltest)))/length(name)
經整理,咱們有以下輸出結果:
能夠看到,神經網絡與支持向量機仍是有必定的可比性,但支持向量機的結果仍是要優於神經網絡的。
這裏咱們神經網絡取25個節點(隱藏層)彷佛出現了過擬合的現象(雖然還不算過於嚴重)咱們應該減小節點個數獲得更佳的預測結果。
關於節點的選擇是個經驗活,咱們沒有必定的規則。能夠多試幾回,結合訓練集正確率與測試集正確率綜合研判,可是構造神經網絡的代價是高昂的,因此有一個不太壞的結果也就能夠中止了。(其餘參數的選擇一樣如此,可是不如size那麼重要)
特徵的選取對於識別問題來講至關的重要,也許主成分在選擇特徵時做用會比咱們這樣的選擇更好,可是代價也更高,還有咱們應該如何選擇主成分,怎麼選擇(選擇哪張圖的主成分)都是須要考慮的。
5、神經網絡仍是支持向量機
從上面的敘述能夠看出,神經網絡與咱們前面說的支持向量機有很多類似的地方,那麼咱們應該選擇誰呢?下面是兩種方法的一個簡明對比:
- – SVM的理論基礎比NN更堅實,更像一門嚴謹的「科學」(三要素:問題的表示、問題的解決、證實)
- – SVM ——嚴格的數學推理
–ANN ——強烈依賴於工程技巧
- –推廣能力取決於「經驗風險值」和「置信範圍值」,ANN不能控制二者中的任何一個。
- –ANN設計者用高超的工程技巧彌補了數學上的缺陷——設計特殊的結構,利用啓發式算法,有時能獲得出人意料的好結果。
正如費曼指出的那樣「咱們必須從一開始就澄清一個觀點,就是若是某事不是科學,它並不必定很差。好比說,愛情就不是科學。所以,若是咱們說某事不是科學,並非說它有什麼不對,而只是說它不是科學。」與SVM相比,ANN不像一門科學,更像一門工程技巧,但並不意味着它就必定就很差。