【darknet速成】Darknet图像分类从模型自定义到测试

1 Darknet是什么

首先不得不夸奖一下Darknet的主页风格不错。

官网地址:https://pjreddie.com/darknet/

GitHub: https://github.com/pjreddie/darknet

Darknet本身是Joseph Redmon为了Yolo系列开发的框架。

Joseph Redmon,一个从look once,到look Better, Faster, Stronger,到An Incremental Improvement,也就是从Yolo v1,干到Yolo v2,Yolo v3的男人,头像很应景。

Darknet几乎没有依赖库,是从C和CUDA开始撰写的深度学习开源框架,支持CPU和GPU。

咱们的第一个开源框架说的是Caffe,现在这最后一个Darknet跟caffe倒是颇有几分相似之处,只是更加轻量级。

2 Darknet结构解读

首先我们看下Darknet的代码结构如下:

cfg,data,examples,include,python,src,scripts几个子目录。

2.1 data目录

以上就是data目录的内容,包含了各种各样的文件。图片就是测试文件了,不必说。我们首先看看imagenet.labels.list和imagenet.shortnames.list里面是什么。

imagenet.labels.list是:

n02120505

n02104365

n02086079

n02101556

·············

看得出来就是imagenet的类别代号,与之对应的imagenet.shortnames.list里是:

kit fox

English setter

Siberian husky

Australian terrier

·············

可知这两个文件配套存储了imagenet1000的类别信息。

接着看9k.labels,9names,9k.trees,里面存储的就是Yolo9000论文中对应的9418个类别了。coco.names,openimages.names,voc.names都类似。

2.2 cfg目录

cfg,下面包含两类文件,一个是.data,一个是.cfg文件。我们打开imagenet1k.data文件看下,可知它配置的就是训练数据集的信息:

classes=1000 ##分类类别数 train = /data/imagenet/imagenet1k.train.list ##训练文件 valid = /data/imagenet/imagenet1k.valid.list ##测试文件 backup = /home/pjreddie/backup/ ##训练结果保存文件夹 labels = data/imagenet.labels.list #标签 names = data/imagenet.shortnames.list top=5

另一类就是.cfg文件,我们打开cifar.cfg文件查看。

##---------1 优化参数配置---------##

[net] batch=128 subdivisions=1 height=28 width=28 channels=3 max_crop=32 min_crop=32 ##数据增强参数 hue=.1 saturation=.75 exposure=.75 ##学习率策略 learning_rate=0.4 policy=poly power=4

max_batches = 5000 ##迭代次数 momentum=0.9 ##动量项 decay=0.0005 ##正则项 ##---------2 网络参数配置---------##

[convolutional] batch_normalize=1 ##是否使用batch_normalization filters=128 size=3 stride=1 pad=1 activation=leaky ##激活函数 [convolutional] batch_normalize=1 filters=128 size=3 stride=1 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=128 size=3 stride=1 pad=1 activation=leaky [maxpool] size=2 stride=2 [dropout] probability=.5 [convolutional] batch_normalize=1 filters=256 size=3 stride=1 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=256 size=3 stride=1 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=256 size=3 stride=1 pad=1 activation=leaky [maxpool] size=2 stride=2 [dropout] probability=.5 [convolutional] batch_normalize=1 filters=512 size=3 stride=1 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=512 size=3 stride=1 pad=1 activation=leaky [convolutional] batch_normalize=1 filters=512 size=3 stride=1 pad=1 activation=leaky [dropout] probability=.5 [convolutional] filters=10 size=1 stride=1 pad=1 activation=leaky [avgpool] [softmax] groups=1

包含两部分,第一部分就是优化参数的定义,类似于caffe的solver.prototxt文件。第二部分就是网络定义,类似于caffe的train.prototxt文件,不同的是网络层用[]来声明,batch normalization以及激活函数等配置进了[convolutional]里面。

最后的avgpool不需要配置池化半径,softmax不需要配置输入输出,在最后设置group参数。

你可能好奇,那残差网络怎么弄呢?

