yolov3 - AlexeyAB版 ubuntu训练自己的数据集(巨详细教程)

工作里用到yolov3,记录一下。
v3和v4用起来差不多,yolov5部署时遇到很多问题(比如focus层移植失败),就舍弃了。

先放官方的仓库地址:AlexeyAB/darknet
里面有英文版教程,也可以看这个英文教程:YOLO: Real-Time Object Detection

好文分享:YOLO优秀博文合集

一、构建自己的数据集

我的方法是先用标注软件人工画框,得到xml文件,再通过脚本转成yolo能用的txt文件。

我用的软件是labelImg,提取码:623i

为了方便查看和管理,我的文件目录层次如下,可根据个人爱好来改:

在这里插入图片描述
其中,annotations文件夹用来存储xml文件(也就是labelImg的保存路径),images文件存放图片,labels用来存放xml转换后的txt文件。

然后通过下面的脚本将xml文件转换成txt然后保存到label文件夹

# xml转txt
class_names = ['car'] # 这里改成自己的类,我只识别汽车,所以就填一个‘car’,这个名字要跟labelImg里标注时的框名一致。
 
xmlpath='C:/Users/admin/Desktop/yolo_car_dataset/annotations/test/' #原xml路径
txtpath='C:/Users/admin/Desktop/yolo_car_dataset/labels/test/'     #转换后txt文件存放路径 
files = []
 
for root, dirs, files in os.walk(xmlpath):
    None
number = len(files)
print(number)
i = 0
while i < number:
 
    name = files[i][0:-4]
    xml_name = name + ".xml"
    txt_name = name + ".txt"
    xml_file_name = xmlpath + xml_name
    txt_file_name = txtpath + txt_name
 
    xml_file = open(xml_file_name)
    tree = ET.parse(xml_file)
    root = tree.getroot()
    filename = root.find('filename').text
 
    image_name = root.find('filename').text
    w = int(root.find('size').find('width').text)
    h = int(root.find('size').find('height').text)
    print(w,h)
    if w or h == 0:
        w = 1920
        h = 1080
    f_txt = open(txt_file_name, 'w+')
    content = ""
 
    first = True
 
    for obj in root.iter('object'):
        
        name = obj.find('name').text
        class_num = class_names.index(name)
 
        xmlbox = obj.find('bndbox')
 
        x1 = int(xmlbox.find('xmin').text)
        x2 = int(xmlbox.find('xmax').text)
        y1 = int(xmlbox.find('ymin').text)
        y2 = int(xmlbox.find('ymax').text)
 
        if first:
            content += str(class_num) + " " + \
                       str((x1 + x2) / 2 / w) + " " + str((y1 + y2) / 2 / h) + " " + \
                       str((x2 - x1) / w) + " " + str((y2 - y1) / h)
            first = False
        else:
            content += "\n" + \
                       str(class_num) + " " + \
                       str((x1 + x2) / 2 / w) + " " + str((y1 + y2) / 2 / h) + " " + \
                       str((x2 - x1) / w) + " " + str((y2 - y1) / h)
 
    # print(str(i / (number - 1) * 100) + "%\n")
    print(content)
    f_txt.write(content)
    f_txt.close()
    xml_file.close()
    i += 1
print("done!")

可能会出现w和h为零的报错情况,这是因为将png转成jpg之后软件无法读取宽高。用下面的脚本就可以打印出出问题的图片,然后自己替换掉再标注这些新图片即可。

#查看哪张图片的xml文件里w和h读取失败
for root, dirs, files in os.walk(xmlpath):
    None
number = len(files)
i = 0
while i < number:
    name = files[i][0:-4]
    xml_name = name + ".xml"
    txt_name = name + ".txt"
    xml_file_name = xmlpath + xml_name
    txt_file_name = txtpath + txt_name
 
    xml_file = open(xml_file_name)
    tree = ET.parse(xml_file)
    root = tree.getroot()
    filename = root.find('filename').text
 
    image_name = root.find('filename').text
    w = int(root.find('size').find('width').text)
    h = int(root.find('size').find('height').text)
    if w == 0 or h == 0:
        print(image_name)
    i += 1

每张图片都会得到一个对应的相同名字的txt文件,其中每行的格式为:
< object-class > < x_center > < y_center > < width > < height >

  • < object-class > 物体的类别,取值从整数 0 到 (类别数-1)
  • < x_center > < y_center > < width> < height> 框中心点的x和y,框的w和h,取值是 (0.0 to 1.0]
  • 比如:< x > = < absolute_x > / < image_width >
    或 < height > = < absolute_height > / < image_height >
    看起来像是这样:

1 0.716797 0.395833 0.216406 0.147222
0 0.687109 0.379167 0.255469 0.158333
1 0.420312 0.395833 0.140625 0.166667

得到txt文件后,我们还需train.txt和test.txt两个文件,这两个文件里包含了每张图片的路径,如:

/home/louis/yolo_car_dataset/images/train/1.jpg
/home/louis/yolo_car_dataset/images/train/10.jpg
/home/louis/yolo_car_dataset/images/train/100.jpg

可以通过下面脚本自动生成:

def make_txt(path1, path2, flag):
    file_list=os.listdir(path1)
    txt = open(flag, 'w+')
    for file in file_list:
        txt.write(path2+file+'\n')
    txt.close()

# path1 是本地数据集的位置,因为我在本地运行这个脚本。path2是服务器上的数据集位置。
path1 = 'C:/Users/admin/Desktop/yolo_car_dataset/images/test/' 
path2 = '/home/louis/yolo_car_dataset/images/test/'
flag = 'test.txt' # 'train.txt'
make_txt(path1, path2, flag)

