YOLOv5訓練過程


YOLOv5訓練過程

1. 數據格式轉為YOLOv5需要的格式

yolov5的項目地址

YOLOv5需要圖像標注的數據格式

大家都知道,用於訓練的圖片都是有對應的標注信息的,主要來標注圖片中的待識別物體(用邊界框和類別表示)

yolov5中每一個圖片對應的標注信息(邊界框和類別)是存放在txt文件中的,內容如下所示:

image-20220404201854580

每一行5個值,含義依次是類別,真實邊界框中心點x坐標,y坐標,寬,高

如果你的數據沒有對應的標注文件,那么可以用標注工具進行標注:(可以用labelme或者labelimg,或者yolov5提供的一個網址數據集制作

如果你有標注文件,但是格式不對的畫,比如你是json格式,就需要自己手動編寫腳本去轉換,或者去網上找別人寫好的腳本

這里以一個我的json文件為例,如果有和這個json格式相同的,可能大多數都與這個不同,可以用下面代碼進行轉換:

{"info": 
{"image_name": "5191_1642654681678.jpg"}, 
"annotations": [{"bbox": [99, 517, 8, 18], "color": "other"}, {"bbox": [113, 519, 9, 17], "color": "other"}, 
{"bbox": [223, 531, 9, 29], "color": "other"}, {"bbox": [237, 555, 7, 14], "color": "other"}, {"bbox": [382, 564, 6, 12], 
"color": "red"}, {"bbox": [325, 484, 10, 28], "color": "other"}, {"bbox": [388, 480, 12, 22], "color": "other"}, 
{"bbox": [453, 481, 13, 29], "color": "other"}, {"bbox": [721, 555, 7, 17], "color": "other"}, {"bbox": [710, 555, 7, 15], 
"color": "other"}, {"bbox": [944, 533, 7, 18], "color": "red"}, {"bbox": [992, 533, 6, 18], "color": "red"}, 
{"bbox": [1261, 566, 6, 15], "color": "red"}, {"bbox": [801, 565, 6, 15], "color": "other"}, {"bbox": [792, 565, 7, 15],
 "color": "other"}, {"bbox": [772, 575, 8, 18], "color": "red"}, {"bbox": [389, 564, 6, 14], "color": "other"}]}
import os
from PIL import Image
import json
import numpy as np
import pandas as pd

# 讀取原始的json數據
ant_root_dir = "./traffic_light_data/annotations"  # 存放json文件的文件夾
img_root_dir = "./traffic_light_data/images"  # 存放圖像的文件夾
output_root = "./traffic_light_data/ant_txt"  # 存放輸出結果的文件夾

json_list = os.listdir(ant_root_dir)
json_dir_list = [os.path.join(ant_root_dir, json_dir) for json_dir in json_list]


def cls_merger_bbox(cls, bbox, size):
	"""
	這個函數需要你修改一下下面的類別映射,如果類別多的話,用下面的代碼則很不好,可以自己改一下
	"""
    # 轉換顏色字符串為類別數字
    if cls == 'red':
        cls = 0
    elif cls == 'green':
        cls = 1
    elif cls == 'yellow':
        cls = 2
    else:
        cls = 3

    # 轉換bbox到0-1之間(除以圖像寬和高)
    # 傳入的bbox格式為(邊界框中心x,中心y,寬,高)
    bbox [0], bbox[2] = bbox[0] / size[0], bbox[2] / size[0]
    bbox[1], bbox[3] = bbox[1] / size[1], bbox[3] / size[1]

    bbox.insert(0, cls)
    bbox = np.around(bbox, decimals=4)
    
    return bbox

for i, json_dir in enumerate(json_dir_list):

    # 將json數據轉為python字典格式,並讀取標注信息
    data = json.load(open(json_dir))

    ant_list = data['annotations']
    image_name = data['info']['image_name']

    # 讀取json文件對應的圖像寬高
    image_dir = os.path.join(img_root_dir, image_name)
    img = Image.open(image_dir)
    size = img.size

    # 用數組存取我們的標注信息
    ant_yolo_np = np.zeros((len(ant_list), 5))

    for i, ant in enumerate(ant_list):
        bbox = ant['bbox']  # list
        cls = ant['color']  # str

        # 將bbox縮放到0-1之間,並把cls轉成對應的數字,將兩者放在一個列表中
        cls_bbox = cls_merger_bbox(cls, bbox, size)

        # 放入數組中
        ant_yolo_np[i, :] = cls_bbox
    
    output = pd.DataFrame(ant_yolo_np)
    output.iloc[:, 0] = output.iloc[:, 0].astype(int)

    output_name = os.path.join(output_root, os.path.splitext(image_name)[0]+'.txt')


    # np.savetxt(output_name, ant_yolo_np, delimiter=' ', fmt='%.04f')
    output.to_csv(output_name, sep=' ', index=False, header=False)

print("轉換完畢")
import random
import shutil

"""
下面代碼用於划分訓練集和驗證集
"""

image_list = os.listdir(img_root_dir)
output_list = os.listdir(output_root)

index_list = random.sample(range(len(image_list)), 80)

for i in index_list:
    image_name = os.path.join(img_root_dir, image_list[i])
    txt_name = os.path.join(output_root, output_list[i])
    shutil.move(image_name, './valid_image')
    shutil.move(txt_name, './valid_txt')

yolov5需要的數據在文件夾中的位置

你的圖像和標注數據應該按照下面的形式放在文件夾中:


datasets

  • traffic_light
    • images
      • train 存放訓練圖像
      • val 存放驗證集圖像
    • labels
      • train 存放訓練圖像對應的標注txt文件
      • val 同上

然后將datasets文件夾放到與你下載到的yolov5項目的同級目錄下

2.訓練時必須修改的文件


創建自己的.yaml文件,里面主要用來配置你的數據的信息,創建位置如下圖所示:

image-20220404212149645

里面的內容如下所示:

主要是把我們剛才放到datasets下的數據集的路徑還有訓練集合驗證集的路徑填一下

image-20220404212523695


修改models文件夾下的yolov5*.yaml文件,這個是你后面用於訓練的模型配置文件(下圖改的是yolov5x.yaml),修改一下類別就行,其他的有能力也可以改:

image-20220404213018982


將數據集配置好,並修改以上兩個文件后就可以訓練啦!

進入yolov5項目文件夾,打開終端,輸入下面命令:

python train.py --img 640 --batch 4 --epochs 30 --data ./data/traffic_light.yaml --weights ./weights/yolov5x.pt --cfg ./models/yolov5x.yaml

  • --img:指的是輸入網絡的圖像尺寸,有兩個選擇,6401280
  • --batch:是1epoch內,一次性喂入網絡的數據中包含的圖像個數,也就是卷積網絡輸入數據的第一個緯度(比如[4,3, 640,640]);可以根據你的顯存大小進行調整,顯存越大可以設置更大,我的就6G,且網絡模型很大,所以就設置小一些,不然會報顯存不足或者其他錯誤
  • --epochs:訓練網絡的次數,一個epoch圖像總數/batch次更新模型的機會,一個epoch進行完之后,說明你的訓練數據集已將全部被網路訓練一遍了,接下來網絡會在驗證集上驗證目前的網絡參數效果如何
  • --data:你的數據集對應的.yaml文件
  • --weights:官方提供的預訓練權重,weights文件夾是我自己建的;下載地址:權重下載,進去之后找到Assets字樣,如果你的網絡比較卡,可以在百度網盤中下載:鏈接:https://pan.baidu.com/s/1CCmJmx4wCIJcmDahIye2Hw權重后面的6表示的是輸入圖像尺寸為1280分辨率的圖像,--cfg也要改成相應的帶6
    提取碼:iltr
  • --cfg:網絡模型對應的文件

正常來說就可以訓練了,如果有什么問題可以留言,看到了會回復


訓練好之后,會提示你本次訓練結果存放在run/train/exp*文件夾下,在該文件夾下的weights文件夾中可以看到本次訓練的最好參數和最后一個epoch訓練完之后的權重

用你訓練好的權重進行測試

執行下面代碼:

python detect.py --weights ./runs/train/exp6/weights/best.pt --source ./test.jpg

執行完之后會提示你結果保存在***

  • 下面是--source參數的值

image-20220404215649008

  • --weights:是你訓練好的權重

3.其他

可視化時,更改邊界框的粗細

修改學習率等超參數

data文件夾下的hyps文件夾中可以修改各種超參數,-low好像是圖像尺寸為640時生效

image-20220404221320561

4.訓練結果記錄

第一次: 本次用的圖像尺寸是640,也就是說會把你輸入的圖像,進行縮放與隨機裁剪等變化,最終用於訓練的大小是640;直接用的最大的模型yolov5x,批次剛開始小一些30個,發現mAP一直在上升,因此可以加大批次數,增大一些學習率

python train.py --img 640 --batch 4 --epochs 30 --data ./data/traffic_light.yaml --weights ./weights/yolov5x.pt --cfg ./models/yolov5x.yaml
image-20220404161601219
測試結果python detect.py --weights ./runs/train/exp6/weights/best.pt --source ./test.jpg
第二次: 與第一次相比,只是把初始學習率改為了0.03,然后訓練次數增大到100;感覺mAP還有上升空間,下面繼續增加訓練次數和學習率

python train.py --img 640 --batch 4 --epochs 100 --data ./data/traffic_light.yaml --weights ./weights/yolov5x.pt --cfg ./models/yolov5x.yaml
image-20220404205703158
python detect.py --weights ./runs/train/exp6/weights/best.pt --source ./detect # 將detect文件夾下的圖片都進行測試
下面是跑了300個epochs的情況,感覺兩次結果很接近
image-20220405180238612


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM