Closed jbericat closed 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
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
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ç:
S'aplica el PR #126 per a solucionar el problema i finalment s'aconsegueix entrenar el model utilitzant la GPU:
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.
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
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
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.
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)
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):
[x] 2 - Implementar tècniques d'ampliació del dataset
[ ] 3 - No s'ha fet un "curat" manual de les imatges del dataset, i n'hi ha bastants que no mostren clarament característiques de la classe etiquetada, o que són de mala qualitat. Això és degut a què és dificil calcular la distància per capturar imatges automàticament a l'entorn Unreal, terreny muntanyos on les alçades varien respecte de diferents punts de captura
[ ] 4 - S'ha detectat que les imatges sense incendis (classe medium-intensity-wildfires
) mostren característiques comunes a les de la classe low-intensity
, segurament indistingibles pel model (s'haurien de fer proves). 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
[ ] 5 - Resituar alguns objectes StaticMesh
de l'entorn Unreal corresponents a les classes de mitjana i baixa intensitat per a que no quedin tant tapats per les branques i quedin més a la vista del dron (un "patch" poc realista, però)
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.
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:
* [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:
_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 %
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")
Després de realitzar diversos entrenaments (veure resums a /bin/CNN/
) realitzant diversos reajustos de hiperparàmetres s'aconsegueix arribar al 85% de rendiment.
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:
********************************************************************************
*** ***
*** 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
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.
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