[shortcut]

activation=leaky

from=-3

如上,通过一个from=-3参数来进行配置,就是往后退3个block的意思了。

2.3 python目录

下面只有两个文件,即darknet.py和proverbot.py。前者就是python调用yolo模型的案例,后者没什么用。

2.4 include,src,examples目录

include和src就是具体的函数实现了,卷积等各类操作都在这里。examples就是高层任务的定义,包括classifier,detector,代码的解读就超过本文的内容了,以后详解。

3 数据准备和模型定义

3.1 数据准备

前面已经把该介绍的都介绍了,下面就开始准备数据进行训练。跟caffe一样,数据准备的流程非常简单。

首先,在data目录下建立我们自己的任务,按照如下目录,把文件准备好

├── genedata.sh

├── labels.txt

├── test

├── test.list

├── train

└── train.list

使用如下命令生成文件

find `pwd`/train -name \*.jpg > train.list

find `pwd`/test -name \*.jpg > test.list

其中每一行都存储一个文件,而标签是通过后缀获得的。

/Users/longpeng/Desktop/darknet/data/mouth/train/60_smile.jpg

/Users/longpeng/Desktop/darknet/data/mouth/train/201_smile.jpg

/Users/longpeng/Desktop/darknet/data/mouth/train/35_neutral.jpg

/Users/longpeng/Desktop/darknet/data/mouth/train/492_smile.jpg

标签的内容存在labels.txt里面,如下

neutral

smile

3.2 配置训练文件路径和网络

去cfg目录下建立文件mouth.data和mouth.cfg,mouth.data内容如下:

classes=2

train = data/mouth/train.list

valid = data/mouth/test.list

labels = data/mouth/labels.txt

backup = mouth/

top=5

mouth.cfg内容如下:

[net]

batch=16

subdivisions=1

height=48

width=48

channels=3

max_crop=48

min_crop=48

hue=.1

saturation=.75

exposure=.75

learning_rate=0.01

policy=poly

power=4

max_batches = 5000

momentum=0.9

decay=0.0005

[convolutional]

batch_normalize=1

filters=12

size=3

stride=1

pad=1

activation=leaky

[maxpool]

size=2

stride=2

[convolutional]

batch_normalize=1

filters=24

size=1

stride=1

pad=1

activation=leaky

[maxpool]

size=2

stride=2

[convolutional]

batch_normalize=1

filters=48

size=3

stride=1

pad=1

activation=leaky

[maxpool]

size=2

stride=2

[connected]

output=128

activation=relu

[connected]

output=2

activation=linear

[softmax]

在这里我们用上了一点数据增强操作,大家在后面会看到它的威力。

4 模型训练

使用如下命令进行训练:

./darknet classifier train cfg/mouth.data cfg/mouth.cfg

训练结果如下:

上面每一行展示的分别是:batch数目,epoch数目,损失,平均损失,学习率,时间,见过的样本数目。

将最后的结果提取出来进行显示,损失变化如下,可知收敛非常完美。

训练完之后使用如下脚本进行测试。

./darknet classifier valid cfg/mouth.data cfg/mouth.cfg mouth/mouth_50.weights

一个样本的结果如下:

darknet/data/mouth/test/27_smile.jpg, 1, 0.006881, 0.993119,

99: top 1: 0.960000, top 5: 1.000000

依次表示样本darknet/data/mouth/test/27_smile.jpg,被分为类别1,分类为0和1的概率是0.006881, 0.993119,该样本是第99个测试样本,此时top1和top5的平均准确率分为是0.96和1。

到这里,我们只用了不到500个样本,就完成了一个精度不错的分类器的训练,如此轻量级的darknet,我决定粉了。

总结

本文讲解了如何使用darknet深度学习框架完成一个分类任务,框架固然小众,但是速度真快,而且非常轻便,推荐每一个玩深度学习,尤其是计算机视觉的朋友都用起来。

原文发布于微信公众号 - 有三AI(yanyousan_ai)

原文发表时间:2019-03-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券