YOLOv5學(xué)習(xí)(一):安全帽檢測(cè)模型訓(xùn)練

YoloV5剛剛于2021年1月發(fā)布了4.0版本,涉及的變化主要包括:替換激活函數(shù)、精簡(jiǎn)模型結(jié)構(gòu)乔夯、引入W&B等×蠛祝現(xiàn)準(zhǔn)備嘗試基于YoloV5訓(xùn)練安全帽檢測(cè)模型征椒,借此熟悉YoloV5的網(wǎng)絡(luò)結(jié)構(gòu)、損失函數(shù)湃累、數(shù)據(jù)增強(qiáng)方法等勃救。
地址:https://github.com/ultralytics/yolov5

環(huán)境配置

由于4.0版本引入的nn.SiLU() 是在pytorch1.7.0才開(kāi)始支持碍讨,因此pytorch版本需>=1.7.0。

git clone https://github.com/ultralytics/yolov5.git
mv yolov5/ yolov5-4.0/
mkvirtualenv yolov5-4.0
pip install https://download.pytorch.org/whl/cu102/torch-1.7.0-cp36-cp36m-linux_x86_64.whl
pip install torchvision==0.8.1
cd yolov5-4.0/
pip install -r requirements.txt

數(shù)據(jù)準(zhǔn)備

數(shù)據(jù)集來(lái)源于https://github.com/njvisionpower/Safety-Helmet-Wearing-Dataset蒙秒,下載數(shù)據(jù)集解壓后目錄結(jié)構(gòu)如下圖:

SHWD數(shù)據(jù)集

其中勃黍, Annotations文件夾中是xml格式的標(biāo)簽文件,JPEGImages文件夾中是圖像文件晕讲。為了基于該數(shù)據(jù)集訓(xùn)練Yolov5模型覆获,我們需要進(jìn)一步將其處理為Yolov5適配的格式和目錄結(jié)構(gòu)。

首先按照下圖創(chuàng)建目錄結(jié)構(gòu):

修改后的目錄結(jié)構(gòu)

然后運(yùn)行下列代碼生成適配YoloV5格式的數(shù)據(jù)集:

import os, sys
import shutil
from tqdm import tqdm
import xml.etree.ElementTree as ET

classes = ["hat", "person"]

def convert(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw  # x_center
    y = y * dh  # y_center
    w = w * dw  # width
    h = h * dh  # height
    return (x, y, w, h)


def parse_xml(xml_path, dst_label_path):
    anno_xml = xml_path
    anno_txt = dst_label_path
    if os.path.exists(anno_xml):
        xml = open(anno_xml, "r")
        txt = open(anno_txt, "w")
        tree = ET.parse(xml)
        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'):
            cls = obj.find('name').text
            difficult = obj.find('difficult').text
            if cls not in classes or difficult == 1:
                continue
            cls_id = classes.index(cls)
            xmlbox = obj.find('bndbox')
            bbox = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
                float(xmlbox.find('ymax').text))
            yolo_bbox = convert((w, h), bbox)
            yolo_anno = str(cls_id) + " " + " ".join([str(i) for i in yolo_bbox]) + '\n'
            txt.write(yolo_anno)
        xml.close()
        txt.close()
    else:
        print(anno_xml, "文件不存在")

def copy_to(src, dst):
    shutil.copyfile(src, dst)


if __name__== "__main__":
    sets = ["train", "val", "test"]
    for s in sets:
        name_path = "VOC2028/ImageSets/Main/{}.txt".format(s)
        f = open(name_path, "r")
        names = f.readlines()
        f.close()
        for name in tqdm(names):
            name = name.replace('\n', '').replace('\r', '')
            image_path = r"VOC2028/JPEGImages/{}.jpg".format(name)
            xml_path = r"VOC2028/Annotations/{}.xml".format(name)
            dst_image_path = r"SHWD/images/{}/{}.jpg".format(s, name)
            dst_label_path = r"SHWD/labels/{}/{}.txt".format(s, name)
            if os.path.exists(image_path) and os.path.exists(xml_path):
                parse_xml(xml_path, dst_label_path)
                if not os.path.exists(dst_image_path):
                    copy_to(image_path, dst_image_path)
                else:
                    print(dst_image_path, "文件已存在")
            else:
                print(image_path, xml_path)

注意:由于數(shù)據(jù)集中存在少量后綴為大寫JPG的圖像瓢省,因此在運(yùn)行上述代碼時(shí)會(huì)漏掉部分?jǐn)?shù)據(jù)沒(méi)處理弄息,需要修改image_path = r"VOC2028/JPEGImages/{}.jpg".format(name)image_path = r"VOC2028/JPEGImages/{}.JPG".format(name)后再次運(yùn)行,才能完成全部數(shù)據(jù)的處理勤婚。

