張睿敏,杜叔強,周秀媛
(蘭州工業(yè)學(xué)院 計算機與人工智能學(xué)院,甘肅 蘭州 730050)
基于深度學(xué)習(xí)的圖像目標(biāo)檢測算法已經(jīng)得到廣泛應(yīng)用,但對于復(fù)雜場景方面的檢測仍然存在很多未能解決的問題。例如,未訓(xùn)練目標(biāo)對數(shù)據(jù)的依賴,數(shù)據(jù)集不充足等。傳統(tǒng)的目標(biāo)檢測的步驟是:圖像預(yù)處理、特征提取和模式分類[1],而果實圖像背景復(fù)雜,并且干擾因素多、分布密集、小目標(biāo)檢測難,這嚴(yán)重影響了檢測的效果。
本文以水果圖像為例,在卷積神經(jīng)網(wǎng)絡(luò)CNN(Convolutional Neural Networks)算法檢測基礎(chǔ)上在最后一個卷積層之后、激活函數(shù)之前插入BN(BatchNorm)層,針對數(shù)據(jù)特點設(shè)計訓(xùn)練方案,使用BN算法對圖像數(shù)據(jù)進(jìn)行批規(guī)范化處理,這種方式會減小圖像之間的絕對差異,突出相對差異,能夠加快分類效果和訓(xùn)練速度。
在經(jīng)典的模式識別方法中,如基于HOG、Gabor等局部特征的圖像檢測,有基于全局特征的圖像檢測[2],不管是基于局部特征還是全局特征,事先要手工對圖像進(jìn)行預(yù)處理。而CNN能夠自動提取圖像特征,CNN 網(wǎng)絡(luò)主要有2個算子,一個是卷積層,另一個是池化層(Pooling)。卷積神經(jīng)網(wǎng)絡(luò)CNN提取圖像特征首先要進(jìn)行卷積操作。將一張圖像看作是一個個像素值組成的矩陣,那么對圖像的分析就是對矩陣的數(shù)字進(jìn)行分析,而圖像的特征,就隱藏在這些數(shù)字規(guī)律中,在卷積層內(nèi)通過滑動窗口,在滑動窗口之內(nèi)做卷積運算[3]。假設(shè)1副圖像信息用7×7的矩陣表示,使用一個3×3的卷積核(filter)進(jìn)行卷積,得到一個3×3的矩陣,把這個矩陣叫做特征映射,卷積過程如圖1所示。
圖1 卷積運算
首先對圖像的每個像素進(jìn)行編號,用χi,j表示圖像的第i行第j列元素;對Filter的每個權(quán)重進(jìn)行編號,用ωm,n表示第m行第n列權(quán)重,用ωb表示filter的偏置項[4];對Feature Map的每個元素進(jìn)行編號,用αi,j表示Feature Map的第i行第j列元素[5];用f表示激活函數(shù)(這個例子選擇ReLU函數(shù)作為激活函數(shù)),然后使用公式(1)計算卷積,即
(1)
對于Feature Map左上角元素α0,0來說,其卷積計算方法為
這樣依次可以計算出Feature Map中所有元素的值,在圖像特征提取過程中不同的卷積核提取不同的特征,圖像在通過卷積運算后會得到圖像的特征映射[6]。
在CNN進(jìn)行圖像特征提取時,如果圖像經(jīng)過了變形、旋轉(zhuǎn)等基本操作后,CNN如何能夠提取到正確的特征呢?具體提取方法如圖2所示。
圖2 圖像像素
圖3中有如上a、b、c三個features特征矩陣,其中像素值1代表白色,像素值-1代表黑色,CNN取3個特征矩陣在圖像的像素圖中通過滑動窗口進(jìn)行匹配,特征a矩陣可以匹配到圖像像素圖的左上角和右下角,特征b矩陣可以匹配到圖像像素圖的中間交叉部分,特征c矩陣則可以匹配到像素圖的右上角和左下角。因此,把3個特征小矩陣可以作為卷積核,每一個卷積核在圖像上進(jìn)行滑動,滑動一次就進(jìn)行一次卷積操作[7],得到一個特征矩陣Feature Map,然后求其平均值,讓所有的特征值回歸到-1到1之間[8]。當(dāng)使用全部卷積核進(jìn)行卷積操作之后,平均值越接近1表示對應(yīng)位置和卷積核代表的特征越接近,越是接近-1,表示對應(yīng)位置和卷積核代表的反向特征越匹配,而值接近0的表示對應(yīng)位置沒有任何匹配或者說沒有什么關(guān)聯(lián)。
當(dāng)圖像為RGB或ARGB(A代表透明度)時,可以在多通道進(jìn)行卷積操作[9],或?qū)τ诙询B卷積層來說,池化層之后可以繼續(xù)接下一個卷積層,對池化層多個Feature Map的操作即為多通道卷積。
池化層的操作就是在內(nèi)積結(jié)果上取每一局部塊的最大值。即CNN 用卷積層和池化層實現(xiàn)了圖片特征自動提取的方法。
池化可以將一幅大的圖像縮小,同時又保留其中的重要信息。池化都是2×2大小,比如對于max-pooling來說,就是取輸入圖像中2×2大小的塊中的最大值,作為結(jié)果的像素值,相當(dāng)于將原始圖像縮小了1/4。同理,對于average-pooling來說,就是取2×2大小塊的平均值作為結(jié)果的像素值。池化操作具體如圖3所示。
圖3 池化操作
因為最大池化(max-pooling)保留了每一個小塊內(nèi)的最大值,所以它相當(dāng)于保留了這一塊最佳的匹配結(jié)果(因為值越接近1表示匹配越好)。這也就意味著它不會具體關(guān)注窗口內(nèi)到底是哪一個地方匹配了,而只關(guān)注是不是有某個地方匹配上了。由此看出,CNN能夠發(fā)現(xiàn)圖像中是否具有某種特征,而不用在意到底在哪里具有這種特征。這也就能夠幫助解決之前提到的計算機逐一匹配像素的死板做法。
當(dāng)對所有的feature map執(zhí)行池化操作之后,相當(dāng)于一系列輸入的大圖變成了一系列小圖。同樣地,我們可以將這整個操作看作是一個操作,這也就是CNN中的池化層(pooling layer),通過加入池化層,可以很大程度上減少計算量,降低機器負(fù)載。
使用卷積神經(jīng)網(wǎng)絡(luò)進(jìn)行多分類目標(biāo)檢測的時候,圖像構(gòu)成比上面的圖像要復(fù)雜得多,我們并不知道哪個局部特征是有效的,即使我們選定局部特征,也會因為太過具體而失去反泛化性。假設(shè)我們使用一個卷積核檢測眼睛位置,但是不同的人,眼睛大小、狀態(tài)是不同的,如果卷積核太過具體化,卷積核代表一個睜開的眼睛特征,那如果一個圖像中的眼睛是閉合的,就可能檢測不出來,針對此類問題就要使用反向傳播算法(BP)確定卷積核的值。
反向傳播算法就是對比預(yù)測值和真實值,繼而返回去修改網(wǎng)絡(luò)參數(shù)的過程[10],一開始隨機初始化卷積核的參數(shù),然后以誤差為指導(dǎo)通過反向傳播算法,自適應(yīng)地調(diào)整卷積核的值,從而最小化模型預(yù)測值和真實值之間的誤差。當(dāng)然,在實際的CNN中不可能存在百分之百的正確,只能是最大可能正確。
本文在最后一個卷積層之后、激活函數(shù)之前插入BN(BatchNorm)層,使用BN算法對圖像數(shù)據(jù)進(jìn)行批規(guī)范化處理,這種方式會減小圖像之間的絕對差異,突出相對差異[11],能夠加快分類效果和訓(xùn)練速度。假設(shè)輸入數(shù)據(jù)是β=χ1…m,共m個數(shù)據(jù),輸出是Yi=BN(X),為了保證非線性的獲得,BN給輸入數(shù)據(jù)增加兩個參數(shù)β和γ,這兩個參數(shù)是通過訓(xùn)練學(xué)習(xí)得到的[12],其具體計算過程如式(2)~(5)所示。
(2)
(3)
(4)
(5)
式(2)求出x的均值,式(3)求出此次Batch的方差,接下來式(4)對x做歸一化,最后式(5)引入縮放和平移變量計算歸一化后的值。在tensorflow中Batchnorm的代碼實現(xiàn)如下:
def batch_norm_layer(x,train_phase,scope_bn):
with tf.variable_scope(scope_bn):
beta = tf.Variable(tf.constant(0.0,shape=[x.shape[-1]]),name='beta',trainable=True)
gamma = tf.Variable(tf.constant(1.0,shape=[x.shape[-1]]),name='gamma',trainable=True)
axises = np.arange(len(x.shape)-1)
batch_mean,batch_var = tf.nn.moments(x,axises,name='moments')
ema = tf.train.ExponentialMovingAverage(decay=0.5)
def mean_var_with_update():
ema_apply_op = ema.apply([batch_mean,batch_var])
with tf.control_dependencies([ema_apply_op]):
return tf.identity(batch_mean),tf.identity(batch_var)
mean,var = tf.cond(train_phase,mean_var_with_update,
lambda:(ema.average(batch_mean),ema.average(batch_var)))
normed = tf.nn.batch_normalization(x,mean,var,beta,gamma,1e-3)
return normed
首先新建2個變量beta和gamma,平移、縮放因子,接著計算此次批量的均值和方差,然后通過Exponential Moving Average(decay=0.5)函數(shù)滑動平均做衰減[13]。訓(xùn)練階段計算runing_mean和runing_var,使用mean_var_with_update()函數(shù),測試的時候直接把之前計算的值拿去用 ema.average(batch_mean)。
CNNBN模型訓(xùn)練時通過給定輸入向量和輸出的目標(biāo)向量,求出隱層以及輸出層中各個單元的輸出[14],然后進(jìn)一步求出目標(biāo)值和實際輸出值之間的偏差值e(這個過程是前向傳播過程);接著拿e的值看它是否在設(shè)定的允許范圍之內(nèi),如果是,訓(xùn)練結(jié)束,固定權(quán)值和閾值;如果e的值不在允許范圍之內(nèi),返回去計算網(wǎng)絡(luò)層中神經(jīng)元的誤差值,并且求出誤差的梯度,進(jìn)一步更新權(quán)值,繼續(xù)求隱層,輸出層各單元的輸出[15](向后傳播過程),不斷循環(huán)這個過程,最后得到一個穩(wěn)定的權(quán)值和閾值,其訓(xùn)練過程如圖4所示。
圖4 CNNBN模型訓(xùn)練流程
本文采用3 000多張圖像作為訓(xùn)練數(shù)據(jù)集,圖像是自然場景下使用海康威視HIKVISION B12V2-I 6MM型攝像頭在果園采用不同角度、不同光線、不同高度拍攝的,拍攝圖像的尺寸為1 920像素*1 080像素,JPG格式,然后使用Labelme軟件給圖片標(biāo)記上PASAL VOC標(biāo)簽。在遠(yuǎn)程云服務(wù)器上使用Anaconda作為IDE,搭建TensorFlow2.1.0深度學(xué)習(xí)框架,訓(xùn)練時將所有訓(xùn)練集圖像統(tǒng)一縮放800*800尺寸大小,然后將整個圖像輸入,訓(xùn)練集和驗證集以4:1的比例隨機劃分。同時通過如下代碼定義了相關(guān)的評估量:
def loss(logits,label_batches):
cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits,labels=label_batches)
cost = tf.reduce_mean(cross_entropy)
return cost
def get_accuracy(logits,labels):
acc = tf.nn.in_top_k(logits,labels,1)
acc = tf.cast(acc,tf.float32)
acc = tf.reduce_mean(acc)
return acc
首先定義訓(xùn)練最小化損失的損失函數(shù)loss(),其次定義評價分類準(zhǔn)確率的量acc。訓(xùn)練時,當(dāng)loss值減小,準(zhǔn)確率acc值增加,說明訓(xùn)練才是收斂的。在設(shè)計loss函數(shù)時,有兩個主要的問題:①對于最后一層長度為7*7*30長度預(yù)測結(jié)果,計算預(yù)測loss通常會選用平方和誤差。然而這種loss函數(shù)的位置誤差和分類誤差是1∶1的關(guān)系。②輸入的整個圖有7*7個網(wǎng)格,大多數(shù)網(wǎng)格實際不包含被檢測對象(當(dāng)被檢測對象的中心位于網(wǎng)格內(nèi)才算包含檢測對象)。直接選用整圖訓(xùn)練模型,這樣做的好處在于可以更好的區(qū)分目標(biāo)和背景區(qū)域,在提升目標(biāo)定位度的同時犧牲了一些正確率。通常一個網(wǎng)格(cell)可以直接預(yù)測出一個檢測目標(biāo)對應(yīng)的bounding box,但是對于某些尺寸較大或靠近圖像邊界的被檢測對象,需要多個網(wǎng)格預(yù)測的結(jié)果通過非極大抑制處理生成bounding box。
在訓(xùn)練和測試時,每個網(wǎng)格預(yù)測B個bounding boxes,每個bounding box對應(yīng)5個預(yù)測參數(shù),即bounding box的中心點坐標(biāo)(x,y),寬高(w,h),和置信度評分。這里的置信度評分(Pr(Object)*IOU(pred|truth))綜合反映基于當(dāng)前模型bounding box內(nèi)存在目標(biāo)的可能性Pr(Object)和bounding box預(yù)測目標(biāo)位置的準(zhǔn)確性IOU(pred|truth)。如果bouding box內(nèi)不存在物體,則Pr(Object)=0。如果存在物體,則根據(jù)預(yù)測的bounding box和真實的bounding box計算IOU。如果將輸入圖像劃分為7*7網(wǎng)格(S=7),每個網(wǎng)格預(yù)測2個bounding box(B=2),有20類待檢測的目標(biāo)(C=20),則相當(dāng)于最終預(yù)測一個長度為S*S*(B*5+C)=7*7*30的向量,從而完成檢測和識別任務(wù)。相關(guān)檢測數(shù)據(jù)對比如圖5所示。圖中:正確率表示正確檢測和識別的比例;目標(biāo)定位度表示目標(biāo)定位的正確性;相似性表示類別的相似性;其它為其它性能指標(biāo),如檢測速度等;背景識別任何目標(biāo)的背景。
圖5 檢測數(shù)據(jù)對比
因為算法訓(xùn)練模型時直接選用整圖,這樣能夠更好的區(qū)分目標(biāo)和背景區(qū)域。從實驗結(jié)果也可以看出雖然檢測正確率稍有犧牲,但目標(biāo)定位度有較大的提升。目標(biāo)定位度較準(zhǔn),在機器人采摘系統(tǒng)中非常重要。另外,實驗中將proposals的數(shù)量限制為300個,因為proposals的數(shù)量影響算法的檢測速度,這樣R-CNN的平均精度mAP(mean Average Precision)值為32,檢測偏差mAP的值為31.6,檢測時間(sec/img)為0.36;而CNNBN 的平均精度mAP(mean Average Precision)值為31.1,檢測偏差mAP的值為30.3,檢測時間(sec/img)為0.33,如表1所示。
表1 各算法實驗參數(shù)
通過與已有同類檢測算法的對比,從數(shù)據(jù)可以看出,在檢測正確率基本持平的情況下,本算法的檢測速度有所提高,目標(biāo)定位正確率較高,可以對任何背景的水果圖像都能進(jìn)行檢測,適用范圍更廣泛,說明本研究算法具有一定的優(yōu)勢與可行性。