yolov3的一次不完整使用手册

原创不易,转载标明出处:https://www.jianshu.com/p/4eab78a46241
因为项目升级,有想法把之前图像识别的工具升级一下(毕竟faster—rcnn是2015年的产品现在都2019年了现在比较新的工具就是yolo v3)以下是我在使用yolo v3的使用的记录,供后来人参考。
工欲善其事,必先利其器 首先我们需要下载yolov3 和一个标图工具

下载yolov3:

git clone https://github.com/pjreddie/darknet
cd darknet
修改makefile配置:
make 因为是本地cpu版本所以不用修改什么直接make
如果是gpu版本需要修改如下文件:darknet/MakeFile

  1. 将GPU=0 --> GPU=1
  2. CUDNN=0 --> CUDNN=1
  3. DEBUG=0 --> DEBUG=1
  4. NVCC=/usr/local/cuda/cuda/bin/nvcc
    -->NVCC=/usr/local/cuda-8.0/bin/nvcc(这里nvcc所在位置注意修改成自己的)
  5. COMMON+= -DGPU -I/usr/local/cuda/include
    -->COMMON+= -DGPU -I/usr/local/cuda-8.0/include
  6. LDFLAGS+= -L/usr/local/cuda/lib64-lcuda -lcudart -lcublas -lcarand
    --> LDFLAGS+= -L/usr/local/cuda-8.0/lib64-lcuda -lcudart -lcublas -lcarand

这些搞定后我们还需要准备数据集,因为官方推荐了labelimg,所以我们就进行第二步:

下载labelimg

因为直接pip,安装不上去,所以我采用了源码的安装方式,下面是mac的源码安装步骤:
git clone https://github.com/tzutalin/labelImg
brew install qt
brew install libxml2
pip3 install pyqt5 lxml
make qt5py3
python3 labelImg.py

开始进行标图

工具打开后效果如下:


image.png

几个很简单的操作,将右上角使用预设标签点上,输入你的标签名称:这个根据你需要做的内容进行自定义。
记住几个快捷键就好了
A 上张图片
D 下张图片
command+s存贮
ok开始你无聊有冗长的标注工作,中间累的话起身喝一杯卡布奇诺。
。。。。。。。n小时过后。。。。。。
打开你下载好的yolo的代码
在scripts文件夹下建立如下文件格式:
—VOCdevkit
——VOC2019
———Annotations
———ImageSets
————Main
———JPEGImages
———labels
其中:Annotations用于存放xml文件,JPEGImages用于存放图片原图
ImageSets下的Main文件夹用于放两个文件train.txt和val.txt分别是指训练的图和测试的图 记住这里只有名字,路径啥的都没有,文件后缀也没有。就像这样:


image.png

这里有一个网上找的代码可以直接用

if __name__ == '__main__':
    source_folder = 'darknet/scripts/VOCdevkit/VOC2019/JPEGImages/'
    dest = 'darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/train.txt'
    dest2 = 'darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/val.txt'
    file_list = os.listdir(source_folder)
    train_file = open(dest, 'a')
    val_file = open(dest2, 'a')
    file_num = 0
    for file_obj in file_list:
        file_path = os.path.join(source_folder, file_obj)
        file_name, file_extend = os.path.splitext(file_obj)
        file_num += 1
        if (file_num < 40000):
            train_file.write(file_name + '\n')
        else:
            val_file.write(file_name + '\n')
    train_file.close()
    val_file.close()

这个代码的作用就是将40000张图片作为训练集,其他的图片作为测试集合来使用。
接下来是我们很重要环节:

代码修改

以下三个代码是需要修改的:

  • scripts下的voc_label.py这一步的目的是将xml文件的位置做一个再处理,生成到对应的labels文件夹下,修改内容:
    sets=[('2019', 'train'), ('2019', 'val')]
    classes = ['XXX'] 这里是你在lableimg中自定义的东西
    这里的set=[('2019', 'train'), ('2019', 'val’)]是指你后面要读的文件的位置,和你main文件夹下的两个文件的路径保持一致。
    classes = ['XXX’]是指你的分类方式,和你在lableimg中自定义的内容保持一致。
    运行完成之后你的文件会多出这样几个文件
    image.png

    同时你的labels里也有东西了。
  • 修改cfg/voc.data文件
classes= 1#分类的类别数目
train  = darknet/scripts/2019_train.txt#上一步生成的文件
valid  = darknet/scripts/2019_val.txt
names = data/voc.names
backup = backup

上面的代码我们其实看到了一个叫做names = data/voc.names这一行,好我们就去修改这个文件

  • 修改data/voc.names
    很简单就是你的imagelabe里自定义的内容
  • 最重要的一步,修改你的隐藏层结构cfg/yolov3-voc.cfg
    打开你的文件如下所示:
[net]
# Testing
batch=1 #批次,显存不够可减小,但会出现Nan问题(解决办法:增大batch。。。)
subdivisions=1 #训练迭代包含16组,每组4张图片
# Training
# batch=64
# subdivisions=16
width=416
height=416
channels=3
momentum=0.9 #滑动平均模型,在训练的过程中不断地对参数求滑动平均,这样能够更有效地保持稳定性,使其对当前参数更新不敏感
decay=0.0005 #权重衰减,防止过拟合
angle=0
saturation = 1.5
exposure = 1.5
hue=.1

learning_rate=0.001 #学习率 学习率决定了参数移动到最优值的速度快慢
burn_in=1000
max_batches = 50200
policy=steps
steps=40000,45000
scales=.1,.1
...
[convolutional]
size=1
stride=1
pad=1
filters=18 #3*(类别+5)
activation=linear

[yolo]
mask = 6,7,8
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=1 #类别
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
...

修改里面所有的yolo标签和跟它连接的那个[convolutional]标签中的filters 修改思路是3*(类别+5)。因为我的类别是1,所以我的filter是18
然后就可以开始训练了

训练

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74
多gpu下的训练
./darknet detector train cfg/coco.data cfg/yolov3.cfg darknet53.conv.74 -gpus 0,1,2,3

测试

./darknet detect cfg/yolov3.cfg yolov3.weights data/one.jpg

训练过程中的内容解析:

Region 94 Avg IOU: 0.078053, Class: 0.423860, Obj: 0.004782, No Obj: 0.083954, .5R: 0.000000, .75R: 0.000000,  count: 1

Region Avg IOU: 表示在当前subdivision内的图片的平均IOU,代表预测的矩形框和真实目标的交集与并集之比。
Class: 标注物体分类的正确率,期望该值趋近于1。
Obj: 越接近1越好。
No Obj: 期望该值越来越小,但不为零。
count: count后的值是所有的当前subdivision图片中包含正样本的图片的数量。

148: 60.560833, 97.261108 avg, 0.000000 rate, 8.694288 seconds, 9472 images

148是总体loss,97是平均loss,一般到0.几的时候就可以退出训练了,0.000000 rate代表学习率,在cfg文件中定义
8.694288 seconds 是这一批次的训练花费总时间,9472 images表示到目前为止参与训练的图片的总量

异常以及处理方式

  • cuda内存报错
    CUDA Error: out of memory
    darknet: ./src/cuda.c:36: check_error: Assertion `0' failed.
    处理方式:
    修改cfg/yolov3-voc.cfg中的batch 将这个值变小 甚至设置为1,上面的代码是修改过的
    注:设置为1很容易出现不收敛且iou为nan情况 也可以将batch=64,subversion=16,跑起来试试效果

参考博客:https://blog.csdn.net/lixiaoyu101/article/details/86537128

你可能感兴趣的:(yolov3的一次不完整使用手册)