AITTSMD / MTCNN-Tensorflow

Reproduce MTCNN using Tensorflow
1.51k stars 713 forks source link

gen_hard_example.py中有些地方没看明白 #1

Open kismde opened 7 years ago

kismde commented 7 years ago

您好,非常感谢您开源了mtcnn的训练代码!我一直比较好奇mtcnn的训练数据是如何构造的,所以主要看了您的prepare_data代码。在看gen_hard_example.py时,有3个疑问,请求解答: 1、这份代码的目的是为RNet或者ONet准备数据,所以,对应的应该是输入数据到PNet或PNet-RNet,得到预测的bbox,再进行IoU判断,最终得到pos,neg,part这三种标记。请问是这样理解的吗? 2、函数t_net中的数据源filename = './wider_face_train_bbx_gt.txt',是如何得到的? 3、函数t_net为什么需要ONet?如代码第142,148行,而且并没有从from train_models.mtcnn_model import O_Net。

AITTSMD commented 7 years ago

@wangkgege 您好,很高兴您对我的工作感兴趣。 1、您的理解是对的。 2、wider_face_train_bbx_gt.txt是wider face官网上给出的标签文件,您可以参考链接http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/ 3、恩,其实没必要再使用ONet,因为ONet是最后一个网络,不需要再用它生成训练数据。

kismde commented 7 years ago

@AITTSMD ,非常感谢!还有两个小问题,请求解答: 1、在代码gen_12net_data.py中,第127-130行,我猜测,公式计算的应该是,裁剪后的图片对应的bbox坐标。但我只看公式的话,还是没想象出是怎样的对应关系?而且计算出来的这些值offset_x1等,是否可能是负值呢? 2、在代码gen_landmark_aug_12.py中,第111行,if iou > -1,这个iou值肯定是>=0的吧?

AITTSMD commented 7 years ago

@wangkgege 1 我们制作bbox回归标签的时候,需要进行转化,具体做法:设随机裁剪box的左上角坐标(nx1,ny1),右下角坐标(nx2,ny2),宽和高分别为width 和height,与之对应的groudtrue box左上角为(x1,y1)。则nx1_offset = (x1-nx1)/width,ny1_offset=(y1-ny1)/height。nx2_offset 和ny2_offset计算方式类似。对!可能出现负值。 2 sorry,这里是我搞错了,应该是IOU>0.65(因为这里通过平移进行数据扩充,需要平移后的bbox与原bbox有较大的IOU的值)。

kismde commented 7 years ago

@AITTSMD ,赞!感谢大神赐教!

wangchust commented 7 years ago

请教一下,gen_hard_example.py 119行的那个threshold的值,RNet对应的怎么和其它两个差了一个数量级呢

AITTSMD commented 7 years ago

@wangchust 这个是为了多产生一些训练样本训练RNet或者ONet,所以将判定正样本的阈值设定的比较低。

wangchust commented 7 years ago

@AITTSMD 多谢,在跑gen_hard_example.py文件时,会在line46报错,是因为line164这个取得是前100个,而num_of_images是全部,我修改的话是去掉100还是在num_of_images加上一百呢,P.S. line166这里跑的非常慢。

AITTSMD commented 7 years ago

@wangchust 去掉100,我当时是为了测试代码的准确性,就是选了前100张图片。line166那里是检测人脸,速度慢正常。

wangchust commented 7 years ago

非常感谢 @AITTSMD

BobLiu20 commented 7 years ago

@AITTSMD 大兄弟,能否把已发现错误的代码修改一下上传呢,方便后面的兄弟们,我研究了好久才发现gen_hard_example.py的Line 164多了一个100,才解决导致每次都后面报错。。。 最后非常感谢你的code!!!

AITTSMD commented 7 years ago

@BobLiu20 修改啦~

BobLiu20 commented 7 years ago

@AITTSMD 代表后来的兄弟们感谢哈。看了166行慢的问题,因为当图片尺寸大时,会产生几十万个候选框,然后用py_nms时,非常非常耗时,速度慢就是因为py_nms这里应对几十万个候选框。可惜现在我没有想出好办法,目前只能在MtcnnDetector里的detect_face函数里开了56进程同时处理处理那些图片,不然不知道跑到什么时候,哭。。。any idea?

AITTSMD commented 7 years ago

@BobLiu20 你的图像数据尺寸是多大的哈?不是用的wider face吗?我记得当时做实验的时候就不是很耗时。

wangchust commented 7 years ago

