K-Fold Cross Validation com Ultralytics
Introdução
Este guia abrangente ilustra a implementação do K-Fold Cross Validation para conjuntos de dados de deteção de objectos no ecossistema Ultralytics . Aproveitaremos o formato de deteção YOLO e as principais bibliotecas Python , como sklearn, pandas e PyYaml, para o guiar através da configuração necessária, do processo de geração de vectores de caraterísticas e da execução de uma divisão de conjunto de dados K-Fold.
Quer o seu projeto envolva o conjunto de dados Fruit Detection ou uma fonte de dados personalizada, este tutorial tem como objetivo ajudá-lo a compreender e aplicar a validação cruzada K-Fold para reforçar a fiabilidade e a robustez do seu aprendizagem automática modelos. Enquanto estivermos a aplicar k=5
dobras para este tutorial, tenha em mente que o número ideal de dobras pode variar dependendo do seu conjunto de dados e das especificidades do seu projeto.
Sem mais demoras, vamos a isto!
Configuração
-
As suas anotações devem estar no formato de deteçãoYOLO .
-
Este guia pressupõe que os ficheiros de anotações estão disponíveis localmente.
-
Para a nossa demonstração, utilizamos o conjunto de dados Fruit Detection.
- Este conjunto de dados contém um total de 8479 imagens.
- Inclui 6 etiquetas de classe, cada uma com o número total de instâncias listado abaixo.
Etiqueta de classe | Contagem de instâncias |
---|---|
Apple | 7049 |
Uvas | 7202 |
Ananás | 1613 |
Laranja | 15549 |
Banana | 3536 |
Melancia | 1976 |
-
Necessário Python pacotes incluem:
ultralytics
sklearn
pandas
pyyaml
-
Este tutorial funciona com
k=5
dobras. No entanto, deve determinar o melhor número de dobras para o seu conjunto de dados específico. -
Iniciar um novo ambiente virtual Python (
venv
) para o seu projeto e activá-lo. Utilizarpip
(ou o seu gestor de pacotes preferido) para instalar:- A biblioteca Ultralytics :
pip install -U ultralytics
. Em alternativa, pode clonar o ficheiro oficial repositório. - Scikit-learn, pandas e PyYAML:
pip install -U scikit-learn pandas pyyaml
.
- A biblioteca Ultralytics :
-
Verifique se as suas anotações estão no formato de deteçãoYOLO .
- Para este tutorial, todos os ficheiros de anotação encontram-se na pasta
Fruit-Detection/labels
diretório.
- Para este tutorial, todos os ficheiros de anotação encontram-se na pasta
Geração de vectores de caraterísticas para o conjunto de dados de deteção de objectos
-
Comece por criar um novo
example.py
Python para os passos seguintes. -
Prossiga para recuperar todos os ficheiros de etiquetas do seu conjunto de dados.
-
Agora, leia o conteúdo do ficheiro YAML do conjunto de dados e extraia os índices das etiquetas das classes.
-
Inicializar um ficheiro vazio
pandas
DataFrame. -
Contar as instâncias de cada etiqueta de classe presente nos ficheiros de anotação.
from collections import Counter for label in labels: lbl_counter = Counter() with open(label, "r") as lf: lines = lf.readlines() for line in lines: # classes for YOLO label uses integer at first position of each line lbl_counter[int(line.split(" ")[0])] += 1 labels_df.loc[label.stem] = lbl_counter labels_df = labels_df.fillna(0.0) # replace `nan` values with `0.0`
-
Segue-se uma vista de amostra do DataFrame preenchido:
0 1 2 3 4 5 '0000a16e4b057580_jpg.rf.00ab48988370f64f5ca8ea4...' 0.0 0.0 0.0 0.0 0.0 7.0 '0000a16e4b057580_jpg.rf.7e6dce029fb67f01eb19aa7...' 0.0 0.0 0.0 0.0 0.0 7.0 '0000a16e4b057580_jpg.rf.bc4d31cdcbe229dd022957a...' 0.0 0.0 0.0 0.0 0.0 7.0 '00020ebf74c4881c_jpg.rf.508192a0a97aa6c4a3b6882...' 0.0 0.0 0.0 1.0 0.0 0.0 '00020ebf74c4881c_jpg.rf.5af192a2254c8ecc4188a25...' 0.0 0.0 0.0 1.0 0.0 0.0 ... ... ... ... ... ... ... 'ff4cd45896de38be_jpg.rf.c4b5e967ca10c7ced3b9e97...' 0.0 0.0 0.0 0.0 0.0 2.0 'ff4cd45896de38be_jpg.rf.ea4c1d37d2884b3e3cbce08...' 0.0 0.0 0.0 0.0 0.0 2.0 'ff5fd9c3c624b7dc_jpg.rf.bb519feaa36fc4bf630a033...' 1.0 0.0 0.0 0.0 0.0 0.0 'ff5fd9c3c624b7dc_jpg.rf.f0751c9c3aa4519ea3c9d6a...' 1.0 0.0 0.0 0.0 0.0 0.0 'fffe28b31f2a70d4_jpg.rf.7ea16bd637ba0711c53b540...' 0.0 6.0 0.0 0.0 0.0 0.0
As linhas indexam os ficheiros de etiquetas, cada um correspondendo a uma imagem no seu conjunto de dados, e as colunas correspondem aos índices das etiquetas de classe. Cada linha representa um pseudo-vetor de caraterísticas, com a contagem de cada etiqueta de classe presente no seu conjunto de dados. Esta estrutura de dados permite a aplicação de K-Fold Cross Validation a um conjunto de dados de deteção de objectos.
Divisão do conjunto de dados K-Fold
-
Agora vamos utilizar o
KFold
classe desklearn.model_selection
para gerark
divisões do conjunto de dados.- Importante:
- Definição
shuffle=True
garante uma distribuição aleatória de classes nas suas divisões. - Por definição
random_state=M
ondeM
é um número inteiro escolhido, é possível obter resultados repetíveis.
- Definição
- Importante:
-
O conjunto de dados foi agora dividido em
k
dobras, cada uma com uma lista detrain
eval
índices. Iremos construir um DataFrame para apresentar estes resultados de forma mais clara. -
Agora vamos calcular a distribuição das etiquetas das classes para cada dobra como um rácio das classes presentes em
val
aos presentes notrain
.fold_lbl_distrb = pd.DataFrame(index=folds, columns=cls_idx) for n, (train_indices, val_indices) in enumerate(kfolds, start=1): train_totals = labels_df.iloc[train_indices].sum() val_totals = labels_df.iloc[val_indices].sum() # To avoid division by zero, we add a small value (1E-7) to the denominator ratio = val_totals / (train_totals + 1e-7) fold_lbl_distrb.loc[f"split_{n}"] = ratio
O cenário ideal é que todos os rácios de classe sejam razoavelmente semelhantes para cada divisão e entre classes. No entanto, isto estará sujeito às especificidades do seu conjunto de dados.
-
Em seguida, criamos os diretórios e os ficheiros YAML do conjunto de dados para cada divisão.
import datetime supported_extensions = [".jpg", ".jpeg", ".png"] # Initialize an empty list to store image file paths images = [] # Loop through supported extensions and gather image files for ext in supported_extensions: images.extend(sorted((dataset_path / "images").rglob(f"*{ext}"))) # Create the necessary directories and dataset YAML files (unchanged) save_path = Path(dataset_path / f"{datetime.date.today().isoformat()}_{ksplit}-Fold_Cross-val") save_path.mkdir(parents=True, exist_ok=True) ds_yamls = [] for split in folds_df.columns: # Create directories split_dir = save_path / split split_dir.mkdir(parents=True, exist_ok=True) (split_dir / "train" / "images").mkdir(parents=True, exist_ok=True) (split_dir / "train" / "labels").mkdir(parents=True, exist_ok=True) (split_dir / "val" / "images").mkdir(parents=True, exist_ok=True) (split_dir / "val" / "labels").mkdir(parents=True, exist_ok=True) # Create dataset YAML files dataset_yaml = split_dir / f"{split}_dataset.yaml" ds_yamls.append(dataset_yaml) with open(dataset_yaml, "w") as ds_y: yaml.safe_dump( { "path": split_dir.as_posix(), "train": "train", "val": "val", "names": classes, }, ds_y, )
-
Por fim, copie as imagens e as etiquetas para o respetivo diretório ('train' ou 'val') para cada divisão.
- NOTA: O tempo necessário para esta parte do código varia consoante o tamanho do conjunto de dados e o hardware do sistema.
import shutil for image, label in zip(images, labels): for split, k_split in folds_df.loc[image.stem].items(): # Destination directory img_to_path = save_path / split / k_split / "images" lbl_to_path = save_path / split / k_split / "labels" # Copy image and label files to new directory (SamefileError if file already exists) shutil.copy(image, img_to_path / image.name) shutil.copy(label, lbl_to_path / label.name)
Guardar registos (opcional)
Opcionalmente, pode guardar os registos dos DataFrames de divisão K-Fold e de distribuição de etiquetas como ficheiros CSV para referência futura.
folds_df.to_csv(save_path / "kfold_datasplit.csv")
fold_lbl_distrb.to_csv(save_path / "kfold_label_distribution.csv")
Treinar YOLO utilizando K-Fold Data Splits
-
Primeiro, carregue o modelo YOLO .
-
Em seguida, itere sobre os ficheiros YAML do conjunto de dados para executar o treino. Os resultados serão salvos em um diretório especificado pelo parâmetro
project
ename
argumentos. Por defeito, este diretório é 'exp/runs#' onde # é um índice inteiro.results = {} # Define your additional arguments here batch = 16 project = "kfold_demo" epochs = 100 for k in range(ksplit): dataset_yaml = ds_yamls[k] model = YOLO(weights_path, task="detect") model.train(data=dataset_yaml, epochs=epochs, batch=batch, project=project) # include any train arguments results[k] = model.metrics # save output metrics for further analysis
Conclusão
Neste guia, explorámos o processo de utilização da validação cruzada K-Fold para treinar o modelo de deteção de objectos YOLO . Aprendemos a dividir o nosso conjunto de dados em K partições, garantindo uma distribuição equilibrada das classes nas diferentes dobras.
Também explorámos o procedimento de criação de DataFrames de relatório para visualizar as divisões de dados e as distribuições de rótulos entre essas divisões, fornecendo-nos uma visão clara da estrutura dos nossos conjuntos de treino e validação.
Opcionalmente, guardámos os nossos registos para referência futura, o que pode ser particularmente útil em projectos de grande escala ou na resolução de problemas de desempenho do modelo.
Por fim, implementámos o treino do modelo real utilizando cada divisão num ciclo, guardando os resultados do treino para análise e comparação posteriores.
Esta técnica de validação cruzada K-Fold é uma forma robusta de tirar o máximo partido dos dados disponíveis e ajuda a garantir que o desempenho do modelo é fiável e consistente em diferentes subconjuntos de dados. Isto resulta num modelo mais generalizável e fiável que tem menos probabilidades de se ajustar excessivamente a padrões de dados específicos.
Lembre-se de que, embora tenhamos utilizado YOLO neste guia, estes passos são, na sua maioria, transferíveis para outros modelos de aprendizagem automática. A compreensão destes passos permite-lhe aplicar a validação cruzada de forma eficaz nos seus próprios projectos de aprendizagem automática. Boa programação!
FAQ
O que é a validação cruzada K-Fold e por que razão é útil na deteção de objectos?
A validação cruzada K-Fold é uma técnica em que o conjunto de dados é dividido em "k" subconjuntos (dobras) para avaliar o desempenho do modelo de forma mais fiável. Cada dobra serve como dados de treino e validação. No contexto da deteção de objectos, a utilização da validação cruzada K-Fold ajuda a garantir que o desempenho do seu modelo Ultralytics YOLO é robusto e generalizável em diferentes divisões de dados, aumentando a sua fiabilidade. Para obter instruções detalhadas sobre como configurar a validação cruzada K-Fold com Ultralytics YOLO , consulte Validação cruzada K-Fold com Ultralytics.
Como é que implemento a validação cruzada K-Fold utilizando Ultralytics YOLO ?
Para implementar a validação cruzada K-Fold com Ultralytics YOLO , é necessário seguir estes passos:
- Verificar se as anotações estão no formato de deteçãoYOLO .
- Utilize as bibliotecas Python como
sklearn
,pandas
epyyaml
. - Crie vectores de caraterísticas a partir do seu conjunto de dados.
- Divida o seu conjunto de dados utilizando
KFold
desklearn.model_selection
. - Treinar o modelo YOLO em cada divisão.
Para obter um guia completo, consulte a secção K-Fold Dataset Split na nossa documentação.
Por que razão devo utilizar Ultralytics YOLO para a deteção de objectos?
Ultralytics YOLO oferece deteção de objectos de última geração e em tempo real com elevada precisão e eficiência. É versátil, suportando várias tarefas de visão computacional, como deteção, segmentação e classificação. Além disso, integra-se perfeitamente com ferramentas como Ultralytics HUB para treinamento e implantação de modelos sem código. Para obter mais detalhes, explore os benefícios e recursos em nossa páginaUltralytics YOLO .
Como posso garantir que as minhas anotações estão no formato correto para Ultralytics YOLO ?
As suas anotações devem seguir o formato de deteção YOLO . Cada ficheiro de anotação deve listar a classe do objeto, juntamente com as coordenadas da sua caixa delimitadora na imagem. O formato YOLO garante um processamento de dados simplificado e padronizado para treinar modelos de deteção de objectos. Para obter mais informações sobre a formatação correta das anotações, visite o guia de formato de deteçãoYOLO .
Posso utilizar a validação cruzada K-Fold com conjuntos de dados personalizados para além da deteção de frutos?
Sim, é possível usar a validação cruzada K-Fold com qualquer conjunto de dados personalizado, desde que as anotações estejam no formato de deteção YOLO . Substitua os caminhos do conjunto de dados e os rótulos de classe por aqueles específicos do seu conjunto de dados personalizado. Esta flexibilidade garante que qualquer projeto de deteção de objectos pode beneficiar de uma avaliação robusta do modelo utilizando o K-Fold Cross Validation. Para um exemplo prático, consulte a nossa secção Gerar vectores de caraterísticas.