yolov3中資料讀入(一)

2021-09-21 18:22:24 字數 4238 閱讀 7801

yolov3的訓練**從 detector.c de train_detector()函式開始,函式如下:

void train_detector(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear, int dont_show)
如果訓練**為:

*datacfg代表的是 voc.data ,*cfgfile代表的是 yolov3-voc.cfg

voc.data格式:

下面解讀train_detector()下的函式.

list *options = read_data_cfg(datacfg);
這個函式的作用是解析voc.data中的資料,並將資料存入到頭結點為options的雙向鍊錶中,

裡面的關鍵函式為:

int read_option(char *s, list *options)

}if(i == len-1) return 0;

char *key = s;

option_insert(options, key, val);

return 1;

}

可以看出程式將voc.data中的資料以「=」為界限分為兩類字元,左邊為key 右邊為val,然後插入到options鍊錶中。在opton_insert()函式中可以看到,作者將key與val包裝成乙個node節點中的val,val的格式如下:

typedef struct kvp;
以上,可以看出作者將voc.data中的資料按照每一行為乙個node節點加入乙個options鍊錶中,每個node中包含三個重要資訊,分別為key,val,used(初始為零,標籤處理),三個資訊包裝成乙個struct。

下面函式:

char *train_images = option_find_str(options, "train", "data/train.list");
將訓練位址傳入到train_images中。同時將options煉表頭指標指向key為train的下一行,used設為1。至此,將訓練位址匯入到train_images中。注意:這裡train_images指向的是個寫入位址的txt檔案的位址。

網路模型的解析:

char *base = basecfg(cfgfile);
上面的函式將訓練**(4)cfg/後的資料傳入到*base中。以例子為視:*base = yolov3-voc.cfg.

轉入到parser.c檔案中,解讀

network parse_network_cfg_custom(char *filename, int batch)

*filename是yolov3-voc.cfg,裡面的batch是0;

這裡看list *read_cfg()函式:

list *read_cfg(char *filename)

break;}}

fclose(file);

return sections;

}

在看這個程式之前先放幾個比價重要的結構體:

typedef struct list list;

typedef structsection;

typedef struct node node;

typedef struct kvp;

這幾個結構體構成鍊錶,下面是程式解讀。

這裡將yolov3-voc.cfg中的網路層鏈入到乙個鍊錶中,名稱為sections,鍊錶中每個節點是list結構體。同時將每一層引數解析到乙個section結構體中,結構體名為current,這裡放出來下面這個函式:

void list_insert(list *l, void *val)

else

l->back = new;

++l->size;

}

從這個函式可以看到,作者將current包裝成乙個node->val,讓後將node作為節點插入到list鍊錶中,這裡node->val(current)結構體是section,包含兩個變數,tpye與options。

section結構體中包含乙個list鍊錶,名為options,往深處扒拉扒拉可以看到,這個options鍊錶主要為了儲存乙個網路層中不同的引數,拿第乙個[net]層為例。

type中的值是』net』,options中的的節點node中儲存著』height=416』這一類資料,node中有key與val ,key = height,val=416。

轉入到list *read_cfg(char *filename)函式的下面的程式段中:

case '[':

current = malloc(sizeof(section));

list_insert(sections, current);

current->options = make_list();

current->type = line;

break;

在這一段可以看出,在識別出"["這個符號後,作者將current插入到sections鍊錶中,轉入到list_insert()這個函式中:

void list_insert(list *l, void *val)

else

l->back = new;

++l->size;

}

這裡是乙個雙向鍊錶插入程式,最後的 ++l->size;表明乙個yolov3網路結構有size個網路層,且第乙個網路層時從1開始的。

將current(代表的是乙個網路層)的頭位址作為節點位址插入到sections(代表的是整個yolov3網路)鍊錶中後,作者以第乙個current->options的頭位址作為鍊錶的頭位址建立乙個鍊錶:

current->options = make_list();
這個鍊錶中儲存的資訊在一下程式段中:

default:

if(!read_option(line, current->options))

break;

read_option()函式如下:

int read_option(char *s, list *options)

}if(i == len-1) return 0;

char *key = s;

option_insert(options, key, val);

return 1;

}

這個函式主要將我上面說的section插入到options中。最後在list *read_cfg(char *filename)中多次迴圈,將乙個網路層以current插入到sections中,而將乙個網路層的引數current->otpions的鍊錶中。

最終:將各個node鏈成乙個options(list結構)鍊錶,代表乙個網路層的引數,將網路層名稱(「net」)賦值給type,而options與type合成為乙個current。然後將current作為乙個節點鏈入到sections(list)中,sections是整個yolov3網路結構。

至此,整個網路載入到鍊錶sections中。

yolov3資料讀入(二)

前面以一篇文章將寫將yolov3網路層引數載入出來。這裡有幾個結構體在yolov3中的鍊錶中作用比較大 typedef struct list list typedef struct node node typedef struct kvp typedef structsection node n ...

yolov3系列 零 yolov3詳解

目標檢測演算法與efficientdet講解 論 文 翻譯 yolov3主頁 yolo系列的目標檢測演算法可以說是目標檢測史上的巨集篇巨作,v3演算法是在v1 v2基礎上形成的,先看下 yolov1 yolov2 下圖為yolov3的網路結構 dbl darknetconv2d bn leaky 是...

YOLOv3 從入門到部署 (一)YOLOv3概述

這是目標檢測領域常用的兩個資料集。voc和coco的區別主要在於影象標註的格式不一樣。voc將目標的標籤資訊以某種格式儲存在.xml格式的檔案中,而coco則是儲存在.txt檔案中。因此有時候voc和coco不是指資料集,而是指資料集標註格式。我們完全沒有必要去研究每種標註格式的細節,網路也有大量的...