风机桨叶故障诊断(三) 识别桨叶——初步构建BP神经网络
風機槳葉故障診斷(三)?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 識別槳葉——初步構建BP神經網絡
? ? ?新的一天,希望有好的運氣。今天開始著手系統的第一個模塊,從一幅圖像中尋找到槳葉所在的位置。第一直覺我們的識別任務屬于難度比較大,干擾因素多的了,所以我沒有考慮先試一下Logistic回歸之類的相對簡單的算法,我準備先簡單抽選一些樣本,直接用BP神經網絡模型快速實現一下,然后再觀察我們的算法問題所在,逐步進行完善,包括修改模型,增加樣本數量等等。說干就干!
? ? ?之前我們已經得到了可以用來提取樣本的風機圖像庫,我手動的從里面截取了一些樣本,數了一下,正樣本49個,負樣本28個。然后將這些大小不一的正負樣本統一縮放成20×20像素的小圖像,下圖所示的就是正樣本最后處理完的結果:
? ? ?準備工作結束后,開始動手編寫一個最簡單的三層BP神經網絡了。
? ? ?我們的輸入是我們歸一化后的20×20的圖像,所以輸入層的神經元個數為400。隱含層的神經元個數我最初選取的是25,輸出層我選擇的節點個數為2。用[1 0]代表正樣本的期望輸出,[0 1]代表負樣本的期望輸出。
? ? ?具體實現我是參考的coursera上吳恩達老師的機器學習課程上的代碼,那個神經網絡的示例代碼是用來訓練手寫體數字識別的,是個多分類問題。由于我是在那份代碼上簡單修改來的,所以這也是為什么我的輸出層有兩個神經元而不是一個的原因,我把問題看成了一個多分類問題。
? ? ?經過了一上午的coding后,成功運行了。由于每次訓練的結果都會不同,我多次運行并觀察,訓練樣本的預測準確率在90%以上,測試集上的預測準確率在80%左右。看起來初步的結果還可以,不過我只有17個測試樣本,再加上都是我手動選取的,有一定的主觀因素,80%的準確率水分還是很大的。我們的初步實現的目的就是發現我們這個識別任務的難點,問題所在,只停留在得到一個準確率的數字是不行的,所以我意識到應該想辦法要做一些誤差分析。
? ? ?讓我們來看一下我們的算法都有哪些問題,到底將測試樣本中的哪些類型的圖像預測錯誤了,也就是算法在哪類物體上表現不好。于是我著手寫了下面的函數,需要提供測試樣本集矩陣(每一行=一個20×20圖像展開后形成的向量),以及表示每個樣本是否被預測正確(用0和1表示)的數組,再提供一個可視化時每個樣本圖像邊長顯示多少的參數,matlab代碼如下:
function [ h, display_array ] = DisplayErrorTestExample( X, example_width,errorIndex ) %顯示所有測試集并標記出有錯誤的測試集 %errorIndex標識測試集每個樣本的預測是否有誤,有誤用1,正確用0表示% Set example_width automatically if not passed in if ~exist('example_width', 'var') || isempty(example_width) example_width = round(sqrt(size(X, 2))); end% Gray Image colormap(gray);% Compute rows, cols [m n] = size(X); example_height = (n / example_width);% Compute number of items to display display_rows = floor(sqrt(m)); display_cols = ceil(m / display_rows);% Between images padding pad = 1;% Setup blank display display_array = ones(pad + display_rows * (example_height + pad), ...pad + display_cols * (example_width + pad));% Copy each example into a patch on the display array curr_ex = 1; for j = 1:display_rowsfor i = 1:display_colsif curr_ex > m, break; end% Copy the patch% Get the max value of the patchmax_val = max(abs(X(curr_ex, :)));display_array(pad + (j - 1) * (example_height + pad) + (1:example_height), ...pad + (i - 1) * (example_width + pad) + (1:example_width)) = ...reshape(X(curr_ex, :), example_height, example_width) / max_val;%如果是錯誤的測試樣本,標紅框if errorIndex(curr_ex)==1display_array(pad + (j - 1) * (example_height + pad) , pad + (i - 1) * (example_width + pad) + (0:example_width+1))=zeros(1,example_width+2);display_array(pad + j * (example_height + pad) , pad + (i - 1) * (example_width + pad) + (0:example_width+1))=zeros(1,example_width+2);display_array(pad + (j - 1) * (example_height + pad) + (0:example_height+1), pad + (i - 1) * (example_width + pad) ) = zeros(example_height+2,1);display_array(pad + (j - 1) * (example_height + pad) + (0:example_height+1), pad + i * (example_width + pad) ) = zeros(example_height+2,1);endcurr_ex = curr_ex + 1;endif curr_ex > m, break; end end% Display Image h = imagesc(display_array, [-1 1]);% Do not show axis axis image offdrawnow;end
? ? ?將上面的方法添加到寫好的代碼中,重新運行,其中兩次的結果如下(圖像顯示的是僅有的17個測試樣本,被黑框圈起的是預測錯誤的樣本):
? ? ?可以看到,算法在負樣本的預測中錯誤較多,我感覺這一方面與本身負樣本就較少,一方面與負樣本間差異很大,造成算法學習起來困難。我們重新思考下我們的系統,我們第一步是要從圖像中識別出槳葉,如果識別錯了,就會將不是槳葉的物體認為成槳葉進行下一步的故障診斷,那結果將是不能接受的。相反,如果我們對于一幅風機圖像中的三個槳葉沒有完全識別出來,卻是無關緊要的,因為我們能在視頻短時間的幾幀之內獲取到數張同一風機的圖片,對于同一槳葉的識別我們有很多次的機會,所以我們算法對于正樣本的漏識率可以相對較高,因為最終的識別率還是很高。
? ? ?所以可以看出,對于負樣本的錯誤預測,也就是假陽性的概率,是必須要降低的。先從算法入手,或許我們可以通過修改神經網絡輸出時的判斷閾值,也就是只有極有把握輸入為正樣本時,才判為正樣本,否則均判為負樣本。這樣做也就是人為選擇犧牲了識別率,降低了誤識率。一切想法的好壞以實際說話,馬上修改代碼重新運行,其中兩次結果如下:
? ? ?可以看到,出現假陽性的概率明顯下降,同時漏識率比較明顯的上升了,不過這是我們愿意看到的現象。說明這點改進對于算法的提升顯著,后面算法的不斷完善中也應當保留這種思想。
? ? ?今天就到這里了,忙了一天,今天的進展著實不小。總結一下,首先簡單的選取了少量的樣本并進行樣本歸一化,這樣就得到了可供訓練的訓練集和測試集。然后訓練了400×25×2的三層BP神經網絡,最后對最初步的模型進行了誤差分析并找到了一種效果顯著的提升方法!
?
? ? ?
總結
以上是生活随笔為你收集整理的风机桨叶故障诊断(三) 识别桨叶——初步构建BP神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WinSock I/O 模型 -- Se
- 下一篇: LwIP应用开发笔记之十:LwIP带操作