yolo-tensorflow復現解析

看到有人使用tensorflow復現了yoloV3,來此記錄下代碼閱讀。感受復現的代碼寫的不是很好,會加一部分其餘人用keras復現的代碼。網絡

tensorflow代碼地址:https://blog.csdn.net/IronMastiff/article/details/79940118函數

源代碼分爲如下幾部分:spa

Train.py爲主程序train.py部分爲訓練本身的數據集,eval.py爲利用訓練好的權重來進行預測。Reader爲讀取數據標籤等,config.yml爲訓練過程當中的一些參數設置,eval_config.yml爲預測過程當中的一些參數設置。Utils包爲其中的一些網絡結構,IOU等中間步驟。下面先介紹utils的中的程序.net

 

Net.py: 設置網絡結構,提取圖片信息。Darknet-53網絡結構以下。1x,2x等分別表示該結構重複了1次兩次等,Residual表示和前面方框外的結構進行按維度疊加,相似於殘差網絡。3d

feature_extractor 函數該提取三個尺度的信息scale1,scale2,scale3,分別爲倒數第1,2,3個方框中網絡結構的輸出。以後,scales函數經過1x1,3x3卷積分別對三個尺度的特徵單元進行特徵交互。返回交互後的三個尺度信息。
最後輸出的三個不一樣尺度分別爲 13X13X75,26X26X75,52X52X75具體交互信息可參考代碼結構。最後訓練時會選取不一樣scale參與計算loss,select_things就是選取不一樣scale的特徵。
不太理解如何使用?是須要手動更改配置文件的scale選擇?如何選擇?

 

IOU.py 爲NMS篩選anchor,用來參與最後的loss計算get_loss.py.先來解釋IOUcode

 1 def IOU_calculator( x, y, width, height, l_x, l_y, l_width, l_height ):
 2     '''
 3     x,y,width,height分別爲預測框的中心座標及寬,高,l_x, l_y, l_width, l_height分別爲真實框的中心座標及寬,高
 4     '''
 5     ##x_min=x-w/2,y_min=y-h/2,x_max=x+w/2,y_max=y+h/2 此段意義爲分別求出四個角座標
 6     x_max = calculate_max( x , width / 2 )
 7     y_max = calculate_max( y, height / 2 )
 8     x_min = calculate_min( x, width / 2 )
 9     y_min = calculate_min( y, height / 2 )
10 
11     l_x_max = calculate_max( l_x, width / 2 )
12     l_y_max = calculate_max( l_y, height / 2 )
13     l_x_min = calculate_min( l_x, width / 2 )
14     l_y_min = calculate_min( l_y, height / 2 )
15 
16     '''求相交部分的面積'''
17     xend = tf.minimum( x_max, l_x_max )
18     xstart = tf.maximum( x_min, l_x_min )
19 
20     yend = tf.minimum( y_max, l_y_max )
21     ystart = tf.maximum( y_min, l_y_min )
22 
23     area_width = xend - xstart
24     area_height = yend - ystart
25 
26     '''IOU=A & B/(A+B-A & B)若A與B交集爲0,則返回1e-8'''
27     area = area_width * area_height
28 
29     all_area = tf.cond( ( width * height + l_width * l_height - area ) <= 0, lambda : tf.cast( 1e-8, tf.float32 ), lambda : ( width * height + l_width * l_height - area ) )
30 
31     IOU = area / all_area
32 
33     IOU = tf.cond( area_width < 0, lambda : tf.cast( 1e-8, tf.float32 ), lambda : IOU )
34     IOU = tf.cond( area_height < 0, lambda : tf.cast( 1e-8, tf.float32 ), lambda : IOU )
35 
36     return IOU

get_loss.py爲計算損失函數,他的損失函數計算是按照yolov1來計算的,有點問題。blog

 

 1 def objectness_loss( input, switch, l_switch, alpha = 0.5 ):
 2     '''
 3     input爲IOU,switch爲若預測該框內有object則爲1,不然爲0,l_switch爲實際該框有object則爲1,不然爲0
 4     '''
 5 
 6     IOU_loss = tf.square( l_switch - input * switch )  ##input * switch類別置信度C
 7     loss_max = tf.square( l_switch * 0.5 - input * switch )
 8 
 9     IOU_loss = tf.cond( IOU_loss < loss_max, lambda : tf.cast( 1e-8, tf.float32 ), lambda : IOU_loss )
10 
11     IOU_loss = tf.cond( l_switch < 1, lambda : IOU_loss * alpha, lambda : IOU_loss )
12 
13     return IOU_loss
14 
15 def location_loss( x, y, width, height, l_x, l_y, l_width, l_height, alpha = 5 ):
16     point_loss = ( tf.square( l_x - x ) + tf.square( l_y - y ) ) * alpha
17     size_loss = ( tf.square( tf.sqrt( l_width ) - tf.sqrt( width ) ) + tf.square( tf.sqrt( l_height ) - tf.sqrt( height ) ) ) * alpha
18 
19     location_loss = point_loss + size_loss
20 
21     return location_loss
22 
23 def class_loss( inputs, labels ):
24     classloss = tf.square( labels - inputs )
25     loss_sum = tf.reduce_sum( classloss )
26 
27     return loss_sum

接下來是提取訓練數據的程序extract_labels.py 可下載pascal voc數據集,對照數據的格式來讀數據。比較麻煩,可是這個也是訓練程序與預測程序最大的不一樣點,這份代碼最大的亮點也在此,其餘部分實現我的感受並非很好。數據既能夠讀取類別標籤,也可讀取物體框的信息。圖片

粗略的寫了一份程序解讀,由於只能找到一個tensorflow代碼實現,我的認爲不是很好,但願有人有比較好的復現能夠說一下。同時學好C++很重要呀,就能夠直接讀取源碼了。ssl

相關文章
相關標籤/搜索