【问题标题】:YoloV4 Custom Dataset Train Test SplitYoloV4 自定义数据集训练测试拆分
【发布时间】:2021-06-09 06:08:14
【问题描述】:

我尝试使用我的自定义数据集训练一个 Yolo 网络。我有一些图像 (*.jpg) 和 yolo 格式的标签/注释作为 txt 文件。

现在我想将数据拆分为训练集和验证集。因此,我想要一个火车和一个验证文件夹,每个文件夹都有自己的图像和注释。

我尝试过这样的事情:

from sklearn.model_selection import train_test_split
import glob


# Get all paths to your images files and text files
PATH = '../TrainingsData/'
img_paths = glob.glob(PATH+'*.jpg')
txt_paths = glob.glob(PATH+'*.txt')
    
X_train, X_test, y_train, y_test = train_test_split(img_paths, txt_paths, test_size=0.3, random_state=42)

将集合保存到新文件夹后,图像和注释混淆了。因此,例如在火车文件夹中,一些图像没有注释(它们在验证文件夹中)并且有一些注释但图像丢失了。

你能帮我拆分我的数据集吗?

【问题讨论】:

    标签: python scikit-learn yolo train-test-split custom-dataset


    【解决方案1】:

    好的!!,你可以这样做

    分图功能

    def split_img_label(data_train,data_test,folder_train,foler_test):
        
        os.mkdir(folder_train)
        os.mkdir(folder_test)
        
        
        train_ind=list(data_train.index)
        test_ind=list(data_test.index)
        
        
        # Train folder
        for i in tqdm(range(len(train_ind))):
            
            os.system('cp '+data_train[train_ind[i]]+' ./'+ folder_train + '/'  +data_train[train_ind[i]].split('/')[2])
            os.system('cp '+data_train[train_ind[i]].split('.jpg')[0]+'.txt'+'  ./'+ folder_train + '/'  +data_train[train_ind[i]].split('/')[2].split('.jpg')[0]+'.txt')
        
        # Test folder
        for j in tqdm(range(len(test_ind))):
            
            os.system('cp '+data_test[test_ind[j]]+' ./'+ folder_test + '/'  +data_test[test_ind[j]].split('/')[2])
            os.system('cp '+data_test[test_ind[j]].split('.jpg')[0]+'.txt'+'  ./'+ folder_test + '/'  +data_test[test_ind[j]].split('/')[2].split('.jpg')[0]+'.txt')
    
    

    代码

    
    import pandas as pd 
    import os 
    
    PATH = './TrainingsData/'
    list_img=[img for img in os.listdir(PATH) if img.endswith('.jpg')==True]
    list_txt=[img for img in os.listdir(PATH) if img.endswith('.txt')==True]
    
    path_img=[]
    
    for i in range (len(list_img)):
        path_img.append(PATH+list_img[i])
        
    df=pd.DataFrame(path_img)
    
    # split 
    data_train, data_test, labels_train, labels_test = train_test_split(df[0], df.index, test_size=0.20, random_state=42)
    
    # Function split 
    split_img_label(data_train,data_test,folder_train_name,folder_test_name)
    
    

    输出

    len(list_img)
    583
    
    100%|████████████████████████████████████████████████████████████████████████████████| 466/466 [00:26<00:00, 17.42it/s]
    100%|████████████████████████████████████████████████████████████████████████████████| 117/117 [00:07<00:00, 16.61it/s]
    

    最后,您将拥有 2 个具有相同图像和标签的文件夹(folder_train_name,folder_test_name)。

    【讨论】:

    • 非常感谢 :) 这就是我要找的。​​span>
    • @Alexbonella,我正在运行此代码,但我的输出文本和火车文件夹只有一个图像和标签。
    【解决方案2】:
    import glob
    import random
    import os
    filelist  = glob.glob('train/*.txt')
    test = random.sample(filelist, int(len(filelist)*0.15))
    output_path = 'test/'
    if not os.path.exists(output_path):
        os.makedirs(output_path)
    
    for file in test:
        txtpath = file
        impath = file[:-4] + '.jpg'
        out_text = os.path.join(output_path, os.path.basename(txtpath))
        out_image = os.path.join(output_path, os.path.basename(impath))
        print(txtpath,impath,out_text,out_image)
        os.system('powershell mv ' + txtpath + ' ' + out_text)
        os.system('powershell mv ' + impath + ' ' + out_image)
    

    设置训练和测试文件夹路径。 设置要发送到测试的图像的百分比。

    如果不使用 Windows,请将 powershell mv 命令替换为 mv

    【讨论】:

      【解决方案3】:

      如果您想拆分图像和标签以训练您的自定义模型,我建议您执行以下步骤:

      1. 创建一个包含图像和标签的 obj 文件夹。
      2. 创建并运行 generate_train.py 脚本
      #generate_train.py
      import os
      
      image_files = []
      os.chdir(os.path.join("data", "obj"))
      for filename in os.listdir(os.getcwd()):
          if filename.endswith(".jpg"):
              image_files.append("data/obj/" + filename)
      os.chdir("..")
      with open("train.txt", "w") as outfile:
          for image in image_files:
              outfile.write(image)
              outfile.write("\n")
          outfile.close()
      os.chdir("..")
      
      1. 最后,当您拥有 train.txt 文件时,您可以运行以下代码:
      df=pd.read_csv('PATH/data/train.txt',header=None)
      
      
      # sklearn split 80 train, 20 test
      
      data_train, data_test, labels_train, labels_test = train_test_split(df[0], df.index, test_size=0.20, random_state=42)
      
      # train.txt contain the PATH of images and label to train 
      data_train=data_train.reset_index()
      data_train=data_train.drop(columns='index')
      with open("train.txt", "w") as outfile:
          for ruta in data_train[0]:
              outfile.write(ruta)
              outfile.write("\n")
          outfile.close()
      
      # test.txt contain the PATH of images and label to test 
      data_test=data_test.reset_index()
      data_test=data_test.drop(columns='index')
      with open("test.txt", "w") as outfile:
          for ruta in data_test[0]:
              outfile.write(ruta)
              outfile.write("\n")
          outfile.close()
      
      

      现在,您可以训练模型了

      YOLO

      !./darknet detector train data/obj.data cfg/yolov4-FENO.cfg yolov4.conv.137 -dont_show -map

      !./darknet detector train data/obj.data cfg/yolov4_tiny.cfg yolov4-tiny.conv.29 -dont_show -map

      【讨论】:

      • 非常感谢您的回答,但这并不是我的问题。我想生成包含图像和标签(.txt 文件)的文件夹。因此,我有一个文件夹,其中包含一些图像及其用于训练的标签,另一个文件夹包含不同的图像及其标签用于验证。
      【解决方案4】:

      拆分图像数据集很棘手,因为正如您所发现的,如果操作不当,最终会将注释和图像放在不同的文件夹中。

      我在使用 Yolo 注释时遇到了同样的问题,最后我创建了一个名为 PyLabel 的 Python 包来作为学校项目来做。

      我有一个示例笔记本来演示如何在https://github.com/pylabel-project/samples/blob/main/dataset_splitting.ipynb 此处将数据集拆分为 2 或 3 组。

      使用 PyLabel 的代码是这样的:

      dataset = importer.ImportYoloV5(path_to_annotations)
      dataset.splitter.StratifiedGroupShuffleSplit(train_pct=.6, val_pct=.2, test_pct=.2, batch_size=1)
      dataset.analyze.ShowClassSplits()
      

      ShowClassSplits 将提供以下输出,以便您检查拆分是否平衡

      PyLabel 有 2 种拆分数据的方法:

      1. GroupShuffleSplit,它使用 sklearn 中的 GroupShuffleSplit 命令。
      2. StratifiedGroupShuffleSplit,它试图在拆分组中平衡类的分布。

      希望这对阅读本文的人有所帮助。如果您遇到任何问题,请随时与我联系,我可以提供帮助。

      【讨论】:

        猜你喜欢
        • 2023-01-21
        • 2018-11-05
        • 1970-01-01
        • 2022-06-25
        • 2017-11-01
        • 1970-01-01
        • 2021-12-08
        • 2018-06-04
        • 1970-01-01
        相关资源
        最近更新 更多