Concepts fondamentaux de TensorFlow

Le nom de TensorFlow vient des structures de base qu'il utilise pour traiter les données - Tensor et Flow.

TensorFlow est une plateforme d'apprentissage automatique open source de bout en bout. Ses principaux avantages sont :

  • Modèle de graphe de calcul flexible: prend en charge les modes de graphe dynamique et de graphe statique
  • Capacité de déploiement multiplateforme: peut s'exécuter sur CPU, GPU, TPU et appareils mobiles
  • Écosystème riche: inclut des sous-projets tels que TensorFlow Lite (mobile) et TensorFlow.js (navigateur)
  • Prêt pour la production: fournit une chaîne d’outils complète, de la recherche à la production

Concepts fondamentaux expliqués

Tenseur

Un tenseur est la structure de données la plus élémentaire dans TensorFlow. Il peut être compris commeun tableau multidimensionnelau sens généralisé.

Mathématiquement, un tenseur est une fonction multilinéaire qui peut être utilisée pour représenter des relations linéaires entre des vecteurs, des scalaires et d’autres tenseurs.

Analogie simple:

  • Scalaire (tenseur à 0 dimension): un nombre, tel que5
  • Vecteur (tenseur à 1 dimension): une liste de nombres, telle que[1, 2, 3, 4]
  • Matrice (tenseur à 2 dimensions): un tableau de nombres, tel que[[1, 2], [3, 4]]
  • Tenseur à 3 dimensions: un cube de nombres, tel qu’une image couleur (hauteur × largeur × canaux de couleur)
  • Tenseurs de dimension supérieure: par exemple, des données vidéo (temps × hauteur × largeur × canaux de couleur)

Propriétés clés des tenseurs

Exemple

# Exemple de tenseur
import tensorflow as tf

# Créer un tenseur matriciel 2x3
tensor = tf.constant([[1, 2, 3], [4, 5, 6]])

print(f"Shape (Shape): {tensor.shape}")        # (2, 3)
print(fData type (Dtype): {tensor.dtype})    # int32
print(fRank (Rank): {tf.rank(tensor)})      # 2
print(fDevice (Device): {tensor.device})      # /job:localhost/replica:0/task:0/device:CPU:0

Explication des propriétés clés:

Forme: décrit la taille de chaque dimension

  • (2, 3)représente une matrice avec 2 lignes et 3 colonnes
  • (224, 224, 3)représente une image RGB de 224×224 pixels

Type de données (Dtype): le type de données dans le tenseur

  • tf.float32: virgule flottante 32 bits (le plus courant)
  • tf.int32: entier 32 bits
  • tf.bool: boolean
  • tf.string: string

Dimension / Rang: la dimensionnalité d’un tenseur

  • Scalaire : rang 0
  • Vecteur : rang 1
  • Matrice : rang 2

Périphérique: l’emplacement du périphérique où le tenseur est stocké

  • CPU:/device:CPU:0
  • GPU:/device:GPU:0

Importance des tenseurs dans l’apprentissage automatique

Représentation des données:

  • Données d’entrée: les images, le texte et l’audio peuvent tous être représentés sous forme de tenseurs
  • Paramètres du modèle: les poids et biais sont des tenseurs
  • Résultats intermédiaires: toutes les données lors du calcul sont des tenseurs
  • Résultats de sortie: résultats de prédiction, valeurs de perte, etc.

Exemples pratiques:

  • Classification d'images: forme du tenseur d'entrée(batch_size, height, width, channels)
  • Traitement de texte: forme du tenseur d'entrée(batch_size, sequence_length)
  • Séries temporelles: forme du tenseur d'entrée(batch_size, time_steps, features)

Graphe de calcul

