一,YOLOV9代码下载
YOLOv9是原YOLOv7团队打造,提出了可编程梯度信息(PGI)的概念来应对深度网络实现多个目标所需的各种变化。 PGI可以为目标任务计算目标函数提供完整的输入信息,从而获得可靠的梯度信息来更新网络权值。此外,还设计了一种新的轻量级网络架构——基于梯度路径规划的通用高效层聚合网络(GELAN)。 GELAN的架构证实了PGI在轻量级模型上取得了优异的结果。
顺便look一下yolo的创作历程:
论文地址:YOLOv9论文地址
GitHub地址:GitHub代码下载地址
先将上面代码下载下来,然后下载自己想要的权重(我下载的是最后两个yolov9-c和yolo9-e)
然后将权重文件放在下载好的yolov9里面
二,环境配置
创建conda环境(名称我用的是yolov9,可换自己的)
conda create -n yolov9 python=3.8
在yolov9下打开终端并激活环境
conda activate yolov9
然后安装requirements.txt文件,后面加清华的镜像源效果更好。
//不加清华源
pip install -r requirements.txt
//加清华源
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
等待安装完成即可。
三,训练自己的数据集
首先在自己的yolov9文件里面创建一个datasets文件,并将图片和标签放入mydata中
以下是文件夹格式:
(里面的三个txt文件后面划分数据集会自动生成)
以下是划分数据集的代码(只需要修改成你们自己的路径即可)
import shutil
import random
import os
# 原始路径
image_original_path = "/home/wuyapeng/yolov9/datasets/mydata/images/"
label_original_path = "/home/wuyapeng/yolov9/datasets/mydata/labels/"
cur_path = os.getcwd()
# 训练集路径
train_image_path = os.path.join(cur_path, "/home/wuyapeng/yolov9/datasets/images/train/")
train_label_path = os.path.join(cur_path, "/home/wuyapeng/yolov9/datasets/labels/train/")
# 验证集路径
val_image_path = os.path.join(cur_path, "/home/wuyapeng/yolov9/datasets/images/val/")
val_label_path = os.path.join(cur_path, "/home/wuyapeng/yolov9/datasets/labels/val/")
# 测试集路径
test_image_path = os.path.join(cur_path, "/home/wuyapeng/yolov9/datasets/images/test/")
test_label_path = os.path.join(cur_path, "/home/wuyapeng/yolov9/datasets/labels/test/")
# 训练集目录
list_train = os.path.join(cur_path, "/home/wuyapeng/yolov9/datasets/train.txt")
list_val = os.path.join(cur_path, "/home/wuyapeng/yolov9/datasets/val.txt")
list_test = os.path.join(cur_path, "/home/wuyapeng/yolov9/datasets/test.txt")
train_percent = 0.8
val_percent = 0.1
test_percent = 0.1
def del_file(path):
for i in os.listdir(path):
file_data = os.path.join(path, i)
os.remove(file_data)
def mkdir():
if not os.path.exists(train_image_path):
os.makedirs(train_image_path)
else:
del_file(train_image_path)
if not os.path.exists(train_label_path):
os.makedirs(train_label_path)
else:
del_file(train_label_path)
if not os.path.exists(val_image_path):
os.makedirs(val_image_path)
else:
del_file(val_image_path)
if not os.path.exists(val_label_path):
os.makedirs(val_label_path)
else:
del_file(val_label_path)
if not os.path.exists(test_image_path):
os.makedirs(test_image_path)
else:
del_file(test_image_path)
if not os.path.exists(test_label_path):
os.makedirs(test_label_path)
else:
del_file(test_label_path)
def clearfile():
if os.path.exists(list_train):
os.remove(list_train)
if os.path.exists(list_val):
os.remove(list_val)
if os.path.exists(list_test):
os.remove(list_test)
def main():
mkdir()
clearfile()
file_train = open(list_train, 'w')
file_val = open(list_val, 'w')
file_test = open(list_test, 'w')
total_txt = os.listdir(label_original_path)
num_txt = len(total_txt)
list_all_txt = list(range(num_txt))
num_train = int(num_txt * train_percent)
num_val = int(num_txt * val_percent)
num_test = num_txt - num_train - num_val
train = random.sample(list_all_txt, num_train)
val_test = [i for i in list_all_txt if i not in train]
val = random.sample(val_test, num_val)
print("训练集数目:{}, 验证集数目:{}, 测试集数目:{}".format(len(train), len(val), len(val_test) - len(val)))
for i in list_all_txt:
name = total_txt[i][:-4]
srcImage = os.path.join(image_original_path, name + '.jpg')
srcLabel = os.path.join(label_original_path, name + ".txt")
if i in train:
dst_train_Image = os.path.join(train_image_path, name + '.jpg')
dst_train_Label = os.path.join(train_label_path, name + '.txt')
shutil.copyfile(srcImage, dst_train_Image)
shutil.copyfile(srcLabel, dst_train_Label)
file_train.write(dst_train_Image + '\n')
elif i in val:
dst_val_Image = os.path.join(val_image_path, name + '.jpg')
dst_val_Label = os.path.join(val_label_path, name + '.txt')
shutil.copyfile(srcImage, dst_val_Image)
shutil.copyfile(srcLabel, dst_val_Label)
file_val.write(dst_val_Image + '\n')
else:
dst_test_Image = os.path.join(test_image_path, name + '.jpg')
dst_test_Label = os.path.join(test_label_path, name + '.txt')
shutil.copyfile(srcImage, dst_test_Image)
shutil.copyfile(srcLabel, dst_test_Label)
file_test.write(dst_test_Image + '\n')
file_train.close()
file_val.close()
file_test.close()
if __name__ == "__main__":
main()
接下来制作data.yaml文件
train: /home/wuyapeng/yolov9/datasets/images/train
val: /home/wuyapeng/yolov9/datasets/images/val
test: /home/wuyapeng/yolov9/datasets/images/test
nc: 2 #换成你自己的类别数量
names: ['one','two']#换成自己的类别名
然后可以用pycharm或者viscode打开yolov9文件(不打开也可以,直接在终端运行即可)
首先更改小错误,打开utils/loss_tal.py文件,到第167行,将p改为p[0]
其次打开trian.py文件,更改如下几个位置:
–weights : 此处更改为yolov9-c.pt的绝对路径
–cfg : 此处更改为yolov9-c.yaml的绝对路径(首先去yolov9/models/detect/yolov9-c.yaml修改类别数nc)
–data : 此处更改为data.yaml的绝对路径 ##上面的data.yaml文件
–hyp : 此处更改为data/hyps/hyp.scratch-high.yaml(原本是data/hyps/hyp.scratch-low.yaml但该文件内并未找到,,,猜测为YOLOv9作者调试过程中的小疏忽)
最后保存修改后,开启正式训练:
在终端运行
python train.py
最后训练完成
注意!!!如果中途报错了,attributeerror: ‘FreeTypeFont‘ object has no attribute ‘getsize‘
这是因为安装了新版本的 Pillow (10),pip install tf-models-official删除了该getsize 功能,降级到 Pillow 9.0.1 解决了该问题
# 降低版本
pip install Pillow==9.0.1
over!!!