水果识别 | SDU.LIN
- 水果识别-搭建框架 | SDU.LIN
- 水果识别-数据集制作 | SDU.LIN
- 水果识别-训练 | SDU.LIN
- 水果识别-测试 | SDU.LIN
训练包括:
1. 更改voc_label.py生成label文件
2. 修改要训练的网络配置文件
3. 修改voc.names
4. 修改voc.data
5. 训练
1. 更改voc_label.py生成label文件
该文件在/darknet/scripts/目录下
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
# sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
# classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]
sets=[('2007', 'train')] 这里只用到训练,数据集命名为VOC2017
classes = ["apple", "pear", "banana"] 只用了三个类别作为展示
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h)
def convert_annotation(year, image_id):
in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))
out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w')
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
for obj in root.iter('object'):
difficult = obj.find('difficult').text
cls = obj.find('name').text
if cls not in classes or int(difficult)==1:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + 'n')
wd = getcwd()
for year, image_set in sets:
if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):
os.makedirs('VOCdevkit/VOC%s/labels/'%(year))
image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split()
list_file = open('%s_%s.txt'%(year, image_set), 'w')
for image_id in image_ids:
list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpgn'%(wd, year, image_id))
convert_annotation(year, image_id)
list_file.close()
修改好后执行python voc_label.py
在scripts/VOCdevkit/VOC2007目录下生成了labels文件夹,文件夹里面长这个样子的:
同时会在/darknet/scripts目录下生成2007_train.txt文件
2. 配置文件的修改
我用到的yolov3,所以就修改/cfg/yolove-voc.cfg
[net]
# Testing
# batch=1
# subdivisions=1
# Training # 训练的时候把Testing的参数注释掉,把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 = 100000 # 训练的总次数
policy=steps
steps=100,10000,70000,80000,90000 # 训练到相应次数后学习率变化
scales=10,10,.1,.1,.1 # 学习率变化情况,是累乘操作
......
[convolutional]
size=1
stride=1
pad=1
filters=24 # filters = 3*(calsses + 5)
activation=linear
[yolo]
mask = 0,1,2
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=3 # 修改类别数量
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1 # 为1时会启用Multi-Scale Training,随机使用不同尺寸的图片进行训练,显存小可以置为0
3. 修改voc.names
该文件在/darknet/data目录下
apple
pear
banana
该文件下记录所有类别名称
4. 修改voc.data
该文件在/darknet/cfg目录下
classes= 3 //类别数量
train = /home/embedded/lm/darknet/scripts/2007_train.txt //指定训练样本
// valid = /home/pjreddie/data/voc/2007_test.txt 指定测试数据,训练用不到
names = /home/embedded/lm/darknet/data/voc.names //指向上一步修改的voc.names文件
backup = /home/embedded/lm/darknet/backup/yolov3_voc_weights //指定训练后的权值放在哪儿
5. 训练
不要与训练权重直接训练:
./darknet detector train cfg/voc.data cfg/yolov3_voc.cfg
也可以下载预训练权重进行训练:
./darknet detector train cfg/voc.data cfg/yolov3_voc.cfg yolo.weights
训练过程中可以随时停止,停止以后可以在保存的权重处接着开始训练,保存的权重就当做预训练权重,yolov3开始没训练100次保存一次权重,过1000以后每训练10000次保存一次权重。然后就等待漫长的训练过程……
原文地址水果识别-训练 | |www.linmao.dev