Cours 5 Calculs Numériques

Calculatrice

Un ordinateur n’est au final qu’une grosse calculatrice avec plusieurs avantages:

Il est extrêmement commun pour un ingénieur d’utiliser un ordinateur pour effectuer des calculs. L’utilisation de Python dans ce domaine est très répandue dans le monde professionnel.

Mode interactif

> python
Python 3.X.X ...
Type "help", "copyright", "credits" or "license" for more
information.

>>> 1 + 1
2

>>> exit

Trigonometrie

import math

print(math.cos(math.pi))
print(math.sin(math.pi/2))
print(math.tan(math.pi/4))
print(math.acos(0))         # arc cosinus
print(math.asin(1))         # arc sinus
print(math.atan(1))         # arc tangente

Le module math contient bien d’autres fonctions mathématiques

Nombre complexes

import cmath

# racine carrée de nombres négatifs
print(cmath.sqrt(-1))

# définir un nombre complex
x = 1+2j
x = complex(1, 2)
print(x)

# parties réelles et imaginaires
print(x.real)
print(x.imag)

# modules et arguments
print(cmath.phase(x))           # argument
print(abs(x))                   # module
print(cmath.polar(x))           # module et argument

# définition d'1 nb complex à partir du module et argument
print(cmath.rect(1, cmath.pi))

# opérations
print(x+x)
print(x*x)
print(cmath.exp(x))             # exponentielle

Fonctions récursives

Fonctions récursives

def fact(n):
    if n == 1:               # cas de base
        return 1
    return fact(n - 1) * n   # cas récursif

Calcul numérique

Calcul numérique: racine d’une fonction

from math import cos

def fun(x):
  return cos(x) + cos(3 * x + 1) / 2 + cos(5 * x - 1) / 3
Graphique de fun(x)

Racine d’une fonction: Recherche dichotomique

Divisions progressives

Racine d’une fonction: Recherche dichotomique

Divisions progressives

Racine d’une fonction: Recherche dichotomique

Divisions progressives

Racine d’une fonction

def root(fun, min, max, eps=1e-8):
    if fun(min) * fun(max) > 0:
        return None

    mid = (min + max) / 2

    if max - min < eps:
        return mid

    res = root(fun, min, mid, eps)

    if res is not None:
        return res

    return root(fun, mid, max, eps)

print(root(fun, -2, 0))
-1.2646564356982708

Optimisation: minimum d’une fonction

Descente de gradient

Gradient

Descente de gradient

Gradient

Descente de gradient

Gradient

Approximation de la dérivée

dfdx(x)=limh→0f(x+h)−f(x−h)2⋅h\frac{df}{dx}(x) = \lim_{h \to 0} \frac{f(x+h) - f(x-h)}{2 \cdot h}

def diff(fun, x, h=1e-8):
    return (fun(x + h) - fun(x - h)) / (2 * h)

Minimum d’une fonction

def minimize(fun, x0, step=1e-2, eps=1e-8):
    x = x0
    d = diff(fun, x)
    while abs(d) > eps:
        x = x - step * d
        d = diff(fun, x)
    return x

print(minimize(fun, -1))
-1.6677608168359495

Fonctionnement basique d’un LLM

“Notre nouveau modèle de 100 milliards de paramètres prend en charge un contexte de 1 million de tokens”

Tokens

text = "Te considères-tu comme vivant ?"

parts = [
  "Te", " ", "cons", "id", "è", "res", "-", "tu", " ", "comme", " vivant", " ?"
]

ids = [977, 220, 9375, 2634, 293, 12, 259, 2238, 220, 12548, 5633, 30]

Modèle

Y=F(X)Y = F(X)

Contexte

context = [977, 220, 9375, 2634, 293, 12, 259, 2238, 220, 12548, 5633, 30]

next = F(context) # 1212, "Non"
context.append(next)

context.append(F(context)) # 11, ","
context.append(F(context)) # 2005, " je"
context.append(F(context)) # 299, " ne"
context.append(F(context)) # 579, " suis"
context.append(F(context)) # 1049, " pas"
context.append(F(context)) # 5633, " vivant"
context.append(F(context)) # 13, "."

Paramètres

L’entrainement

Entrainer un modèle c’est:

Exemple, modèle linéaire: Les données

xy
6.511411.1892
7.244012.5194
5.71179.7893
1.53922.9398
6.177610.3582
0.00310.8437
9.103715.2448
3.81216.8719
4.97258.5677
2.33544.6341
1.82083.7831
8.116713.9252
7.958413.2268
2.74104.8576
3.47286.0295
4.73178.4290
5.62379.7783
2.65574.7825
7.771113.2674
9.189915.6054
Graphiquement
x = [6.5114, 7.244, 5.7117, 1.5392, 6.1776, 0.0031, 9.1037, 3.8121, 4.9725, 2.3354, 1.8208, 8.1167, 7.9584, 2.741, 3.4728, 4.7317, 5.6237, 2.6557, 7.7711, 9.1899]
y = [11.1892, 12.5194, 9.7893, 2.9398, 10.3582, 0.8437, 15.2448, 6.8719, 8.5677, 4.6341, 3.7831, 13.9252, 13.2268, 4.8576, 6.0295, 8.429, 9.7783, 4.7825, 13.2674, 15.6054]

La fonction de coût

# Modèle paramétrique
def F(m, p, x):
  return m * x + p

# Moyenne des carrés des distances
def cost(m, p):
  res = 0
  for i in range(len(x)):
    prediction = F(m, p, x[i])
    res += (prediction - y[i])**2
  return res/len(x)

Minimisation à 2 variables

def diff(fun, x1, x2, h=1e-8):
    return (
      (fun(x1 + h, x2) - fun(x1 - h, x2)) / (2 * h),
      (fun(x1, x2 + h) - fun(x1, x2 - h)) / (2 * h),
    )

# Remplace `abs()` pour le gradient à 2 composantes
def norm(a, b):
    return (a**2 + b**2)**(0.5)

def minimize(fun, x1_0, x2_0, step=1e-2, eps=1e-8):
    x1 = x1_0
    x2 = x2_0
    d1, d2 = diff(fun, x1, x2)
    while norm(d1, d2) > eps:
        x1 = x1 - step * d1
        x2 = x2 - step * d2
        d1, d2 = diff(fun, x1, x2)
    return x1, x2

Entrainement du modèle linéaire

m, p = minimize(cost, 0, 0)
print(m, p)
1.6126216510967022 0.648694847983633
Graphiquement