Un graphe de calcul est une structure de graphe qui utilisenœudsetarêtespour représenter des opérations mathématiques :

  • Nœud: représente des opérations mathématiques (addition, multiplication, fonctions d'activation, etc.)
  • Arête: représente le chemin du flux de données (tenseurs)

Exemple simple:

计算 z = (x + y) * w 的计算图:

x ──┐
    ├─→ [+] ──→ [×] ──→ z
y ──┘         ├
w ────────────┘

Avantages des graphes de calcul

1. Différenciation automatique:

  • Permet de calculer automatiquement les gradients et de mettre en œuvre la rétropropagation
  • Pas besoin de dériver manuellement des formules de gradient complexes

2. Opportunités d'optimisation:

  • Optimisation à la compilation : fusionner les opérations, éliminer les redondances
  • Optimisation à l'exécution : réutilisation de la mémoire, calcul parallèle

3. Débogage visuel:

  • Utiliser TensorBoard pour visualiser la structure du modèle
  • Il est plus facile de comprendre et de déboguer des modèles complexes

4. Calcul distribué:

  • Différentes parties du graphe peuvent être affectées à différents appareils
  • Prend en charge l'entraînement distribué sur plusieurs machines

Graphe statique vs graphe dynamique

TensorFlow 1.x (graphe statique):

Exemple

# Style TensorFlow 1.x (à titre de compréhension uniquement, non recommandé à l'utilisation)
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

# Définir le graphe de calcul
x = tf.placeholder(tf.float32, shape=[None, 784])
W = tf.Variable(tf.random.normal([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.matmul(x, W) + b

# Créer une session et exécuter
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    result = sess.run(y, feed_dict={x: input_data})

TensorFlow 2.x (graphe dynamique / exécution immédiate):

Exemple

# Style TensorFlow 2.x (recommandé)
import tensorflow as tf

# Exécuter directement les opérations
x = tf.constant([[1.0, 2.0, 3.0]])
W = tf.Variable(tf.random.normal([3, 2]))
b = tf.Variable(tf.zeros([2]))
y = tf.matmul(x, W) + b

print(y)  # Obtenir le résultat immédiatement

Session et exécution immédiate

Mécanisme de session dans TensorFlow 1.x

Dans TensorFlow 1.x, la construction et l'exécution du graphe de calcul sont séparées :

Processus en deux étapes:

  1. Étape de construction: définir le graphe de calcul, mais ne réaliser aucun calcul
  2. Étape d'exécution: exécuter le graphe dans une session et obtenir les résultats

Le rôle de la session:

  • Gérer l'environnement d'exécution du graphe
  • Allouer et gérer les ressources (mémoire, périphériques)
  • Fournir le contexte d'exécution du graphe

3.2 Exécution immédiate dans TensorFlow 2.x

TensorFlow 2.x active l'exécution immédiate par défaut, ce qui rend TensorFlow plus « Pythonic » :

Caractéristiques de l'exécution immédiate:

  • Évaluation immédiate: les opérations sont exécutées immédiatement après leur définition
  • Facile à déboguer: on peut utiliser les outils de débogage Python
  • Programmation intuitive: comme écrire du code Python normal

Exemple de comparaison:

Exemple

# TensorFlow 2.x - Exécution immédiate
import tensorflow as tf

a = tf.constant(2.0)
b = tf.constant(3.0)
c = a + b
print(f"Result: {c}")  # Résultat : 5.0

# On peut accéder directement à la valeur
print(f"c's numpy value: {c.numpy()}")  # Valeur numpy de c : 5.0

Mode graphe vs mode d'exécution Eager

Mode d'exécution Eager (par défaut, adapté au développement et au débogage):

  • Les opérations s'exécutent immédiatement
  • Facile à déboguer et à comprendre
  • Performances légèrement inférieures

Mode graphe (adapté au déploiement en production):

  • Préconstruire le graphe de calcul complet
  • Meilleures possibilités d'optimisation
  • Efficacité d'exécution supérieure

Passer au mode graphe:

Exemple

@tf.function
def compute_function(x, y):
    return x * y + x

# Cette fonction sera compilée en un graphe
result = compute_function(tf.constant(2.0), tf.constant(3.0))

Variable et constante

Constante

Une constante estun tenseur immuablequi ne peut pas être modifié une fois créé :

Exemple

# Créer une constante
scalar_const = tf.constant(3.14)
vector_const = tf.constant([1, 2, 3, 4])
matrix_const = tf.constant([[1, 2], [3, 4]])

# La valeur d'une constante ne peut pas être modifiée
print(scalar_const)  # tf.Tensor(3.14, shape=(), dtype=float32)

Utilisations des constantes:

  • Stocker les hyperparamètres (taux d'apprentissage, taille de lot, etc.)
  • Stocker des données de configuration qui ne nécessitent pas d'entraînement
  • Servir de valeurs fixes dans les calculs

Variable

Une variable estuntenseur mutable, généralement utilisée pour stocker les paramètres du modèle :

Exemple

# Créer une variable
weight = tf.Variable(tf.random.normal([2, 3]))
bias = tf.Variable(tf.zeros([3]))

print(f"Poids initiaux :\n{weight}")

# Modifier la valeur de la variable
weight.assign(tf.ones([2, 3]))
print(f"Poids modifiés :\n{weight}")

# Mise à jour partielle
weight[0, 0].assign(5.0)
print(f"Après mise à jour partielle :\n{weight}")

Caractéristiques clés des variables:

  1. Persistance de l'état: maintient l'état pendant l'entraînement
  2. Suivi du gradient: peut calculer les gradients par rapport aux variables
  3. Optimisable: peut être mis à jour par des algorithmes d'optimisation
  4. Sauvegardable: peut être sauvegardé dans des fichiers de point de contrôle

Cas d'utilisation : Variable vs Constant

Propriété Variable Constante
Mutabilité Modifiable Non modifiable
Utilisation principale Paramètres du modèle (poids, biais) Hyperparamètres, données d'entrée
Calcul du gradient Pris en charge Non pris en charge
Utilisation de la mémoire Stockage persistant Stockage temporaire
Exemples typiques W = tf.Variable(...) learning_rate = tf.constant(0.01)

Flux de données et différenciation automatique

Propagation avant

Le processus par lequel les données circulent des nœuds d'entrée vers les nœuds de sortie dans le graphe de calcul :

Exemple

# Exemple simple de propagation avant
import tensorflow as tf

# Données d'entrée
x = tf.constant([[1.0, 2.0]])

# Paramètres du modèle
W1 = tf.Variable(tf.random.normal([2, 3]))
b1 = tf.Variable(tf.zeros([3]))
W2 = tf.Variable(tf.random.normal([3, 1]))
b2 = tf.Variable(tf.zeros([1]))

# Propagation avant
hidden = tf.nn.relu(tf.matmul(x, W1) + b1)  # Couche cachée
output = tf.matmul(hidden, W2) + b2         # Couche de sortie

print(f"Sortie finale : {output}")

Différenciation automatique

TensorFlow utiliseGradientTapepour enregistrer les opérations et calculer automatiquement les gradients :

Exemple

# Exemple de différenciation automatique
x = tf.Variable(3.0)

# Utiliser GradientTape pour enregistrer les opérations
with tf.GradientTape() as tape:
    y = x**2 + 2*x + 1  # y = x² + 2x + 1

# Calculer dy/dx
gradient = tape.gradient(y, x)
print(f"Lorsque x=3, dy/dx = {gradient}")  # Devrait être 2x + 2 = 8

Comment fonctionne GradientTape:

  1. Enregistrer les opérations: la bande enregistre toutes les opérations dans son contexte
  2. Construire le graphe arrière: crée un graphe de calcul inverse pour le calcul du gradient
  3. Calculer les gradients: calcule les gradients à l'aide de la règle de chaîne

Intégration des concepts dans la boucle d'entraînement

Exemple

# Exemple complet d'étape d'entraînement
import tensorflow as tf

# Modèle et données
model = tf.keras.Sequential([
    tf.keras.layers.Dense(10, activation='relu'),
    tf.keras.layers.Dense(1)
])

x_train = tf.random.normal([100, 5])
y_train = tf.random.normal([100, 1])

optimizer = tf.keras.optimizers.Adam(0.01)

# Étape d'entraînement
@tf.function
def train_step(x, y):
    with tf.GradientTape() as tape:
        predictions = model(x)
        loss = tf.keras.losses.mse(y, predictions)
   
    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    return loss

# Exécuter l'entraînement
for epoch in range(10):
    loss = train_step(x_train, y_train)
    print(f"Époque {epoch}: Perte = {loss:.4f}")

Résumé des concepts clés

Diagramme des relations entre concepts

Relations entre les concepts clés de TensorFlow :

输入数据 (Tensor) ──→ 计算图 (Graph) ──→ 输出结果 (Tensor)
      ↑                    ↓
   常量/变量            前向传播
      ↑                    ↓
   参数存储 ←──── 梯度更新 ←──── 自动微分
                              ↑
                        GradientTape

Autres extensions