配置 yolov5 环境(Windows)踩坑史

一、前言

前一段时间打了一个数据科学竞赛,发现自己的不足之处,并未对深度学习进行下一步学习,而是去实操,练习一下应用能力。

这一次,参加另外一个比赛,做一个智能垃圾桶。

所谓智能,就是能够识别垃圾类别,放到对应的垃圾桶里面。核心是目标检测算法,这里采用的是yolov5。接下来讲一下配置环境后,运行yolov5测试所遇到的报错,帮助大家避雷。

二、配置环境

配置环境,我没有什么可说的,网上教程一抓一大把,这里我推荐的是 史上最详细yolov5环境配置搭建+配置所需文件.

需要注意的是,看好自己电脑是否有英伟达显卡,没有的话,pytorch需要按照CPU版本的。

三、运行yolo报错

1、本人环境

  • conda 23.7.4
  • PyCharm 2023.2.1 (Professional Edition)
  • Python 3.8.18
  • Pytorch 2.0.1+cpu

2、AttributeError: Can’t get attribute ‘SPPF’ on <module ‘models.common’ from ‘E:\yolov5\models\common.py’>

配置好环境后,使用 python detect.py 测试是否部署成功,结果出现了第一个报错。

报错内容如下

Traceback (most recent call last):
  File "detect.py", line 175, in <module>
    detect()
  File "detect.py", line 33, in detect
    model = attempt_load(weights, map_location=device)  # load FP32 model
  File "E:\yolov5\models\experimental.py", line 118, in attempt_load
    ckpt = torch.load(w, map_location=map_location)  # load
  File "D:\Anaconda\envs\Smart_Garbage_Can\lib\site-packages\torch\serialization.py", line 809, in load
    return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
  File "D:\Anaconda\envs\Smart_Garbage_Can\lib\site-packages\torch\serialization.py", line 1172, in _load
    result = unpickler.load()
  File "D:\Anaconda\envs\Smart_Garbage_Can\lib\site-packages\torch\serialization.py", line 1165, in find_class
    return super().find_class(mod_name, name)
AttributeError: Can't get attribute 'SPPF' on <module 'models.common' from 'E:\\yolov5\\models\\common.py'>

报错原因:无法在名为models.common的模块中找到SPPF属性引起的。

首先在网上搜索了一下,发现都是在 models/common.py 里面添加 SPPF 类,可是这样治标不治本啊,为什么要添加这个类?

然后,我在Github yolov5的issues里面查了一下,发现有一个优质解答

在这里插入图片描述

大致原因就是 Ultralytics 发布了yolo新版本,与v5不兼容,想要用v5的代码需要修改一个地方。

修改文件路径 : yolov5/utils/google_utils.py 第25行

原来代码为

response = requests.get(f'https://api.github.com/repos/{repo}/releases/lastest').json()  # github api

可以看到,默认获取是最新版本的,咱们需要改为v5的即可

response = requests.get(f'https://api.github.com/repos/{repo}/releases/tag/v5.0').json()  # github api

在这里插入图片描述

3、AttributeError: ‘Upsample’ object has no attribute ‘recompute_scale_factor’

紧接着,第二个报错就出现了。

image 1/2 E:\yolov5\data\images\bus.jpg: Traceback (most recent call last):
  File "detect.py", line 175, in <module>
    detect()
  File "detect.py", line 72, in detect
    pred = model(img, augment=opt.augment)[0]
  File "D:\Anaconda\envs\Smart_Garbage_Can\lib\site-packages\torch\nn\modules\module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "E:\yolov5\models\yolo.py", line 121, in forward
    return self.forward_once(x, profile)  # single-scale inference, train
  File "E:\yolov5\models\yolo.py", line 137, in forward_once
    x = m(x)  # run
  File "D:\Anaconda\envs\Smart_Garbage_Can\lib\site-packages\torch\nn\modules\module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "D:\Anaconda\envs\Smart_Garbage_Can\lib\site-packages\torch\nn\modules\upsampling.py", line 157, in forward
    recompute_scale_factor=self.recompute_scale_factor)
  File "D:\Anaconda\envs\Smart_Garbage_Can\lib\site-packages\torch\nn\modules\module.py", line 1614, in __getattr__
    raise AttributeError("'{}' object has no attribute '{}'".format(
AttributeError: 'Upsample' object has no attribute 'recompute_scale_factor'

该错误的原因是使用了一个过时的API

在早期版本的PyTorch中,使用’recompute_scale_factor’属性来重新计算缩放因子。然而,在较新的版本中,API已经更新,’recompute_scale_factor’属性被删除了,因此代码会引发上述错误。

而网络上普遍的解决办法都是修改torch源码,这样是不正确的,因为这个是底层,在其他地方也有调用,可能会导致一些未知的错误出现。

所以我们应该采取另外一种方案,加一个判断语句。

修改文件路径:yolov5\models\yolo.py 第124行

修改代码如下

    def forward_once(self, x, profile=False):
        y, dt = [], []  # outputs
        for m in self.model:
            #添加下面两行判断语句
            if isinstance(m, nn.Upsample):
                m.recompute_scale_factor = None
            #分割线
            if m.f != -1:  # if not from previous layer
                x = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f]  # from earlier layers

            if profile:
                o = thop.profile(m, inputs=(x,), verbose=False)[0] / 1E9 * 2 if thop else 0  # FLOPS
                t = time_synchronized()
                for _ in range(10):
                    _ = m(x)
                dt.append((time_synchronized() - t) * 100)
                print('%10.1f%10.0f%10.1fms %-40s' % (o, m.np, dt[-1], m.type))

            x = m(x)  # run
            y.append(x if m.i in self.save else None)  # save output

        if profile:
            print('%.1fms total' % sum(dt))
        return x

其实就是一个判断语句,为了适应新版本的要求。

isinstance(m, nn.Upsample) 用于判断变量 m 是否是 nn.Upsample 类的实例。如果是,则执行下一行代码 m.recompute_scale_factor = None,将 recompute_scale_factor 属性设置为 None,以适应新版本PyTorch的要求。

四、测试结果

经过上面的修改后,在PyCharm的控制台输入 python detect.py 即可成功运行。运行成功后,会在 yolov5文件夹下出现一个 runs文件夹,在里面查看即可。

查看路径 yolov5/runs/detect/exp

在这里插入图片描述

在这里插入图片描述

五、写在最后

当出现报错后,在网上搜索后,不要盲目跟着 CSDN 的解决方法去做。而是应该先去知道为什么报错,然后再去解决它。现在网上很多博客都是为了解决这个问题而解决,从未想过为什么会出现这个报错。盲目修改底层源码后,会导致后面可能会出现从未见过的报错,尽量不要轻易修改。

后面会讲一下如何做一个智能垃圾桶(程序方面),敬请期待哈。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值