YOLOv8 从环境搭建到推理训练
0、引言
硬件配置:使用Mobaxterm_personal_21.4遠程操控3060服務器(Linux系統),CUDA版本11.7。
使用anaconda作為python環境環境,python為3.8版本。(最好使用3.8版本)
本文最終安裝的pytorch版本是1.13.1,torchvision版本是0.14.1,其他的依賴庫按照requirements.txt文件安裝即可。
YOLOv8創新點:🍺🍺🍺 1😃Backbone。使用的依舊是CSP的思想,不過YOLOv5中的C3模塊被替換成了C2f模塊,實現了進一步的輕量化,同時YOLOv8依舊使用了YOLOv5等架構中使用的SPPF模塊; 2😁PAN-FPN。毫無疑問YOLOv8依舊使用了PAN的思想,不過通過對比YOLOv5與YOLOv8的結構圖可以看到,YOLOv8將YOLOv5中PAN-FPN上采樣階段中的卷積結構刪除了,同時也將C3模塊替換為了C2f模塊 3😑Decoupled-Head。是不是嗅到了不一樣的味道?是的,YOLOv8走向了Decoupled-Head; 4😂Anchor-Free。YOLOv8拋棄了以往的Anchor-Base,使用了Anchor-Free的思想; 5😊損失函數。YOLOv8使用VFL Loss作為分類損失,使用DFL Loss+CIOU Loss作為分類損失; 6😚樣本匹配。YOLOv8拋棄了以往的IOU匹配或者單邊比例的分配方式,而是使用了Task-Aligned Assigner匹配方式。 |
1、代碼下載
代碼連接:
https://github.com/ultralytics/ultralytics
權重連接:
https://github.com/ultralytics/assets/releases
先睹為快:
下載:點擊右上角的綠色Code按鈕,再點擊Download,即可完成代碼下載。下載之后導入到服務器端解壓。
解壓之后如下圖所示。
2、環境準備
2.1創建新環境
啟動遠程軟件,進入base環境,創建新環境yolov8。
conda create -n yolov8 python=3.8激活新環境yolov8。
conda activate yolov82.2安裝依賴(各種第三方庫)
運行requirements.txt文件即可完成對所有庫的安裝,包括pytorch等眾多第三方庫。
運行該文件需要先進入到該文件所在的文件夾:cd 各層文件夾。進入所在文件夾之后再運行該文件。
pip install -r requirements.txt -i https://mirrors.bfsu.edu.cn/pypi/web/simple/2.3安裝ultralytics
ultralytics集成了yolo的各種包以及模型等,程序中直接調用。
pip install ultralytics2.4手動下載權重
雖然在(2)中可以自動下載yolov8n.pt,但是經常打不開,所以給出手動下載連接。
下載鏈接:https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt
位置:拷到yolov8\ultralytics-main\ultralytics\yolo\v8\detect\yolov8n.pt
3、測試運行
操作:首先進入到yolov8\ultralytics-main\ultralytics\yolo\v8\detect\predict.py,運行predict.py
python predict.py完成測試:
查看結果:
4、訓練自己的數據
4.1數據準備
由于本文的實驗是進行圖像檢測,故將數據集放在detect目錄下。
操作:在detect文件下新建mydata_tuomin文件夾(可自定義),再在mydata_tuomin目錄下新建Annotations, images, ImageSets, labels 四個文件夾。
📌Annotations目錄下存放圖片的xml文件 📌images目錄下存放數據集的圖片文件 📌ImageSets 目錄之后會在Main文件夾內自動生成train.txt,val.txt,test.txt和trainval.txt四個文件 📌labels目錄下存放xml文件轉換后的txt標準格式標簽 |
4.2按比例劃分數據集
操作:在detect目錄下新建一個文件splitDataset.py,運行。
作用:隨機分配訓練/驗證/測試集圖片,會在ImageSet 目錄下生成四個txt文件,存放訓練集、驗證集、測試集的劃分文件(各集合包含的圖片)。
代碼如下所示:
import os import randomtrainval_percent = 0.9 train_percent = 0.9 xmlfilepath = 'mydata_tuomin/Annotations' txtsavepath = 'mydata_tuomin/ImageSets' total_xml = os.listdir(xmlfilepath)num = len(total_xml) list = range(num) tv = int(num * trainval_percent) tr = int(tv * train_percent) trainval = random.sample(list, tv) train = random.sample(trainval, tr)ftrainval = open('mydata_tuomin/ImageSets/trainval.txt', 'w') ftest = open('mydata_tuomin/ImageSets/test.txt', 'w') ftrain = open('mydata_tuomin/ImageSets/train.txt', 'w') fval = open('mydata_tuomin/ImageSets/val.txt', 'w')for i in list:name = total_xml[i][:-4] + '\n'if i in trainval:ftrainval.write(name)if i in train:ftrain.write(name)else:fval.write(name)else:ftest.write(name)ftrainval.close() ftrain.close() fval.close() ftest.close()查看結果:
4.3標簽格式轉換
由于yolov8使用的labels是txt格式的文件,故需將原始數據集xml格式的標簽轉換為txt格式。
即將每個xml標注提取box信息為txt格式,每個圖像對應一個txt文件,文件每一行為一個目標的信息,包括class, x_center, y_center, width, height格式。
操作:在detect目錄下新建一個文件XML2TXT.py,運行。
📌注意代碼第11行,classes = ['…']一定需要填寫自己數據集的類別,在這里我是三個類別'greenplate','blueplate','face'。 📌如果數據集中的類別不知道或者比較多不想手敲,可以使用4.4中的腳本直接獲取類別,如果不需要可以直接跳過4.4。 |
結果:生成的標簽存放在labels目錄下,并且在mydata_tuomin目錄下生成三個txt文件,文件內是訓練集、驗證集、測試集的圖片路徑。
代碼如下:
# -*- coding: utf-8 -*- # xml解析包 import xml.etree.ElementTree as ET import pickle import os from os import listdir, getcwd from os.path import joinsets = ['train', 'test', 'val'] classes = ['greenplate','blueplate','face']# 進行歸一化操作 def convert(size, box): # size:(原圖w,原圖h) , box:(xmin,xmax,ymin,ymax)dw = 1./size[0] # 1/wdh = 1./size[1] # 1/hx = (box[0] + box[1])/2.0 # 物體在圖中的中心點x坐標y = (box[2] + box[3])/2.0 # 物體在圖中的中心點y坐標w = box[1] - box[0] # 物體實際像素寬度h = box[3] - box[2] # 物體實際像素高度x = x*dw # 物體中心點x的坐標比(相當于 x/原圖w)w = w*dw # 物體寬度的寬度比(相當于 w/原圖w)y = y*dh # 物體中心點y的坐標比(相當于 y/原圖h)h = h*dh # 物體寬度的寬度比(相當于 h/原圖h)return (x, y, w, h) # 返回 相對于原圖的物體中心點的x坐標比,y坐標比,寬度比,高度比,取值范圍[0-1]# year ='2012', 對應圖片的id(文件名) def convert_annotation(image_id):# 對應的通過year 找到相應的文件夾,并且打開相應image_id的xml文件,其對應bund文件in_file = open('mydata_tuomin/Annotations/%s.xml' % (image_id), encoding='utf-8')# 準備在對應的image_id 中寫入對應的label,分別為# <object-class> <x> <y> <width> <height>out_file = open('mydata_tuomin/labels/%s.txt' % (image_id), 'w', encoding='utf-8')# 解析xml文件tree = ET.parse(in_file)# 獲得對應的鍵值對root = tree.getroot()# 獲得圖片的尺寸大小size = root.find('size')# 如果xml內的標記為空,增加判斷條件if size != None:# 獲得寬w = int(size.find('width').text)# 獲得高h = int(size.find('height').text)# 遍歷目標objfor obj in root.iter('object'):# 獲得difficult ??difficult = obj.find('difficult').text# 獲得類別 =string 類型cls = obj.find('name').text# 如果類別不是對應在我們預定好的class文件中,或difficult==1則跳過if cls not in classes or int(difficult) == 1:continue# 通過類別名稱找到idcls_id = classes.index(cls)# 找到bndbox 對象xmlbox = obj.find('bndbox')# 獲取對應的bndbox的數組 = ['xmin','xmax','ymin','ymax']b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))print(image_id, cls, b)# 帶入進行歸一化操作# w = 寬, h = 高, b= bndbox的數組 = ['xmin','xmax','ymin','ymax']bb = convert((w, h), b)# bb 對應的是歸一化后的(x,y,w,h)# 生成 calss x y w h 在label文件中out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')# 返回當前工作目錄 wd = getcwd() print(wd)for image_set in sets:# 先找labels文件夾如果不存在則創建if not os.path.exists('mydata_tuomin/labels/'):os.makedirs('mydata_tuomin/labels/')# 讀取在ImageSets/Main 中的train、test..等文件的內容# 包含對應的文件名稱image_ids = open('mydata_tuomin/ImageSets/%s.txt' % (image_set)).read().strip().split()# 打開對應的2012_train.txt 文件對其進行寫入準備list_file = open('mydata_tuomin/%s.txt' % (image_set), 'w')# 將對應的文件_id以及全路徑寫進去并換行for image_id in image_ids:list_file.write('mydata_tuomin/images/%s.jpg\n' % (image_id))# 調用 year = 年份 image_id = 對應的文件名_idconvert_annotation(image_id)# 關閉文件list_file.close()4.4查看自己的數據集標簽類別
操作:在detect目錄下新建一個文件ViewCategory.py,運行。
代碼如下:(文件路徑也可以使用絕對路徑)
# coding=gbk import xml.dom.minidom as xmldom import os#voc數據集獲取所有標簽的所有類別數" annotation_path="/mydata_tuomin/Annotations/"annotation_names=[os.path.join(annotation_path,i) for i in os.listdir(annotation_path)]labels = list() for names in annotation_names:xmlfilepath = namesdomobj = xmldom.parse(xmlfilepath)# 得到元素對象elementobj = domobj.documentElement#獲得子標簽subElementObj = elementobj.getElementsByTagName("object")for s in subElementObj:label=s.getElementsByTagName("name")[0].firstChild.data#print(label)if label not in labels:labels.append(label) print(labels)4.5創建數據加載配置文件
操作:在mydata_tuomin文件夾下新建一個tuomin.yaml文件(可以自定義命名),用來存放訓練集、驗證集、測試集的路徑文件(train.txt、val.txt、test.txt),以上三個文件是在步驟4.3中生成的路徑文件(存放在mydata_tuomin目錄下),然后是目標的類別數目和具體類別列表。
代碼如下:???注意txt需要使用絕對路徑。
train: /home/xxxxxx/Yolov8/ultralyticsmain/ultralytics/yolo/v8/detect/mydata_tuomin/train.txt val: /home/xxxxxx/Yolov8/ultralyticsmain/ultralytics/yolo/v8/detect/mydata_tuomin/val.txt test: /home/xxxxxx/Yolov8/ultralyticsmain/ultralytics/yolo/v8/detect/mydata_tuomin/test.txt# number of classes nc: 3# class names names: ['greenplate', 'blueplate', 'face']4.6選擇模型
在ultralytics/models/v8/目錄下是模型的配置文件,提供了n、s、m、l、x版本,逐漸增大(隨著架構的增大,訓練時間也是逐漸增大),五種模型對比圖如下所示。
操作:本文限于硬件配置,采用yolov8s.yaml,接下來只用修改一個參數,把nc改成自己的類別數
代碼如下:
# Ultralytics YOLO 馃殌, GPL-3.0 license# Parameters nc: 3 # number of classes(只需要改這里!!!!!!!) depth_multiple: 0.33 # scales module repeats width_multiple: 0.50 # scales convolution channels# YOLOv8.0s backbone backbone:# [from, repeats, module, args]- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4- [-1, 3, C2f, [128, True]]- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8- [-1, 6, C2f, [256, True]]- [-1, 1, Conv, [512, 3, 2]] # 5-P4/16- [-1, 6, C2f, [512, True]]- [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32- [-1, 3, C2f, [1024, True]]- [-1, 1, SPPF, [1024, 5]] # 9# YOLOv8.0s head head:- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 6], 1, Concat, [1]] # cat backbone P4- [-1, 3, C2f, [512]] # 13- [-1, 1, nn.Upsample, [None, 2, 'nearest']]- [[-1, 4], 1, Concat, [1]] # cat backbone P3- [-1, 3, C2f, [256]] # 17 (P3/8-small)- [-1, 1, Conv, [256, 3, 2]]- [[-1, 12], 1, Concat, [1]] # cat head P4- [-1, 3, C2f, [512]] # 20 (P4/16-medium)- [-1, 1, Conv, [512, 3, 2]]- [[-1, 9], 1, Concat, [1]] # cat head P5- [-1, 3, C2f, [1024]] # 23 (P5/32-large)- [[15, 18, 21], 1, Detect, [nc]] # Detect(P3, P4, P5)4.7開始訓練
輸入如下命令開始訓練。
yolo task=detect mode=train model=yolov8s.yaml data=mydata_tuomin/tuomin.yaml epochs=100 batch=4以上參數解釋如下: 📌task:選擇任務類型,可選['detect', 'segment', 'classify', 'init']。 📌mode: 選擇是訓練、驗證還是預測的任務蕾西 可選['train', 'val', 'predict']。 📌model: 選擇yolov8不同的模型配置文件,可選yolov8s.yaml、yolov8m.yaml、yolov8x.yaml等。 📌data: 選擇生成的數據集配置文件 📌epochs:指的就是訓練過程中整個數據集將被迭代多少次,顯卡不行你就調小點。 📌batch:一次看完多少張圖片才進行權重更新,梯度下降的mini-batch,顯卡不行你就調小點。 |
查看訓練過程:
查看結果:
總結
以上是生活随笔為你收集整理的YOLOv8 从环境搭建到推理训练的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海天蚝油《挑战不可能》迎来真·火眼金睛的
- 下一篇: 广东省民营企业合作交流协会会长谭铭卓一行