中國鐵路監(jiān)理建設(shè)協(xié)會網(wǎng)站搭建一個網(wǎng)站需要什么
目錄
1.? 介紹
2. 完整代碼
3. 代碼講解
3.1 生成 my_train_data.txt和my_val_data.txt
3.2 生成 my_data.data 文件
3.3 ?生成 my_yolov3.cfg
3.4 關(guān)于my_data_label.names文件
1.? 介紹
根據(jù)?第一節(jié)?的操作,已經(jīng)生成了下圖中圓圈中的部分,而本章的內(nèi)容就是通過代碼生成矩形框中的部分,為后面的工作做準(zhǔn)備
- my_yolov3.cfg 是將官方的yolov3-spp.cfg 網(wǎng)絡(luò)的配置文件根據(jù)自定義的數(shù)據(jù)集修改得到的自己的網(wǎng)絡(luò)配置(因為檢測的分類個數(shù)不同,yolo輸出的信息也會不同)
- my_train_data.txt 和 my_val_data.txt 是訓(xùn)練集 / 驗證集中,所有圖片的完整路徑,也就是my_yolo_dataset 中 兩個 images 下面的所有圖片的路徑
- my_data.data 是分類個數(shù)、my_train_data.txt 和 my_val_data.txt這兩個文件的路徑、以及my_data_label.names 的路徑(如果,一開始數(shù)據(jù)集就是yolo格式的,就不會經(jīng)過第一節(jié)的操作,也不會生成這個.names文件,所以要自己建立)
?
2. 完整代碼
實現(xiàn)代碼為 calculate_dataset.py
"""
該腳本有3個功能:
1.統(tǒng)計訓(xùn)練集和驗證集的數(shù)據(jù)并生成相應(yīng).txt文件
2.創(chuàng)建my_data.data文件,記錄目標(biāo)檢測的 classes個數(shù), train以及 val數(shù)據(jù)集文件(.txt)路徑和 label.names文件路徑
3.根據(jù) yolov3-spp.cfg創(chuàng)建 my_yolov3.cfg文件修改其中的 predictor filters以及 yolo classes參數(shù)(這兩個參數(shù)是根據(jù)類別數(shù)改變的)
"""
import os# 生成訓(xùn)練集、驗證集的所有數(shù)據(jù)路徑文件
def calculate_data_txt(txt_path, dataset_dir):with open(txt_path, "w") as w:for file_name in os.listdir(dataset_dir): # 遍歷數(shù)據(jù)的標(biāo)注文件train、val下的labelsif file_name == "classes.txt":continue# 根據(jù)標(biāo)注文件找到對應(yīng)的圖片,圖片后綴需要是jpgimg_path = os.path.join(dataset_dir.replace("labels", "images"),file_name.split(".")[0]) + ".jpg"line = img_path + "\n" # 寫入一個數(shù)據(jù)路徑就換行assert os.path.exists(img_path), "file:{} not exist!".format(img_path)w.write(line)# 創(chuàng)建data.data文件,記錄分類類別個數(shù)、訓(xùn)練集、驗證集、分類類別的文件路徑
def create_data_data(create_data_path, train_path, val_path, classes_info):with open(create_data_path, "w") as w:w.write("classes={}".format(len(classes_info)) + "\n") # 記錄類別個數(shù)w.write("train={}".format(train_path) + "\n") # 記錄訓(xùn)練集對應(yīng)txt文件路徑w.write("valid={}".format(val_path) + "\n") # 記錄驗證集對應(yīng)txt文件路徑w.write("names=data/my_data_label.names" + "\n") # 記錄label.names文件路徑# 創(chuàng)建yolo v3 spp的配置信息
def change_and_create_cfg_file(classes_info, save_cfg_path="./cfg/my_yolov3.cfg"):filters_lines = [636, 722, 809]classes_lines = [643, 729, 816]cfg_lines = open(cfg_path, "r").readlines()for i in filters_lines:assert "filters" in cfg_lines[i-1], "filters param is not in line:{}".format(i-1)output_num = (5 + len(classes_info)) * 3 # (x,y,w,h+置信度 + 類別的個數(shù)) * 每一個cell生成 3 個預(yù)測框cfg_lines[i-1] = "filters={}\n".format(output_num)for i in classes_lines:assert "classes" in cfg_lines[i-1], "classes param is not in line:{}".format(i-1)cfg_lines[i-1] = "classes={}\n".format(len(classes_info))with open(save_cfg_path, "w") as w:w.writelines(cfg_lines)def main():# 統(tǒng)計訓(xùn)練集和驗證集的數(shù)據(jù)并生成相應(yīng) txt文件train_txt_path = "data/my_train_data.txt"val_txt_path = "data/my_val_data.txt"calculate_data_txt(train_txt_path, train_annotation_dir) # 所有訓(xùn)練集的路徑calculate_data_txt(val_txt_path, val_annotation_dir) # 所有驗證集的路徑# 獲取檢測的所有類別classes_info = [line.strip() for line in open(classes_label, "r").readlines() if len(line.strip()) > 0]# 創(chuàng)建data.data文件,記錄classes個數(shù), train以及val數(shù)據(jù)集文件(.txt)路徑和 label.names文件路徑create_data_data("./data/my_data.data", train_txt_path, val_txt_path, classes_info)# 根據(jù)yolov3-spp.cfg創(chuàng)建my_yolov3.cfg文件修改其中的predictor filters以及yolo classes參數(shù)(這兩個參數(shù)是根據(jù)類別數(shù)改變的)change_and_create_cfg_file(classes_info)if __name__ == '__main__':train_annotation_dir = "./my_yolo_dataset/train/labels" # 訓(xùn)練集的標(biāo)注文件val_annotation_dir = "./my_yolo_dataset/val/labels" # 驗證集的標(biāo)注文件classes_label = "./data/my_data_label.names" # 檢測的分類labelcfg_path = "./cfg/yolov3-spp.cfg" # 官方的yolov3-spp 的配置文件assert os.path.exists(train_annotation_dir), "train_annotation_dir not exist!"assert os.path.exists(val_annotation_dir), "val_annotation_dir not exist!"assert os.path.exists(classes_label), "classes_label not exist!"assert os.path.exists(cfg_path), "cfg_path not exist!"main()
3. 代碼講解
代碼有些部分自己又加了些注釋,這里會挑著講解
首先將相關(guān)路徑設(shè)定好
3.1 生成 my_train_data.txt和my_val_data.txt
?
然后生成數(shù)據(jù)集圖片的路徑,這里訓(xùn)練集和測試集一樣,只講解訓(xùn)練集
對于訓(xùn)練集來說,寫入my_train_data.txt 文件。
?其中,file_name 就是labels 下面文件名,因為這里文件名就是圖片的名稱。通過路徑替換就能、后綴替換就可以找到images所有的圖片完整路徑,寫入my_train_data.txt 文件即可
生成的my_train_data.txt 和my_val_data.txt 如下:
?
3.2 生成 my_data.data 文件
代碼如下
?
其中,classes_info 信息如下:['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor'] ,其實就是分類的名稱
然后,進入create_data_data 函數(shù)內(nèi)部,將對應(yīng)的文件路徑寫入即可
?
my_data.data 文件
3.3 ?生成 my_yolov3.cfg
因為不同檢測任務(wù)的分類個數(shù)可能不同,因此需要更改yolo的配置信息
?
實現(xiàn)的方式如下:
因為yolo輸出是三個尺度的,而 filters_lines = [636, 722, 809] classes_lines = [643, 729, 816]就是對應(yīng)三個尺度的信息。除了檢測的類別更改自定義數(shù)據(jù)集的類別個數(shù)外。預(yù)測框輸出的tensor也和類別有關(guān)
?
如下,官方的classes 是coco所以是80類別。這里使用的是pascal voc 所以是20類別
75 = (x、y、w、h+置信度 + 類別個數(shù))* 3(每一個cell生成3個預(yù)測框)? = 25 * 3
官方是? (5 + 80)*3 = 255
?
3.4 關(guān)于my_data_label.names文件
如果本身就是yolo 數(shù)據(jù)集的話,是不需要進行第一節(jié)的操作的
那么這個文件my_data_label.names是不存在的,需要手工建立,如下:
只需要更改文件名就行了
?