yolov3训练实现火焰检测(pytorch)

前言

最近因为某些原因所以弄了个火焰检测,所以就上网找了一些攻略,发现这个博主写的确实挺详细的,所以就fork他的代码跑了一下,不跑不知道,bug有一堆,没有不尊敬的意思,是因为时效性的问题,很多数据包更新会导致bug。于是耐下心慢慢debug,最后还是顺利的跑通了。
不得不说yolov3还是蛮厉害的。
先献上博主链接:pytorch版本下的yolov3训练实现火焰检测_Mind_programmonkey的博客-CSDN博客
大家也可以看看他是如何实现的,虽然有bug,感谢该博主的贡献。
然后献上我的github:https://github.com/Niki173/YOLOV3_Fire_Detection ,喜欢记得star哦!(划重点!!!)
该选哪个,大家看着办吧。哈哈哈。现在我就沿着该博主的思路,给大家讲解一下,并告诉存在bug在哪。

正文

1、首先无脑clone

!git clone https://github.com/Niki173/YOLOV3_Fire_Detection.git

2安装所需要的环境,安装包

!pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt

3.下载所需的权重预训练权重
先运行

cd weights/

进入该文件夹再运行

bash download_weights.sh

4.配置本次yolov3的数据格式

首先你要去找火焰数据集,数据集要包含这两个Annotations和JPEGImages的文件夹,将准备好的图片和xml标记信息放于其中。具体怎么找就看你们搜索能力的,我也搜了好久才找到合适的,本来放上来的,但是太懒了,总不能惯着你们吧,哈哈哈。回到正题,准备好之后,要在data/custom文件夹下先建立两个新的文件夹,一个images(存照片)和labels(存标签信息),然后把JPEGmages的照片复制到images,因为之后用得着。用下列代码就可以自动复制过去了,真丝滑。

import os
import shutil
path = '/content/gdrive/MyDrive/VOC2020/JPEGImages'#原先图片放的文件夹
new_path ='/content/gdrive/MyDrive/YOLOV3_Fire_Detection/data/custom/images'#新建的文件夹
for root, dirs, files in os.walk(path):
    for i in range(len(files)):
        if (files[i][-3:] == 'jpg'):
            file_path = root + '/' + files[i]
            new_file_path = new_path + '/' + files[i]
            shutil.copy(file_path, new_file_path)

然后就可以运行voc2yolov3文件,生成train.txt和valid.txt文件信息,将数据集划分,即将图片路径保存在两个txt文件中。
yolov3训练实现火焰检测(pytorch)_第1张图片

yolov3训练实现火焰检测(pytorch)_第2张图片

要改的地方我都帮你们画出来了,是不是很贴心。

之后运行voc_annotation.py对xml标记信息进行处理,处理成下列的txt文件形式
yolov3训练实现火焰检测(pytorch)_第3张图片

运行成功之后labels文件夹下就会有一堆.txt文件了。

然后把/config/custom.data文件train,vaild路径换成你刚刚生成train.txt,vaild.txt文件的路径,names也是换成新的路径。

这样制作数据集就大功告成了。如果你想自己制作数据集也是可以的,需要下载标注软件自己进行标注,过程无聊且繁琐耗费时间,但是也是一个学习过程。(我就免了,我怕麻烦。)
按照我的方法去做,到这里基本不会报错,如果是基本都是路径报错的原因,虽然之前跑的时候,也报错了好几次,巧的是基本都是路径的问题,所以也是属于小问题,而且现在我已经把坑填好了,你们就放心的跟着做吧。

5.执行训练过程
你们期待已久bug终于到了

# 训练命令
python train.py --model_def config/yolov3-custom.cfg --data_config config/custom.data --pretrained_weights weights/darknet53.conv.74
# 添加其他参数请见 train.py 文件
    
# 从中断的地方开始训练
python train.py --model_def config/yolov3-custom.cfg --data_config config/custom.data --pretrained_weights checkpoints/yolov3_ckpt_99.pth --epoch 

一开始这里就有Bug了,难顶。运行的时候,一直提示我索引超出范围,并且是关于网络结构的问题。
然后我又从另外一篇文章发现到同样的bug。

