赞
踩
一、
打开对应路径 E:\darknet-master\build\darknet\x64
然后在目录下新建个文件夹train
train 文件夹里放这些东西
pictures文件夹是存放图片和xml文件的
举个列子,我这里放红蓝方块的图片和红蓝方块xml文件
可以看到我蓝色方块标签是A3,红色方块标签是A1
图片序号有时候需要重新命名
所以我们需要用到
双击打开
根据注释修改
1、先将jpg图片重新命名
打开cmd 使用python脚本
回车运行
出现ok即为结束
2、重新命名xml文件
还是之前那个change_name.py
稍作更改继续命令行运行脚本
出现ok就是结束
这时候我们的pictures文件夹就是这个样子的
可以用labeling打开看看是否对应
对应没有出错。
然后就是获取txt文本
这时候需要用到
文本内部是这样的,我们需要根据注释进行修改
- import xml.etree.ElementTree as ET
- import os
-
- classes = ["A1","A2","A3","A4","b","L1","L2","L3","L4","L5","L6","L7","L8","L9","L10","L11","L12","L13","L14","L15","L16","L17","L18","L19","L20","M21","M22","M23","M24","M25","M26","M27","M28","M29","M30","M31","M32","M33","M34","M35","M36","TLS","WZ","LZ"] # 这里是你的所有分类的名称
- myRoot = r'd:\Desktop\打标好的' # 这里是你项目的根目录
- train_xmlRoot = myRoot + r'/train'
- train_txtRoot = myRoot + r'/train'
- train_imageRoot = myRoot + r'/train'
-
-
- def getFile_name(file_dir):
- L = []
- for root, dirs, files in os.walk(file_dir):
- print(files)
- for file in files:
- if os.path.splitext(file)[1] == '.jpg':
- L.append(os.path.splitext(file)[0]) # L.append(os.path.join(root, file))
- return L
-
-
- def convert(size, box):
- dw = 1. / size[0]
- dh = 1. / size[1]
- x = (box[0] + box[1]) / 2.0
- y = (box[2] + box[3]) / 2.0
- 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(xmlRoot,txtRoot,image_id):
- in_file = open(xmlRoot + '\\%s.xml' % (image_id),encoding='utf-8')
-
- out_file = open(txtRoot + '\\%s.txt' % (image_id), 'w',encoding='utf-8') # 生成txt格式文件
- 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'):
- cls = obj.find('name').text
- if cls not in classes:
- 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')
-
-
- image_ids_train = getFile_name(train_imageRoot)
- list_file_train = open(myRoot + r'\train.txt', 'w')
-
- for image_id in image_ids_train:
- list_file_train.write(train_imageRoot + '\\%s.jpg\n' % (image_id))
- convert_annotation(train_xmlRoot,train_txtRoot,image_id)
- list_file_train.close() # 只生成训练集,自己根据自己情况决定
-
-

就比如这次我们是红蓝方块,他们标签一个是A1一个是A3,就需要把
改为
然后项目根目录是E:\darknet-master\build\darknet\x64\train,所以也需要改
改完之后是这样子的
- import xml.etree.ElementTree as ET
- import os
-
- classes = ["A1","A3"] # 这里是你的所有分类的名称
- myRoot = r'E:\darknet-master\build\darknet\x64\train' # 这里是你项目的根目录
- train_xmlRoot = myRoot + r'/pictures' #这是你xml文件夹
- train_txtRoot = myRoot + r'/pictures' #这是你txt文件夹
- train_imageRoot = myRoot + r'/pictures' #这是你image文件夹 我反正都放一起了所以是同一个文件夹
-
-
- def getFile_name(file_dir):
- L = []
- for root, dirs, files in os.walk(file_dir):
- print(files)
- for file in files:
- if os.path.splitext(file)[1] == '.jpg':
- L.append(os.path.splitext(file)[0]) # L.append(os.path.join(root, file))
- return L
-
-
- def convert(size, box):
- dw = 1. / size[0]
- dh = 1. / size[1]
- x = (box[0] + box[1]) / 2.0
- y = (box[2] + box[3]) / 2.0
- 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(xmlRoot,txtRoot,image_id):
- in_file = open(xmlRoot + '\\%s.xml' % (image_id),encoding='utf-8')
-
- out_file = open(txtRoot + '\\%s.txt' % (image_id), 'w',encoding='utf-8') # 生成txt格式文件
- 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'):
- cls = obj.find('name').text
- if cls not in classes:
- 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')
-
-
- image_ids_train = getFile_name(train_imageRoot)
- list_file_train = open(myRoot + r'\train.txt', 'w')
-
- for image_id in image_ids_train:
- list_file_train.write(train_imageRoot + '\\%s.jpg\n' % (image_id))
- convert_annotation(train_xmlRoot,train_txtRoot,image_id)
- list_file_train.close() # 只生成训练集,自己根据自己情况决定
-
-

