(1.浙江國際海運職業技術學院,浙江 舟山 316000; 2.浙江大學 舟山海洋研究中心,浙江 舟山 316000)
根據世界編程語言排行TIOBE統計,Python榮獲“2018年度編程語言”稱號。在統計領域、人工智能編程領域、腳本編寫方面、系統測試方面,Python均排名第一,另外還在Web編程與科學計算方面也處于領先地位。[1]
機器視覺(Machine Vision)是用計算機模擬生物的視覺功能,在圖像中提取、分辨、理解信息。目前機器視覺在人臉識別、同類商品推薦、目標跟蹤、產品缺陷監測、醫療診斷、自動駕駛等領域已有非常廣泛的應用。同時,機器視覺也是人工智能機器學習的強有力的分支,為機器學習的模型分析、數據調試產生重要的影響。
根據2019年3月,教育部公布的2018年普通高等本科專業的備案和審批結果[2],增設人工智能專業35個,但我國高等院校在實驗平臺的開發較薄弱,與專業建設存在脫節的現象。為提高高等院校的機器視覺的專業教育水平,提升學生的機器視覺的訓練、研發、優化能力,對機器視覺實驗平臺進行研發,整合常見機器視覺所使用的模型。
機器視覺實驗教學平臺的總體設計框架如圖1所示。整個機器視覺實驗教學平臺分為圖像分類、圖像目標識別兩類功能模塊,兩個功能模塊能滿足機器視覺的教學需求。其中圖像分類功能模塊包括K臨近(k-NearestNeighbor,KNN)圖像分類模塊、向量機(support vector machine,SVM)圖像分類模塊,圖像目標識別模塊包括神經網絡(artificial neural network,ANN)目標識別模塊、卷積神經網絡(convolutional neural networks,CNN)目標識別模塊[3-4],涵蓋真實產品在機器視覺方面的需求。

圖1 機器視覺實驗教學平臺的總體設計框架
在機器視覺實驗教學平臺程序設計方面,采用Python語言開發。機器視覺實驗教學平臺的圖形用戶界面(graphical user interface,GUI)設計采用PyQt5庫,機器學習(Machine Learning)采用TensorFlow框架,圖像處理部分采用opencv-python庫。
在界面設計上,首先讓用戶通過菜單欄選擇以哪個模塊進行試驗, 此時選擇樣本目錄、訓練樣本、數據測試、修改參數按鈕均不可用。如圖2所示。

圖2 待用戶選擇界面
機器視覺實驗教學平臺采用模塊化的設計架構,將整個系統分成四個模塊,分別為基于K臨近分類(KNN)的圖像分類模塊、基于向量機(SVM)的圖像分類模塊、基于神經網絡(ANN)的目標識別模塊、基于卷積神經網絡(CNN)的目標識別模塊,其中圖像分類與目標識別為兩個數據源,通過將每個模塊的類(Class)抽象,構建兩個工廠方法,方便維護拓展。
K臨近分類算法,通俗的講是找K個最近的點,核心思想是根據最近樣本的類別確定樣本所屬的類別[5]。使用歐幾里德距離公式計算距離,如式(1)所示。
(1)
計算向量點A與點B之間的距離,表示A(x1,x2,x3,…,xn)樣本與B(y1,y2,y3,…,yn)樣本在n個特征上的距離。
本實驗平臺有kaggle的手寫數字數據集,通過訓練可以達到對手寫數字的分類。
用戶在選擇K臨近分類(KNN)的圖像分類菜單后,選擇樣本目錄按鈕可用,此時可以選擇樣本數據目錄,如圖3、圖4所示。

圖3 菜單欄選擇

