tensorflow-yolov3 icon indicating copy to clipboard operation
tensorflow-yolov3 copied to clipboard

evaluate时,检测结果的confidence非常低,导致全部被score_threshold过滤掉。但是把.ckpt文件转换成pb文件后,测试图片正常。

Open llllearner opened this issue 5 years ago • 25 comments

image 如图,输出的检测结果中confidence非常低。 但是下图中用该.ckpt文件转换成的pb进行image_demo测试时,没问题。 image

说明:evaluate.py中self.trainable设置为False时会出现上述问题,设置成True时则可以输出正常的confidence,但是和pb文件检测出来的结果也有比较大的差异,不够这也是正常的毕竟为True的时候表示正在训练。

看其他人问的问题有人说是欠拟合,我感觉不是。我把yolo改成20层,数据集用VOC中的person类,而且训练的loss已经在很多个epoch内应为训练次数没有下降。而且既然欠拟合,为什么pb测试出来的效果还可以接受呢?

llllearner avatar Oct 18 '19 08:10 llllearner

目前排查了这么久,欠拟合的可能性是最大的,毕竟网络在保持原有的基本结构上被删减到20层,性能肯定是大幅度的下降。我还有一个34层的版本,确实没有发生上述问题;但是我的另一个版本,19层(只保留两个输出),按道理应该检测性能更差,但是却没有发生上述问题,所以就很迷。

llllearner avatar Oct 18 '19 08:10 llllearner

另外,其实关于这个问题,我更关心的是,.ckpt文件和pb文件到底差别在哪里,为什么感觉差异如此巨大。希望有大佬看到可以帮我解答一下,在这里先谢过了!!!

llllearner avatar Oct 18 '19 08:10 llllearner

@EEeEhh 欠拟合怎么理解啊老哥,我测试了3个模型,最小的模型把trainable设置为True之后,mAP 上升了,其余两个大一点的模型,都下降了

phoenares avatar Oct 19 '19 06:10 phoenares

@phoenares 我的已经发现原因了:因为我的config文件中的__C.YOLO.MOVING_AVE_DECAY参数的值设置为0.99995,太接近于1。导致ExponentialMovingAverage得到的值和梯度更新得到的值差异比较大,才会出现trainable不同检测结果差异绝大的原因。

trainable=True的时候用的是梯度更新得到的值,train=False的时候用什么值取决于代码。YunYang1994大佬的evaluate.py文件里面有一行代码: image 这里非常关键,表示evaluate的时候用的是ExponentialMovingAverage得到的值;而我们从ckpt文件转换到pb文件的时候,只保存了梯度更新得到的值(我猜测的,这样也可以很好的解释为什么ckpt文件和pb文件的size差异如此巨大),因此会出现pb文件可以正常检测出结果,但是ckpt没有任何输出。

llllearner avatar Oct 19 '19 08:10 llllearner

@phoenares 其实说成欠拟合也勉强可以,因为__C.YOLO.MOVING_AVE_DECAY这个参数过于接近于1,因此即使你看到loss已经收敛完毕,但是其实ExponentialMovingAverage计算的值和当前梯度更新的值差异比较大,因此,继续训练下去的话,理论上是可以消除这个问题的。

llllearner avatar Oct 19 '19 09:10 llllearner

@phoenares 要解决这个问题其实很简单,要么训练的时候就不要用ExponentialMovingAverage(效果有限),这样就可以达到“实时美颜”的效果;要么在上面我画出的evaluate.py文件中的代码,去掉Saver括号里面的代码。

llllearner avatar Oct 19 '19 09:10 llllearner

@phoenares 我的已经发现原因了:因为我的config文件中的__C.YOLO.MOVING_AVE_DECAY参数的值设置为0.99995,太接近于1。导致ExponentialMovingAverage得到的值和梯度更新得到的值差异比较大,才会出现trainable不同检测结果差异绝大的原因。

trainable=True的时候用的是梯度更新得到的值,train=False的时候用什么值取决于代码。YunYang1994大佬的evaluate.py文件里面有一行代码: image 这里非常关键,表示evaluate的时候用的是ExponentialMovingAverage得到的值;而我们从ckpt文件转换到pb文件的时候,只保存了梯度更新得到的值(我猜测的,这样也可以很好的解释为什么ckpt文件和pb文件的size差异如此巨大),因此会出现pb文件可以正常检测出结果,但是ckpt没有任何输出。

您好,我也遇到了类似的情况。按照你的解释是不是在evaluate.py(评估的时候)采用的是指数加权平均得到的值来做检测。而将ckpt文件转化为pb后,使用梯度下降得到的参数来做检测的。那请问一下在用pb文件时,你有没有试过用指数加权平均得到参数来做检测呢?谢谢。

