???????
目錄
一、簡介
配置
環(huán)境準(zhǔn)備
二、環(huán)境配置
1.安裝anaconda
2.安裝TensorFlow
3.安裝pytorch
4.pyqt5安裝
?5.安裝labelimg
6.下載yolov5
7.pycharm安裝
三、使用labelimg標(biāo)記圖片
1.準(zhǔn)備工作
2.標(biāo)記圖片
四、 劃分?jǐn)?shù)據(jù)集以及配置文件修改
1. 劃分訓(xùn)練集、驗證集、測試集
2.XML格式轉(zhuǎn)yolo_txt格式
3.配置文件
4.聚類獲得先驗框
五、使用CPU訓(xùn)練
六、訓(xùn)練結(jié)果可視化
一、簡介
? ?最近為了應(yīng)付畢業(yè)論文,學(xué)習(xí)了目標(biāo)檢測,目的是檢測車輛和行人,使用了yolov5,想到了是否可以在mac 上跑yolov5 ,因為是m1芯片,以及系統(tǒng)的更新,踩了不少坑,總結(jié)了幾個博主的經(jīng)驗,順利的在mac上實現(xiàn)了yolov5的訓(xùn)練和檢測。
踩坑點:pyqt5安裝、labelimg安裝(需前置pyqt5)、yolov5訓(xùn)練時隱藏文件文件.DS_store無法識別
配置
電腦型號:2021 mbp? m1 pro
系統(tǒng)版本:ventura 13.0 (22A380)
環(huán)境準(zhǔn)備
anaconda individual?最新版
python 3.9.13
pytorch 2.0 (后面有教程)
TensorFlow 2.11.0(后面有教程)
Pyqt5 5.15.7(后面有教程)
labelimg 1.8.6
pycharm 2022.3
yolov5?
二、環(huán)境配置
1.安裝anaconda
(1)進(jìn)入官網(wǎng)
官網(wǎng)鏈接:Anaconda | The World's Most Popular Data Science Platform
直接在這里下載并安裝anaconda就可以
(2)點擊安裝包進(jìn)行安裝
直接無腦點下一步
在這一步時選擇僅為我安裝。
安裝好之后再應(yīng)用程序里就可以看見。
(3)打開終端之后
發(fā)現(xiàn)前面有個(base)就是安裝成功了。
2.安裝TensorFlow
(1)創(chuàng)建一個新的anaconda環(huán)境
conda create -n tf python=3.9.13
(2)切換到tf環(huán)境(再打開終端時要記得切到這個環(huán)境)
conda activate tf
前面有(tf)則是轉(zhuǎn)換成功?
(3)安裝macos版本的TensorFlow。
如果顯示404等錯誤,可以嘗試掛個梯子。
conda install -c apple tensorflow-deps
python3 -m pip install tensorflow-macos
(如果不確定使用python3還是python,可以使用which python查看路徑,使用虛擬環(huán)境下的python才有效)
python3 -m pip install tensorflow-metal?
(4)然后在終端輸入
python3
import tensorflow?
如果出現(xiàn)
則是成功
exit()
可以退出python命令行
報錯——>提示numpy版本不兼容(numpy版本過低要重新裝)
conda uninstall numpy
pip install numpy
再次嘗試導(dǎo)入tensorflow重復(fù)(4)中
成功
3.安裝pytorch
進(jìn)入pytorch官網(wǎng)
官網(wǎng)鏈接:PyTorch
點擊install 出現(xiàn)
?選擇相應(yīng)的配置
在終端運行
pip3 install torch torchvision torchaudio
?等待安裝完成即可。
4.pyqt5安裝
因為labelimg需要Pyqt5,但高版本macos 的pyqt安裝會出錯。
可以先運行一下
pip install pyqt5
如果成功則這步省略
出錯則需要進(jìn)行安裝homebrew 再用brew去安裝pyqt5
(1)安裝homebrew
Homebrew — The Missing Package Manager for macOS (or Linux)
首頁就是安裝方法
終端運行
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
安裝完成之后 使用brew 安裝pyqt5
brew install pyqt5
如果你的brew 長時間沒更新
會報404找不到資源的錯誤,那就先要更新brew,csdn搜索即可。
安裝完成之后進(jìn)入homebrew的cellar文件夾
我的在
/opt/homebrew/Cellar
找到pyqt@5文件夾點進(jìn)去
目錄如下所示
/opt/homebrew/Cellar/pyqt@5/5.15.7_2/lib/python3.9/site-packages
把下列文件全部放到anaconda環(huán)境中
?首先找到conda的環(huán)境
conda env list
我的tf環(huán)境在
/Users/qishuocheng/anaconda3/envs/tf
使用前往文件夾就可以
點進(jìn)去找到lib文件夾
/Users/qishuocheng/anaconda3/envs/tf/lib/python3.9/site-packages
?把上面pyqt5的文件放進(jìn)來
python?
import PyQt5
不報錯就算成功
?5.安裝labelimg
上述完成后進(jìn)行
pip install labelimg
安裝完成之后
輸入
labelimg
?出現(xiàn)這個即可。
6.下載yolov5
GitHub - ultralytics/yolov5 at v6.1
直接下載zip
或者git clone到本地
git clone https://github.com/ultralytics/yolov5.git (加本地文件地址)
沒有g(shù)it 的要先
pip install git
7.pycharm安裝
PyCharm: the Python IDE for Professional Developers by JetBrains
進(jìn)入官網(wǎng)
下載之后配置
切到你的conda環(huán)境
如果沒有就添加本地解釋器
?
?
選擇你的環(huán)境點擊確定就可以切換環(huán)境啦。?
三、使用labelimg標(biāo)記圖片
1.準(zhǔn)備工作
在yolov5目錄下新建一個名為VOCData的文件夾
在VOCData文件夾下創(chuàng)建 Annotations 和 images 文件夾
images放要訓(xùn)練的圖片
(【??易錯】:images的文件名不建議修改,否則之后訓(xùn)練時容易出現(xiàn)No labels found的錯誤,原因見下)
[說明]:
Annotations 文件夾用于存放使用labelimg標(biāo)記后的圖片(XML格式)
images 文件夾用于存放用于標(biāo)記的圖片
(【??易錯】:images 文件夾下直接放圖片,內(nèi)部不要嵌套有文件夾,否則之后訓(xùn)練可能會出現(xiàn) No label found 的錯誤,具體原因見下文中 xml_to_yolo.py文件的第67行)
2.標(biāo)記圖片
在cmd窗口下輸入 labelimg 或者運行 labelimg.py 文件進(jìn)入labelimg的可執(zhí)行程序(注:如果是在虛擬環(huán)境下安裝的labelimg,記得先激活虛擬環(huán)境)
conda activate tf(你自己的虛擬環(huán)境名)
分別設(shè)置需要標(biāo)注圖片的文件夾和存放標(biāo)記結(jié)果的文件夾的地址
圖像放在之前設(shè)置好的images里
更改存放目錄改為Annotions文件夾里
推薦設(shè)置自動保存
?
?
標(biāo)記圖片快捷鍵:w:標(biāo)記 ??a:上一張圖片 ??d:下一張圖片
標(biāo)注的時候盡可能貼近物體輪廓
四、 劃分?jǐn)?shù)據(jù)集以及配置文件修改
1. 劃分訓(xùn)練集、驗證集、測試集
?在VOCData目錄下創(chuàng)建程序 split_train_val.py 并運行以下代碼。代碼可以不做任何修改
?注意注意:在macos下,文件夾內(nèi)會生成.Ds_store隱藏文件要先刪除 不然會讀取錯誤
打開images文件夾(之前創(chuàng)建的文件)
這是我的文件夾 根據(jù)自己路徑找
?cd /Users/qishuocheng/Desktop/yolov5/VOCData/images?
ls -a
刪除這個文件后
rm .DS_Store
運行下面的代碼(images下存放你的圖片)
# coding:utf-8
import os
import random
import argparse
parser = argparse.ArgumentParser()
#xml文件的地址,根據(jù)自己的數(shù)據(jù)進(jìn)行修改 xml一般存放在Annotations下
parser.add_argument('--xml_path', default='Annotations', type=str, help='input xml label path')
#數(shù)據(jù)集的劃分,地址選擇自己數(shù)據(jù)下的ImageSets/Main
parser.add_argument('--txt_path', default='ImageSets/Main', type=str, help='output txt label path')
opt = parser.parse_args()
trainval_percent = 1.0 ?# 訓(xùn)練集和驗證集所占比例。 這里沒有劃分測試集
train_percent = 0.9 ? ? # 訓(xùn)練集所占比例,可自己進(jìn)行調(diào)整
xmlfilepath = opt.xml_path
txtsavepath = opt.txt_path
total_xml = os.listdir(xmlfilepath)
if not os.path.exists(txtsavepath):
? ? os.makedirs(txtsavepath)
num = len(total_xml)
list_index = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list_index, tv)
train = random.sample(trainval, tr)
file_trainval = open(txtsavepath + '/trainval.txt', 'w')
file_test = open(txtsavepath + '/test.txt', 'w')
file_train = open(txtsavepath + '/train.txt', 'w')
file_val = open(txtsavepath + '/val.txt', 'w')
for i in list_index:
? ? name = total_xml[i][:-4] + '\n'
? ? if i in trainval:
? ? ? ? file_trainval.write(name)
? ? ? ? if i in train:
? ? ? ? ? ? file_train.write(name)
? ? ? ? else:
? ? ? ? ? ? file_val.write(name)
? ? else:
? ? ? ? file_test.write(name)
file_trainval.close()
file_train.close()
file_val.close()
file_test.close()
運行結(jié)束后會在生成一個名為 ImageSets 的文件夾:
?測試集里的內(nèi)容為空,因為在劃分?jǐn)?shù)據(jù)的時候,將90%的數(shù)據(jù)劃分到訓(xùn)練集,將10%的數(shù)據(jù)劃分到訓(xùn)練集。如果要分配,則調(diào)整上面14,15行代碼中trainval和train的所占的比例
[說明]:
訓(xùn)練集是用來訓(xùn)練模型的,通過嘗試不同的方法和思路使用訓(xùn)練集來訓(xùn)練不同的模型
驗證集使用交叉驗證來挑選最優(yōu)的模型,通過不斷的迭代來改善模型在驗證集上的性能
測試集用來評估模型的性能
2.XML格式轉(zhuǎn)yolo_txt格式
在VOCData目錄下創(chuàng)建程序 xml_to_yolo.py 并運行以下代碼,注意:
將classes改為自己標(biāo)注時設(shè)置的類名(我這里叫"car")
將各個絕對路徑修改為自己的
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd
sets = ['train', 'val', 'test']
classes = ["car"] # 改成自己的類別
abs_path = os.getcwd()
print(abs_path)
def convert(size, box):
dw = 1. / (size[0])
dh = 1. / (size[1])
x = (box[0] + box[1]) / 2.0 - 1
y = (box[2] + box[3]) / 2.0 - 1
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(image):
in_file = open('/Users/qishuocheng/Desktop/yolov5/VOCData/Annotations/%s.xml' % image,encoding='utf-8')
out_file = open('/Users/qishuocheng/Desktop/yolov5/VOCData/labels/%s.txt' % image, 'w')
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'):
difficult = obj.find('difficult').text
# difficult = obj.find('Difficult').text
cls = obj.find('name').text
if cls not in classes or int(difficult) == 1:
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))
b1, b2, b3, b4 = b
# 標(biāo)注越界修正
if b2 > w:
b2 = w
if b4 > h:
b4 = h
b = (b1, b2, b3, b4)
bb = convert((w, h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
wd = getcwd()
for image_set in sets:
if not os.path.exists('/Users/qishuocheng/Desktop/yolov5/VOCData/labels/'):
os.makedirs('/Users/qishuocheng/Desktop/yolov5/VOCData/labels/')
image_ids = open(
'/Users/qishuocheng/Desktop/yolov5/VOCData/ImageSets/Main/%s.txt' % image_set).read().strip().split()
if not os.path.exists('/Users/qishuocheng/Desktop/yolov5/VOCData/dataSet_path/'):
os.makedirs('/Users/qishuocheng/Desktop/yolov5/VOCData/dataSet_path/')
list_file = open('dataSet_path/%s.txt' % image_set, 'w')
# 這行路徑不需更改,這是相對路徑
for image_id in image_ids:
list_file.write('/Users/qishuocheng/Desktop/yolov5/VOCData/images/%s.jpeg\n' % image_id)
convert_annotation(image_id)
list_file.close()
?運行后會生成如下圖所示的 dataSet_path 和 labels 文件夾。dataSet_path下會有三個數(shù)據(jù)集的txt文件,labels下存放各個圖像的標(biāo)注文件
3.配置文件
?在 yolov5 的 data 文件夾下創(chuàng)建一個名為 myvoc.yaml,模板如下,改成自己的路徑,根據(jù)自己實際情況填寫:
(【??易錯】:注意冒號后面是有空格的)
train: /Users/qishuocheng/Desktop/yolov5/VOCData/dataSet_path/train.txt
val: /Users/qishuocheng/Desktop/yolov5/VOCData/dataSet_path/val.txt
# number of classes
nc: 1
# class names
names: ["car"]
4.聚類獲得先驗框
在 models 文件夾下找到 yolov5s.yaml(如果使用這個權(quán)重模型訓(xùn)練的話),將其中的 nc 改為實際上標(biāo)注類的數(shù)量,和 myvoc.yaml 一樣(記得保存)。
# YOLOv5 ?? by Ultralytics, GPL-3.0 license
# Parameters
nc: 1 # 只改這里 改成自己的類的數(shù)量
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# YOLOv5 v6.0 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, C3, [128]],
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
[-1, 6, C3, [256]],
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
[-1, 9, C3, [512]],
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
[-1, 3, C3, [1024]],
[-1, 1, SPPF, [1024, 5]], # 9
]
# YOLOv5 v6.0 head
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 13
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 17 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, C3, [512, False]], # 20 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, C3, [1024, False]], # 23 (P5/32-large)
[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
五、使用CPU訓(xùn)練
?在cmd窗口下激活相應(yīng)虛擬環(huán)境后 cd 到 yolov5 文件夾后,輸入下列指令即可開始訓(xùn)練
mac也可以調(diào)用mps加速,聽說有bug 不如用cpu訓(xùn)練的快,所以建議用cpu
python train.py --weights yolov5s.pt ?--cfg models/yolov5s.yaml ?--data data/myvoc.yaml --epoch 200 --batch-size 8 --img 640 ? --device cpu
[參數(shù)說明]:
--weights :權(quán)重文件所在的相對路徑
--cfg:存儲模型結(jié)構(gòu)配置文件的相對路徑
--data:存儲訓(xùn)練、測試數(shù)據(jù)的文件的相對路徑
--epoch:訓(xùn)練過程中整個數(shù)據(jù)集將被迭代(訓(xùn)練)了多少次
--batch-size:訓(xùn)練完多少張圖片才進(jìn)行權(quán)重更新
--img:img-size
--device:選擇用CPU或者GPU訓(xùn)練
(開始訓(xùn)練)
訓(xùn)練完成!
六、訓(xùn)練結(jié)果可視化
訓(xùn)練結(jié)果將保存在/yolov5/runs/train/exp 文件夾下,部分文件意義如下:
weights:訓(xùn)練生成權(quán)重。包含 best.pt (最好的權(quán)重,detect時用到它),和 last.pt(最近生成的權(quán)重模型)
confusion:混淆矩陣?;煜仃囎屛覀兞私夥诸惸P退傅腻e誤,更重要的是可以了解哪些錯誤類型正在發(fā)生。
F1_curve:置信度和F1分?jǐn)?shù)的關(guān)系圖
P_curve:準(zhǔn)確率和置信度的關(guān)系圖
R_curve:召回率和置信度之間的關(guān)系
PR_curve:PR曲線中的P代表的是precision(精準(zhǔn)率),R代表的是recall(召回率),其代表的是精準(zhǔn)率與召回率的關(guān)系
labels:左上圖表示個類別的數(shù)據(jù)量;右上圖表示標(biāo)簽;左下圖表示 center 的 xy 坐標(biāo);右下圖表示各個標(biāo)簽的長和寬
?訓(xùn)練時或者訓(xùn)練后,輸入tensorboard --logdir=runs,即可利用 tensorboard 實現(xiàn)訓(xùn)練結(jié)果可視化
?tensorboard --logdir=runs
在高版本的tensorboard中 有個很惡心的點需要更改 = 為 "" 不然識別不出來。
?tensorboard --logdir "runs"
?訪問網(wǎng)頁 http://localhost:6006/即可看到各種訓(xùn)練結(jié)果(注:localhost指的是你所在的計算機(jī)本身)
使用剛剛訓(xùn)練好的 best.pt模型來檢測:
python detect.py --weights runs/train/exp/weights/best.pt --source ../source/test.png
[說明]:
--weights:表示我們選擇的權(quán)重模型
--source:表示待檢測的圖片的路徑 (…/表示上級路徑)
成功實現(xiàn)了惡劣環(huán)境下的DM碼的定位
識別成功文章來源:http://www.zghlxwxcb.cn/news/detail-449737.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-449737.html
到了這里,關(guān)于【yolov5 安裝教程】(入門篇)避免踩雷保姆級教程 在m1芯片下 使用yolov5本地訓(xùn)練自己的數(shù)據(jù)集 ——mac m1的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!