使用Faster-Rcnn训练自己的数据集遇见的问题

最近使用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环境下配置实现。

你可能感兴趣的:(faster-rcnn)