目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测

简记

    • 步骤0:环境
      • step0:环境配置
    • 步骤1:数据集转换
      • step1:用 `voc2ssd.py` 生成索引文件
      • step2:用 `voc_annotation.py` 生成用于训练的文件
    • 步骤2:训练网络
      • step3:修改 `config.py` 文件
      • step4:运行 `train.py` 文件
    • 步骤3:预测
      • step5:修改根目录下 `ssd.py` 文件
      • step6:修改nets目录下 `ssd.py` 文件
      • step7:运行 `predict.py` 文件
    • 踩坑记
    • 步骤4:批量预测
      • step8:修改 `predict.py` 文件
    • 步骤5:计算 mAP
      • step9:用 `get_gt_txt.py` 获取测试集的真实框
      • step10:用 `get_dr_txt.py` 获取测试集的预测框
      • step11:用 `get_map.py` 计算mAP
    • 5.7 更新

步骤0:环境

因为电脑配置比较差(NVIDIA Geforce MX230,2G),就不想自己尝试训练 SSD,但是五一假期马上要结束了,避免再见导师时被追问进度,还是硬着头皮试试看了。

我用的图像是肠镜图片,目的是检测其上是否有LST肿瘤(也就是病变区域)。对于存在LST的图像,希望返回有边界框标注病变区域的图片,对于正常图像则返回原图。

所以接下来的内容将存在LST的图像记为病变图像,否则为正常图像。数据集情况如下:

批次 正常图像 病变图像
01 181张 162张
02 61张 109张

一共 513 张图像(大概率就是这个数量少导致我第一次训练+预测失败)。

step0:环境配置

我是90%的参考了该up主的配置,Anaconda + cuda10.0 + cudnn7.4.1.5 + torch1.2.0 + torchvision0.4.0,亲测可用奥。

深度学习环境配置-Anaconda以及pytorch1.2.0的环境配置

剩下的10%就是我用的 Pycharm 而不是 VS,视频教程真的超贴心了,下面是文字版的教程。

神经网络学习小记录48——windows下的torch=1.2.0环境配置

步骤1:数据集转换

在上一篇文章末尾已介绍了数据集如何转换为可供训练 SSD 使用的格式,这里再简单记录一下。

step1:用 voc2ssd.py 生成索引文件

按照 VOCdevkit 的格式,在 VOC2007 下有三个文件夹:

  • Annotations:用于存放标签文件;
  • ImageSets:用于存放索引文件;
  • JPEGimages:用于存放图像文件。

正常图像的标签文件中没有目标信息,而病变图像标签文件中的目标信息至少为1个,比如: 目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第1张图片 目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第2张图片
目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第3张图片
划重点啦!!!如何获取索引文件

ImageSets 目录下有个 Main 文件夹,包含:
test.txt、teain.txt、trainval.txt、val.txt 均用于存放图像文件和标签文件的索引内容。

然后在根目录下的 voc2ssd.py ,我们需要按照自己的需求设置测试集的比例,我是打算用 20% 的图作为测试集,也就是 103 张图。修改部分为:

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第4张图片
然后运行根目录下的 voc2ssd.py 来生成 test.txt、teain.txt、trainval.txt、val.txt 四个文件。

因为我用的是 Pycharm,所以直接运行子目录下的 voc2ssd.py 会报错: FileNotFoundError: [WinError 3] 系统找不到指定的路径。: './VOCdevkit/VOC2007/Annotations'

最直接的解决办法是把 voc2ssd.py 放到根目录下去运行,然后就可以得到我们需要的索引文件了。

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第5张图片

step2:用 voc_annotation.py 生成用于训练的文件

用于训练的 txt 文件有三个:
2007_test.txt、2007_train.txt、2007_val.txt

需要用到的代码是 voc_annotation.py,需要修改的地方如下图红框标注:

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第6张图片
然后直接运行即可。

步骤2:训练网络

开始训练之前需要按照自己的数据集修改一些参数,具体如下。

step3:修改 config.py 文件

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第7张图片

step4:运行 train.py 文件

训练好的权重会保存在 logs目录下。下图是生成的部分权值文件。

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第8张图片

步骤3:预测

step5:修改根目录下 ssd.py 文件

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第9张图片

step6:修改nets目录下 ssd.py 文件

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第10张图片

step7:运行 predict.py 文件

运行后输入图像名称 img/101001.jpg,放一个预测成功的图。

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第11张图片

踩坑记

由于配置问题、或参数设置,训练可能以各种原因失败,我第一次训练就以显存不足结束了,可能是没训练好,或者数据集太少或者…,预测时病变图像也不显示预测框,然后就开始各种百度需要修改哪些参数,好在第二次训练慢悠悠地成功结束了,预测图至少也有预测框了。

第一次没有修改原代码的学习率、epoch等参数,之后训练失败,根据 显存不足和预测图像不显示预测框 这两点查了些解决方式:

  • 显存不足的话可以降低 batch_size,所以我将原代码中的 batch_size 缩小了一半;
  • 不显示预测框可能是由于目标较小,而 SSD 对小目标不敏感,或者是由于数据集过少导致网络没有训练好,在数据集暂时无法增加的情况下只能从小目标下手了,所以我降低了 IoU阈值,就是啥也不知道盲猜的,但是好歹结果有点改善。