@BobLiu20 是的,我也统计了下时间,发现是nms最耗时 predict time: 0.104 gen_box time:0.005 nms time: 13.303 predict time: 0.065 gen_box time:0.003 nms time: 6.353 predict time: 0.067 gen_box time:0.002 nms time: 1.345 predict time: 0.051 gen_box time:0.001 nms time: 0.728 predict time: 0.043 gen_box time:0.001 nms time: 0.285 predict time: 0.026 gen_box time:0.001 nms time: 0.115 predict time: 0.022 gen_box time:0.000 nms time: 0.057 predict time: 0.021 gen_box time:0.000 nms time: 0.031 predict time: 0.009 gen_box time:0.000 nms time: 0.013 predict time: 0.011 gen_box time:0.000 nms time: 0.007 predict time: 0.006 gen_box time:0.000 nms time: 0.003 predict time: 0.010 gen_box time:0.000 nms time: 0.002 predict time: 0.005 gen_box time:0.000 nms time: 0.001 predict time: 0.013 gen_box time:0.000 nms time: 0.000 predict time: 0.004 gen_box time:0.000 nms time: 0.000 predict time: 0.002 gen_box time:0.000 nms time: 0.000 merge time: 14.779
time cost 42.612 pnet 37.727 rnet 0.000 onet 0.000 一张图片大概这样@AITTSMD

AITTSMD commented 7 years ago

@wangchust 这个是用PNet产生RNet的训练数据?修改别的参数了吗(下采样的比率,最小人脸大小),我记得做实验的时候,生成RNet训练数据,速度没这么慢呀

BobLiu20 commented 7 years ago

@AITTSMD 我用的和你一样的数据,其它地方没有更改,生成RNet训练数据时,一张图片需要耗时16秒,都是nms消耗的,在最大size时会生成出几十万个候选框,导致nms很耗时。和你有差别,难道是我PNet训练的不够好?导致预测生成的候选框超级多?我是用你默认的训练到最大epoch,有点奇怪

wangchust commented 7 years ago

@AITTSMD 没有改参数

wangchust commented 7 years ago

@BobLiu20 有可能,生成PNET训练数据的文件gen_12net_data.py line35 for annotation in annotations[:20]:只选取了前20个

AITTSMD commented 7 years ago

@BobLiu20 @wangchust 对不起大家了,我之前的代码中[:20]和[:100]是为了测试一下修改代码后的正确性,所以只选择了部分样本。你们在实际训练过程中应该把这些去掉,因为我们需要对所有的数据进行训练。sorry!

velvetcake commented 6 years ago

你好,非常感谢您开源的代码。 1、在准备数据过程中:gen_hard_example.py产生RNet和ONet训练的数据,但是使用的wider_face_train_bbx_gt.txt数据为什么和PNet的训练数据不是同一个数据呢?\2、我已将celea数据修正,能否统一用这个数据呢?这样的话,该如何修改?

AITTSMD commented 6 years ago

@velvetcake 你好 1 数据是一样的哈,只是格式不同。 2 按landmark部分的数据格式,整理数据就可以了。 ps:celea的数据你是怎么修正的呢?

velvetcake commented 6 years ago

@AITTSMD 谢谢你。 celea数据中landmark可视化出来是准确的,通过landmark反过来重新画出的bbox

Victcode commented 6 years ago

您好,非常感谢您的分享,我有个问题想请教一下: gen_hard_example.py产生hard样本,hard是怎么体现的?

AITTSMD commented 6 years ago

@Victoth 参考一下论文哈,loss值大的样本就是hard的

tpys commented 6 years ago

@AITTSMD gen_hard_example.py Doesn't this hard example generate by cascade and IoU definite? the sorted loss value is used during training, so called online HEM, right ?

AITTSMD commented 6 years ago

@tpys According to original paper,the author sorts the loss computed in the forward propagation phase from all samples and selects the top 70% of them as hard samples.That is called OHEM.

tpys commented 6 years ago

@AITTSMD I got it, thanks.

qiudi0127 commented 6 years ago

@AITTSMD您好,我有两个问题想请教一下: 1如果自己生成wider_face_train_bbx_gt.txt标注文件的话,文件的0都是代表什么? 2我看训练人脸和关键点是两个数据集,那么这两部分训练时分开的么?

AITTSMD commented 6 years ago

@qiudi0127 不好意思,回复晚了。 1 widerface数据集中的readme.txt给了详细的说明,你可以参考一下。x1, y1, w, h, blur, expression, illumination, invalid, occlusion, pose 2 训练的方式Some Details中给了说明。两个数据集都制作成tfrecord的形式,训练的时候是一起训练的。

