日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 循环神经网络 >内容正文

循环神经网络

BP神经网络识别手写数字项目解析及matlab实现

發布時間:2024/7/23 循环神经网络 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BP神经网络识别手写数字项目解析及matlab实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

BP神經網絡指傳統的人工神經網絡,相比于卷積神經網絡(CNN)來說要簡單些。
人工神經網絡具有復雜模式和進行聯想、推理記憶的功能, 它是解決某些傳統方法所無法解決的問題的有力工具。目前, 它日益受到重視, 同時其他學科的發展, 為其提供了更大的機會。1986 年, Romelhart 和Mcclelland提出了誤差反向傳播算法(Error Back Propagation Algorithm) ,簡稱BP 算法,由于多層前饋網絡的訓練經常采用誤差反向傳播算法, 人們也把多層前饋網絡稱為BP 網絡。

為了便于閱讀,下面說一下全文的邏輯順序:
1,通俗說下神經網絡的結構和工作原理,簡單好理解,推薦觀看
2,逆向傳播算法的數學推導,如果覺得太復雜可以暫時跳過
3,matlab代碼和圖像庫
?

(1) 大白話講解傳統神經網絡

首先,我們看一下神經網絡的基本單元——單個的神經元:

圖中圓形表示一個神經元,我們知道,一個神經元接收相鄰的神經元傳來的刺激,神經元對這些刺激以不同的權重進行積累,到一定的時候產生自己的刺激將其傳遞給一些與它相鄰的神經元。這樣工作的無數個神經元便構成了人腦對外界的感知。而人腦對世界的學習的機制就是通過調節這些相鄰連接的神經元刺激的權重。
在圖中,周圍神經元傳過來的刺激表示為Y,權重表示為W,圓形表示的神經元得到的刺激是所有刺激按照權重累加起來,即

同時這個神經元作為網絡的一份子,也像其他神經元一樣需要向外傳播刺激信號,但是不是直接把s傳播,而是傳播一個f(s)出去,為什么呢?其實無關大局,我們后面分析。其中f(s)學名稱為“激活函數”,常用的函數如下:

好了,理解到這里如果沒什么問題的話,恭喜你你已經入門了,現在我們把這一個個的基本單元連接起來,就構成我們最終的神經網絡了。傳統的神經網絡結構如下圖所示:

是不是覺得很亂?不著急我們一點一點看,由整體到細微來解剖它。首先整體上,它的結構分為三部分,輸入層,隱藏層和輸出層,一般輸入層和輸出層各一個,隱藏層若干個,圖中畫出了一個。細微處,連接結構上,后一層的每個神經元都由前一層的所有神經元連接進來。
手寫數字識別實驗使用的是三層的神經網絡結構,即只有一個隱藏層,下面以此說明。
下面說明一下各層的表示和各層的關系:
輸入層:X=(x1,x2,x3…xn)
隱藏層:Y=(y1,y2,y3…ym)
輸出層:O=(o1,o2,o3…or)

兩個權重:
輸入層到隱藏層的權重:V=(V1,V2,V3…Vm),Vj是一個列向量,表示輸入層所有神經元通過Vj加權,得到隱藏層的第j個神經元
隱藏層到輸出層的權重:W=(W1,W2,W3…Wr),Wk是一個列向量,表示隱藏層的所有神經元通過Wk加權,得到輸出層的第k個神經元

根據我們上面說到的單個神經元的刺激傳入和刺激傳出,相信到這里很多人應該已經得出下面的各層之間的關系了:


到這里,神經網絡的工作過程就清楚一些了。實例說明一下,假設輸入是一張圖像, 16x16大小,轉換為一個二維的灰度值矩陣,再把每一行拼接在上一行的末尾,拼接成一個1x256的行向量,作為輸入層的輸入,即X,接下來按照公式2就可以計算出隱藏層,然后根據公式1又可以計算出輸出層,輸出層的輸出就得到了。在這個手寫數字識別的項目中,我使用的圖片輸入正是16x16,所以輸入層有256個神經元,隱藏層的神經元我取了64個,最后的輸出層神經元我取的是10個,為什么是10個呢?因為數字0到9一共10個,期望上是,比如輸入一張寫著數字1的圖像,在輸出端得到的輸出是{1 0 0 0 0 0 0 0 0 0},輸入的圖像為2時,輸出{ 0 1 0 0 0 0 0 0 0 0},以此類推,實際上輸出的未必就是剛好1和剛好0,經過調參和訓練,基本是輸出0.9多和正負的0.0多,不過也足夠了,僅僅用判斷最大值所在位置的方式就可以識別到圖像上的數字。

至此,我們已經了解了整個網絡的結構和正向工作的具體流程。可以說我們已經對神經網絡理解了有50%了。為什么才50%呢?仔細想想相信你會發現,我們還不知道兩個在網絡中很重要的量,就是權重矩陣W和V。