zhouxianming avatar Oct 20 '19 14:10 zhouxianming

@phoenares 要解决这个问题其实很简单,要么训练的时候就不要用ExponentialMovingAverage(效果有限),这样就可以达到“实时美颜”的效果;要么在上面我画出的evaluate.py文件中的代码,去掉Saver括号里面的代码。

我试一下,感谢

phoenares avatar Oct 21 '19 03:10 phoenares

@phoenares 我的已经发现原因了:因为我的config文件中的__C.YOLO.MOVING_AVE_DECAY参数的值设置为0.99995,太接近于1。导致ExponentialMovingAverage得到的值和梯度更新得到的值差异比较大,才会出现trainable不同检测结果差异绝大的原因。

trainable=True的时候用的是梯度更新得到的值,train=False的时候用什么值取决于代码。YunYang1994大佬的evaluate.py文件里面有一行代码: image 这里非常关键,表示evaluate的时候用的是ExponentialMovingAverage得到的值;而我们从ckpt文件转换到pb文件的时候,只保存了梯度更新得到的值(我猜测的,这样也可以很好的解释为什么ckpt文件和pb文件的size差异如此巨大),因此会出现pb文件可以正常检测出结果,但是ckpt没有任何输出。

您好,我也遇到了类似的情况。按照你的解释是不是在evaluate.py(评估的时候)采用的是指数加权平均得到的值来做检测。而将ckpt文件转化为pb后,使用梯度下降得到的参数来做检测的。那请问一下在用pb文件时,你有没有试过用指数加权平均得到参数来做检测呢?谢谢。

llllearner avatar Oct 21 '19 06:10 llllearner

@phoenares 我的已经发现原因了:因为我的config文件中的__C.YOLO.MOVING_AVE_DECAY参数的值设置为0.99995,太接近于1。导致ExponentialMovingAverage得到的值和梯度更新得到的值差异比较大,才会出现trainable不同检测结果差异绝大的原因。

trainable=True的时候用的是梯度更新得到的值,train=False的时候用什么值取决于代码。YunYang1994大佬的evaluate.py文件里面有一行代码: image 这里非常关键,表示evaluate的时候用的是ExponentialMovingAverage得到的值;而我们从ckpt文件转换到pb文件的时候,只保存了梯度更新得到的值(我猜测的,这样也可以很好的解释为什么ckpt文件和pb文件的size差异如此巨大),因此会出现pb文件可以正常检测出结果,但是ckpt没有任何输出。

您好,我也遇到了类似的情况。按照你的解释是不是在evaluate.py(评估的时候)采用的是指数加权平均得到的值来做检测。而将ckpt文件转化为pb后,使用梯度下降得到的参数来做检测的。那请问一下在用pb文件时,你有没有试过用指数加权平均得到参数来做检测呢?谢谢。


在前面我说了,我猜测pb文件只保存了梯度更新得到的值,才会在size上和ckpt文件差异那么大。

llllearner avatar Oct 21 '19 06:10 llllearner

我现在测试ckpt和pb文件指标可以对齐了。加载模型的时候用不用ExponentialMovingAverage会有一点影响,在我这里是1个多点的影响。我这边主要是把image_demo.py里BGR转RGB那行去掉了,因为在utils.image_preprocess里做过了

phoenares avatar Oct 21 '19 12:10 phoenares

我现在测试ckpt和pb文件指标可以对齐了。加载模型的时候用不用ExponentialMovingAverage会有一点影响,在我这里是1个多点的影响。我这边主要是把image_demo.py里BGR转RGB那行去掉了,因为在utils.image_preprocess里做过了

这个是一方面,但是这个影响是比较小的。

llllearner avatar Oct 22 '19 02:10 llllearner

用作者提供的model,无论是ckpt和pb画出来的框都特别大

hp-cuiwb avatar Oct 23 '19 04:10 hp-cuiwb

用作者提供的model,无论是ckpt和pb画出来的框都特别大

框大指的是?然后和这里的讨论的问题是什么关系?

llllearner avatar Oct 24 '19 05:10 llllearner

如图,输出的检测结果中confidence非常低。 但是下图中用该.ckpt文件转换成的pb进行image_demo测试时,没问题。

说明:evaluate.py中self.trainable设置为False时会出现上述问题,设置成True时则可以输出正常的confidence,但是和pb文件检测出来的结果也有比较大的差异,不够这也是正常的毕竟为True的时候表示正在训练。 看其他人问的问题有人说是欠拟合,我感觉不是。我把yolo改成20层,数据集用VOC中的person类,而且训练的loss已经在很多个epoch内应为训练次数没有下降。而且既然欠拟合,为什么pb测试出来的效果还可以接受呢?