二、修改训练配置文件

我在服务器上跑,系统是ubuntu,以yolov3为例:
下载darknet:

git clone https://github.com/AlexeyAB/darknet
cd darknet/

下载预训练权重:darknet53.conv.74,提取码:861y
也可以去文章开头提到的官方仓库下载。
创建一个自己的文件夹(纯属为了文件夹没那么乱)

mkdir yolov3

然后将上面生成的train.txt和test.txt复制到yolov3目录下
复制一个yolov3.cfg文件并修改名字为:yolov3-cus.cfg存放到我们的文件夹里:

cp ./cfg/yolov3.cfg ./yolov3/yolov3-cus.cfg

打开这个文件做修改:

vim ./yolov3/yolov3-cus.cfg
  • 修改前面部分
batch = 64
subdivisions = 16
max_batches = (类别数 * 2000# 但不能少于训练图片的数目,也不能少于6000(如一共3个类,则填6000)
steps = (max_batches的80%90%# 比如max_batches是6000,则填4800,5400

width和height按自己需求改,这是输入的宽和高,不过必须为32的倍数。

  • 往下拉,修改每一层yolo层的[classes = 类别数](一共三个yolo层)
  • 修改每一层yolo层前面的卷积层的[filter = 255]为[filter = (类别数 + 5) *3]
    如classes=1 则 filters=18

同样的,复制coco.names文件并改名:

cp ./data/coco.names ./yolov3/obj.names

然后将里面的类名改为自己的类名即可。
在darknet目录下创建一个obj.data文件

vim obj.data

在里面填写并保存:

classes = 2  #你的类别数目
train  = yolov3/train.txt
valid  = yolov3/test.txt
names = yolov3/obj.names
backup = backup/

以上,我们的准备工作就完成啦~

三、训练

./darknet detector train yolov3/obj.data yolov3/yolov3-cus.cfg darknet53.conv.74

如果想在web端看训练过程的图表,可在命令后面加:

-dont_show -mjpeg_port 8090 -map

然后在浏览器上打开:http://你服务器的IP地址:8090
效果如下:
在这里插入图片描述
基本的训练过程就是这样了,如果想知道其他方法或训练技巧,可以看文章开头的两个链接。peace~

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是在 Ubuntu 系统下使用 YOLOv5 训练自己的数据集详细步骤: 1. 安装必要的依赖项 在终端中执行以下命令,以安装必要的依赖项: ``` sudo apt-get update sudo apt-get upgrade sudo apt-get install git sudo apt-get install python3-pip sudo apt-get install python3-venv sudo apt-get install libjpeg-dev zlib1g-dev ``` 2. 克隆 YOLOv5 代码库 在终端中执行以下命令,以克隆 YOLOv5 代码库: ``` git clone https://github.com/ultralytics/yolov5.git cd yolov5 ``` 3. 创建 Python 虚拟环境 在终端中执行以下命令,以创建 Python 虚拟环境: ``` python3 -m venv yolov5 source yolov5/bin/activate ``` 4. 安装依赖项 在虚拟环境中执行以下命令,以安装依赖项: ``` pip install -U pip pip install -r requirements.txt ``` 5. 准备数据集 将准备好的数据集放入 `yolov5/data` 目录中,并且将标注文件放入 `yolov5/data/labels` 目录中。 标注文件应该是以 `.txt` 后缀名结尾的文件,每个文件对应一张图片,其中每一行都表示一个目标的标注信息,格式为: ``` <class> <x_center> <y_center> <width> <height> ``` 其中 `<class>` 是目标的类别,从 0 开始编号;`<x_center>` 和 `<y_center>` 是目标框的中心坐标;`<width>` 和 `<height>` 是目标框的宽度和高度,都是相对于图片宽度和高度的比例。 例如,对于一张包含两个目标的图片,标注文件的内容可能如下所示: ``` 1 0.5625000000000001 0.475 0.125 0.2 2 0.69375 0.665 0.125 0.125 ``` 6. 配置训练参数 在 `yolov5/models` 目录中有一些预定义的模型配置文件,可以根据需要选择一个并进行修改。 在 `yolov5/data` 目录中创建一个 `.yaml` 文件,用于指定数据集的相关信息,例如: ``` train: ../train/images val: ../valid/images nc: 2 names: ['person', 'car'] ``` 其中 `train` 和 `val` 分别指定训练集和验证集的图片路径,`nc` 表示类别的数量,`names` 是一个字符串列表,表示每个类别的名称。 7. 开始训练 在终端中执行以下命令,以开始训练: ``` python train.py --img 640 --batch 16 --epochs 50 --data data/custom.yaml --weights yolov5s.pt --name custom --cache --device 0 ``` 其中 `--img` 指定输入图片的大小,`--batch` 指定批量大小,`--epochs` 指定训练的轮数,`--data` 指定数据集的配置文件,`--weights` 指定预训练模型的权重文件,`--name` 指定训练的名称,`--cache` 开启数据缓存,`--device` 指定使用的 GPU 设备编号。 8. 测试模型 在终端中执行以下命令,以测试模型: ``` python detect.py --weights runs/train/custom/weights/best.pt --img 640 --conf 0.4 --source /path/to/test/images ``` 其中 `--weights` 指定训练好的模型权重文件,`--img` 指定输入图片的大小,`--conf` 指定置信度阈值,`--source` 指定测试图片的路径。 至此,YOLOv5 训练自己的数据集详细步骤就介绍完了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值