最近还有项目是多目标跟踪,所以开始接触目标检测器,那就从最普遍的YOLOV3开始。无奈网上教程参差不齐,甚至有大段大段的错误,以及大段大段的省略,估计这就是大佬效应吧,因为觉得有些过程太过理所应当,所以就省略了。
这篇文章非常详细地介绍了整个过程,基本做到了每个细节都写清楚,希望对像我这样的小白能有帮助。
基础的YOLO知识,计划在之后整理,这里就写一下代码过程。
软硬件环境:
python 3.6.5
Ubuntu18.04 LTS
PyTorch 1.1.0
CUDA 10.0
cudnn 7.5.0
GPU: NVIDIA TITAN XP
第一步就是准备一个目标检测的数据集,这个数据集可以使用官方提供的,感觉下载也可以自己制作,这里我使用的数据集是细胞数据集,进入页面下载后解压就行。
尽管使用的别人的数据集,我还是下载了labelImg,ubuntu版本的官方下载地址:https://github.com/tzutalin/labelImg/
具体的过程按照官方教程即可,我放在下面:
sudo apt-get install pyqt5-dev-tools
sudo pip3 install -r requirements/requirements-linux-python3.txt
make qt5py3
python3 labelImg.py
注:如果在执行第二步的之后如果出现sudo: pip3: command not found
,可以参考我上一篇文章:https://blog.csdn.net/Cheungleilei/article/details/103503754
之后会打开一个界面
具体的标注过程在这里我就不再赘述,可以参考一些其他文章。
1.官方代码下载地址:https://github.com/pjreddie/darknet
当然,你也可以采用:
git clone https://github.com/pjreddie/darknet
我采用第一种,下载完毕后,看到压缩包,右键“Extract here"
2. 现在开始编译:
cd darknet
sudo gedit Makefile
打开后,根据自己的需求修改文件夹,因为我用GPU,所以修改为GPU=1,CUDNN=1,OPENCV我设为0,因为我不使用摄像头。
make
解压后得到的文件中含有两个文件夹——Annotations和JPEGImages
import os
import random
trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')
for i in list:
name = total_xml[i][:-4] + '\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftest.write(name)
else:
fval.write(name)
else:
ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
wget https://pjreddie.com/media/files/voc_label.py
下载得很快,打开,修改一下:
(1)sets部分,把有(‘2012’)的删去
(2)classes保存自己要检测的类别即可,我用的数据集只有一个类别,所以就只写了“RBC”
2. 在终端输入
python voc_label.py
cat 2007_train.txt 2007_val.txt > train.txt
结束后,应该会发现,出现三个txt文件2007_train.txt,2007_val.txt,2007_test.txt,这是真正有用的三个文件。
classes=<你需要检测的类别数量>
train = <2007_train.txt 文件所在的位置>
valid = <2007_test.txt/2007_valid.txt 文件所在位置,这不太重要>
names = <names文件所在位置>
backup = <backup文件夹所在位置,没有就自己建一个>
例如,我的例子中,我这样写的:
classes=1
train=/home/user/Downloads/darknet-master/2007_train.txt
valid=/home/user/Downloads/darknet-master/2007_test.txt
names=/home/user/Downloads/darknet-master/data/cell.names
backup=backup/
[net]
# Testing
batch=1
subdivisions=1
# Training
# batch=64
# subdivisions=2
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 = 500200
policy=steps
steps=400000,450000
scales=.1,.1
[convolutional]
batch_normalize=1
filters=16
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=1
[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky
###########
[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky
[convolutional]
size=1
stride=1
pad=1
#filters=255
filters=18 #此处有修改
activation=linear
[yolo]
mask = 3,4,5
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
classes=80
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
[route]
layers = -4
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[upsample]
stride=2
[route]
layers = -1, 8
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[convolutional]
size=1
stride=1
pad=1
#filters=255
filters=18 #3*(class=1+4+1)
activation=linear
[yolo]
#mask = 1,2,3
mask = 0,1,2
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
#classes=80
classes=1 #只有一个类别
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
wget https://pjreddie.com/media/files/darknet53.conv.74
./darknet detector train cfg/cell.data cfg/yolov3.cfg darknet53.conv.74
这里再提醒一下,上面那句代码,cell.data换为你自己刚才建立的data文件,yolov3.cfg是因为我使用的是yolov3模型,如果用其他模型,就输入其他模型比如yolov3-tiny.cfg之类的,那么就要在第5步下载相对应的权重。
好了,今天就介绍到这儿,是不是超级详细?(__) 嘻嘻!有什么疑惑和建议都可以在下面留言,同时不要吝啬你的点赞哦!