我的经验适用于直接下载解压别人源码后无法运行的,如果是自己改写的代码,还是检查一下__init__.py里有没有import xxx,或者 __all__里有没有注册xxx。
直入主题,先说解决方案:从python环境里卸载mmdet (pip uninstall mmdet -y),删除源程序目录,重新解压项目源代码 (unzip YourProject.zip)。进入项目目录 (cd YourProject),再编译打包整个项目 (python setup.py develop),这样就可以正常跑程序了。
解释原因:
今天第一次接触用mmdet写的项目,把别人的源码下载后想跑一下学习学习。结果怎么着都运行不起来,各种'xxx is not in the xxx registry',百度后说多运行几遍 python setup.py develop,可惜一点卵用都没有。
最后我研究了一下setup.py里面的内容,最后明白了 setup.py 的作用是把整个项目源代码打包,作为一个新的python包供自己跑程序使用,这个包的名字就叫 mmdet,没错,原作者自己写了一个python项目,叫mmdet。
那作为小白,很容易犯的一个错误就是说,我要跑的程序是用mmdet的,那我得先安装mmcv-full和mmdet,于是愉快的 pip install mmcv-full, pip install mmdet==1.18.1。然后解压源码,输入python tools/train.py config.py --no-validate,这时傻眼了:冒出一堆错误,各种未注册。但是看init.py里也清清楚楚的注册了,奇了怪了。
最后我猜测,项目源码经过python setup.py develop打包后叫mmdet,我之前pip install的也叫mmdet,有可能是冲突了,从清华源安装的mmdet肯定不包括自定义的各种模块,自然也就全都未注册了。
所以对症下药,把原来从清华源下载的mmdet卸载,删掉项目目录,重新解压项目源码,编译项目python setup.py develop,大功告成!
至于为什么自己的项目源码要打包成mmdet这样的名字,个人理解,mmdet可以当做是一个可自由定制的python模块,自己有什么想法就实现之,注册后就往config里加,渐渐地,mmdet里包含的内容远不止原始的mmdet那么简单,就需要编译打包成自己的包,而恰好train.py 里面 import mmdet了,那就打包成mmdet呗。
困扰了我一周的玄学问题,终于解决了,泪奔。
补充,如果卸载重装mmdet还是会报错xxx未注册,在pycharm里写个xxx,然后右键选择Find in Files查看一下未注册的那个类在哪,比如我后来又报错 PartAttention 这个类未注册,查看发现它在mmcv/mmcv/ops里面注册的。
但是我刚才只卸载重装了mmdet,mmcv没管,那很简单,把mmcv也卸载重装一次就好了。 先pip uninstall mmcv-full,pip uninstall mmcv,再cd mmcv,MMCV_WITH_OPS=1 pip install -e .
这里需要注意的是,在Windows下 cmd中 MMCV_WITH_OPS=1是无法识别的,执行pip install -e .后安装的是mmcv(我们需要mmcv-full),等会训练时还是会报错No module named 'mmcv._ext'。因此,重装mmcv尽量在Linux上安装,实在想在Windows下安装了,打开Windows powershell,MMCV_WITH_OPS=1 pip install -e .就行了,不过我安装时发现powershell下无法切换conda环境,有人说是要把conda版本改成4.6.3才行,我没试。