如何求得W和V呢,這里要用到一種算法,就是誤差反向傳播算法(Error Back Propagation Algorithm) ,簡稱BP 算法。說的很晦澀,我們來翻譯成人話。先來看看算法的工作過程,首先隨機地初始化W和V的值,然后代入一些圖片進行計算,得到一個輸出,當然由于W和V參數不會剛好很完美,輸出自然不會是像上文說的,剛好就是{1 0 0 0 0 0 0 0 0 0}這一類,所以存在誤差,根據這個誤差就可以反過來修正W和V的值,修正后的W和V可以使輸出更加的靠近于理想的輸出,這就是所謂的“誤差反向傳播”的意思,修正一次之后,再代入其他一些圖片,輸出離理想輸出又靠近了一點,我們又繼續計算誤差,然后修正W和V的值,就這樣經過很多次的迭代計算,最終多次修正得到了比較完美的W和V矩陣,它可以使得輸出非常靠近于理想的輸出,至此我們的工作完成度才是100%了。這種在輸出端計算誤差,根據誤差來作調節的思想,學自動化的或者接觸過飛思卡爾一類的智能車比賽的同學體會應該是比較深的,跟PID自控算法有很大相似性。

下面是數學推導,關于實際輸出和理想輸出之間的誤差如何具體來調節W和V的值,調節多少的問題。上面說過了,暫時不理解的話可以先跳過推導,看最后的結論就好,自己最后跟著代碼實踐一遍,有了更深的體會,慢慢會理解的。
?

(2)逆向傳播算法的數學推導

輸出層的理想輸出:d=(d1,d2,d3…dr),例如{1 0 0 0 0 0 0 0 0 0}和{0 1 0 0 0 0 0 0 0 0}等
假設實際輸出和理想輸出之間的差距是E,明顯W是一個關于輸入X,權重W和V,輸出O的函數。要修正W,則需要知道具體的修正增量ΔW,離散情況下,表征微分增量,可以得到:


這樣,改變η的大小即可改變每一次調節的幅度,η大的話調節更快,小則調節慢,但是過大容易導致振蕩,這一點也跟PID中的比例系數P是一樣的。一般η的大小需要經過多次嘗試來找到合適值。

好了,到這里神經網絡就講解完畢,下面是一個較次要的內容,我們上面說了,通過不斷迭代來調整權重W和V,那么如何衡量迭代是否可以停止了呢。一個自然的想法是判斷每次的輸出和理想輸出是否足夠接近,所以我們可以用算向量距離的方法,跟均方差是一個 道理,如下:

這樣,主要s足夠小,迭代就可以結束了。


(3)實踐

下面是我試驗用的MATLAB代碼。

訓練部分:recognize_handwriting_numbers_by_simple_NN_train.m