圖4 選擇樣本目錄
用戶選擇樣本目錄后,訓練樣本、修改參數按鈕可用,就可以根據樣本目錄文件訓練樣本。但在每個樣本文件的命名中,有一定的格式要求,必須要有下劃線,且下劃線前為標簽名,下劃線后為該圖片的文件序號或文件名。其中標簽名也就是最終的分類標簽。
在完成樣本訓練之后,就可以進行數據測試。當需要優化K臨近分類(KNN)的算法參數時,可以通過點擊修改參數按鈕,鏈接到代碼視圖,修改需要優化的代碼及參數。其他幾個模塊的操作與K臨近分類(KNN)的圖像分類模塊類似。其中,K臨近分類(KNN)的主要訓練代碼如下所示:
import numpy as np
# KNN分類函數參數說明
# testData-待分類的數據
# trainData-用于訓練的數據
# labes-訓練數據的分類標簽
# k-kNN參數,選擇距離最小的k個點
def KNNclassify(testData, trainData, labels, k):
#統計trainData的行數
trainDataSize = trainData.shape[0]
#在列向量方向上(橫向)重復testData共1次,行向量方向上(縱向)重復testData共trainDataSize次
differMat=np.tile(testData,(trainDataSize, 1)) - trainData
#二維特征相減后平方
sqdifferMat = differMat**2
#sum()所有元素相加
tDistances = sqdifferMat.sum(axis=1)
#歐幾里德距離公式計算距離
distances = tDistances**0.5
#返回distances中元素從小到大排序后的索引值
sortedDistances = distances.argsort()
#定一個記錄類別次數的字典
classNum = {}
for i in range(k):
#取出前k個元素的類別
votedLabel=labels[sortedDistances[i]]
#計算類別次
classNum[votedLabel]=classNum.get(votedLabel,0) + 1
#根據字典的值進行降序排列
sortedClassNum = sorted(classNum.items(),reverse=True,key=operator.itemgetter(1))
#返回出現次數最多的類別
return sortedClassNum[0][0]
#trainFileList為待訓練的文件列表,由用戶選擇而來,count為文件數
count = len(trainFileList)
#mLabels是存放訓練的標簽
mLabels = []
#將待訓練矩陣初始化,1024是32*32像素的圖像轉成一而來
trainMat = np.zeros((m, 1024))
#通過下劃線找到該樣本的標簽
for i in range(count):
#獲取文件的名字
fileName = trainFileList[i]
#獲得分類的數字標簽
classNumber=int(fileName.split('_')[0])
#將獲得的類別添加到mLabels中
mLabels.append(classNumber)
#將每一個樣本的1x1024數據存儲到已經初始化的trainMat矩陣中
trainMat[i,:] = pic2mat(fileName)
# kNNclassify分類器
neigh=KNNclassify(myTest,trainMat, mLabels,3)
# myTest需要測試數據,trainMat為待訓練矩陣,mLabels為對應的標簽
#所有元素相加并用歐幾里德公式計算距離
distances = tDistances**0.5
用戶在K臨近分類(KNN)的圖像分類模塊,也可以修改其中源代碼,將歐幾里德距離改成馬哈頓距離或者余弦距離等。
支持向量機 (SVM)簡單來講,去找一個超平面,使得兩種數據類型距離這個超平面的間隔最大化[6]。兩種數據類型,如果能找到一個函數p(x)=ωTx+b,且p(x)> 0表示一種數據;p(x)<0表示另外一種數據,那么就實現了SVM。如圖5所示。

圖5 SVM線性分割圖
機器視覺所涉及的圖像或視頻特征量眾多,數據集又非線性。因此,為了讓圖像或視頻樣本特征屬性可分割,將特征量映射到多維空間,進而通過多維切面將特征進行分割。而高維度直接求內積非常困難,因此需要通過核函數(kernel function)將任意兩個樣本點在擴維后的空間的內積,等于這兩個樣本點在原來空間經過一個函數后的輸出。
本系統SVM可采用徑向基核函數(RBF,Radial Basis Function)、多項式核函數(poly,Polynomial Kernel)、Sigmoid 核函數[6]。
徑向基核函數公式如下:
(2)
多項式核函數公式如下:
k(x,y)=(axty+c)d
(3)
徑向基核函數公式如下:
k(x,y)=tanh(αxty+c)
(4)
本模塊可以對kaggle的手寫數字數據集進行區分,操作與K臨近分類(KNN)的圖像分類模塊類似。
神經網絡是使用多組處理單元(神經元)將輸入、隱含、輸出,組成一個網狀結構,結構示意圖如圖6,它有自學習、自組織、自適應、容錯性、較強的非線性函數逼近的特點[7]。其中在誤差修正上,一般利用誤差反傳播(BP,Back Propagation)訓練算法,提高權重(Weight)與偏差(Biases)的精確性[8]。

圖6 神經網絡結構圖
神經網絡(ANN)在機器視覺方面,能用于圖像特征識別,也能用于圖像分類,圖像處理等,是機器視覺常用的方法之一,在本實驗教學平臺中,將神經網絡用于圖像特征識別。
由于神經網絡(ANN)的權值太多,計算非常困難,因此Yann Lecun在1988年提出了卷積神經網絡(CNN)[4]。卷積(Convolution)計算的主要方法是通過濾波器(Filter),將原始圖像去除噪聲,并將特征提取出來,常用的濾波器為高斯濾波器,然后通過激活函數,將數據正則化,進而通過池化(Pooling)將特征圖進行壓縮,以減少神經網絡權值數[4]。
在本實驗教學平臺中,默認第一層、第二層采用3*3的卷積核,步長為1,兩端采用全填充方式補零,使得寬卷積具有交換性,激活函數采用ReLU激活函數,如式(5)所示。第三層采用最大值池化層,以2*2矩陣篩選區域最大值。第四層使用隨機失活,丟棄部分神經網絡,防止過擬合。第五至八層與第一至四層一致。第九層將多維特征向量壓至一維向量,過渡進入全連接層。第十層采用全連接層,與神經網絡(ANN)類似,但激活函數仍舊用ReLU激活函數。第十一層進一步采用隨機失活,隨機丟棄一半的神經元,防止過擬合。第十二層采用全連接的SoftMax多分類回歸,其中SoftMax函數如式(6)所示,其中WT為權重向量,1為全1向量。