處理完成后的每一幅圖像和其對(duì)應(yīng)標(biāo)簽文件的路徑只有文件后綴名以及images-labels字段的區(qū)別摹量,代碼讀取數(shù)據(jù)集時(shí)則只需要替換這兩個(gè)位置就可訪問(wèn)相對(duì)應(yīng)的數(shù)據(jù):

SHWD/images/train/001320.jpg
SHWD/labels/train/001320.txt

轉(zhuǎn)換后的txt標(biāo)簽文件中如下圖所示,每一行表示一個(gè)目標(biāo)框馒胆,行內(nèi)五個(gè)元素分別是類別缨称、中心點(diǎn)x坐標(biāo)、中心點(diǎn)y坐標(biāo)国章、寬具钥、高,數(shù)值都進(jìn)行了歸一化處理液兽。

轉(zhuǎn)換后的標(biāo)簽文件
目標(biāo)框示意圖.png

訓(xùn)練模型

  • 創(chuàng)建shwd.yaml文件配置數(shù)據(jù)
# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: SHWD/images/train  
val: SHWD/images/val
test: SHWD/images/test

# number of classes
nc: 2

# class names
names: ["hat", "no-hat"]
  • 訓(xùn)練

這里選擇YOLOv5s網(wǎng)絡(luò)來(lái)訓(xùn)練安全帽檢測(cè)骂删,

$ python train.py --img 640 --batch 16 --epochs 50 --data data/shwd.yaml --weights yolov5s.pt

W&B可視化

Weights & Biases現(xiàn)在集成到了YOLOV5的4.0版本,用于實(shí)時(shí)可視化訓(xùn)練記錄四啰,可以更好地觀測(cè)和對(duì)比網(wǎng)絡(luò)的訓(xùn)練情況宁玫。
首先用pip安裝wandb:

pip install wandb

然后在運(yùn)行上一節(jié)的訓(xùn)練命令時(shí),終端會(huì)提示進(jìn)行wandb的相關(guān)配置:


按照要求創(chuàng)建賬戶后柑晒,會(huì)提供一個(gè)API key用于終端賬戶驗(yàn)證欧瘪,然后在網(wǎng)絡(luò)訓(xùn)練期間,可以訪問(wèn)https://www.wandb.com/查看實(shí)時(shí)更新匙赞。

參考

https://blog.csdn.net/ayiya_Oese/article/details/112249173
https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佛掖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子涌庭,更是在濱河造成了極大的恐慌芥被,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,331評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坐榆,死亡現(xiàn)場(chǎng)離奇詭異拴魄,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門匹中,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)夏漱,“玉大人,你說(shuō)我怎么就攤上這事顶捷」掖拢” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 167,755評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵焊切,是天一觀的道長(zhǎng)扮授。 經(jīng)常有香客問(wèn)我,道長(zhǎng)专肪,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,528評(píng)論 1 296
  • 正文 為了忘掉前任堪侯,我火速辦了婚禮嚎尤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伍宦。我一直安慰自己芽死,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布次洼。 她就那樣靜靜地躺著关贵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪卖毁。 梳的紋絲不亂的頭發(fā)上揖曾,一...
    開(kāi)封第一講書人閱讀 52,166評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音亥啦,去河邊找鬼炭剪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛翔脱,可吹牛的內(nèi)容都是我干的奴拦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,768評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼届吁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼错妖!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起疚沐,我...
    開(kāi)封第一講書人閱讀 39,664評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤暂氯,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后濒旦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體株旷,經(jīng)...
    沈念sama閱讀 46,205評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晾剖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锉矢。...
    茶點(diǎn)故事閱讀 40,435評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖齿尽,靈堂內(nèi)的尸體忽然破棺而出沽损,到底是詐尸還是另有隱情,我是刑警寧澤循头,帶...
    沈念sama閱讀 36,126評(píng)論 5 349
  • 正文 年R本政府宣布绵估,位于F島的核電站,受9級(jí)特大地震影響卡骂,放射性物質(zhì)發(fā)生泄漏国裳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評(píng)論 3 333
  • 文/蒙蒙 一全跨、第九天 我趴在偏房一處隱蔽的房頂上張望缝左。 院中可真熱鬧,春花似錦浓若、人聲如沸渺杉。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,276評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)是越。三九已至,卻和暖如春碌上,著一層夾襖步出監(jiān)牢的瞬間倚评,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工绍赛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔓纠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,818評(píng)論 3 376
  • 正文 我出身青樓吗蚌,卻偏偏與公主長(zhǎng)得像腿倚,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蚯妇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容