# YOLO: You Only Look Once ## Introdução ### Darknet framework Darknet é um framework de rede neural de código aberto escrita em C e CUDA. É rápido, fácil de instalar e suporta computação de CPU e GPU. Tal como todas as CNN é um algoritmo de Deep Learning que pode receber como entrada uma imagem, atribuir diferentes pesos, que são aprenddidos pelo próprio algoritmo, a diferentes aspectos da imagem, diferenciando assim um objeto de outro. ## Catalogando imagens no formato YOLO Um conjunto de dados catalogado no formato YOLO é composto pelas imagens do conjunto e um arquivo .txt com o mesmo nome do arquivo da imagem. Dentro do arquivo .txt cada linha descreve um objeto e consiste, em sequência, do número da classe, do centro do objeto em x, centro do objeto em y, largura e altura do objeto. Os valores das medidas são normalizados pela largura e altura da imagem real. Existem diferentes ferramentas para utilizadas no processo de marcação de imgagens. Dentre elas, **LabelIMG** se destaca por ter instação simples, interface amigável e ser compatível com o formato YOLO. Instruções de como instalar e utilizar podem ser encontradas no [repositório oficial](https://github.com/heartexlabs/labelImg). Utilizando a LabelIMG é possível desenhar as bouding boxes, ou caixa delimitadores, usadas para classificar os objetos do YOLO nas próprias imagens usadas para construir o conjunto de dados. A ferramente fará o trabalho de converter as marcações no formato .txt do algoritmo. Um conjunto de dado de alta qualidade é essencial para o modelo apresentar uma maior performance e uma boa marcação é fundamental para tal. Algumas boas práticas são: marcar todos os objetos de interesse em todas as imagens, marcar o objeto por completo, marcar objetos ocluídos, utilizar bounding boxes menores o possível e manter instruções claras. ## Treinando um modelo YOLO v3 ## Instalando o framework Darknet Segue alguns exemplos de como instalar o framework Darknet, ou seja, o mais popular fork AlexeyAB, que também suporta Windows e tem uma comunidade ativa grande. ### CPU + Linux A instação da opção básica do framework Darknet para ser usado com CPU no Linux consiste dos passos abaixo: **Clonar o repositório**: Navegar até o diretório desejado e clonar o repositório: ```bash! git clone https://github.com/AlexeyAB/darknet.git ``` **Compilar o framework Darknet**: Devemos navegar até o diretório raiz do framework Darkent e compilar: ```bash! cd darknet make ``` **Checar a instalação** usando o comando `./darknet`. Como resposta o terminal deve mostrar `usage: ./darknet <function>`. ### GPU + Linux A instação do framework Darknet para ser usado com GPU no Linux consiste dos passos abaixo: **Instalar o CMake** com suporte a CUDA moderno seguindo as instruções descritos na [documentação oficial](https://cmake.org/download/). **Instalar CUDA 10.0** seguindo algumas verificações antes da instalação no [guia oficial da NVDIA](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#pre-installation-actions). Em seguida baixar o NVIDIA CUDA Toolkit version 10 do [link](https://developer.nvidia.com/cuda-10.0-download-archive). E por fim instalar utilizando comandos listados na [documentação](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#package-manager-installation). **Instalar cuDNN 7.4 (OPCIONAL)**: Biblioteca acelerada por GPU de para redes neurais profundas. Baixar o arquivo do cuDNN versão 7.4.1 para a versão CUDA 10.0 da [documentação oficial](https://developer.nvidia.com/rdp/cudnn-archive). Executar a instalação seguindo as instruções descritas na [documentação](https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html#installlinux-tar) e encontrar, copiar e colar os arquivos conforme descritos [aqui](https://docs.nvidia.com/deeplearning/sdk/cudnn-install/index.html#installlinux-tar). **Clonar o repositório**: Navegar até o diretório desejado e clonar o repositório: ```! git clone https://github.com/AlexeyAB/darknet.git ``` **Alteras as flags no arquivo makefile**: Navegue até o diretório raiz do framework Darknet e abra o arquivo Makefile. Altere as seguintes flags de 0 para 1 (não altere o sinalizador de CUDNN para 1 se você pulou essa etapa): ``` GPU=1 CUDNN=1 OPENCV=1 ``` **Compilar o framework Darknet**: Devemos navegar até o diretório raiz do framework Darkent e compilar: ```! cd darknet make ``` **Checar a instalação** usando o comando `./darknet`. Como resposta o terminal deve mostrar `usage: ./darknet <function>`. ## Preparando arquivos de treinamento Depois de todas as imagens estiverem catalogadas é necessário configurar os arquivos do framework darknet para o treinamento. Os arquivos são **labelled_data.data**, **classes.names**, **train.txt** e **test.txt**. O arquivo **labelled_data.data** tem o formato abaixo. A **primeira linha** aponta o número de objetos rotulados em que o YOLO v3 será treinado, e que será usado para detecção após o treinamento. A **segunda linha** especifica o diretório completo para o arquivo train.txt que, por sua vez, consiste em caminhos completos para os arquivos de imagens para treinamento. O mesmo vale para a **terceira linha** com a diferença de que as imagens são usadas para validação durante o treinamento. A **quarta linha** especifica o diretório completo para o arquivo classes.names que possui os nomes dos objetos rotulados e a **quinta linha** especifica a pasta onde os pesos treinados serão salvos. ``` classes = 3 train = /home/heitor/train.txt valid = /home/heitor/test.txt names = /home/heitor/classes.names backup = backup ``` Os arquivos **train.txt** e **test.txt** têm a seguinte aparência (todos os diretórios estão em uma nova linha). ``` /home/heitor/imagens-dataset/imagem001.jpg /home/heitor/imagens-dataset/imagem002.jpg /home/heitor/imagens-dataset/imagem003.jpg ... /home/heitor/imagens-dataset/imagem799.jpg /home/heitor/imagens-dataset/imagem800.jpg ``` O arquivo **classes.names** tem o formato abaixo, em que cada linha representa uma classe: ``` presilha-cinza presilha-verde sem-presilha ``` ## Preparando arquivos de configuração Além dos arquivos anteriores é necessário criar dois arquivos .cfg e especificar alguns parâmentros para o processo de treinamento. **Criar arquivos .cfg**: Encontre o arquivo de configuração existente na pasta cfg dentro do diretório raiz Darknet com nome `yolov3.cfg` e crie dois novos arquivos com nomes `yolov3_custom_train.cfg` e `yolov3_custom_test.cfg` e copie o conteúdo do arquivo `yolov3.cfg` para dentro desses dois arquivos. **Atualizar parâmetros de batch e subdivisions**: Abra o arquivo de treinamento, descomente as linhas `# batch=64` e `# subdivisions=16` e delete as linhas `batch=1` e `subdivisions=1`. Abra o arquivo de teste e delete as linhas `# batch=64` e `# subdivisions=16` . Também é possível definir números diferentes, mas apenas para treinamento. Pode-se definir em arquivos de treinamento `batch` e `subdivisions` seguindo os números mostrados abaixo. Se houver erro de memória, é necessário diminuir o número do `batch` e aumentar `subdivisions`. Preste atenção, o parâmetro de `subdivisions` deve ser menor que o de `batch`. <center> | batch= | subdivisions= | | -------- | -------- | | 64 | 8 ou 16 ou 32 | | 32 | 8 ou 16 | | 16 | 8 ou 4 | | 8 | 4 ou 2 | </center> **Atualizar número de iterações para treinamento**: É necessário alterar `max_batches` que é o número total de iterações para treinamento e `steps` que são usadas para atualizar a taxa de aprendizado. O parâmetro `max_batches` é atualizado de acordo com o número de classes. A equação geral é a seguinte: `max_batches = classes * 2000 (mas não menor que 4000)`. Os parâmetros de `steps` são calculados como 80% e 90% de `max_batches`. **Atualizar o number of classes em 3 camadas \[yolo\] e filters em 3 camadas \[convolutional\]**: É necessário atualizar o `number of classes` em cada uma das três camadas **\[yolo\]** no final dos arquivos de configuração. Além disso, é necessário atualizar o número de `filters` nas camadas **\[convolutional\]** logo antes de cada camada **\[yolo\]**, mas não em qualquer outro lugar. É necessário para que seja devidamente conectada a camada **\[convolutional\]** que está logo antes da camada **\[yolo\]** de acordo com o número de classes no conjunto de dados. A equação geral que representa como calcular o número adequado de `filters` em três camadas **\[convolutional\]** logo antes de cada uma das três camadas **\[yolo\]** é a seguinte: `filters = (classes + coordinates + 1) * masks`. ## Parâmetros dentro do arquivo de configuração Os arquivos .cfg possuem parâmetros usados durante o treinamento e testo do modelo Yolo v3, os links na referência detalham cada parâmetro e o seu uso. ## Executando o treinamento Para começar o treinamento do framework Darknet, navegue até o diretório raiz darknet e dig ``` ./darknet detector train <arquivo .data> <arquivo .cfg> <arquivo weights> ``` Por exemplo: ``` ./darknet detector train cfg/ts_data.data cfg/yolov3_ts_train.cfg weights/darknet53.conv.74 ``` É possível parar o treinamento, por exemplo, após 1000 iterações e continuar mais tarde usando pesos já salvos. Para continuar treinando basta especificar no final do comando a localização dos pesos necessários para continuar o treinamento, por exemplo: ``` tector train cfg/ts_data.data cfg/yolov3_ts_train.cfg backup/yolo-obj_1000.weights ``` ## Detectando imagens Para detectar uma imagem usando o framework, basta usar o comando abaixo, por exemplo: ``` ./darknet detector test cfg/coco.data cfg/yolov3.cfg weights/yolov3.weights data/test-image.jpg ``` Para descartar objetos com previsões fracas, adicione o argumento de threshold no final do comando antes do caminho da imagem e especifique a taxa de limite: -thresh 0,85, exemplo: ``` ./darknet detector test cfg/coco.data cfg/yolov3.cfg weights/yolov3.weights -thresh 0.85 data/test-image.jpg ``` ## Referências * [**Darknet fork de AlexeyAB**](https://github.com/AlexeyAB/darknet): O fork mais popular do framework Darknet com melhorias no desempenho e respostas sobre os problemas comuns. * [**CFG Parameters in the [net] section**](https://github.com/AlexeyAB/darknet/wiki/CFG-Parameters-in-the-different-layers): Descrição dos parâmetros dentro do arquivo de configuração na seção \[net\] * [**CFG Parameters in the different layers**](https://github.com/AlexeyAB/darknet/wiki/CFG-Parameters-in-the-different-layers): Descrição dos parâmetros dentro do arquivo de configuração nas camadas * [**Site do autor do algoritmo**](https://pjreddie.com/): Site oficial com vídeos, artigos e material sobre o YOLO v3. * [**YOLOv3 in the CLOUD : Install and Train Custom Object Detector (FREE GPU)**](https://www.youtube.com/watch?v=10joRJt39Ns&ab_channel=TheAIGuy) * [**Create Labels and Annotations for Custom YOLOv3 Google Images Dataset** ](https://www.youtube.com/watch?v=EGQyDla8JNU&ab_channel=TheAIGuy) * [**Train YOLOv3 Custom Object Detector with Darknet** ](https://www.youtube.com/watch?v=zJDUhGL26iU&t=300s&ab_channel=TheAIGuy) * [**Training a YOLOv3 Object Detection Model with a Custom Dataset**](https://blog.roboflow.com/training-a-yolov3-object-detection-model-with-a-custom-dataset/) * [**Seven Tips for Labeling Images for Computer Vision**](https://blog.roboflow.com/tips-for-how-to-label-images/#7-use-these-labeling-tools) * [**Pre-trained models**](https://pjreddie.com/darknet/imagenet/#darknet53)