




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
機器學習入門——淺談神經網路〔摘自百度貼吧〕先從回歸(Regression)問題說起。我在本吧已經看到不少人提到如果想實現強AI,就必須讓機器學會觀察并總結規律的言論。具體地說,要讓機器觀察什么是圓的,什么是方的,區分各種顏色和形狀,然后根據這些特征對某種事物進行分類或預測。其實這就是回歸問題。如何解決回歸問題?我們用眼睛看到某樣東西,可以一下子看出它的一些根本特征。可是計算機呢?它看到的只是一堆數字而已,因此要讓機器從事物的特征中找到規律,其實是一個如何在數字中找規律的問題。例:假設有一串數字,前六個是1、3、5、7,9,11,請問第七個是幾?你一眼能看出來,是13。對,這串數字之間有明顯的數學規律,都是奇數,而且是按順序排列的。那么這個呢?前六個是0.14、0.57、1.29、2.29、3.57、5.14,請問第七個是幾?這個就不那么容易看出來了吧!我們把這幾個數字在坐標軸上標識一下,可以看到如下列圖形:用曲線連接這幾個點,延著曲線的走勢,可以推算出第七個數字——7。由此可見,回歸問題其實是個曲線擬合(CurveFitting)問題。那么究竟該如何擬合?機器不可能像你一樣,憑感覺隨手畫一下就擬合了,它必須要通過某種算法才行。假設有一堆按一定規律分布的樣本點,下面我以擬合直線為例,說說這種算法的原理。其實很簡單,先隨意畫一條直線,然后不斷旋轉它。每轉一下,就分別計算一下每個樣本點和直線上對應點的距離(誤差),求出所有點的誤差之和。這樣不斷旋轉,當誤差之和到達最小時,停止旋轉。說得再復雜點,在旋轉的過程中,還要不斷平移這條直線,這樣不斷調整,直到誤差最小時為止。這種方法就是著名的梯度下降法(GradientDescent)。為什么是梯度下降呢?在旋轉的過程中,當誤差越來越小時,旋轉或移動的量也跟著逐漸變小,當誤差小于某個很小的數,例如0.0001時,我們就可以收工(收斂,Converge)了。啰嗦一句,如果隨便轉,轉過頭了再往回轉,那就不是梯度下降法。我們知道,直線的公式是y=kx+b,k代表斜率,b代表偏移值(y軸上的截距)。也就是說,k可以控制直線的旋轉角度,b可以控制直線的移動。強調一下,梯度下降法的實質是不斷的修改k、b這兩個參數值,使最終的誤差到達最小。求誤差時使用累加(直線點-樣本點)^2,這樣比直接求差距累加(直線點-樣本點)的效果要好。這種利用最小化誤差的平方和來解決回歸問題的方法叫最小二乘法(LeastSquareMethod)。問題到此使似乎就已經解決了,可是我們需要一種適應于各種曲線擬合的方法,所以還需要繼續深入研究。我們根據擬合直線不斷旋轉的角度(斜率)和擬合的誤差畫一條函數曲線,如圖:從圖中可以看出,誤差的函數曲線是個二次曲線,凸函數(下凸,Convex),像個碗的形狀,最小值位于碗的最下端。如果在曲線的最底端畫一條切線,那么這條切線一定是水平的,在圖中可以把橫坐標軸看成是這條切線。如果能求出曲線上每個點的切線,就能得到切線位于水平狀態時,即切線斜率等于0時的坐標值,這個坐標值就是我們要求的誤差最小值和最終的擬合直線的最終斜率。這樣,梯度下降的問題集中到了切線的旋轉上。切線旋轉至水平時,切線斜率=0,誤差降至最小值。切線每次旋轉的幅度叫做學習率(LearningRate),加大學習率會加快擬合速度,但是如果調得太大會導致切線旋轉過度而無法收斂。注意:對于凹凸不平的誤差函數曲線,梯度下降時有可能陷入局部最優解。下列圖的曲線中有兩個坑,切線有可能在第一個坑的最底部趨于水平。微分就是專門求曲線切線的工具,求出的切線斜率叫做導數(Derivative),用dy/dx或f'(x)表示。擴展到多變量的應用,如果要同時求多個曲線的切線,那么其中某個切線的斜率就叫偏導數(PartialDerivative),用?y/?x表示,?讀“偏(partial)”。由于實際應用中,我們一般都是對多變量進行處理,我在后面提到的導數也都是指偏導數。以上是線性回歸(LinearRegression)的根本內容,以此方法為根底,把直線公式改為曲線公式,還可以擴展出二次回歸、三次回歸、多項式回歸等多種曲線回歸。下列圖是Excel的回歸分析功能。在多數情況下,曲線回歸會比直線回歸更精確,但它也增加了擬合的復雜程度。直線方程y=kx+b改為二次曲線方程y=ax^2+bx+c時,參數(Parameter)由2個(分別是k、b)變為3個(分別是a、b、c),特征(Feature)由1個(x)變為2個(x^2和x)。三次曲線和復雜的多項式回歸會增加更多的參數和特征。前面講的是總結一串數字的規律,現實生活中我們往往要根據多個特征(多串數字)來分析一件事情,每個原始特征我們都看作是一個維度(Dimension)。例如一個學生的學習成績好壞要根據語文、數學、英語等多門課程的分數來綜合判斷,這里每門課程都是一個維度。當使用二次曲線和多變量(多維)擬合的情況下,特征的數量會劇增,特征數=維度^2/2這個公式可以大概計算出特征增加的情況,例如一個100維的數據,二次多項式擬合后,特征會增加到100*100/2=5000個。下面是一張50*50像素的灰度圖片,如果用二次多項式擬合的話,它有多少個特征呢?——大約有3百萬!它的維度是50*50=2500,特征數=2500*2500/2=3,125,000。如果是彩色圖片,維度會增加到原來的3倍,那么特征數將增加到接近3千萬了!這么小的一張圖片,就有這么巨大的特征量,可以想像一下我們的數碼相機拍下來的照片會有多大的特征量!而我們要做的是從十萬乃至億萬張這樣的圖片中找規律,這可能嗎?很顯然,前面的那些回歸方法已經不夠用了,我們急需找到一種數學模型,能夠在此根底上不斷減少特征,降低維度。于是,“人工神經網絡(ANN,ArtificialNeuralNetwork)”就在這樣苛刻的條件下粉墨〔閃亮〕登場了,神經科學的研究成果為機器學習領域開辟了廣闊的道路。考前須知:如果是a,b,c三個原始特征,那么轉換為2次多項式為a^2+a*b+a*c+b^2+b*c+c^2,一共6項(6個特征);如果是a,b,c,d四個原始特征,那么轉換為a^2+a*b+a*c+a*d+b^2+b*c+b*d+c^2+b*c+d^2,共10個特征,當原始特征數越來越大時,轉換的特征數會趨于"原始特征數的平方/2"。,可以用O(n^2)來表示。神經元有一種假說:“智能來源于單一的算法(OneLearningAlgorithm)”。如果這一假說成立,那么利用單一的算法(神經網絡)處理世界上千變萬化的問題就成為可能。我們不必對萬事萬物進行編程,只需采用以不變應萬變的策略即可。有越來越多的證據證明這種假說,例如人類大腦發育初期,每一局部的職責分工是不確定的,也就是說,人腦中負責處理聲音的局部其實也可以處理視覺影像。下列圖是單個神經元(Neuron),或者說一個腦細胞的生理結構:下面是單個神經元的數學模型,可以看出它是生理結構的簡化版,模仿的還挺像:解釋一下:+1代表偏移值(偏置項,BiasUnits);X1,X2,X2代表初始特征;w0,w1,w2,w3代表權重(Weight),即參數,是特征的縮放倍數;特征經過縮放和偏移后全部累加起來,此后還要經過一次激活運算然后再輸出。激活函數有很多種,后面將會詳細說明。舉例說明:55/5=11X1*w1+X2*w2+...+Xn*wn這種計算方法稱為加權求和(WeightedSum)法,此方法在線性代數里極為常用。加權求和的標準數學符號是,不過為了簡化,我在教程里使用女巫布萊爾的符號表示,剛好是一個加號和一個乘號的組合。這個數學模型有什么意義呢?下面我對照前面那個y=kx+b直線擬合的例子來說明一下。這時我們把激活函數改為Purelin(45度直線),Purelin就是y=x,代表保持原來的值不變。這樣輸出值就成了Y直線點=b+X直線點*k,即y=kx+b。看到了吧,只是換了個馬甲而已,還認的出來嗎?下一步,對于每個點都進行這種運算,利用Y直線點和Y樣本點計算誤差,把誤差累加起來,不斷地更新b、k的值,由此不斷地移動和旋轉直線,直到誤差變得很小時停住(收斂)。這個過程完全就是前面講過的梯度下降的線性回歸。一般直線擬合的精確度要比曲線差很多,那么使用神經網絡我們將如何使用曲線擬合?答案是使用非線性的激活函數即可,最常見的激活函數是Sigmoid(S形曲線),Sigmoid有時也稱為邏輯回歸(LogisticRegression),簡稱logsig。logsig曲線的公式如下:還有一種S形曲線也很常見到,叫雙曲正切函數(tanh),或稱tansig,可以替代logsig。下面是它們的函數圖形,從圖中可以看出logsig的數值范圍是0~1,而tansig的數值范圍是-1~1。自然常數e公式中的e叫自然常數,也叫歐拉數,e=2.71828...。e是個很神秘的數字,它是“自然律”的精髓,其中暗藏著自然增長的奧秘,它的圖形表達是旋渦形的螺線。融入了e的螺旋線,在不斷循環縮放的過程中,可以完全保持它原有的彎曲度不變,就像一個無底的黑洞,吸進再多的東西也可以保持原來的形狀。這一點至關重要!它可以讓我們的數據在經歷了多重的Sigmoid變換后仍維持原先的比例關系。e是怎么來的?e=1+1/1!+1/2!+1/3!+1/4!+1/5!+1/6!+1/7!+...=1+1+1/2+1/6+1/24+1/120+...≈2.71828(!代表階乘,3!=1*2*3=6)再舉個通俗點的例子:從前有個財主,他特別貪財,喜歡放債。放出去的債年利率為100%,也就是說借1塊錢,一年后要還給他2塊錢。有一天,他想了個壞主意,要一年算兩次利息,上半年50%,下半年50%,這樣上半年就有1塊5了,下半年按1塊5的50%來算,就有1.5/2=0.75元,加起來一年是:上半年1.5+下半年0.75=2.25元。用公式描述,就是(1+50%)(1+50%)=(1+1/2)^2=2.25元。可是他又想,如果按季度算,一年算4次,那豈不是更賺?那就是(1+1/4)^4=2.44141,果然更多了。他很快樂,于是又想,那干脆每天都算吧,這樣一年下來就是(1+1/365)^365=2.71457。然后他還想每秒都算,結果他的管家把他拉住了,說要再算下去別人都會瘋掉了。不過財主還是不死心,算了很多年終于算出來了,當x趨于無限大的時候,e=(1+1/x)^x≈2.71828,結果他成了數學家。e在微積分領域非常重要,e^x的導數依然是e^x,自己的導數恰好是它自己,這種巧合在實數范圍內絕無僅有。一些不同的稱呼:e^x和e^-x的圖形是對稱的;ln(x)是e^x的逆函數,它們呈45度對稱。神經網絡好了,前面花了不少篇幅來介紹激活函數中那個暗藏玄機的e,下面可以正式介紹神經元的網絡形式了。下列圖是幾種比擬常見的網絡形式:-左邊藍色的圓圈叫“輸入層”,中間橙色的不管有多少層都叫“隱藏層”,右邊綠色的是“輸出層”。-每個圓圈,都代表一個神經元,也叫節點(Node)。-輸出層可以有多個節點,多節點輸出常常用于分類問題。-理論證明,任何多層網絡可以用三層網絡近似地表示。-一般憑經驗來確定隱藏層到底應該有多少個節點,在測試的過程中也可以不斷調整節點數以取得最正確效果。計算方法:-雖然圖中未標識,但必須注意每一個箭頭指向的連線上,都要有一個權重(縮放)值。-輸入層的每個節點,都要與的隱藏層每個節點做點對點的計算,計算的方法是加權求和+激活,前面已經介紹過了。(圖中的紅色箭頭指示出某個節點的運算關系)-利用隱藏層計算出的每個值,再用相同的方法,和輸出層進行計算。-隱藏層用都是用Sigmoid作激活函數,而輸出層用的是Purelin。這是因為Purelin可以保持之前任意范圍的數值縮放,便于和樣本值作比擬,而Sigmoid的數值范圍只能在0~1之間。-起初輸入層的數值通過網絡計算分別傳播到隱藏層,再以相同的方式傳播到輸出層,最終的輸出值和樣本值作比擬,計算出誤差,這個過程叫前向傳播(ForwardPropagation)。前面講過,使用梯度下降的方法,要不斷的修改k、b兩個參數值,使最終的誤差到達最小。神經網絡可不只k、b兩個參數,事實上,網絡的每條連接線上都有一個權重參數,如何有效的修改這些參數,使誤差最小化,成為一個很棘手的問題。從人工神經網絡誕生的60年代,人們就一直在不斷嘗試各種方法來解決這個問題。直到80年代,誤差反向傳播算法(BP算法)的提出,才提供了真正有效的解決方案,使神經網絡的研究絕處逢生。BP算法是一種計算偏導數的有效方法,它的根本原理是:利用前向傳播最后輸出的結果來計算誤差的偏導數,再用這個偏導數和前面的隱藏層進行加權求和,如此一層一層的向后傳下去,直到輸入層(不計算輸入層),最后利用每個節點求出的偏導數來更新權重。為了便于理解,后面我一律用“殘差(errorterm)”這個詞來表示誤差的偏導數。輸出層→隱藏層:殘差=-(輸出值-樣本值)*激活函數的導數隱藏層→隱藏層:殘差=(右層每個節點的殘差加權求和)*激活函數的導數如果輸出層用Purelin作激活函數,Purelin的導數是1,輸出層→隱藏層:殘差=-(輸出值-樣本值)如果用Sigmoid(logsig)作激活函數,那么:Sigmoid導數=Sigmoid*(1-Sigmoid)輸出層→隱藏層:殘差=-(Sigmoid輸出值-樣本值)*Sigmoid*(1-Sigmoid)=-(輸出值-樣本值)*輸出值*(1-輸出值)隱藏層→隱藏層:殘差=(右層每個節點的殘差加權求和)*當前節點的Sigmoid*(1-當前節點的Sigmoid)如果用tansig作激活函數,那么:tansig導數=1-tansig^2殘差全部計算好后,就可以更新權重了:輸入層:權重增加=輸入值*右層對應節點的殘差*學習率隱藏層:權重增加=當前節點的Sigmoid*右層對應節點的殘差*學習率偏移值的權重增加=右層對應節點的殘差*學習率學習率前面介紹過,學習率是一個預先設置好的參數,用于控制每次更新的幅度。此后,對全部數據都反復進行這樣的計算,直到輸出的誤差到達一個很小的值為止。以上介紹的是目前最常見的神經網絡類型,稱為前饋神經網絡(FeedForwardNeuralNetwork),由于它一般是要向后傳遞誤差的,所以也叫BP神經網絡(BackPropagationNeuralNetwork)。BP神經網絡的特點和局限:-BP神經網絡可以用作分類、聚類、預測等。需要有一定量的歷史數據,通過歷史數據的訓練,網絡可以學習到數據中隱含的知識。在你的問題中,首先要找到某些問題的一些特征,以及對應的評價數據,用這些數據來訓練神經網絡。-BP神經網絡主要是在實踐的根底上逐步完善起來的系統,并不完全是建立在仿生學上的。從這個角度講,實用性>生理相似性。-BP神經網絡中的某些算法,例如如何選擇初始值、如何確定隱藏層的節點個數、使用何種激活函數等問題,并沒有確鑿的理論依據,只有一些根據實踐經驗總結出的有效方法或經驗公式。-BP神經網絡雖然是一種非常有效的計算方法,但它也以計算超復雜、計算速度超慢、容易陷入局部最優解等多項弱點著稱,因此人們提出了大量有效的改良方案,一些新的神經網絡形式也層出不窮。文字的公式看上去有點繞,下面我發一個詳細的計算過程圖。參考這個:我做了整理這里介紹的是計算完一條記錄,就馬上更新權重,以后每計算完一條都即時更新權重。實際上批量更新的效果會更好,方法是在不更新權重的情況下,把記錄集的每條記錄都算過一遍,把要更新的增值全部累加起來求平均值,然后利用這個平均值來更新一次權重,然后利用更新后的權重進行下一輪的計算,這種方法叫批量梯度下降(BatchGradientDescent)。推薦的入門級學習資源:AndrewNg的《機器學習》公開課:Coursera公開課筆記中文版〔神經網絡的表示〕:://52opencourse/139/coursera公開課筆記-斯坦福大學機器學習第八課-神經網絡的表示-neural-networks-representationCoursera公開課視頻〔神經網絡的學習〕:://52opencourse/289/coursera公開課視頻-斯坦福大學機器學習第九課-神經網絡的學習-neural-networks-learning斯坦福深度學習中文版:教程關于Matlab的入門教程,參看這個帖子:例1:我們都知道,面積=長*寬,假設我們有一組數測量據如下:我們利用這組數據來訓練神經網絡。〔在Matlab中輸入以下的代碼,按回車即可執行〕p=[25;36;122;16;92;812;47;79]';%特征數據X1,X2t=[101824618962863];%樣本值net=newff(p,t,20);%創立一個BP神經網絡ff=FeedForwardnet=train(net,p,t);%用p,t數據來訓練這個網絡出現如下的信息,根據藍線的顯示,可以看出最后收斂時,誤差已小于10^-20。你也許會問,計算機難道這樣就能學會乘法規那么嗎?不用背乘法口訣表了?先隨便選幾個數字,試試看:s=[37;69;45;57]';%準備一組新的數據用于測試y=sim(net,s)%模擬一下,看看效果%結果是:25.102961.588229.584837.5879看到了吧,預測結果和實際結果還是有差距的。不過從中也能看出,預測的數據不是瞎蒙的,至少還是有那么一點靠譜。如果訓練集中的數據再多一些的話,預測的準確率還會大幅度提高。你測試的結果也許和我的不同,這是因為初始化的權重參數是隨機的,可能會陷入局部最優解,所以有時預測的結果會很不理想。例2:下面測試一下擬合正弦曲線,這次我們隨機生成一些點來做樣本。p=rand(1,50)*7%生成1行50個0~7之間的隨機數t=sin(p)%計算正弦曲線s=[0:0.1:7];%生成0~7的一組數據,間隔0.1,用于模擬測試plot(p,t,'x')%畫散點圖net=newff(p,t,20);%創立神經網絡net=train(net,p,t);%開始訓練y=sim(net,s);%模擬plot(s,y,'x')%畫散點圖從圖中看出,這次的預測結果顯然是不理想的,我們需要設置一些參數來調整。下面的設置是一種標準的批量梯度下降法的配置。%創立3層神經網絡[隱藏層10個節點->logsig,輸出層1個節點->purelin]traingd代表梯度下降法net=newff(p,t,10,{'logsig''purelin'},'traingd');%10不能寫成[101]%設置訓練參數net.trainparam.show=50;%顯示訓練結果(訓練50次顯示一次)net.trainparam.epochs=500;%總訓練次數net.trainparam.goal=0.01;%訓練目標:誤差<0.01net.trainParam.lr=0.01;%學習率(learningrate)net=train(net,p,t);%開始訓練注意:newff的第三個參數10不能寫成[101],否那么就是4層網絡,兩個隱藏層,分別是10個和1個節點。這個很容易弄錯。〔輸出層的節點數程序會自動根據t的維度自動判斷,所以不用指定〕y=sim(net,s);%模擬plot(s,y,'x')%畫散點圖這時的效果顯然更差了。把精度調高一點看看。訓練次數加到9999,誤差<0.001;學習率調到0.06,希望能加快點速度。%創立2層神經網絡[隱藏層10個節點->logsig,輸出層1個節點->purelin]traingd代表梯度下降法net=newff(p,t,10,{'logsig''purelin'},'traingd');%設置訓練參數net.trainparam.show=50;%每間隔50次顯示一次訓練結果net.trainparam.epochs=9999;%總訓練次數net.trainparam.goal=0.001;%訓練目標:誤差<0.001net.trainParam.lr=0.06;%學習率(learningrate)net=train(net,p,t);%開始訓練標準的批量梯度下降法的速度確實夠慢,這次計算花了一分多鐘。y=sim(net,s);%模擬plot(s,y,'x')%畫散點圖效果比上次稍好一點。不過這條曲線顯得坑坑洼洼的很難看,這是一種過擬合(Overfitting)現象,與之相反的是欠擬合(Underfitting)。先來解決速度問題,把traingd改為trainlm即可。trainlm使用LM算法,是介于牛頓法和梯度下降法之間的一種非線性優化方法,不但會加快訓練速度,還會減小陷入局部最小值的可能性,是Matlab的默認值。net=newff(p,t,10,{'logsig''purelin'},'trainlm');...后面的代碼不變這個速度比擬驚嘆了,1秒鐘之內完成,只做了6輪計算,效果也好了一些。不過,LM算法也有弱點,它占用的內存非常大,所以沒把其它算法給淘汰掉。下面解決過擬合問題,把隱藏層的節點數目設少一點就行了。net=newff(p,t,3,{'logsig''purelin'},'trainlm');...后面的代碼不變這回終于到達滿意的效果了。(有時會出現局部最優解,可以多試幾次)如果節點數目太少,會出現欠擬合的情況。關于隱藏層的節點個數,一般是要憑感覺去調的。如果訓練集的維數比擬多,調節起來比擬耗時間,這時可以根據經驗公式上下浮動地去調整。下面給出幾個經驗公式供參考:如果把輸出層改為logsig激活會是什么樣子呢?net=newff(p,t,3,{'logsig''logsig'});%創立神經網絡net=train(net,p,t);%開始訓練y=sim(net,s);%模擬plot(s,y,'x')%畫散點圖可以看出,-1~0范圍之間的點都變為0了。使用logsig輸出時要想得到完整數值范圍的效果,必須先對數據進行歸一化才行。歸一化(Normalization),也叫標準化,就是把一堆數字按比例縮放到0~1或-1~1的范圍。雖然用Purelin輸出可以不必歸一化,但歸一化能在一定程度上加快收斂速度,因此被許多教程定為訓練前的必須步驟。公式為:歸一值=(當前值x-最小值min)/(最大值max-最小值min)如果限定了范圍,公式為:y=(ymax-ymin)*(x-xmin)/(xmax-xmin)+ymin;0.1~0.9的范圍:(0.9-0.1)*(x-min)/(max-min)*(0.9-0.1)+0.1把5,2,6,3這四個數歸一化:Matlab的歸一化命令為:mapminmax注:網上的不少教程里用premnmx命令來歸一化,要注意Matlab版本R2007b和R2008b,premnmx在處理單列數據時有bug,Matlab已給出了警告,R2009a版才修正。因此推薦使用mapminmax。mapminmax的輸入輸出值和premnmx是行列顛倒的,使用時要注意代碼中是否添加轉置符號。a=[5,2,6,3];b=mapminmax(a,0,1)%歸一化到0~1之間%b=0.750001.00000.2500可以用下面的代碼歸一化到〔0,1〕a=[5,2,6,3];b=mapminmax(a)+1/2c=mapminmax(a)%歸一化到-1~1之間%c=0.5000-1.00001.0000-0.5000反歸一化(Denormalization)就是按歸一化時的比例復原數值。a=[5,2,6,3];[c,PS]=mapminmax(a);%PS記錄歸一化時的比例mapminmax('reverse',c,PS)%利用PS反歸一化%ans=5263神經網絡的歸一化(0~1范圍)代碼:p=rand(1,50)*7;%特征數據t=sin(p);%樣本值s=[0:0.1:7];%測試數據[pn,ps]=mapminmax(p,0,1);%特征數據歸一化[tn,ts]=mapminmax(t,0,1);%樣本值歸一化sn=mapminmax('apply',s,ps);%測試數據,按ps比例縮放net=newff(pn,tn,[51],{'logsig''logsig'});%創立神經網絡net=train(net,pn,tn);%開始訓練yn=sim(net,sn);%模擬y=mapminmax('reverse',yn,ts);%按ps的比例復原plot(s,y,'x')%畫散點圖神經網絡工具箱還有一個UI圖形操作界面,執行nntool就可以翻開。我覺得不如寫代碼方便,所以不怎么用。我提供一個相關的教程鏈接,有興趣的可以看一下:matlab神經網絡工具箱創立神經網絡:://blog.sina/s/blog_8684880b0100vxtv.html〔新浪替換成sina〕logsigSigmoid函數(S形函數,LogisticFunction)是受統計學模型的啟發而產生的激活函數。基于生物學的神經元激活函數是這樣的:參看:實踐證明了基于統計學的Sigmoid函數激活效果要比基于生物學的模型好,而且計算起來很方便,所以說不能以機器和人的相似度為標準來判斷AI算法的好壞。Sigmoid函數原先是個描述人口增長的數學模型,1838提出,給出的是導數形式(概率密度)。人口增長規律:起初階段大致是指數增長;然后逐漸開始變得飽和,增長變慢;到達成熟時幾乎停止增長;整個過程形如一條S型曲線。導數的形式知道了,那么它的原函數是什么樣子呢?導數求原函數,用統計學的話來講,即根據概率密度函數(PDF)求累積分布函數(CDF),不定積分(IndefiniteIntegral)就是專門用來做這個的工具。根據不定積分的知識可知,由于常數項是可變的,所以存在無數個原函數的可能。讓我們先用圖解法看一下:既然導數是函數曲線的斜率,那么可以把一定數值范圍內的斜率,都畫成一根根的短斜線,組成斜率場(SlopeFields,DirectionFields),然后根據這些斜線的走勢,畫出積分曲線。Matlab可以用quiver命令來畫斜率場。從上圖中可以看出,在y軸的0~1之間是個分水嶺,0和1處的方向趨于水平。下面放大0~1的范圍看看是什么樣子的。看到了吧,我們要的LogisticSigmoid就在這里呢。下面給出符號求解的過程:tansig雙曲正切函數(雙極S形函數,tanh,HyperbolicTangent),讀tanch,18世紀就已經出現了。它的定義是:tanh(x)=sinh(x)/cosh(x),可以由著名的歐拉公式(Euler'sformula)推導出來。用tanh作激活函數,收斂比擬快,效果比Logistic函數還要好。歐拉公式:i是虛數(ImaginaryNumber)單位,它的定義是:(即i^2=-1)題外話:根據上面的公式變換,可以得出史上最美的數學公式:,數學中最神秘的5個符號e、i、π、1和0,全包含在里面了。求tanh的導數:logsig和tansig的關系:matlab神經網絡工具箱創立神經網絡為了看懂師兄的文章中使用的方法,研究了一下神經網絡昨天花了一天的時間查怎么寫程序,但是費了半天勁,不能運行,百度知道里倒是有一個,可以運行的,先貼著做標本%生成訓練樣本集clearall;clc;P=[1100.8072400.21511821.5;1102.8652400.11521212;1102.592400.11242411.5;2200.62400.31231821;22032400.32532111.5;1101.5622400.31531811.5;1100.5472400.3151921.5];01.3183000.11521812];T=[54248162787168380314797;28614639586963782898;86002402710644415328084;230802445102362823335913;602571278927675373541;346159353280762110049;56783172907164548144040];@907117437120368130179];m=max(max(P));n=max(max(T));P=P'/m;T=T'/n;%-------------------------------------------------------------------------%pr(1:9,1)=0;%輸入矢量的取值范圍矩陣pr(1:9,2)=1;bpnet=newff(pr,[124],{'logsig','logsig'},'traingdx','learngdm');%建立BP神經網絡,12個隱層神經元,4個輸出神經元%tranferFcn屬性'logsig'隱層采用Sigmoid傳輸函數%tranferFcn屬性'logsig'輸出層采用Sigmoid傳輸函數%trainFcn屬性'traingdx'自適應調整學習速率附加動量因子梯度下降反向傳播算法訓練函數%learn屬性'learngdm'附加動量因子的梯度下降學習函數
net.trainParam.epochs=1000;%允許最大訓練步數2000步net.trainParam.goal=0.001;%訓練目標最小誤差0.001net.trainParam.show=10;%每間隔100步顯示一次訓練結果net.trainParam.lr=0.05;%學習速率0.05bpnet=train(bpnet,P,T);%-------------------------------------------------------------------------p=[1101.3183000.11521812];p=p'/m;r=sim(bpnet,p);R=r'*n;display(R);運行的結果是出現這樣的界面點擊performance,trainingstate,以及regression分別出現下面的界面再搜索,發現可以通過神經網絡工具箱來創立神經網絡,比擬友好的GUI界面,在輸入命令里面輸入nntool,就可以開始了。點擊import之后就出現下面的具體的設置神經網絡參數的對話界面,
這是輸入輸出數據的對話窗
首先是訓練數據的輸入
然后點擊new,創立一個新的神經網絡network1,并設置其輸入輸出數據,包括名稱,神經網絡的類型以及隱含層的層數和節點數,還有隱含層及輸出層的訓練函數等
點擊view,可以看到這是神經網絡的可視化直觀表達
創立好了一個network之后,點擊open,可以看到一個神經網絡訓練,優化等的對話框,選擇了輸入輸出數據后,點擊train,神經網絡開始訓練,如右下方的圖,可以顯示動態結果
下面三個圖形那么是點擊performance,trainingstate以及regression而出現的
下面就是simulate,輸入的數據是用來檢驗這個網絡的數據,output改一個名字,這樣就把輸出數據和誤差都存放起來了
在主界面上點擊export就能將得到的out結果輸入到matlab中并查看
下列圖就是輸出的兩個outputs結果
關于神經網絡〔matlab〕歸一化的整理BP神經網絡matlab實現實例經過最近一段時間的神經網絡學習,終于能初步使用matlab實現BP網絡仿真試驗。這里特別感謝研友sistor2004的帖子《自己編的BP算法〔工具:matlab〕》和研友wangleisxcc的帖子《用C++,Matlab,Fortran實現的BP算法》前者幫助我對BP算法有了更明確的認識,后者讓我對matlab下BP函數的使用有了初步了解。因為他們發的帖子都沒有加注釋,對我等新手閱讀時有一定困難,所以我把sistor2004發的程序稍加修改后加注了詳細解釋,方便新手閱讀。%嚴格按照BP網絡計算公式來設計的一個matlab程序,對BP網絡進行了優化設計%yyy,即在o(k)計算公式時,當網絡進入平坦區時(<0.0001)學習率加大,
出來后學習率又復原%v(i,j)=v(i,j)+deltv(i,j)+a*dv(i,j);動量項clearallclcinputNums=3;
%輸入層節點outputNums=3;
%輸出層節點hideNums=10;
%隱層節點數maxcount=20000;
%最大迭代次數samplenum=3;
%一個計數器,無意義precision=0.001;
%預設精度yyy=1.3;
%yyy是幫助網絡加速走出平坦區
alpha=0.01;
%學習率設定值a=0.5;
%BP優化算法的一個設定值,對上組訓練的調整值按比例修改error=zeros(1,maxcount+1);%error數組初始化;目的是預分配內存空間errorp=zeros(1,samplenum);%同上v=rand(inputNums,hideNums);
%3*10;v初始化為一個3*10的隨機歸一矩陣;v表輸入層到隱層的權值deltv=zeros(inputNums,hideNums);%3*10;內存空間預分配dv=zeros(inputNums,hideNums);%3*10;
w=rand(hideNums,outputNums);
*3;同Vdeltw=zeros(hideNums,outputNums);*3dw=zeros(hideNums,outputNums);*3samplelist=[0.1323,0.323,-0.132;0.321,0.2434,0.456;-0.6546,-0.3242,0.3255];
%3*3;指定輸入值3*3(實為3個向量)expectlist=[0.5435,0.422,-0.642;0.1,0.562,0.5675;-0.6464,-0.756,0.11];
%3*3;期望輸出值3*3(實為3個向量),有導師的監督學習count=1;while(count<=maxcount)
%結束條件1迭代20000次c=1;while(c<=samplenum)fork=1d(k)=expectlist(c,k);%獲得期望輸出的向量,d(1:3)表示一個期望向量內的值endfori=1:inputNumsx(i)=samplelist(c,i);%獲得輸入的向量〔數據〕,x(1:3)表一個訓練向量end%Forward();forj=1:hideNumsnet=0.0;fori=1:inputNumsnet=net+x(i)*v(i,j);%輸入層到隱層的加權和∑X(i)V(i)
endy(j)=1/(1+exp(-net));
%輸出層處理f(x)=1/(1+exp(-x))單極性sigmiod函數endfork=1net=0.0;forj=1:hideNumsnet=net+y(j)*w(j,k);endifcount>=2&&error(count)-error(count+1)<=0.0001o(k)=1/(1+exp(-net)/yyy);
%平坦區加大學習率elseo(k)=1/(1+exp(-net));
%同上endend%BpError(c)反應/修改;errortmp=0.0;fork=1errortmp=errortmp+(d(k)-o(k))^2;%第一組訓練后的誤差計算enderrorp(c)=0.5*errortmp;%誤差E=∑(d(k)-o(k))^2*1/2%end?ckward();fork=1【轉】BP神經網絡matlab實現實例utputNumsyitao(k)=(d(k)-o(k))*o(k)*(1-o(k));%輸入層誤差偏導endforj=1:hideNumstem=0.0;fork=1【轉】BP神經網絡matlab實現實例utputNumstem=tem+yitao(k)*w(j,k);%為了求隱層偏導,而計算的∑endyitay(j)=tem*y(j)*(1-y(j));%隱層偏導end%調整各層權值forj=1:hideNumsfork=1【轉】BP神經網絡matlab實現實例utputNumsdeltw(j,k)=alpha*yitao(k)*y(j);%權值w的調整量deltw(已乘學習率)w(j,k)=w(j,k)+deltw(j,k)+a*dw(j,k);%權值調整,這里的dw=dletw(t-1),實際是對BP算法的一個dw(j,k)=deltw(j,k);%改良措施--增加動量工程的是提高訓練速度endendfori=1:inputNumsforj=1:hideNumsdeltv(i,j)=alpha*yitay(j)*x(i);%同上deltwv(i,j)=v(i,j)+deltv(i,j)+a*dv(i,j);dv(i,j)=deltv(i,j);endendc=c+1;end%第二個while結束;表示一次BP訓練結束doubletmp;tmp=0.0;fori=1:samplenumtmp=tmp+errorp(i)*errorp(i);%誤差求和endtmp=tmp/c;error(count)=sqrt(tmp);%誤差求均方根,即精度if(error(count)<precision)%另一個結束條件break;endcount=count+1;%訓練次數加1end%第一個while結束error(maxcount+1)=error(maxcount);p=1:count;pp=p/50;plot(pp,error(p),'-');%顯示誤差制作雙縱坐標excel圖常看到雙縱坐標軸的圖,但是一直也沒要用,所以沒有深究。今天要用,才發現不會,百度了一番之后試驗成功,為防止我這腦袋忘記了,還是記下來,很簡單。下表是我需要制作的兩個地方的面積,想做一個每個月份兩個地區面積的比擬圖。如果之間插入散點圖,可以看到如下列圖,由于數據相差比擬大,造成低值的那個地區幾乎值都在最底下,看不出高地變化。鼠標點擊紅色區域,就是我們覺得要編輯的數據,右鍵,如下列圖,點擊設置數據系列格式在系列選項中,可以看到系列選項,選擇次坐標
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年金鹵筒燈項目市場調查研究報告
- 2025年醇基涂料項目市場調查研究報告
- 2025年遙控臺項目市場調查研究報告
- 2025年過濾帆布項目市場調查研究報告
- 2025年特技玩具車項目市場調查研究報告
- 2025年染料溶解劑項目市場調查研究報告
- 2025年填料總成項目市場調查研究報告
- 基于云計算的醫療數據智能分析與決策
- 教育產業投資分析融資模式創新探討
- 教育機構如何通過KPI實現高效數字化管理
- 用表格為網頁布局教學設計
- GB/T 3733.1-1983卡套式端直通管接頭
- GB/T 1689-1998硫化橡膠耐磨性能的測定(用阿克隆磨耗機)
- 病原微生物實驗室生物安全管理手冊
- 上消化道出血病人的觀察與護理-課件
- 光纜測試報告
- 初中物理教育科學八年級下冊第十一章 機械與功《功》教學設計
- 神經病學人衛版習題集題庫
- (統編版小學語文教師)語文新課標新舊對比變化
- 達希納(尼洛替尼)毒副反應及處理
- 中班語言活動《傘》
評論
0/150
提交評論