如果运行报错:IndexError: index 0 is out of range那么就将算法文件夹下面的config文件内的yolov3-custom.cfg删除,自己重新生成一个。在该文件终端下运行命令:

bash create_custom_model.sh '1'

然而我运行之后,一点反应都没有,可能我不是在终端训练的缘故,所以我去仔细看了这两个文件的区别,好家伙,不看不知道,一看吓一跳。原来原作者的yolov3-custom.cfg文件中,yolov3网络结构代码写了3遍,怪不得索引会超出范围。可能我这样说,你还不太明白,我说直白点就是,yolov3-custom.cfg文件中网络结构应该只有789行,但是原作者却又1000多快2000行,所以会报错。
**解决办法:**把后面多余的删除。(PS:我已经帮你们删除了!)

好了。解决一个bug,另外一个bug也会跟着来。
首先应该会报TF版本错误,是关于utils/logger.py文件的问题好像是什么没有FileWriter模块,这个问题不怪大家,是因为版本升级,旧代码就会报错。
解决方法:把utils/logger.py文件部分代码替换掉就可以了

import tensorflow as tf


class Logger(object):
    def __init__(self, log_dir):
        """Create a summary writer logging to log_dir."""
        self.writer = tf.summary.create_file_writer(log_dir)
        #self.writer = tf.summary.FileWriter(log_dir)

    def scalar_summary(self, tag, value, step):
        """Log a scalar variable."""
        with self.writer.as_default():
            tf.summary.scalar(tag, value, step=step)
            self.writer.flush()
#         summary = tf.Summary(value=[tf.Summary.Value(tag=tag, simple_value=value)])
#         self.writer.add_summary(summary, step)

    def list_of_scalars_summary(self, tag_value_pairs, step):
        """Log scalar variables."""
        with self.writer.as_default():
            for tag, value in tag_value_pairs:
                tf.summary.scalar(tag, value, step=step)
            self.writer.flush()
#         summary = tf.Summary(value=[tf.Summary.Value(tag=tag, simple_value=value) for tag, value in tag_value_pairs])
#         self.writer.add_summary(summary, step)

注释掉的都是源代码,然后换成新的代码。

后面就是基本没有版本错误的问题,多数是检测的时候没有发现目标从而进行报错。

我遇到有2个错误,然后在网上搜解决方法,幸好还是有大佬遇到同样的问题并解决了。

**错误1.:**TypeError: ‘NoneType’ object is not subscriptable
**解决办法:**把utils/dataset.py128行左右
if self.augment:改为:

if self.augment and targets is not None: 

**错误2:**ValueError: not enough values to unpack (expected 3, got 0)
**解决办法:**在test.py53行左右 在# concatenate sample statistics 之前,插入

if len(sample_metrics) == 0:
    return np.array([0]), np.array([0]), np.array([0]), np.array([0]), np.array([0], dtype=np.int)

好了,这下子基本应该没问题了,如果还有问题我就不会了,因为其他的我就没遇到过了
我把batch_size=1换成16了,然后训练100epochs.

原作者训练之后出来mAP是0.8几,我的才0.47,虽然也有上过0.5几,不过只是拿来检测问题应该还是没问题。

6.执行预测文件

python detect.py --image_folder data/imgs/ --weights_path checkpoints/yolov3_ckpt_99.pth --model_def config/yolov3-custom.cfg --class_path data/custom/classes.names

–image_folder指定的是预测图片的路径,最后生成的结果会在output/imgs文件下

yolov3训练实现火焰检测(pytorch)_第4张图片
yolov3训练实现火焰检测(pytorch)_第5张图片

虽然有点误差,但是效果还是不错的,毕竟mAP才0.5左右,为了验证它的泛化性能,我用自己拍的照片进行预测
yolov3训练实现火焰检测(pytorch)_第6张图片
yolov3训练实现火焰检测(pytorch)_第7张图片

效果还是杠杠的。但是对火焰不是正常的黄色,红色,貌似就预测不出来,就存在这个bug。
yolov3训练实现火焰检测(pytorch)_第8张图片

这样就检测不出来了。

总的来说还是顺利完成了,感谢各位博主的贡献!
大功告成!

你可能感兴趣的:(火焰检测,yolov3,计算机视觉,pytorch,深度学习)