Data Augmentation#

Vous le savez, le potentiel des modĂšles de deep learning est limitĂ© par la quantitĂ© de donnĂ©es disponibles pour entraĂźner notre modĂšle. En gĂ©nĂ©ral, on a besoin d’une Ă©norme quantitĂ© de donnĂ©es : les modĂšles de vision les plus performants sont entraĂźnĂ©s sur des milliards d’images et les modĂšles de NLP (LLM) sur des trillions de tokens.

Bien souvent, obtenir des données de qualité labellisées est une tùche complexe et surtout coûteuse.

Est-il possible d’augmenter artificiellement nos donnĂ©es grĂące Ă  des transformations ingĂ©nieuses ?

Oui ! C’est possible et c’est ce qu’on appelle la data augmentation. Dans cette partie, nous allons regarder diffĂ©rentes mĂ©thodes de data augmentation pour les images et prĂ©senter rapidement les possibilitĂ©s de data augmentation pour le NLP et l’audio.

Data augmentation pour les images#

Les techniques de data augmentation prĂ©sentĂ©es dans cette partie ont montrĂ© des intĂ©rĂȘts pour l’entraĂźnement de modĂšles de deep learning. En revanche, il faut ĂȘtre prudent car parfois certains types de data augmentation ne sont pas en accord avec notre objectif d’entraĂźnement (par exemple, si on veut dĂ©tecter les personnes allongĂ©es, on va Ă©viter de tourner l’image de 90 degrĂ©s).

Pour introduire les différentes méthodes de data augmentation, nous utilisons PyTorch et plus particuliÚrement torchvision, qui propose un large choix de techniques de data augmentation.

Commençons avec notre image de base :

from PIL import Image
image_pil=Image.open("images/tigrou.png")
image_pil
../_images/f148aede37f561d9189f5a4758f3cec09ee7dd0085bc32241d67500e33c423d2.png

Transformons notre image en tensor PyTorch.

import torchvision.transforms as T 
transform=T.Compose([T.ToTensor(),T.Resize((360,360))])
image=transform(image_pil)[0:3,:,:]
/home/aquilae/anaconda3/envs/dev/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

Inversion horizontale/verticale et rotation#

Une premiĂšre idĂ©e pour la data augmentation consiste Ă  appliquer des transformations comme l’inversion de l’image (horizontalement ou verticalement) ou la rotation de l’image. En effet, un chat Ă  l’envers reste un chat.

À considĂ©rer : Si on voulait diffĂ©rencier la classe “chat” et la classe “chat Ă  l’envers”, on ne pourrait pas utiliser cette technique. Il faut toujours bien ĂȘtre sĂ»r de ce dont on a besoin.

import matplotlib.pyplot as plt

horiz_flip=T.Compose([T.RandomHorizontalFlip(p=1)])
image_horiz_flip=horiz_flip(image)
vert_flip=T.Compose([T.RandomVerticalFlip(p=1)])
image_vert_flip=vert_flip(image)
rot=T.Compose([T.RandomRotation(degrees=90)])
image_rot=rot(image)

plt.figure(figsize=(5,5))
plt.subplot(221)
plt.imshow(image.permute(1,2,0))
plt.axis("off")
plt.subplot(222)
plt.imshow(image_horiz_flip.permute(1,2,0))
plt.axis("off")
plt.subplot(223)
plt.imshow(image_vert_flip.permute(1,2,0))
plt.axis("off")
plt.subplot(224)
plt.imshow(image_rot.permute(1,2,0))
plt.axis("off")
plt.show()
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
../_images/d59bf2399e0cd5f612df158341467108943fdffde6ddafe04deb9fd36873ec49.png

Image cropping#

Une autre technique consiste Ă  cropper une partie de l’image et utiliser ce crop comme image d’entrĂ©e. Il y a la possibilitĂ© de CenterCrop (un crop au centre) ou RandomCrop (crop alĂ©atoire dans l’image).

À considĂ©rer : Avec cette mĂ©thode, il faut faire attention Ă  ce que l’objet soit bien prĂ©sent dans notre crop. Si on choisit une valeur de crop trop petite ou que l’objet n’occupe pas une place assez importante dans l’image, ce type de data augmentation peut ĂȘtre nĂ©faste (voir derniĂšre image).

crop=T.Compose([T.RandomCrop(200)])
image_crop=crop(image)
center_crop=T.Compose([T.CenterCrop(150)])
image_center_crop=center_crop(image)

crop_small=T.Compose([T.RandomCrop(100)])
image_crop_small=crop_small(image)