V=double(rand(256,64)); W=double(rand(64,10)); delta_V=double(rand(256,64)); delta_W=double(rand(64,10));yita=0.2;%縮放系數,有的文章稱學習率 yita1=0.05;%我自己加的參數,縮放激活函數的自變量防止輸入過大進入函數的飽和區,可以去掉體會一下變化 train_number=9;%訓練樣本中,有多少個數字,一共9個,沒有0 train_num=30;%訓練樣本中,每種數字多少張圖,一共100張 x=double(zeros(1,256));%輸入層 y=double(zeros(1,64));%中間層,也是隱藏層 output=double(zeros(1,10));%輸出層 tar_output=double(zeros(1,10));%目標輸出,即理想輸出 delta=double(zeros(1,10));%一個中間變量,可以不管%記錄總的均方差便于畫圖 s_record=1:1000; tic %計時 for train_control_num=1:1000 %訓練次數控制,在調參的最后發現1000次其實有多了,大概400次完全夠了s=0; %讀圖,輸入網絡 for number=1:train_number ReadDir=['E:\Matlab\recognize_handwiting_numbers\train_lib\'];%讀取樣本的路徑 for num=1:train_num %控制多少張 photo_name=[num2str(number),num2str(num,'%05d'),'.png'];%圖片名 photo_index=[ReadDir,photo_name];%路徑加圖片名得到總的圖片索引 photo_matrix=imread(photo_index);%使用imread得到圖像矩陣 photo_matrix=uint8(photo_matrix<=230);%二值化,黑色是1 tmp=photo_matrix'; tmp=tmp(:);%以上兩步完成了圖像二維矩陣轉變為列向量,256維,作為輸入 %計算輸入層輸入 x=double(tmp');%轉化為行向量因為輸入層X是行向量,并且化為浮點數 %得到隱層輸入 y0=x*V; %激活 y=1./(1+exp(-y0*yita1)); %得到輸出層輸入 output0=y*W; output=1./(1+exp(-output0*yita1)); %計算預期輸出 tar_output=double(zeros(1,10)); tar_output(number)=1.0; %計算誤差 %按照公式計算W和V的調整,為了避免使用for循環比較耗費時間,下面采用了直接矩陣乘法,更高效 delta=(tar_output-output).*output.*(1-output); delta_W=yita*repmat(y',1,10).*repmat(delta,64,1); tmp=sum((W.*repmat(delta,64,1))'); tmp=tmp.*y.*(1-y); delta_V=yita*repmat(x',1,64).*repmat(tmp,256,1); %計算均方差 s=s+sum((tar_output-output).*(tar_output-output))/10; %更新權值 W=W+delta_W; V=V+delta_V; end end s=s/train_number/train_num %不加分號,隨時輸出誤差觀看收斂情況 train_control_num %不加分號,隨時輸出迭代次數觀看運行狀態 s_record(train_control_num)=s;%記錄 end toc %計時結束 plot(1:1000,s_record);

?

測試部分:recognize_handwriting_numbers_by_simple_NN_test.m

?

correct_num=0;%記錄正確的數量 incorrect_num=0;%記錄錯誤數量 test_number=9;%測試集中,一共多少數字,9個,沒有0 test_num=100;%測試集中,每個數字多少個,最大100個 % load W;%%之前訓練得到的W保存了,可以直接加載進來 % load V; % load yita1;%記錄時間 tic %計時開始 for number=1:test_number ReadDir=['E:\Matlab\recognize_handwiting_numbers\test_lib\']; for num=1:test_num %控制多少張 photo_name=[num2str(number),num2str(num,'%05d'),'.png']; photo_index=[ReadDir,photo_name]; photo_matrix=imread(photo_index); %大小改變 photo_matrix=imresize(photo_matrix,[16 16]); %二值化 photo_matrix=uint8(photo_matrix<=230);%黑色是1 %行向量 tmp=photo_matrix'; tmp=tmp(:); %計算輸入層輸入 x=double(tmp'); %得到隱層輸入 y0=x*V; %激活 y=1./(1+exp(-y0*yita1)); %得到輸出層輸入 o0=y*W; o=1./(1+exp(-o0*yita1)); %最大的輸出即是識別到的數字 [o,index]=sort(o); if index(10)==numbercorrect_num=correct_num+1 elseincorrect_num=incorrect_num+1;%顯示不成功的數字,顯示會比較花時間 % figure(incorrect_num) % imshow((1-photo_matrix)*255); % title(num2str(number)); end end end correct_rate=correct_num/test_number/test_num toc %計時結束

?

使用的庫來自于http://www.ee.surrey.ac.uk/CVSSP/demos/chars74k/#download
使用其中的EnglishFnt.tgz庫,從其中的數字選出前100張作為訓練,再另外取100張作為測試。圖片集有需要也可以郵件我發送。

?

運行結果:

最后調參得到比較好的結果,使用η=0.2,η1=0.05,在我電腦上,i5-3210M,4G內存,迭代1000次所需要的時間是468s,最終得到下面的曲線,橫坐標是訓練的迭代次數,縱坐標是均方差,可以看到,其實在350次迭代的時候已經取得了很小的均方差,考慮時間和性能的折中的話,迭代350次已經可以了。

最后訓練結束,使用η=0.2,η1=0.05,用測試集測試,可以得到89.11%的準確率,繼續調節參數,曾經可以得到90.56%的準確率,不過也難再上去,估計瓶頸了。

如果你跟著本文的步驟一步一步下來,最后還自己動手打一遍代碼,應該會很好的理解了傳統類型的神經網絡,對接下來理解卷積神經網絡應該會有些幫助。
?

個人對神經網絡的的一些理解:

? ? ? ?以識別圖片手寫數字為例,圖片中黑色像素點和白色像素點之間的空間編排關系構成了我們看到的數字,如果我們能找到一個很厲害的方程組,方程的輸入參數是一張圖片,返回一個數字表示識別結果,那肯定是很理想的,但是可惜,很難找到的方程來映射圖片像素點的空間排布和識別結果這樣的一種關系。而神經網絡剛好就完成了這樣的映射功能,所有的關于像素點空間排布信息的解析都隱藏于矩陣W和V之中,所以W和V實際上代表了這樣一種映射關系。而神經網絡聰明的地方在于,當這樣的映射關系未知時,我們設計了一套機理讓它自己來尋找,這就是學習和訓練的過程,而最后得到的W和V就是學習的結果,這個過程很像嬰兒開始認東西的過程,一開始嬰兒的認知體系是空白的,像剛隨機初始化的W和V,我們給它看一本書,像給了網絡一個輸入,告訴他這個是“書”,像告訴網絡,理想輸出應該是“書”,他會開始嘗試來理解,建立書這個物品到“書”這個字的映射關系,一開始他會犯錯,看到相似的比如一張紙也會認為是書,但是在看到更多的書之后,并且我們告訴他這個是“書”之后,他又會不斷修正這樣一種映射關系,最后建立完整的對于書這樣一種物品到“書”這個字的映射過程,初步的認知體系建立。現在可以說說上面的“激活函數”是干嘛用的了,可以想象,自然界的各種各樣的映射關系顯然是比較復雜的,關靠線性關系是無力描述的,而神經網絡中用的是加權相加的運算,如果沒有經過激活函數處理,后層的所有輸入都可以由多層之前的信號經過線性運算來得到,一個現象模型顯然表現力是遠遠不夠的,所以我們在神經網絡模型中加入了非線性的因素,就是激活函數。

?

//

轉載:https://blog.csdn.net/huang_miao_xin/article/details/51364152

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的BP神经网络识别手写数字项目解析及matlab实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。