qiudi0127 commented 6 years ago

@AITTSMD 了解,感谢回复。

zengbing1992 commented 6 years ago

@AITTSMD 您好,请问一下: 关于wider_face_train_bbx_gt.txt的后面六位(blur, expression, illumination, invalid, occlusion, pose)在训练时是否需要用到,如果没有后面6位没有,只有x1, y1, w, h能正常训练吗?

AITTSMD commented 6 years ago

@zengbing1992 我没有用到哦,后六位是控制难度的,你可以看看widerface中的readme

LvNianZu commented 6 years ago

您好,请问一下.MtcnnDetector.py的generate_bbox函数里面 stride = 2是什么意思呢? @AITTSMD

qianwenjun0801 commented 6 years ago

如果修改了网络后,之前的模型都不可以用了。那么模型没有的情况下,怎么启动gen_hard_example呢? 请问您上传的MTCNN_model怎么得到的?

AITTSMD commented 6 years ago

@qianwenjun0801 rnet的训练样本通过pnet得到的,onet的训练样本通过rnet得到的,必须要有前面的网络。

qiudi0127 commented 6 years ago

@AITTSMD 您好,gen_hard_example.py可以用detector.py去定义Pnet人脸检测器么

ZhangMeiwei commented 6 years ago

你好,我在gen_12net_data.py中读取wider_face_train_bbx_gt.txt(你的代码是wider_face_train.txt,但我下载下来的数据集是mat格式的,txt格式的并不是这个名字),因为代码是按行来读取的,但是这个txt中一个样本分很多行 请问我的txt哪里出错了呢?

zzzzzz0407 commented 6 years ago

@ZhangMeiwei 这个wider_face_train.txt是作者直接帮你整理完的,当前文件夹就又,我看了一下应该和bbx_gt的box数据是一样的,直接用就好了

stone226 commented 6 years ago

@velvetcake , 你好,能共享你修改后的celea数据吗

grainw commented 6 years ago

@AITTSMD 有个问题咨询下,在训练rnet时,副样本大约60万,正样本2.5万。训练完rnet,运行gen_hard_example.py 时,产生的副样本为8546条,而正样本3.8万条。这种情况正常吗?是因为rnet模型过拟合了吗,导致产生的候选框,都比较精确。所以正样本更多了。

grainw commented 6 years ago

@AITTSMD 继续追问一下,训练完rnet,运行gen_hard_example.py 为ONet 提供训练样本时,为了能让ONet有足够多的副样本,现在发现两种方式,一种是用只迭代2次epoch的rnet模型来生成样本,第二种是提高IOU的阈值。那种方式更可行呢。可否提个建议

grainw commented 6 years ago

@AITTSMD 还是保持这个样,不管正负样本的数量,不去改程序

AITTSMD commented 6 years ago

@grainw 这种情况不正常,我觉得主要问题如下: 1 训练rnet时的正样本数目太少,我当时训练rnet时会产生14w+的正样本。 2 在用rnet生成onet的训练数据集时,不可能产生这么少的负样本(检查一下参数)。 3 如果还是有问题, 训练完成rnet后,观察一下rnet的训练准确率,再用fddb测试一下rnet的召回率。 4 用迭代2次epoch的rnet模型来生成样本可以试试,但意义不大,因为训练好的rnet会把这些负样本排除,不需要onet再次判断。 5 总之我认为问题主要是rnet没有训练好,pnet也有问题,因为其产生的正样本数量太少。

Edwardmark commented 6 years ago

@wangchust 我也遇到了这个问题,请问你之前时怎么解决的?生成数据确实太慢了啊

wangchust commented 6 years ago

@Edwardmark 是因为生成训练数据的代码之前是测试正确性用的,只选取了前20个,导致Pnet训练的不好,预选框超多。你把[:20]去掉就行,楼上有讨论过

Edwardmark commented 6 years ago

@wangchust 我现在生成一张图的Pnet结果,大概平均要1s,感觉还是太慢了啊,我没有使用[:20][:100]

zaidao2023 commented 6 years ago

@BobLiu20 你好 开了多线程后生成难例 速度有提升么?我的也非常慢,可以把多线程版的detector分享一下 么

Maxwell2016LeChouchou commented 5 years ago

您好,感谢您的开源代码,我想问一下当我开始跑gen_hard_example.py的时候,调用fcn_detector.py和data_utils.py,可是在data_utils.py里面第71行train.txt和137行wider_face_train_bbx_gt在哪里找?