目次
3.1 my_train_data.txt と my_val_data.txt を生成する
3.4 my_data_label.names ファイルについて
1 はじめに
最初のセクションの操作により 、下図の円内の部分が 生成されました。この章の内容は、次の作業に備えて、四角いボックス内の部分をコードによって生成することです。
- my_yolov3.cfg は、公式の yolov3-spp.cfg ネットワーク構成ファイルをカスタム データセットに従って変更して取得した独自のネットワーク構成です (検出されたカテゴリの数が異なるため、yolo が出力する情報も異なります)
- my_train_data.txt と my_val_data.txt は、トレーニング セット/検証セット内のすべてのピクチャの完全なパス、つまり、 my_yolo_dataset 内の 2 つのイメージの下にあるすべてのピクチャのパスです。
- my_data.data はカテゴリの数、2 つのファイル my_train_data.txt と my_val_data.txt のパス、および my_data_label.names のパスです (データセットが最初に yolo 形式である場合、最初のファイルは通過しません)操作のセクションでは、この .names ファイルは生成されないため、自分で作成する必要があります)
2. 完全なコード
実装コードはcalculate_dataset.pyです。
"""
该脚本有3个功能:
1.统计训练集和验证集的数据并生成相应.txt文件
2.创建my_data.data文件,记录目标检测的 classes个数, train以及 val数据集文件(.txt)路径和 label.names文件路径
3.根据 yolov3-spp.cfg创建 my_yolov3.cfg文件修改其中的 predictor filters以及 yolo classes参数(这两个参数是根据类别数改变的)
"""
import os
# 生成训练集、验证集的所有数据路径文件
def calculate_data_txt(txt_path, dataset_dir):
with open(txt_path, "w") as w:
for file_name in os.listdir(dataset_dir): # 遍历数据的标注文件train、val下的labels
if file_name == "classes.txt":
continue
# 根据标注文件找到对应的图片,图片后缀需要是jpg
img_path = os.path.join(dataset_dir.replace("labels", "images"),file_name.split(".")[0]) + ".jpg"
line = img_path + "\n" # 写入一个数据路径就换行
assert os.path.exists(img_path), "file:{} not exist!".format(img_path)
w.write(line)
# 创建data.data文件,记录分类类别个数、训练集、验证集、分类类别的文件路径
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") # 记录类别个数
w.write("train={}".format(train_path) + "\n") # 记录训练集对应txt文件路径
w.write("valid={}".format(val_path) + "\n") # 记录验证集对应txt文件路径
w.write("names=data/my_data_label.names" + "\n") # 记录label.names文件路径
# 创建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+置信度 + 类别的个数) * 每一个cell生成 3 个预测框
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():
# 统计训练集和验证集的数据并生成相应 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) # 所有训练集的路径
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]
# 创建data.data文件,记录classes个数, train以及val数据集文件(.txt)路径和 label.names文件路径
create_data_data("./data/my_data.data", train_txt_path, val_txt_path, classes_info)
# 根据yolov3-spp.cfg创建my_yolov3.cfg文件修改其中的predictor filters以及yolo classes参数(这两个参数是根据类别数改变的)
change_and_create_cfg_file(classes_info)
if __name__ == '__main__':
train_annotation_dir = "./my_yolo_dataset/train/labels" # 训练集的标注文件
val_annotation_dir = "./my_yolo_dataset/val/labels" # 验证集的标注文件
classes_label = "./data/my_data_label.names" # 检测的分类label
cfg_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. コードの説明
コードの一部にコメントが追加されています。これについては、ここで説明します。
まず関連するパスを設定します
3.1 my_train_data.txt と my_val_data.txt を生成する
次に、データセット画像のパスを生成します。ここでは、トレーニング セットはテスト セットと同じです。トレーニング セットについてのみ説明します。
トレーニング セットについては、my_train_data.txt ファイルに書き込みます。
このうち、file_name はラベルの下のファイル名です。ここでのファイル名は画像の名前です。パス置換とサフィックス置換により、画像内のすべての画像の完全なパスを見つけて、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' 、「ダイニングテーブル」、「犬」、「馬」、「バイク」、「人」、「鉢植え」、「羊」、「ソファ」、「電車」、「tvmonitor」] は実際にはカテゴリの名前です。
次に、create_data_data 関数を入力し、対応するファイル パスを書き込みます。
my_data.data ファイル
3.3 my_yolov3.cfg の生成
検出タスクごとに分類数が異なる場合があるため、yoloの設定情報を変更する必要がある
これは次の方法で行われます。
yoloの出力は3スケールなので、filters_lines = [636, 722, 809]classes_lines = [643, 729, 816]が3つのスケールに対応する情報となります。ただし、検出されたカテゴリによってカスタム データセットのカテゴリの数が変更されます。予測ボックスによるテンソル出力もカテゴリに関連しています
以下の通り、公式クラスはココなので80カテゴリーです。ここではPascal vocが使用されているため、20のカテゴリがあります
75 = (x、y、w、h + 信頼度 + カテゴリ数) * 3 (各セルは 3 つの予測ボックスを生成します) = 25 * 3
公式は (5 + 80)*3 = 255
3.4 my_data_label.names ファイルについて
yolo データセット自体の場合、操作の最初のセクションを実行する必要はありません。
この場合、このファイル my_data_label.names は存在しないため、次のように手動で作成する必要があります。
ファイル名を変更するだけです