然后运行脚本
然后你的pictures文件夹里就会有txt文本了
然后就是配置 coco.data coco.names 还有 yolov4.cfg
先配置coco.names
保存即可
然后配置 yolov4.cfg
- [net]
- # Testing
- #batch=1
- #subdivisions=1
- # Training
- batch=64 #每64个样本更新一次参数
- subdivisions=16 #将batch分割为64个子batch 训练中出现out of memory 则改大到64或更大
- width=512 #width和height为32倍数 越大训练的效果越好 但是不能超过图像高宽 验证耗时也越大
- height=512
- channels=3
- momentum=0.9
- decay=0.0005
- angle=0
- saturation = 1.5 #饱和度
- exposure = 1.5 #曝光
- hue=.01 #色调
-
- learning_rate=0.0001
-
- burn_in=1000
-
- max_batches = 20000 #训练的最大批次数 值越大耗时越久 class*2000;不能小于图片数量;不能小于6k
- policy=steps
- steps=40000,45000 #max_batches*0.8和0.9的值
- scales=.1,.1
-
-
- #weights_reject_freq=1001
- #ema_alpha=0.9998
- #equidistant_point=1000
- #num_sigmas_reject_badlabels=3
- #badlabels_rejection_percentage=0.2
-
-
- [convolutional]
- batch_normalize=1
- filters=32
- size=3
- stride=2
- pad=1
- activation=leaky
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=3
- stride=2
- pad=1
- activation=leaky
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers=-1
- groups=2
- group_id=1
-
- [convolutional]
- batch_normalize=1
- filters=32
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [convolutional]
- batch_normalize=1
- filters=32
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -1,-2
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=1
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -6,-1
-
- [maxpool]
- size=2
- stride=2
-
- [convolutional]
- batch_normalize=1
- filters=128
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers=-1
- groups=2
- group_id=1
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -1,-2
-
- [convolutional]
- batch_normalize=1
- filters=128
- size=1
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -6,-1
-
- [maxpool]
- size=2
- stride=2
-
- [convolutional]
- batch_normalize=1
- filters=256
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers=-1
- groups=2
- group_id=1
-
- [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
-
- [route]
- layers = -1,-2
-
- [convolutional]
- batch_normalize=1
- filters=256
- size=1
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -6,-1
-
- [maxpool]
- size=2
- stride=2
-
- [convolutional]
- batch_normalize=1
- filters=512
- 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=51 #找离yolo最近的 (classes+5)*3(下面的mask的值)
- activation=linear
-
-
-
- [yolo]
- mask = 3,4,5
- anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
- classes=12 #总共有几个类别
- num=6
- jitter=.3
- scale_x_y = 1.05
- cls_normalizer=1.0
- iou_normalizer=0.07
- iou_loss=ciou
- ignore_thresh = .7
- truth_thresh = 1
- random=0
- resize=1.5
- nms_kind=greedynms
- beta_nms=0.6
- #new_coords=1
- #scale_x_y = 2.0
-
- [route]
- layers = -4
-
- [convolutional]
- batch_normalize=1
- filters=128
- size=1
- stride=1
- pad=1
- activation=leaky
-
- [upsample]
- stride=2
-
- [route]
- layers = -1, 23
-
- [convolutional]
- batch_normalize=1
- filters=256
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [convolutional]
- size=1
- stride=1
- pad=1
- filters=51 #同理
- activation=linear
-
- [yolo]
- mask = 1,2,3
- anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
- classes=12 #这边也要设置
- num=6
- jitter=.3
- scale_x_y = 1.05
- cls_normalizer=1.0
- iou_normalizer=0.07
- iou_loss=ciou
- ignore_thresh = .7
- truth_thresh = 1
- random=0
- resize=1.5
- nms_kind=greedynms
- beta_nms=0.6
- #new_coords=1
- #scale_x_y = 2.0

根据注释修改
比如红蓝方块就两类,训练批次数=4000,steps=3200,3600 #max_batches*0.8和0.9的值
classes=2 然后改 距离yolo最近的 filters=21 改完后是这样子的
- [net]
- # Testing
- #batch=1
- #subdivisions=1
- # Training
- batch=64 #每64个样本更新一次参数
- subdivisions=16 #将batch分割为64个子batch 训练中出现out of memory 则改大到64或更大
- width=512 #width和height为32倍数 越大训练的效果越好 但是不能超过图像高宽 验证耗时也越大
- height=512
- channels=3
- momentum=0.9
- decay=0.0005
- angle=0
- saturation = 1.5 #饱和度
- exposure = 1.5 #曝光
- hue=.01 #色调
-
- learning_rate=0.0001
-
- burn_in=1000
-
- max_batches = 4000 #训练的最大批次数 值越大耗时越久 class*2000;不能小于图片数量;不能小于6k
- policy=steps
- steps=3200,3600 #max_batches*0.8和0.9的值
- scales=.1,.1
-
-
- #weights_reject_freq=1001
- #ema_alpha=0.9998
- #equidistant_point=1000
- #num_sigmas_reject_badlabels=3
- #badlabels_rejection_percentage=0.2
-
-
- [convolutional]
- batch_normalize=1
- filters=32
- size=3
- stride=2
- pad=1
- activation=leaky
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=3
- stride=2
- pad=1
- activation=leaky
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers=-1
- groups=2
- group_id=1
-
- [convolutional]
- batch_normalize=1
- filters=32
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [convolutional]
- batch_normalize=1
- filters=32
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -1,-2
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=1
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -6,-1
-
- [maxpool]
- size=2
- stride=2
-
- [convolutional]
- batch_normalize=1
- filters=128
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers=-1
- groups=2
- group_id=1
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [convolutional]
- batch_normalize=1
- filters=64
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -1,-2
-
- [convolutional]
- batch_normalize=1
- filters=128
- size=1
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -6,-1
-
- [maxpool]
- size=2
- stride=2
-
- [convolutional]
- batch_normalize=1
- filters=256
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers=-1
- groups=2
- group_id=1
-
- [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
-
- [route]
- layers = -1,-2
-
- [convolutional]
- batch_normalize=1
- filters=256
- size=1
- stride=1
- pad=1
- activation=leaky
-
- [route]
- layers = -6,-1
-
- [maxpool]
- size=2
- stride=2
-
- [convolutional]
- batch_normalize=1
- filters=512
- 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=21 #找离yolo最近的 (classes+5)*3(下面的mask的值)
- activation=linear
-
-
-
- [yolo]
- mask = 3,4,5
- anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
- classes=2 #总共有几个类别
- num=6
- jitter=.3
- scale_x_y = 1.05
- cls_normalizer=1.0
- iou_normalizer=0.07
- iou_loss=ciou
- ignore_thresh = .7
- truth_thresh = 1
- random=0
- resize=1.5
- nms_kind=greedynms
- beta_nms=0.6
- #new_coords=1
- #scale_x_y = 2.0
-
- [route]
- layers = -4
-
- [convolutional]
- batch_normalize=1
- filters=128
- size=1
- stride=1
- pad=1
- activation=leaky
-
- [upsample]
- stride=2
-
- [route]
- layers = -1, 23
-
- [convolutional]
- batch_normalize=1
- filters=256
- size=3
- stride=1
- pad=1
- activation=leaky
-
- [convolutional]
- size=1
- stride=1
- pad=1
- filters=21 #同理
- activation=linear
-
- [yolo]
- mask = 1,2,3
- anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
- classes=2 #这边也要设置
- num=6
- jitter=.3
- scale_x_y = 1.05
- cls_normalizer=1.0
- iou_normalizer=0.07
- iou_loss=ciou
- ignore_thresh = .7
- truth_thresh = 1
- random=0
- resize=1.5
- nms_kind=greedynms
- beta_nms=0.6
- #new_coords=1
- #scale_x_y = 2.0

这就配置好了yolov4.cfg
最后配置coco.data
然后在
路径下打开终端输入训练指令
darknet.exe detector train train/coco.data train/yolov4.cfg train/yolov4-tiny.conv.29
等待训练结束就行。然后就会在你之前的
这个位置出现权重文件,之后用这个权重文件检测图片,是对应目标标签即可。
1、识别图片格式:./darknet.exe detector test <.data文件位置> <.cfg文件位置> <权重文件位置> <识别文件位置>
darknet.exe detector test train/coco.data train/yolov4.cfg train/backup/yolov4_last.weights train/pictures/1.jpg
就会有下面这种结果,标签和物体对上了,置信度也高。
2、调用电脑摄像头识别
darknet.exe detector demo D:/desktop/shape/shape.data D:/desktop/shape/yolov4-tiny.cfg D:/desktop/shape/F.weights -c 0
3、继续上次模型的训练
darknet.exe detector train train/coco.data train/yolov4.cfg train/yolov4_last.weights
就是权重从预训练模型yolov4-tiny.conv.29变为之前训练得到的权重yolov4_last.weights,如果报错的话,更改cfg文件里max_batches #训练的最大批次数 让cfg文件和之前训练的不一样就可以了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。