plt.figure(figsize=(5,5))
plt.subplot(221)
plt.imshow(image.permute(1,2,0))
plt.axis("off")
plt.subplot(222)
plt.imshow(image_crop.permute(1,2,0))
plt.axis("off")
plt.subplot(223)
plt.imshow(image_center_crop.permute(1,2,0))
plt.axis("off")
plt.subplot(224)
plt.imshow(image_crop_small.permute(1,2,0))
plt.axis("off")
plt.show()
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
../_images/062e9cdb5bd7d67455b6049a6903de4547a946163b7390966b92e8c6a3734a58.png

Contraste, luminosité, saturation et teinte#

On peut également choisir de modifier les valeurs de luminosité (brightness), contraste (contrast), saturation (saturation) et teinte (hue) grùce à la transformation ColorJitter.

bright=T.Compose([T.ColorJitter(brightness=0.8)])
image_bright=bright(image)
contr=T.Compose([T.ColorJitter(contrast=0.8)])
image_contr=contr(image)

satur=T.Compose([T.ColorJitter(saturation=0.8)])
image_satur=satur(image)

plt.figure(figsize=(5,5))
plt.subplot(221)
plt.imshow(image.permute(1,2,0))
plt.axis("off")
plt.subplot(222)
plt.imshow(image_bright.permute(1,2,0))
plt.axis("off")
plt.subplot(223)
plt.imshow(image_contr.permute(1,2,0))
plt.axis("off")
plt.subplot(224)
plt.imshow(image_satur.permute(1,2,0))
plt.axis("off")
plt.show()
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
../_images/1979f2ce0c6a0d110b9f67310c68737e27cc5c765f8e6759c3c6b20de7e2ff0a.png

Autres transformations#

Beaucoup d’autres transformations sont possibles. On peut supprimer une partie de l’image. On peut Ă©galement ajouter un padding autour de l’image ou solariser l’image. Il est aussi possible de dĂ©finir une transformation affine prĂ©cise de ce que l’on va appliquer comme transformation Ă  l’image.

erase=T.Compose([T.RandomErasing(p=1)])
image_erase=erase(image)
solar=T.Compose([T.Pad(50),T.RandomSolarize(0.5,p=1)])
image_solar=solar(image)

affin=T.Compose([T.RandomAffine(degrees=30,scale=(0.8,1.2),shear=30)])
image_affin=affin(image)

plt.figure(figsize=(5,5))
plt.subplot(221)
plt.imshow(image.permute(1,2,0))
plt.axis("off")
plt.subplot(222)
plt.imshow(image_erase.permute(1,2,0))
plt.axis("off")
plt.subplot(223)
plt.imshow(image_solar.permute(1,2,0))
plt.axis("off")
plt.subplot(224)
plt.imshow(image_affin.permute(1,2,0))
plt.axis("off")
plt.show()
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
../_images/e33be7d03b7b4afc17866eae7f11569cba1c2a07b3a33dd5e27c160a8fd45c21.png

La data augmentation est une technique trĂšs intĂ©ressante permettant d’augmenter artificiellement les donnĂ©es d’entraĂźnement. Cela permet d’entraĂźner de plus gros modĂšles sans overfitting. En pratique, il est trĂšs souvent intĂ©ressant d’en inclure dans l’entraĂźnement de son rĂ©seau de neurones, mais il faut quand mĂȘme faire attention Ă  ne pas faire n’importe quoi.

Je vous invite à tester votre data augmentation sur quelques éléments de votre dataset pour voir si rien ne vous choque.

Note : Il existe d’autres mĂ©thodes de data augmentation, notamment l’ajout de bruit sur l’image. Vous pouvez retrouver la liste des transformations possibles dans la documentation PyTorch.

Data augmentation pour le texte#

On peut Ă©galement faire de la data augmentation en NLP. Voici une liste de ce qu’il est possible de faire :

  • On peut changer alĂ©atoirement la position de certains mots dans une phrase (rend le modĂšle robuste mais potentiellement dangereux Ă  faire)

  • On peut remplacer certains mots par un de leurs synonymes

  • On peut paraphraser

  • On peut ajouter ou supprimer des mots au hasard dans la phrase

Ces techniques ne sont pas adaptées à tous les problÚmes de NLP et il faut faire bien attention en les utilisant.

Note : Avec l’arrivĂ©e des LLM, il est souvent possible de fine-tuner notre modĂšle de maniĂšre efficace, mĂȘme avec trĂšs peu de donnĂ©es, ce qui diminue le recours Ă  la data augmentation en NLP.

Data augmentation pour l’audio#

Dans le domaine de l’audio, il est aussi parfois utile d’utiliser de la data augmentation. Voici une liste de certaines techniques pour augmenter vos donnĂ©es artificiellement en audio :

  • Ajout de bruit dans l’audio (gaussien ou alĂ©atoire) pour augmenter la performance du modĂšle dans des situations complexes

  • DĂ©calage de l’enregistrement

  • Changement de la vitesse de l’enregistrement

  • Changer la hauteur du son (plus aigu ou plus grave)