Contenu du cours
Introduction à TensorFlow
Introduction à TensorFlow
Exécution de Graphe
Décorateur de Fonction
Un décorateur de fonction est un outil qui 'enveloppe' une fonction pour modifier son comportement. Dans TensorFlow, le décorateur le plus couramment utilisé est @tf.function
, qui convertit une fonction Python en un graph TensorFlow.
Objectif de @tf.function
Le principal objectif de l'utilisation de décorateurs comme @tf.function
est d'optimiser les calculs. Lorsqu'une fonction est décorée avec @tf.function
, TensorFlow convertit la fonction en un graphique hautement efficace qui peut être exécuté beaucoup plus rapidement, en particulier pour les opérations complexes. Cette conversion permet à TensorFlow d'appliquer des optimisations et d'exploiter le parallélisme, ce qui est crucial pour la performance dans les tâches d'apprentissage automatique.
Exemple
Passons en revue un exemple pour mieux comprendre.
import tensorflow as tf # Define a simple function and decorate it with `@tf.function` @tf.function def compute_area(radius): return 3.1415 * radius ** 2 # Call the function area = compute_area(tf.constant(3.0)) print(f"The area is: {area.numpy()}")
Dans ce code, compute_area()
est converti en un graphe TensorFlow, ce qui le rend plus rapide et plus efficace.
Comment fonctionne l'exécution de graphes ?
TensorFlow fonctionne en deux modes : Exécution Eager et Exécution de Graphes. Par défaut, TensorFlow s'exécute en mode Exécution Eager, ce qui signifie que les opérations sont exécutées au fur et à mesure qu'elles sont définies, offrant une interface flexible et intuitive. Cependant, l'Exécution Eager peut être moins efficace pour les calculs complexes et les modèles à grande échelle.
C'est là que @tf.function
et l'Exécution de Graphes entrent en jeu. Lorsque vous utilisez le décorateur @tf.function
sur une fonction, TensorFlow convertit cette fonction en un graphe de calcul statique d'opérations.
Techniques d'optimisation
-
Optimisation de Graphe : TensorFlow optimise le graphe en élaguant les nœuds inutilisés, en fusionnant les sous-graphes dupliqués et en effectuant d'autres optimisations au niveau du graphe. Cela se traduit par une exécution plus rapide et une utilisation réduite de la mémoire ;
-
Exécution plus rapide : Les graphes sont exécutés plus rapidement que les opérations eager car ils réduisent la surcharge de Python. Python n'est pas impliqué dans l'exécution du graphe, ce qui élimine la surcharge des appels de l'interpréteur Python ;
-
Parallélisme et Distribution : Les graphes permettent à TensorFlow d'identifier facilement les opportunités de parallélisme et de distribuer les calculs sur plusieurs appareils, tels que les CPU et les GPU ;
-
Mise en cache et Réutilisation : Lorsqu'une fonction décorée avec
@tf.function
est appelée avec la même signature d'entrée, TensorFlow réutilise le graphe précédemment créé, évitant ainsi la nécessité de recréer le graphe, ce qui permet de gagner du temps.
Exemple avec Gradient Tape
import tensorflow as tf @tf.function def compute_gradient(x): with tf.GradientTape() as tape: y = x * x * x return tape.gradient(y, x) x = tf.Variable(3.0) grad = compute_gradient(x) print(f"The gradient at x = {x.numpy()} is {grad.numpy()}")
Dans cet exemple, compute_gradient
est une fonction qui calcule le gradient de y = x^3
à un point donné x
. Le décorateur @tf.function
garantit que la fonction est exécutée en tant que graphe TensorFlow.
Exemple avec logique conditionnelle
import tensorflow as tf @tf.function def compute_gradient_conditional(x): with tf.GradientTape() as tape: if tf.reduce_sum(x) > 0: y = x * x else: y = x * x * x return tape.gradient(y, x) x = tf.Variable([-2.0, 2.0]) grad = compute_gradient_conditional(x) print(f"The gradient at x = {x.numpy()} is {grad.numpy()}")
Dans cet exemple, la fonction calcule différents gradients en fonction d'une condition. Le @tf.function
de TensorFlow ne convertit pas seulement le graphe de calcul statique mais gère également efficacement les éléments dynamiques comme les conditionnels et les boucles.
Swipe to start coding
Dans cette tâche, vous allez comparer les temps d'exécution de deux fonctions TensorFlow qui effectuent une multiplication de matrices : l'une avec le décorateur @tf.function
et l'autre sans.
Étapes
- Définissez la fonction
matrix_multiply_optimized
en vous assurant qu'elle inclut le décorateur@tf.function
. - Complétez les deux fonctions en calculant la moyenne des matrices résultantes.
- Générez deux matrices aléatoires uniformément distribuées en utilisant les fonctions de génération de matrices aléatoires de TensorFlow.
Solution
Merci pour vos commentaires !
Exécution de Graphe
Décorateur de Fonction
Un décorateur de fonction est un outil qui 'enveloppe' une fonction pour modifier son comportement. Dans TensorFlow, le décorateur le plus couramment utilisé est @tf.function
, qui convertit une fonction Python en un graph TensorFlow.
Objectif de @tf.function
Le principal objectif de l'utilisation de décorateurs comme @tf.function
est d'optimiser les calculs. Lorsqu'une fonction est décorée avec @tf.function
, TensorFlow convertit la fonction en un graphique hautement efficace qui peut être exécuté beaucoup plus rapidement, en particulier pour les opérations complexes. Cette conversion permet à TensorFlow d'appliquer des optimisations et d'exploiter le parallélisme, ce qui est crucial pour la performance dans les tâches d'apprentissage automatique.
Exemple
Passons en revue un exemple pour mieux comprendre.
import tensorflow as tf # Define a simple function and decorate it with `@tf.function` @tf.function def compute_area(radius): return 3.1415 * radius ** 2 # Call the function area = compute_area(tf.constant(3.0)) print(f"The area is: {area.numpy()}")
Dans ce code, compute_area()
est converti en un graphe TensorFlow, ce qui le rend plus rapide et plus efficace.
Comment fonctionne l'exécution de graphes ?
TensorFlow fonctionne en deux modes : Exécution Eager et Exécution de Graphes. Par défaut, TensorFlow s'exécute en mode Exécution Eager, ce qui signifie que les opérations sont exécutées au fur et à mesure qu'elles sont définies, offrant une interface flexible et intuitive. Cependant, l'Exécution Eager peut être moins efficace pour les calculs complexes et les modèles à grande échelle.
C'est là que @tf.function
et l'Exécution de Graphes entrent en jeu. Lorsque vous utilisez le décorateur @tf.function
sur une fonction, TensorFlow convertit cette fonction en un graphe de calcul statique d'opérations.
Techniques d'optimisation
-
Optimisation de Graphe : TensorFlow optimise le graphe en élaguant les nœuds inutilisés, en fusionnant les sous-graphes dupliqués et en effectuant d'autres optimisations au niveau du graphe. Cela se traduit par une exécution plus rapide et une utilisation réduite de la mémoire ;
-
Exécution plus rapide : Les graphes sont exécutés plus rapidement que les opérations eager car ils réduisent la surcharge de Python. Python n'est pas impliqué dans l'exécution du graphe, ce qui élimine la surcharge des appels de l'interpréteur Python ;
-
Parallélisme et Distribution : Les graphes permettent à TensorFlow d'identifier facilement les opportunités de parallélisme et de distribuer les calculs sur plusieurs appareils, tels que les CPU et les GPU ;
-
Mise en cache et Réutilisation : Lorsqu'une fonction décorée avec
@tf.function
est appelée avec la même signature d'entrée, TensorFlow réutilise le graphe précédemment créé, évitant ainsi la nécessité de recréer le graphe, ce qui permet de gagner du temps.
Exemple avec Gradient Tape
import tensorflow as tf @tf.function def compute_gradient(x): with tf.GradientTape() as tape: y = x * x * x return tape.gradient(y, x) x = tf.Variable(3.0) grad = compute_gradient(x) print(f"The gradient at x = {x.numpy()} is {grad.numpy()}")
Dans cet exemple, compute_gradient
est une fonction qui calcule le gradient de y = x^3
à un point donné x
. Le décorateur @tf.function
garantit que la fonction est exécutée en tant que graphe TensorFlow.
Exemple avec logique conditionnelle
import tensorflow as tf @tf.function def compute_gradient_conditional(x): with tf.GradientTape() as tape: if tf.reduce_sum(x) > 0: y = x * x else: y = x * x * x return tape.gradient(y, x) x = tf.Variable([-2.0, 2.0]) grad = compute_gradient_conditional(x) print(f"The gradient at x = {x.numpy()} is {grad.numpy()}")
Dans cet exemple, la fonction calcule différents gradients en fonction d'une condition. Le @tf.function
de TensorFlow ne convertit pas seulement le graphe de calcul statique mais gère également efficacement les éléments dynamiques comme les conditionnels et les boucles.
Swipe to start coding
Dans cette tâche, vous allez comparer les temps d'exécution de deux fonctions TensorFlow qui effectuent une multiplication de matrices : l'une avec le décorateur @tf.function
et l'autre sans.
Étapes
- Définissez la fonction
matrix_multiply_optimized
en vous assurant qu'elle inclut le décorateur@tf.function
. - Complétez les deux fonctions en calculant la moyenne des matrices résultantes.
- Générez deux matrices aléatoires uniformément distribuées en utilisant les fonctions de génération de matrices aléatoires de TensorFlow.
Solution
Merci pour vos commentaires !