第二次训练就很随意的盲改了参数,如下:

参数 修改前 修改后
nets/ssd.py中:detect() 的参数 nms_thresh 0.45 0.35
nets/ssd.py中:get_ssd() 的参数 confidence 0.5 0.4
nets/ssd.py中:get_ssd() 的参数 nms_iou 0.45 0.35
utils/box_utils.py中:nms() 的参数 overlap 0.5 0.3
train.py中:MultiBoxLoss 的参数 overlap_thresh 0.5 0.3
train.py中:batch_size & epoch 16, 50 8, 30
train.py中:batch_size & epoch 8, 50,100 4, 30, 60

这些参数就是凭感觉改的,如果有不对的地方请各位指出来。
今天写到这里差不多了,good night。

——————————————————————————————————————————
——————————————————————————————————————————
来补充内容了。既然能够成功预测一张图,那么对一个测试集的预测效果能达到什么程度才是我们主要关心的问题,所以我尝试着进行批量预测,并计算 mAP 值。

步骤4:批量预测

step8:修改 predict.py 文件

修改的目的是为了能进行整个测试集的批量预测,所以我们需要遍历测试集并对每一张图进行预测。修改后的代码如下:

from PIL import Image
from ssd import SSD
from tqdm import tqdm
import os

ssd = SSD()

# 这部分用于单张图片预测
# while True:
#     img = input('Input image filename:')
#     try:
#         image = Image.open(img)
#     except:
#         print('Open Error! Try again!')
#         continue
#     else:
#         r_image = ssd.detect_image(image)
#         r_image.save("img.jpg")
#         r_image.show()

# 以下用于批量预测
image_ids = open('VOCdevkit/VOC2007/ImageSets/Main/test.txt').read().strip().split()  

for image_id in tqdm(image_ids):  # 遍历测试图像
    image_path = "./VOCdevkit/VOC2007/JPEGImages/" + image_id + ".jpg"  # 原图像的存储路径
    try:
        image = Image.open(image_path)
    except:
        print('Open Error! Try again!')
        continue
    else:
        r_image = ssd.detect_image(image)  # 使用网络进行预测
        image_results_path = "./image_results/"  # 创建用于存放预测好的图像的文件夹
        if not os.path.exists(image_results_path):
            os.mkdir(image_results_path)
        r_image.save(os.path.join(image_results_path, image_id+".jpg"))  # 存储图像

运行该文件后,在根目录下会出现 image_results 文件夹,存放的就是预测好的图像。

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第12张图片

步骤5:计算 mAP

有了测试集的预测结果后,我们就可以着手计算该模型的 mAP,所以首先需要将测试集图像中的真实框以及预测框信息提取出来。

step9:用 get_gt_txt.py 获取测试集的真实框

这个没有需要修改的地方,直接运行即可。

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第13张图片

step10:用 get_dr_txt.py 获取测试集的预测框

同上,不需修改,直接运行即可。

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第14张图片

当上述两个文件运行完毕后,根目录下会出现 input 文件夹:

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第15张图片

  • detection-results 存放预测框信息
  • detection-results 存放真实框信息
  • images-optional 存放测试集图像,通过get_dr_txt.py生成,可有可无,作用是在计算mAP时能够可视化图像。
    目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第16张图片

step11:用 get_map.py 计算mAP

这个没有需要修改的地方,直接运行即可。运行后在根目录下会出现 results 文件夹,存放各种评估指标的可视化图。由于我的数据集只有一个类别 LST,因此每类指标下只有一幅图。

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第17张图片

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第18张图片
目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第19张图片
目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第20张图片
最终获得了 m A P = 83.79 mAP=83.79% mAP=83.79,好像也不算太低,感觉再调整下参数然后多训练几次可能还会增加。

最后,希望大家努力发现我的错误。

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第21张图片
——————————————————————————————————————————
——————————————————————————————————————————

5.7 更新

补充内容。

看了一遍预测好的图像,发现标注的预测框有点问题,如果一张图有多个目标的话,预测框框之间可能会相互重叠,这样看起来就有那么一丝丝不爽,比如:

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第22张图片

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第23张图片
所以本着不能完美但要努力追求完美的想法,我决定改一改框框的标注:

  • 把看起来令人不悦的标签下的大红色背景去掉;
  • 然后发现标签的字体颜色保持黑色或改成红色都很不顺眼,但绿色就很nice奥~。

具体修改部分在根目录下 ssd.py --> detect_image(self, image)

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第24张图片
修改后的图如下所示:

目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第25张图片
目标检测(五):用个人数据集实现SSD-Pytorch的训练与预测_第26张图片
然后昨晚上又训练了一次,将 epoch 增加到了 80,结果!!!预测的 mAP 值居然下降了 7% 多,心痛啊 /(ㄒoㄒ)/~~

但感觉模型还是有些改善,loss 的波动没有那么剧烈了,继续努力叭~

你可能感兴趣的:(目标检测系列文章笔记,深度学习)