问题描述:今日在Tensorflow框架中复现Faster R-CNN时,train.py出现中意外中止(不是终止),即程序并未报错,但停止训练
具体问题:出现keep_inds = np.append(fg_inds, bg_inds) (Pdb)?
网上对于该问题的分析较少,我首先在笔记本(i5 + 某N垃圾独显)上搭建了anaconda+pycharm环境,使用tensorflow-cpu对faster rcnn进行训练,中途发现参数忘记修改,于是stop,之后再进行train.py的时候就出现了(pdb)这个问题;后来换了主机(i7+某A垃圾独显)也出现了上述问题;不服输,换到了服务器(E5 + 4*Titan X)上,依旧出现了该问题
出现该原因的主要原因是多次训练过程中cache缓存文件的积累与交叉不匹配,导致程序不能继续执行。完全删除对应的cache缓存文件,然后对相应代码进行注释,就可以成功执行了。
先是把proposal_target_layer.py中出现的pdb的地方注释了,再把代码生成的库清理干净,重新编译和安装(andaconda的环境中faster-rcnn对应的包是pycocotools)后,再train。 我训练了10000次(代码中40000次,时间太长,改为10000次。但后来发现改成10000次确实能够跑完代码,但是与40000词的iters对比还是有很大的精度差距,本文末会给出差异对比)花了3day(CPU)/8hours(GPU)左右。题外话(GPU确实比CPU要更加强劲)
# Small modification to the original version where we ensure a fixed number of regions are sampled
if fg_inds.size > 0 and bg_inds.size > 0:
fg_rois_per_image = min(fg_rois_per_image, fg_inds.size)
fg_inds = npr.choice(fg_inds, size=int(fg_rois_per_image), replace=False)
bg_rois_per_image = rois_per_image - fg_rois_per_image
to_replace = bg_inds.size < bg_rois_per_image
bg_inds = npr.choice(bg_inds, size=int(bg_rois_per_image), replace=to_replace)
elif fg_inds.size > 0:
to_replace = fg_inds.size < rois_per_image
fg_inds = npr.choice(fg_inds, size=int(rois_per_image), replace=to_replace)
fg_rois_per_image = rois_per_image
elif bg_inds.size > 0:
to_replace = bg_inds.size < rois_per_image
bg_inds = npr.choice(bg_inds, size=int(rois_per_image), replace=to_replace)
fg_rois_per_image = 0
else:
#import pdb
#pdb.set_trace()
print("pdb.set_trace")
训练次数太少,导致没有达到模型的最佳效果
其实很简单,本error背景下手动清除即可完成
其实用python编写好一个工程并在第一次运行后,每个工程根目录下生成了一__pycache__文件夹(里面是和py文件同名的各种 *.pyc 或者 *.pyo 文件)。
原理补充
- 前言
先大概了解一下python基本运行机制。Python程序运行时不需要编译成二进制代码,而直接从源码运行程序,简单来说是,Python解释器将源码转换为字节码,然后再由解释器来执行这些字节码。- 解释器的具体工作:
1 完成模块的加载和链接;
2 将源代码编译为PyCodeObject对象(即字节码),写入内存中,供CPU读取;
3 从内存中读取并执行,结束后将PyCodeObject写回硬盘当中,也就是复制到.pyc或.pyo文件中,以保存当前目录下所有脚本的字节码文件;- 后续
之后若再次执行该脚本,它先检查【本地是否有上述字节码文件】和【该字节码文件的修改时间是否与其脚本一致】。是就直接执行,否则重复上述步骤。- 为什么会出现__pycache__文件夹?
python解释器会将 *.py 脚本文件进行编译,并将编译结果保存到__pycache__目录中。下次再执行工程时,若解释器发现这个 *.py 脚本没有修改过,就会跳过编译这一步,直接运行以前生成的保存在 __pycache__文件夹里的 *.pyc 文件。这样工程较大时就可以大大缩短项目运行前的准备时间;如果你只需执行一个小工程,没关系 忽略这个文件夹就行。- 什么时候会出现__pycache__文件夹?
工程目录下有__main__.py文件,和其他将要调用的模块时。如果只有当前运行的脚本 “main”,则不会生成 pycache 的文件。- 如何使__pycache__文件夹不出现?
1 单次:
运行脚本时添加 -B 参数
python -B foo.py
2 永久:
设置环境变量 PYTHONDONTWRITEBYTECODE=1