(5)

(6)
在卷積神經網絡學習過程中,學習參數為卷積層中的權重與偏差,與神經網絡類似,卷積神經網絡也可以通過誤差反向傳播訓練算法學習參數。
在本實驗教學平臺中,將卷積神經網絡用于圖像目標識別,測試數據采用32*32彩色牛馬圖,因此包括長、寬、RGB值的四維數據。
基于Python的機器視覺實驗教學平臺在浙江國際海運職業技術學院進行了實驗教學,學生對數據集劃分、函數特性、特征發現、過擬合與欠擬合等機器視覺實驗問題上有更深入的認知,大大縮短了他們訓練機器視覺的實驗周期。
通過K臨近分類(KNN)的圖像分類模塊,對kaggle的手寫數字數據集進行學習,并優化KNN參數后,其識別準確率最高為98.73%,其中識別錯誤數據如圖7所示。而通過向量機(SVM)的圖像分類模塊,學習該數據集后,并優化參數,其識別準確率最高為99.15%,其中識別錯誤數據如圖8所示。在圖7、圖8中Res表示機器視覺的判斷結果,True表示真實結果。


圖8 SVM分類識別錯誤數據
kaggle的手寫數字數據集中,測試數據樣本共946個,KNN與SVM對各個數字的錯誤判斷情況圖9所示。

圖9 SVM與KNN手寫數字識別錯誤量
其中SVM使用多項式核函數在區分手寫數字時準確率最高,圖10是徑向基核函數、多項式核函數、Sigmoid 核函數結合懲罰系數進行對比,得出該結論。

圖10 SVM核函數與懲罰系數對錯誤率的影響
通過卷積神經網絡(CNN)的目標識別模塊,學習牛與馬圖片,實現圖片中的牛馬識別區分。樣本一共1 000張牛圖、1 000張馬圖,測試數據一共500張牛圖、500張馬圖。初始的卷積神經網絡模型如表1所示。

表1 初始的卷積神經網絡模型
經過100次的迭代,初始的卷積神經網絡最低訓練試誤差值為0.317 183,最低測試誤差值為0.370 668,最高訓練準確率為86.212 3%,最高測試準確率為84.342 8%。
對該神經網絡結構進行優化,優化后的卷積網絡模型如表2所示,開始仍舊采用3*3的卷積核,兩端采用全填充方式補零,激活函數采用ReLU,經過5次卷積與激活函數后,第十一層采用最大值池化層,以2*2矩陣篩選區域最大值;第十二層采用隨機失活,丟棄25%的神經網絡數據。并以上述方式進行三輪卷積,共卷積15層,如表2的

表2 優化后的卷積神經網絡模型
conv2d_1至dropout_3,但在最后一次池化時,采用全域最大值池化,即global_max_pooling,最后進行兩層全連接層,并使用SoftMax進行多分類回歸。
對優化后的模型,經過100次的迭代,初始的卷積神經網絡最低訓練試誤差值為0.229 262,最低測試誤差值為0.222 37,最高訓練準確率為90.530 3%,最高測試準確率為91.881 4%。
記錄下每次迭代后的誤差值與準確率,通過對比優化前與優化后的卷積神經網絡,確定優化的方向與關鍵點。誤差分析與準確率分析如圖11、圖12所示。

圖11 CNN優化前后誤差分析

圖12 CNN優化前后準確率分析
基于Python的機器視覺實驗教學平臺綜合了機器視覺常見模型,結合opencv-python計算機視覺庫與TensorFlow機器學習框架可以實現圖像分類、識別,并且支持參數修改,為學生在學習機器視覺學科,提供一個交互式、可視化的實驗環境,不僅能增強學生對機器視覺理論知識的理解,還能將理論與實際應用結合,解決機器視覺在工業與電子產品中的實際問題,有效提高學生的實踐解決問題能力和創新能力,進一步推動國務院發布的《新一代人工智能發展規劃》[9]。