# 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)