最近使用Faster-rcnn在自己的數據集上訓練,標註格式和VOC2007一樣,期間遇見了很多的bug,希望能幫助到遇見同樣bug的小夥伴。
歡迎大家一起探討,有問題的地方請大家指出。
1.數據集製作
數據集製作的話是用label image軟件對圖片中的box進行標註,會自動生成相應的xml文件,labelimage的github地址。
注意:VOC2007數據集的標註是1-based的,所以讀進來的(Xmin,Ymin,Xmax,Ymax)均要進行減1的操作。但是使用label-image標註的圖片是0-based的,不必減1,不然某些圖片的box的座標值出現0-1=65535,數據溢出,在調用append_flipped_images函數時出現:
assert (boxes[:, 2] >= boxes[:, 0]).all()的錯誤,此類錯誤的解決辦法方法參考Faster-RCNN訓練自己數據集遇到的問題集錦。
2.遇見的錯誤
error1: image invalid, skipping
出現問題的來源是train.py文件中的異常:
try:
rpn_loss_cls, rpn_loss_box, loss_cls, loss_box, total_loss = self.net.train_step(sess, blobs, train_op)
except Exception:
# if some errors were encountered image is skipped without increasing iterations
print('image invalid, skipping')
continue
此時打印出異常類型即可知道報錯的位置,修改後的代碼如下:
except Exception as e:
print(e.message)
print(e)
# if some errors were encountered image is skipped without increasing iterations
print('image invalid, skipping')
continue
大部分情況是fg_inds和bg_inds的數量都小於0,導致proposal_target_layer.py中的 _sample_rois函數拋出異常,所以直接跳過這張圖。
解決辦法:將config.py中的roi_bg_threshold_low的值從改爲0,如果仍然報錯,根據上述代碼找到報錯的位置並具體分析。
error2 圖片不resize引起的一系列問題
我實際使用的圖片的shape爲(32,512),原始的網絡需要將height經過縮放變爲600,並將這個縮放比例乘以原始的width得到新的圖片。這樣的話圖片非常巨大,因此我選擇直接輸入(32,512)的圖片,不進行resize,此時將config.py中的FLAGS2[“scales”] = (32,)設置爲32即可,即將FLAGS2[“scales”]的第一個參數調整爲你將要輸入圖片的height,那麼圖片不會resize。
此外,直接使用原來的VGG16的預訓練模型提取特徵會導致特徵過小以致於anchor的數量不夠。在vgg16.py中的build_head函數中有四個步長爲2的最大池化,那麼原圖經過build_head函數得到的feature的width,height均會縮減至原圖的width,height的1/16(估算,實際有padding,feature的width,height會大於原圖的1/16)。
步驟1:修改網絡框架
此時需要刪除一些max_pool層及相應的conv層,我選擇刪除build_head函數中的最後兩層,輸出的feature 變爲[1,8,128,256],因此需要將build_rpn中第一層的卷積核的深度從512變爲256.
由於feature的shape出現變化,因此不能加載vgg16的預訓練模型訓練,此處我選擇的初始化爲:
initializer = tf.truncated_normal_initializer(mean=0.0, stddev=0.01)
步驟2:修改ancor的大小
a:由於將4層池化變爲兩層池化,需要將network.py以下代碼的16變爲4:
self._feat_stride = [16, ]
self._feat_compress = [1. / 16., ]
當然也可以選擇在vgg16中__init__函數對上述變量進行重新賦值:
class vgg16(Network):
def __init__(self, batch_size=1):
Network.__init__(self, batch_size=batch_size)
self._feat_stride = [4, ] # 賦值爲4
self._feat_compress = [1. / 4., ] # 賦值爲1/4
b 在train.py中的調用的self.net.create_architecture傳入新的anchor_scales和anchor_ratio,因爲默認設置的是anchor_scales=[8,16,32],直接就超出了,需要根據實際情況調整scales的值,我是將其變爲(2,4,8)。
layers = self.net.create_architecture(sess, "TRAIN",
self.imdb.num_classes,tag='default',
anchor_scales=(2, 4, 6),
anchor_ratios=(0.5, 1, 2))
此外,初始的anchor大小也得設置。這部分需要更改generate_anchors.py中的generate_anchors()函數中的anchor_base的數值,原來的anchor_base是16,由於我現在的圖片比較小,我將其設置爲4。
參考文獻
1.我使用的faster-rcnn在github上的地址。
2.Faster-RCNN訓練自己數據集遇到的問題集錦。
3.Faster-RCNN源碼解析。
4.用自己的數據訓練Faster-RCNN,tensorflow版本。
5.faster-rcnn的tensorflow的代碼理解 。
6.Faster R-CNN Tensorflow+python 3.5 在Windows10環境下配置實現。