我也出现了和您一样的问题,不过我self.trainable设置成什么都不能出现正常的confidence。。

robinjoe93 avatar Oct 29 '19 07:10 robinjoe93

如图,输出的检测结果中confidence非常低。 但是下图中用该.ckpt文件转换成的pb进行image_demo测试时,没问题。 说明:evaluate.py中self.trainable设置为False时会出现上述问题,设置成True时则可以输出正常的confidence,但是和pb文件检测出来的结果也有比较大的差异,不够这也是正常的毕竟为True的时候表示正在训练。 看其他人问的问题有人说是欠拟合,我感觉不是。我把yolo改成20层,数据集用VOC中的person类,而且训练的loss已经在很多个epoch内应为训练次数没有下降。而且既然欠拟合,为什么pb测试出来的效果还可以接受呢?

我也出现了和您一样的问题,不过我self.trainable设置成什么都不能出现正常的confidence。。

decay设置成0.995,多跑一会,基本上就不会有啥问题了。炼丹技术好一点的decay可以设置的大一些!

llllearner avatar Oct 29 '19 09:10 llllearner

我现在测试ckpt和pb文件指标可以对齐了。加载模型的时候用不用ExponentialMovingAverage会有一点影响,在我这里是1个多点的影响。我这边主要是把image_demo.py里BGR转RGB那行去掉了,因为在utils.image_preprocess里做过了

确实如你所说,pb文件输出了正确的图片检测结果,但是图片的色彩发生了变换,和原图不一样,偏蓝,我觉得还需要转回来

gzz1529657064 avatar Nov 29 '19 10:11 gzz1529657064

太感谢了!更改evaluate.py后就可以了。解决了大问题。

netist123 avatar Dec 16 '19 08:12 netist123

@EEeEhh 請問你是如何刪減yolo層數的,我試著更改yolov3.py裡的build_nework,更改後能夠訓練,loss也會收斂,但在進行evaluate.py的時候會出現error如下, Assign requires shapes of both tensors to match. lhs shape= [1,1,256,147] rhs shape= [1,1,256,18] [[node save/Assign_60 (defined at freeze_graph.py:29) ]]

Errors may have originated from an input operation. Input Source operations connected to node save/Assign_60:

prockonp avatar Feb 18 '20 17:02 prockonp

@EEeEhh 請問你是如何刪減yolo層數的,我試著更改yolov3.py裡的build_nework,更改後能夠訓練,loss也會收斂,但在進行evaluate.py的時候會出現error如下, Assign requires shapes of both tensors to match. lhs shape= [1,1,256,147] rhs shape= [1,1,256,18] [[node save/Assign_60 (defined at freeze_graph.py:29) ]]

Errors may have originated from an input operation. Input Source operations connected to node save/Assign_60:

你这个问题暂时没有遇到过。一般可以训练的网络,在测试的时候都是可以的。

llllearner avatar Mar 06 '20 02:03 llllearner

我现在测试ckpt和pb文件指标可以对齐了。加载模型的时候用不用ExponentialMovingAverage会有一点影响,在我这里是1个多点的影响。我这边主要是把image_demo.py里BGR转RGB那行去掉了,因为在utils.image_preprocess里做过了

可能需要去看看cv2里面转换这个到底什么意思。因为image_demo.py只转一次的话 得到图片颜色是不对的。 所以需要知道到底是image.py转两次是正确的,还是evaluate转一次是正确的。

ggdonald avatar Mar 19 '20 17:03 ggdonald

感谢楼主!修改evaluate.py后解决了问题!

sqWa avatar May 07 '20 12:05 sqWa

楼主,我把作者的单路检测复制了一遍,改成了双路检测(其他不变),分别输入两种数据,出现了evaluate.py运行时confidence特别低的情况,loss在第二个迭代基本稳定了,有什么解决办法吗,谢谢

CNUyue avatar May 24 '20 02:05 CNUyue

我测试过,跟滑动均值无关,即使按照上面的方法也预测的不行,我用的是我的数据集,所有重新生成了anchor,重新训练后,置信度很高,没有出现很低的情况

xinghuokang avatar Jun 09 '20 02:06 xinghuokang

@phoenares 要解决这个问题其实很简单,要么训练的时候就不要用ExponentialMovingAverage(效果有限),这样就可以达到“实时美颜”的效果;要么在上面我画出的evaluate.py文件中的代码,去掉Saver括号里面的代码。

事实证明,这个解决方案是对的。 我的情况是pb测试正确,但evaluate.py的结果是所有的目标的检测框都是一样的,而且每个框的右边和下面都框到了图片的右边界和下边界。

改变evaluate.py的self.trainable为True并没有什么影响,可能我的数据集比较简单

taojianggit avatar May 06 '21 08:05 taojianggit