UOC-Assignments / uoc.tfg.jbericat

Entrenament d’un model de IA en un entorn virtual per a la seva aplicació en la extinció d’incendis forestals: Prova de concepte - Universitat Oberta de Catalunya - Treball Final de Grau
1 stars 0 forks source link

TASK#05.3 – Wrapping-Up: Implementació d'un algorisme d'entrenament i generació de gràfiques i estadístiques #96

Closed jbericat closed 2 years ago

jbericat commented 2 years ago

S'utilitza pyTorch per a dissenyar el model proposat al següent enllaç -> https://docs.microsoft.com/en-us/windows/ai/windows-ml/tutorials/pytorch-train-model. La implementació es troba a /src/DCNN/PyTorchTraining.py

jbericat commented 2 years ago

Un cop instal·lat pytorch+CUDA (veure #124), al tractar d'entrenar el model /src/DCNN/PyTorchTraining.py trobem el que sembla ser un problema de gestió de la memòria de la GPU a l'hora d'establir les variables d'entorn de pyTorch:

RuntimeError: CUDA out of memory. Tried to allocate 136.00 MiB (GPU 0; 3.82 GiB total capacity; 1.95 GiB already allocated; 76.50 MiB free; 2.05 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

Es procedeix a fer recerca per a tractar de resoldre el problema

jbericat commented 2 years ago

Un cop instal·lat pytorch+CUDA (veure #124), al tractar d'entrenar el model /src/DCNN/PyTorchTraining.py trobem el que sembla ser un problema de gestió de la memòria de la GPU a l'hora d'establir les variables d'entorn de pyTorch:

RuntimeError: CUDA out of memory. Tried to allocate 136.00 MiB (GPU 0; 3.82 GiB total capacity; 1.95 GiB already allocated; 76.50 MiB free; 2.05 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

Es procedeix a fer recerca per a tractar de resoldre el problema

Segurament el problema sigui que estic configurant paràmetres del model de manera incorrecta (batch size, etc):

https://github.com/CorentinJ/Real-Time-Voice-Cloning/issues/913

jbericat commented 2 years ago

Després de resoldre el problema anterior (el problema era la mida del batch) i de fer proves sense èxit de la implementació del model escollit amb l'entorn pyTorch+CUDA, me'n dono compte de què el codi original conté errades:

https://docs.microsoft.com/en-us/windows/ai/windows-ml/tutorials/pytorch-train-model

Concretament, a PyTorchTraining.py , la implementació del mètode testAccuracy() no estava movent les dades del dataset (imatges i etiquetes) a l'espai de memòria de la GPU, mentre que el model sí que estava carregat a la GPU. Això provocava el següent error durant l'entrenament del model:

RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same or input should be a MKLDNN tensor and weight is a dense tensor

Per a arreglar-ho s'ha utilitzat una solució anàloga a la utilitzada al següent enllaç:

https://stackoverflow.com/questions/63339144/training-a-cnn-model-with-dataloader-on-a-gpu-in-pytorch

S'aplica el PR #126 per a solucionar el problema i finalment s'aconsegueix entrenar el model utilitzant la GPU:

screenshot_2

jbericat commented 2 years ago

Es realitza una primera reconfiguració dels paràmetres del model per tal que aquest accepti imatges de mida 229x229x3, ja que el codi original estava adaptat per a treballar amb dataset d'imatges de mida 32x32x3. Els canvis aplicats es troben al PR #126.

jbericat commented 2 years ago

Es procedeix a entrenar el model amb diferents mides de batch-size i el millor rendiment obntingut correspon a una mida batch-size = 10:

The number of images in a training set is:  610
The number of images in a test set is:  210
The number of batches per epoch is:  61
The model will be running on cuda:0 device
For epoch 1 the test accuracy over the whole test set is 43 %
For epoch 2 the test accuracy over the whole test set is 38 %
For epoch 3 the test accuracy over the whole test set is 39 %
For epoch 4 the test accuracy over the whole test set is 32 %
For epoch 5 the test accuracy over the whole test set is 36 %
Finished Training
Real labels:  high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire
Predicted:  no-wildfire low-intensity-wildfire  high-intensity-wildfire low-intensity-wildfire  no-wildfire low-intensity-wildfire  no-wildfire low-intensity-wildfire  low-intensity-wildfire  no-wildfire

screenshot_3

El rendiment assolit és molt pobre, segurament degut a la pròpia naturalesa de les imatges:

jbericat commented 2 years ago

Es reobre task per tal de tornar a entrenar el model amb un dataset millorat segons les observacions fetes al comentari del post anterior d'aquest fil:

El rendiment assolit és molt pobre, segurament degut a la pròpia naturalesa de les imatges:

* La mida original de les imatges hauria de ser quadrada i no 640x512, ja que d'aquesta manera al fer el crop potser estem converting algunes imatges de la seva classe a la classe "no-wildfire" (és a dir, potser s'està retallant la part de la imatge que conté l'incendi)

* Caldria provar a generar un altre cop el dataset amb imatges molt més properes, en les que no s'hi trobin tantes instàncies de classe d'incend

S'envia correu a @danirivas per a sol·licitar assesorament en aquest sentit; concretament per a saber si val la pena posar-se a generar nous datasets i comparar resultats.

jbericat commented 2 years ago

Correu enviat. Al final es decideix generar dataset v5.0 amb les condicions esmentades i comparar els resultats amb els del dataset v4.0 (fer-ho de mentres que s'espera resposta per a guanyar temps)

jbericat commented 2 years ago

Un cop generada una nova versió del dataset (v5.0) tot aplicant el canvis esmentats:

El rendiment assolit és molt pobre, segurament degut a la pròpia naturalesa de les imatges:

* La mida original de les imatges hauria de ser quadrada i no 640x512, ja que d'aquesta manera al fer el crop potser estem converting algunes imatges de la seva classe a la classe "no-wildfire" (és a dir, potser s'està retallant la part de la imatge que conté l'incendi)

* Caldria provar a generar un altre cop el dataset amb imatges molt més properes, en les que no s'hi trobin tantes instàncies de classe d'incendi

S'aconsegueix millorar lleugerament el rendiment del model, tot i que encara segueix sense ser acceptable:

(py364) jbericat@TFG-UOC:~/Workspaces/uoc.tfg.jbericat$  cd /home/jbericat/Workspaces/uoc.tfg.jbericat ; /usr/bin/env /home/jbericat/anaconda3/envs/py364/bin/python /home/jbericat/.vscode/extensions/ms-python.python-2021.12.1559732655/pythonFiles/lib/python/debugpy/launcher 40617 -- /home/jbericat/Workspaces/uoc.tfg.jbericat/src/CNN/PyTorchTraining.py 
Type the dataset version you want to use to train the model (4 = v4 / 5 = v5): 5
The number of images in a training set is:  540
The number of images in a test set is:  220
The number of batches per epoch is:  54
The model will be running on cuda:0 device
For epoch 1 the test accuracy over the whole test set is 55 %
For epoch 2 the test accuracy over the whole test set is 45 %
For epoch 3 the test accuracy over the whole test set is 48 %
For epoch 4 the test accuracy over the whole test set is 55 %
For epoch 5 the test accuracy over the whole test set is 44 %
Finished Training
Real labels:  high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire
Predicted:  low-intensity-wildfire  low-intensity-wildfire  no-wildfire high-intensity-wildfire low-intensity-wildfire  high-intensity-wildfire low-intensity-wildfire  low-intensity-wildfire  low-intensity-wildfire  low-intensity-wildfire 
(py364) jbericat@TFG-UOC:~/Workspaces/uoc.tfg.jbericat$ 

Amb l'objectiu d'assolir al menys un 80%-85% de precisió en les prediccions es podrien fer els següents canvis en el dataset (per ordre de prioritat):

screenshot_4

https://medium.com/@RaghavPrabhu/cnn-architectures-lenet-alexnet-vgg-googlenet-and-resnet-7c81c017b848

OBSERVACIÓ (INCÍS):

Com que l'entrenament del model correspon a la FITA#06, però encara no s'ha acabat de validar el disseny del model CNN fet a la FITA#05, aleshores abans d'executar les accions esmentades amunt es procedeix a fer un incís per tal d'actualitzar la documentació de la FITA#05 i el codi associat, tancar-la i procedir amb la següent fita.

jbericat commented 2 years ago

Tenint en compte les consideracions del post anterior, s'han completat els següents punts:

Amb l'objectiu d'assolir al menys un 80%-85% de precisió en les prediccions es podrien fer els següents canvis en el dataset (per ordre de prioritat):

* [x]  1 - Refer la configuració de paràmetres del model: batch-size, etc:

screenshot_4

https://medium.com/@RaghavPrabhu/cnn-architectures-lenet-alexnet-vgg-googlenet-and-resnet-7c81c017b848

* [x]  2 - Implementar tècniques d'ampliació del dataset

S'ha procedit a la seva implementació (versió 3 del model) i no s'ha observat cap millora substancial en el rendiment (65%), però si en el temps d'entrenament (amb 2/3 epochs n'hi ha prou per a assolir rendiment màxim).

D'altra banda, pel que respecta al punt 4:

* [ ]  4 - S'ha detectat que les imatges sense incendis (classe `no-wildfires`) mostren característiques comunes a la classe `low-intensity`, gairebé no apreciables per la vista humana però segurament detectables pel model. Es tracta d'una errada de disseny a l'hora de preparar l'entorn per a prendre aquesta classe d'imatges en particular, caldrà pensar un workaround

Després d'eliminar el subset d'imatges de classe no-wildfire no s'ha observat cap millora substancial. Tanmateix, donada la gran similitud entre imatges de classe low-intensity-wildfire i medium-intensity-wildfire, s'ha fet la prova d'eliminar el subset de classe medium-intensity-wildfire i (dataset v7) i en aquestes circumstàncies, amb la versió 3 del model (14 capes) s'assoleix un rendiment del 83%, que era l'objectiu mínim a assolir:

loss-curve

epoch-accuracies


_For epoch 1 the test accuracy over the whole test set is 66 % For epoch 2 the test accuracy over the whole test set is 80 % For epoch 3 the test accuracy over the whole test set is 83 % For epoch 4 the test accuracy over the whole test set is 74 % For epoch 5 the test accuracy over the whole test set is 83 %

labels-prediction

Real labels: high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire

Predicted: high-intensity-wildfire high-intensity-wildfire low-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire high-intensity-wildfire_


Ara encara es podria provar a jugar amb els valors dels hiper-paràmetres, en especial la mida i la quantitat de kernels, tornar a fer els càlculs, i comparar rendiments fent servir les mateixes versions del model (v3.0) i del dataset (v7.0)

OBSERVACIÓ IMPORTANT:

Cal anotar a la memòria que el problema del baix rendiment era la "mala qualitat" de la simulació de les imatges de classe medium-intensity-wildfire (explicar que hauria d'haver utilitzat un altre tips d'objecte StaticMesh de Unreal que no s'assemblés tant als que s'utilitaven per a la classe low-intensity-wildfire. Explicar també que la simulació de visió tèrmica s'ha adaptat d'un altre projecte que tenia com a objectiu la detecció d'animals, i no de foc, i que això ha sigut un handicap / mochila que ha "marcat" el projecte, però que al s'ha pogut aprofitar per a fer una PdC de tipus "programa joguina")

jbericat commented 2 years ago

Després de realitzar diversos entrenaments (veure resums a /bin/CNN/) realitzant diversos reajustos de hiperparàmetres s'aconsegueix arribar al 85% de rendiment.

jbericat commented 2 years ago

S'ha millorat la implementació de pytorch-training.py degut a què els resultats de les proves anteriors no proporcionaven resultats coherents amb la accuracy obtinguda (85%), en el sentit que les prediccions realitzades al final no es corresponien amb aquest rendiment (veure PR v05.36). També s'ha implementat la divisió dels dataset de training + validació en temps d'execució, s'han inclòs estadístiques de rendiment per a train+val i finalment s'ha millorat la presentació de les gràfiques (plots). Un cop fets els primers entrenaments de proves amb el nou algorisme, els resultats obtinguts són els següents:

model-accuracies

********************************************************************************
***                                                                          ***
***                      PoC's CNN Model Training Summary                    ***
***                                                                          ***
********************************************************************************
***                                                                          ***
***                             Model version: v3.0                          ***
***                            Dataset version: v7.0                         ***
***                                                                          ***
********************************************************************************

 TRAINING PARAMETERS:

 - Image size = (229 x 229 x 1)
 - Number of classes / labels = 3
 - Batch size = 128
 - Learning rate = 1e-05

********************************************************************************

 DATASET TOTALS:

 - The number of images in a training set is:  768
 - The number of images in a validation set is:  256
 - The number of images in a test set is:  384
 - The number of batches per epoch is:  6

********************************************************************************

 CNN BLUEPRINT:

 Network_v3(
  (conv1): Conv2d(1, 16, kernel_size=(9, 9), stride=(2, 2), padding=(2, 2))
  (bn1): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (conv2): Conv2d(16, 16, kernel_size=(5, 5), stride=(2, 2), padding=(2, 2))
  (bn2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (pool): MaxPool2d(kernel_size=2, stride=1, padding=0, dilation=1, ceil_mode=False)
  (conv3): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1), padding=(2, 2))
  (bn3): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (conv4): Conv2d(32, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
  (bn4): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (fc1): Linear(in_features=107648, out_features=3, bias=True)
)

********************************************************************************

  MODEL TRAINING STATS:

 Model trained on cuda:0 device

 Training + validation time:  237.085171875  seconds

********************************************************************************

 MODEL TESTING STATS:

 For epoch 1 the TEST accuracy over the whole TEST dataset is 55 %
 For epoch 2 the TEST accuracy over the whole TEST dataset is 54 %
 For epoch 3 the TEST accuracy over the whole TEST dataset is 53 %
 For epoch 4 the TEST accuracy over the whole TEST dataset is 59 %
 For epoch 5 the TEST accuracy over the whole TEST dataset is 64 %
 For epoch 6 the TEST accuracy over the whole TEST dataset is 66 %
 For epoch 7 the TEST accuracy over the whole TEST dataset is 72 %
 For epoch 8 the TEST accuracy over the whole TEST dataset is 75 %
 For epoch 9 the TEST accuracy over the whole TEST dataset is 80 %
 For epoch 10 the TEST accuracy over the whole TEST dataset is 82 %

Real labels:  high-intensity-wildfires high-intensity-wildfires no-wildfires high-intensity-wildfires no-wildfires high-intensity-wildfires no-wildfires no-wildfires no-wildfires no-wildfires low-intensity-wildfires no-wildfires high-intensity-wildfires no-wildfires low-intensity-wildfires low-intensity-wildfires no-wildfires low-intensity-wildfires high-intensity-wildfires no-wildfires

Predicted:  low-intensity-wildfires low-intensity-wildfires no-wildfires high-intensity-wildfires no-wildfires high-intensity-wildfires low-intensity-wildfires no-wildfires low-intensity-wildfires no-wildfires low-intensity-wildfires no-wildfires high-intensity-wildfires no-wildfires low-intensity-wildfires low-intensity-wildfires no-wildfires no-wildfires high-intensity-wildfires no-wildfires

screenshot_1

jbericat commented 2 years ago

Del resum d'entrenament del model detallat al post anterior es poden treure les següents conclusions:

El fet que la accuracy del dataset de training i de validació sigui gairebé de fins al 95%, mentre que la del dataset de test sigui del 82% vol dir que podria estar-se produïnt overfitting durant l'entrenament, ja que el model no generalitza al 100% (es perd un 13% de precisió) quan s'analitzen imatges "desconegudes" pel model. També podem dir que d'una manera més precissa que el model només generalitza en un 87% dels casos.

El fet què s'estigui produint overfitting pot ser degut a diferents causes: En primer lloc al alt grau d'homogeneitat de les dades sintètiques utilitzades per a entrenar el model, o dit d'una altra manera, a l'elevada semblança que hi ha entre les imatges generades per software d'una mateixa classe. Un altre causa pot ser el fet de no haver-se realitzar un curat manual de les imatges preses de manera automàtica amb l'script /src/AirSim/PythonClient/TFG-PoC/capture-ir-segmentation.py per tal d'eliminar aquelles que no presenten clares característiques de classe.

Aquesta darrera hipòtesi es pot verificar si a la funció testBatch() (línia 544) de /src/CNN/pytorch-training.py li assignem imatges del dataset de training en comptes del dataset de test. Aleshores trobem que el resum de prediccions del final encerta aproximadament el 95% de casos la majoria de vegades, mentre que si s'assignen imatges del dataset de test, el promig d'encert de prediccions del final és del 80% la majoria de vegades.