Programmation pour l’IA
numpy.
matplotlib.
La regression linéaire permet de résoudre le problème suivant : étant donnée un ensemble de point \(D = \{(x_i,y_i) \in \mathbb{R}^2, i = 1 .. n\}\), on cherche une fonction linéaire \(f \colon x \mapsto \alpha x\) telle que \(y_i \simeq f(x_i)\). Comme nous sommes dans le cas simple où nos points sont dans le plan, on cherche plus exactement le “meilleur” \(\alpha\) tel que \(y_i \simeq \alpha x_i\). On va définir le meilleur \(\alpha\) comme celui qui minimise la quantité suivante :
\[\ell_D(\alpha) = (1/n) \sum_{1 \leq i \leq n} (y_i-\alpha x_i)^2\]
En remarquant que \(\ell_D\) est quadratique en \(\alpha\) et positive, on en déduit que le minimum de \(\ell_D\) est atteint là où sa dérivée s’annule. Un calcul permet de voir que le minimum est atteint en \(\alpha_0 = {\sum_{i\leq n} x_iy_i \over \sum_{i \leq n} x_i^2}\).
En utilisant la syntaxe numpy, écrivez une fonction
dataset(size: int, a: float, noise: float) qui retourne une
paire de listes (X,Y) tel que
Y[i] = a*X[i]+k[i] oĂą X est une liste de
taille size, X[i] une valeur uniforme entre
\(0\) et \(100\) et k[i] est une valeur
aléatoire, tirée selon la loi normale centrée en 0 et d’écart-type
noise. On pourra utiliser les fonctions random.normal
et random.uniform
de numpy
En utilisant matplotlib, affichez sur un graphique
les points \((x_i,y_i)\) générés par
votre fonction précédente. On pourra utiliser la méthode scatter.
Voici un example :
Créer une fonction regression(X,Y) qui prend en
argument deux listes X et Y ayant la mĂŞme
taille et renvoie la valeur \(\alpha_0\) comme définie dans
l’énoncé.
Utilisez matplotlib pour afficher en rouge la droite
\(y=\alpha_0 x\) par-dessus les points
affichés précédemment.
loss(X,Y,a) qui affiche la fonction
d’erreur \(\ell_D\) pour le jeu de
donnée défini par X,Y et la valeur a.On souhaite étudier les performances de la fonction
np.sum par rapport Ă la fonction Python sum en
fonction de la taille du tableau d’entrée. On va utiliser pour cela la
librairie time ainsi :
import time
start = time.time()
f()
end = time.time()
t = end-startCe code calcule le temps d’exécution de la fonction f()
dans la variable t.
np.random.uniform, écrire un code qui
génère un tableau contenant 10000 nombres entre 0 et 100 choisis
uniformément.sum et de
np.sum sur ce tableau. Qu’en pensez-vous ?sum et np.sum sur
chaque tableau et affichez les comme des nuages de points avec
matplotlib. Le temps de np.sum doit ĂŞtre en rouge, le temps
de sum en vert. On affichera la légende et le nom des
axes.On considère le programme suivant :
import matplotlib.pyplot as plt
import numpy as np
img = plt.imread("mon_image.jpg") # img est non modifiable
img = img.astype(int) # transforme l'image en tableau modifiable de int
plt.imshow(img) # affichage de l'image dans une fenĂŞtre
plt.show()Ce programme utilise matplotlib pour charger une image,
la transformer en un tableau et l’afficher.
En utilisant la méthode shape, donnez les dimensions
du tableau img.
Écrire :
invert(img) qui inverse les couleurs de
l’image en place, c’est-à -dire que le tableau img est
directement modifié (sans être copié) et la couleur \((r,g,b)\) devient \((255-r, 255-b, 255-b)\).level_grey(img,k) qui transforme l’image
en k niveau de gris. Pour cela, on calcule la moyenne \((r+g+b)/3\) et on décide de la tranche de
gris dans laquelle elle se trouve. Par exemple, Ă trois niveau de gris,
un pixel \((20, 200, 200)\) sera envoyé
sur la couleur \((86, 86, 86)\) parce
que la moyenne des valeurs est \(140\)
et qu’on quantifie l’image en trois niveau de gris: entre \(0\) et \(85\), entre \(86\) et \(171\) et entre \(171\) et \(255\).Écrire une fonction histogram(img) qui affiche un
histogramme des couleurs, c’est-à -dire qu’on affiche, pour chaque valeur
\(v\) entre \(0\) et \(255\) et chaque couleur \(c\) dans \(\{R,G,B\}\), un histogramme présentant le
nombre de pixel dont la couleur \(c\) a
valeur \(v\). On pourra utiliser pour
cela :
numpy.histogram.
Attention à bien spécifier le paramètre bins pour contrôler
les différentes valeurs. On peut utiliser de façon alternative la
fonction numpy.bincount
ou la fonction numpy.unique
avec le paramètre return_counts=True.pyplot.bar.On va s’intéresser à une technique connue sous le nom de Seam Carving qui permet de redimmensionner une image en gardant les éléments importants. Pour appliquer la méthode du Seam Carving, on a besoin de calculer l’“énergie” de chaque pixel. Intuitivement, un pixel a une petite énergie s’il est entouré de pixels de valeur similaires, et une grande énergie s’il diffère beaucoup des autres. Pour un pixel en \((i,j)\), on évalue cela, pour la couleur \(c \in \{r,g,b\}\), par :
\[(c[i-1,j]-c[i+1,j])^2 + (c[i,j-1]-c[i,j+1])^2\]
L’énergie d’un pixel est alors la racine carré de la somme de cette valeur pour chacune des trois couleurs. Le seam carving rétrécit l’image en enlevant un chemin de moindre énergie.
matplotlib. On
utilisera pour cela la méthode imshow
qui permet d’afficher une image, comme dans l’exemple. Lorsqu’un tableau
de valeurs numériques est donné en argument, matplotlib le
convertit automatiquement en une information RGB visible. On devrait
avoir :paths de la mĂŞme taille que
l’image. On veut calculer la valeur suivante : path[i][j]
doit être l’énergie minimal d’un chemin qui part de la première ligne de
l’image et qui finit à la case \(i\),
\(j\). On le calcule en remarquant que
path[0][j] = energy[0][j] et que
path[i][j] = energy[i][j]+min(path[i-1][j-1], path[i-1][j], path[i-1][j+1]).
Conclure avec un programme qui peut redimensionner une image.
Réfléchir à un moyen d’écrire un code vectoriel avec
numpy pour accélérer le calcul d’énergie.