Ya está disponible TensorFlow 2.0 alpha. Este framework ha tenido un gran impacto en la comunidad de deep learning. Practicantes, investigadores y desarrolladores lo han adoptado como nunca. Es, sin duda, uno de los principales motores detrás del despegue de muchas de las aplicaciones con deep learning que vemos hoy. Dicho esto, TensorFlow 1.x también tenía sus contras (como muchos otros frameworks). Como dijo Martin Wicke (ingeniero de software del equipo de TensorFlow) durante el TF Dev Summit '19:
Hemos aprendido mucho desde la 1.0.
Con todas las lecciones aprendidas de su amplia base de usuarios y de los issues en GitHub, el equipo de TensorFlow lanzó TensorFlow 2.0 alpha con un buen número de cambios importantes para mejorar el rendimiento, la experiencia de uso y más. Te permite crear prototipos rápidos e incorpora muchas prácticas modernas de deep learning. En este artículo verás algunas de estas novedades con implementaciones concretas.
Nota: las actualizaciones comentadas son, a juicio del autor, las más relevantes. Necesitarás experiencia previa con TensorFlow y Keras para seguir el artículo. Estos recursos pueden venirte bien si quieres refrescar TensorFlow y Keras:
Para actualizar a TensorFlow 2.0 ejecuta esta línea en un Jupyter Notebook:
!pip install tensorflow==2.0.0-alpha0
La variante para GPU se instala igual (requiere tener CUDA previamente):
!pip install tensorflow-gpu==2.0.0-alpha0
Puedes consultar más detalles del proceso de instalación aquí.
Algunas de las novedades que verás incluyen implementaciones de código. En esos casos necesitarás un dataset. En este artículo usaremos el dataset Adult del archivo UCI.
import pandas as pd
columns =["Age","WorkClass","fnlwgt","Education","EducationNum","MaritalStatus","Occupation","Relationship","Race","Gender","CapitalGain","CapitalLoss","HoursPerWeek","NativeCountry","Income"]
data = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data',
header=None,
names=columns)
data.head()Con la tecnología de
Age
WorkClass
fnlwgt
Education
EducationNum
MaritalStatus
Occupation
Relationship
Race
Gender
CapitalGain
CapitalLoss
HoursPerWeek
NativeCountry
Income
0
39
State-gov
77516
Bachelors
13
Never-married
Adm-clerical
Not-in-family
White
Male
2174
0
40
United-States
<=50K
1
50
Self-emp-not-inc
83311
Bachelors
13
Married-civ-spouse
Exec-managerial
Husband
White
Male
0
0
13
United-States
<=50K
2
38
Private
215646
HS-grad
9
Divorced
Handlers-cleaners
Not-in-family
White
Male
0
0
40
United-States
<=50K
3
53
Private
234721
11th
7
Married-civ-spouse
Handlers-cleaners
Husband
Black
Male
0
0
40
United-States
<=50K
4
28
Private
338409
Bachelors
13
Married-civ-spouse
Prof-specialty
Wife
Black
Female
0
0
40
Cuba
<=50K
Este dataset plantea una clasificación binaria: predecir si una persona ganará más de 50.000 $ al año o no a partir de varios datos personales.
Hagamos un preprocesado básico y preparemos los splits en una proporción 80:20:
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
import numpy as np
# Label Encode
le = LabelEncoder()
data = data.apply(le.fit_transform)# Segregar características y convertir a arrays de NumPy
X = data.iloc[:,0:-1].values
y = data['Income'].values
# Split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=7)Con la tecnología de
A estas alturas deberías tener un entorno funcional con TensorFlow 2.0 instalado y el dataset cargado en tu espacio de trabajo. Ya puedes pasar a las novedades.
1. Eager execution por defecto
En TensorFlow 2.0 ya no necesitas crear una sesión y ejecutar el grafo computacional dentro de ella. La ejecución eager está activada por defecto en la versión 2.0 para que puedas construir y ejecutar tus modelos al instante. Si lo prefieres, puedes desactivarla así:
tf.compat.v1.disable_eager_execution() (si has importado tensorflow como tf).
Aquí tienes una pequeña comparación en código que ilustra la diferencia:
2. tf.function y AutoGraph
Aunque la ejecución eager permite programación imperativa, para entrenamiento distribuido, optimización a gran escala y producción, la ejecución por grafos al estilo de TensorFlow 1.x tiene ventajas. En TensorFlow 2.0 mantienes la ejecución basada en grafos, pero de forma más flexible. Se consigue con tf.function y AutoGraph.
tf.function te permite definir grafos de TensorFlow con sintaxis de Python gracias a AutoGraph. AutoGraph soporta buena parte del lenguaje Python, como if, for, while, iteradores, etc. Hay limitaciones, eso sí. Aquí puedes ver la lista completa de compatibilidades disponibles. Abajo tienes un ejemplo que muestra lo sencillo que es definir un grafo de TensorFlow con un simple decorator.
import tensorflow as tf
# Define la pasada hacia delante@tf.functiondefsingle_layer(x, y):return tf.nn.relu(tf.matmul(x, y))# Genera datos aleatorios de una distribución uniforme
x = tf.random.uniform((2,3))
y = tf.random.uniform((3,5))
single_layer(x, y)Con la tecnología de
<tf.Tensor: id=73, shape=(2,5), dtype=float32, numpy=array([[0.5779363,0.11255255,0.26296678,0.12809312,0.23484911],[0.5932371,0.1793559,0.2845083,0.23249313,0.21367362]],
dtype=float32)>Con la tecnología de
Fíjate en que no has tenido que crear sesiones ni placeholders para ejecutar single_layer(). Esta es una de las ventajas de tf.function. Por debajo, aplica las optimizaciones necesarias para que tu código vaya más rápido.
3. tf.variable_scope ya no es necesario
En TensorFlow 1.x, para usar tf.layers como variables y reutilizarlas, debías usar el bloque tf.variable. En TensorFlow 2.0 ya no hace falta. Al estar keras como API de alto nivel central en TensorFlow 2.0, todas las capas creadas con tf.layers pueden integrarse fácilmente en una definición tf.keras.Sequential. El código se vuelve más legible y, además, puedes llevar control de variables y pérdidas.
Un ejemplo:
# Define el modelo
model = tf.keras.Sequential([
tf.keras.layers.Dropout(rate=0.2, input_shape=X_train.shape[1:]),
tf.keras.layers.Dense(units=64, activation='relu'),
tf.keras.layers.Dropout(rate=0.2),
tf.keras.layers.Dense(units=64, activation='relu'),
tf.keras.layers.Dropout(rate=0.2),
tf.keras.layers.Dense(units=1, activation='sigmoid')])# Obtén las probabilidades de salida
out_probs = model(X_train.astype(np.float32), training=True)print(out_probs)Con la tecnología de
tf.Tensor([[1.][0.12573627][1.]...[1.][1.][1.]], shape=(26048,1), dtype=float32)Con la tecnología de
En el ejemplo anterior pasas los datos de entrenamiento por el model para obtener probabilidades crudas. Es solo una forward pass. Por supuesto, puedes entrenar el modelo:
model.compile(loss='binary_crossentropy', optimizer='adam')
model.fit(X_train, y_train,
validation_data=(X_test, y_test),
epochs=5, batch_size=64)Con la tecnología de
Train on 26048 samples, validate on 6513 samples
Epoch 1/526048/26048[==============================]- 2s 62us/sample - loss:79.5270- val_loss:0.7142
Epoch 2/526048/26048[==============================]- 1s 48us/sample - loss:2.0096- val_loss:0.5894
Epoch 3/526048/26048[==============================]- 1s 47us/sample - loss:0.8750- val_loss:0.5761
Epoch 4/526048/26048[==============================]- 1s 49us/sample - loss:0.6650- val_loss:0.5629
Epoch 5/526048/26048[==============================]- 1s 47us/sample - loss:0.6885- val_loss:0.5539<tensorflow.python.keras.callbacks.History at 0x7fc2b1944780>Con la tecnología de
Puedes listar los parámetros entrenables del modelo, capa a capa, así:
# Parámetros entrenables del modelo por capas
model.trainable_variables
Con la tecnología de
En investigación y también en entornos industriales, a menudo necesitas escribir capas personalizadas para casos de uso concretos. TensorFlow 2.0 lo pone muy fácil para crear una capa a medida y combinarla con las existentes. También puedes personalizar la pasada hacia delante de tu modelo como quieras.
Para crear una capa personalizada, lo más sencillo es extender la clase Layer de tf.keras.layers y definirla. Crearás una capa propia y después definirás sus cálculos en la forward pass. Este es el resultado de ejecutar help(tf.keras.layers.Layer), donde verás qué debes especificar para lograrlo:
Siguiendo esas indicaciones, vas a:
Definir el constructor con el número de salidas
En el método build() añadir los pesos de tu capa
Y en call() definir la forward pass encadenando la multiplicación de matrices y relu()
classMyDenseLayer(tf.keras.layers.Layer):# Define el constructordef__init__(self, num_outputs):super(MyDenseLayer, self).__init__()
self.num_outputs = num_outputs
# Añade los pesos en builddefbuild(self, input_shape):
self.kernel = self.add_variable("kernel",
shape=[input_shape[-1],
self.num_outputs])# Define la pasada hacia delantedefcall(self,input):
matmul = tf.matmul(input, self.kernel)return tf.nn.relu(matmul)# Inicializa la capa con 10 unidades de salida
layer = MyDenseLayer(10)# Proporciona la forma de entrada
layer(tf.random.uniform((10,3)))# Muestra los parámetros entrenables de la capaprint(layer.trainable_variables)Con la tecnología de
[<tf.Variable 'my_dense_layer_7/kernel:0' shape=(3,10) dtype=float32, numpy=array([[0.43613756,0.21344548,0.37803996,0.65583944,0.11884308,0.13909656,0.30802298,0.5313586,0.04967308,0.32889426],[0.1680265,-0.59944266,-0.4014195,0.14887196,0.07071263,0.37862527,-0.5822403,-0.5963166,0.3106798,0.05353856],[-0.44345278,-0.23122305,-0.62959856,-0.43062705,0.13194847,-0.60124606,-0.62745696,0.12254918,-0.09806103,-0.45324165]],
dtype=float32)>]Con la tecnología de
Puedes componer múltiples capas extendiendo la clase Model de tf.keras. Más información sobre cómo componer modelos aquí.
5. Flexibilidad en el entrenamiento de modelos
TensorFlow puede usar diferenciación automática para calcular los gradientes de la función de pérdida respecto a los parámetros del modelo. tf.GradientTape crea un contexto de cinta que TensorFlow usa para registrar los gradientes de cada operación. Para entenderlo, definamos un modelo a bajo nivel extendiendo tf.keras.Model.
from tensorflow.keras import Model
classCustomModel(Model):def__init__(self):super(CustomModel, self).__init__()
self.do1 = tf.keras.layers.Dropout(rate=0.2, input_shape=(14,))
self.fc1 = tf.keras.layers.Dense(units=64, activation='relu')
self.do2 = tf.keras.layers.Dropout(rate=0.2)
self.fc2 = tf.keras.layers.Dense(units=64, activation='relu')
self.do3 = tf.keras.layers.Dropout(rate=0.2)
self.out = tf.keras.layers.Dense(units=1, activation='sigmoid')defcall(self, x):
x = self.do1(x)
x = self.fc1(x)
x = self.do2(x)
x = self.fc2(x)
x = self.do3(x)return self.out(x)
model = CustomModel()Con la tecnología de
La topología de este modelo es exactamente la misma que definiste antes. Para entrenarlo con diferenciación automática, define la función de pérdida y el optimizador de forma explícita:
loss_func = tf.keras.losses.BinaryCrossentropy()
optimizer = tf.keras.optimizers.Adam()Con la tecnología de
Ahora define las métricas para medir el rendimiento durante el entrenamiento: pérdida y accuracy del modelo.
# Media de la pérdida por batch dentro de cada epoch
train_loss = tf.keras.metrics.Mean(name='train_loss')
train_acc = tf.keras.metrics.BinaryAccuracy(name='train_acc')
valid_loss = tf.keras.metrics.Mean(name='test_loss')
valid_acc = tf.keras.metrics.BinaryAccuracy(name='valid_acc')Con la tecnología de
tf.data ofrece utilidades para definir pipelines de entrada de datos. Es especialmente útil con grandes volúmenes de datos.
Ahora define el generador que creará batches durante el entrenamiento.
X_train, X_test = X_train.astype(np.float32), X_test.astype(np.float32)
y_train, y_test = y_train.astype(np.int64), y_test.astype(np.int64)
y_train, y_test = y_train.reshape(-1,1), y_test.reshape(-1,1)# Batches de 64
train_ds = tf.data.Dataset.from_tensor_slices((X_train, y_train)).batch(64)
test_ds = tf.data.Dataset.from_tensor_slices((X_test, y_test)).batch(64)Con la tecnología de
Ya puedes entrenar el modelo con tf.GradientTape. Primero define un método que entrene el modelo con los datos generados por tf.data.DataSet. Envuelve los pasos de entrenamiento con el decorador tf.function para aprovechar su aceleración.
Entrenamiento y validación del modelo
# Entrena el modelo@tf.functiondefmodel_train(features, labels):# Define el contexto de GradientTapewith tf.GradientTape()as tape:# Obtén las probabilidades
predictions = model(features)# Calcula la pérdida
loss = loss_func(labels, predictions)# Obtén los gradientes
gradients = tape.gradient(loss, model.trainable_variables)# Actualiza los pesos
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
train_loss(loss)
train_acc(labels, predictions)Con la tecnología de
# Valida el modelo@tf.functiondefmodel_validate(features, labels):
predictions = model(features)
t_loss = loss_func(labels, predictions)
valid_loss(t_loss)
valid_acc(labels, predictions)Con la tecnología de
Usa los dos métodos anteriores para entrenar y validar el modelo durante 5 epochs.
for epoch inrange(5):for features, labels in train_ds:
model_train(features, labels)for test_features, test_labels in test_ds:
model_validate(test_features, test_labels)
template ='Epoch {}, train_loss: {}, train_acc: {}, train_loss: {}, test_acc: {}'print(template.format(epoch+1,
train_loss.result(),
train_acc.result()*100,
valid_loss.result(),
valid_acc.result()*100))Con la tecnología de
Epoch 1,train_loss:9.8155517578125,train_acc:66.32754516601562,train_loss:2.8762073516845703,test_acc:78.96514892578125
Epoch 2,train_loss:10.235926628112793,train_acc:67.04353332519531,train_loss:3.508544921875,test_acc:79.0572738647461
Epoch 3,train_loss:8.876679420471191,train_acc:67.97962951660156,train_loss:4.440890789031982,test_acc:78.7348403930664
Epoch 4,train_loss:8.136384963989258,train_acc:68.46015167236328,train_loss:3.812603235244751,test_acc:73.58360290527344
Epoch 5,train_loss:7.779866695404053,train_acc:68.70469665527344,train_loss:3.80180025100708,test_acc:74.73975372314453Con la tecnología de
Este ejemplo está inspirado en este ejemplo de los autores de TensorFlow 2.0.
6. TensorFlow Datasets
Un módulo aparte llamado DataSets se usa para operar con el modelo de forma elegante. Ya lo viste en el ejemplo anterior. En esta sección, verás cómo cargar MNIST justo como necesitas.
Puedes instalar la librería tensorflow_datasets con pip. Una vez instalada, listo. Proporciona varias funciones útiles para construir con flexibilidad tu pipeline de datos. Puedes aprender más aquí y aquí. Ahora verás cómo montar un pipeline de entrada para cargar MNIST.
import tensorflow_datasets as tfds
# Obtén la clase DatasetBuilder por cadena
mnist_builder = tfds.builder("mnist")# Descarga el dataset
mnist_builder.download_and_prepare()# Construye un tf.data.Dataset: train y test
ds_train, ds_test = mnist_builder.as_dataset(split=[tfds.Split.TRAIN, tfds.Split.TEST])Con la tecnología de
Puedes ignorar el warning. Fíjate en lo bien que tensorflow_datasets gestiona el pipeline.
# Prepara batches de 128 del conjunto de entrenamiento
ds_train = ds_train.batch(128)# Carga el dataset de la forma más simplefor features in ds_train:
image, label = features["image"], features["label"]Con la tecnología de
Ahora puedes mostrar la primera imagen del lote cargado. Nota: tensorflow_datasets funciona tanto en modo eager como con grafos.
import matplotlib.pyplot as plt
%matplotlib inline
# Convierte un tensor de TensorFlow con# .numpy()
plt.imshow(image[0].numpy().reshape(28,28), cmap=plt.cm.binary)
plt.show()Con la tecnología de
7. Política de precisión mixta automática
La política de precisión mixta fue propuesta por NVIDIA el año pasado. El artículo original está aquí. La idea es combinar media precisión (FP16) y precisión completa (FP32) para aprovechar lo mejor de ambas. Ha mostrado resultados espectaculares entrenando redes neuronales muy profundas (en tiempo y en puntuación).
Si trabajas en un entorno GPU con CUDA (por ejemplo, generación Volta o Tesla T4) y has instalado la variante GPU de TensorFlow 2.0, puedes indicar a TensorFlow que entrene en precisión mixta así:
Esto convertirá automáticamente las operaciones del grafo según convenga. Verás un buen aumento de rendimiento. También puedes optimizar operaciones core de TensorFlow con precisión mixta. Consulta este artículo para saber más.
TensorFlow 2.0 facilita muchísimo distribuir el entrenamiento en varias GPUs. Es especialmente útil en producción cuando hay que soportar cargas muy altas. Basta con meter el bloque de entrenamiento dentro de un bloque with.
Primero, define una estrategia de distribución así:
La estrategia mirrored crea una réplica por GPU y las variables del modelo se reflejan por igual. Ahora puedes usarla de este modo:
with mirrored_strategy.scope():
model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
model.compile(loss='mse', optimizer='sgd')
model.fit(X_train, y_train,
validation_data=(X_test, y_test),
batch_size=128,
epochs=10)Con la tecnología de
Nota: este código solo será útil si tienes varias GPUs en un mismo sistema. Hay varias estrategias de distribución que puedes configurar. Más información aquí.
9. TensorBoard dentro de Jupyter Notebook
Probablemente, la parte más emocionante de esta actualización. Puedes visualizar el entrenamiento directamente en tu Jupyter Notebook con TensorBoard. El nuevo TensorBoard viene cargado de funciones como perfiles de memoria, visualización de imágenes (incluida la matriz de confusión), grafo conceptual del modelo y mucho más. Más detalles aquí.
En esta sección configurarás el entorno para que TensorBoard se muestre dentro de Jupyter Notebook. Primero carga la extensión tensorboard.notebook:
Ahora define el callback de TensorBoard con el módulo tf.keras.callbacks.
from datetime import datetime
import os
# Crea un directorio para los logs de entrenamiento
os.mkdir("logs")# Configura el callback
logdir ="logs"
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=logdir)Con la tecnología de
Reconstruye el modelo con la API Sequential de tf.keras:
# Define el modelo
model = tf.keras.Sequential([
tf.keras.layers.Dropout(rate=0.2, input_shape=X_train.shape[1:]),
tf.keras.layers.Dense(units=64, activation='relu'),
tf.keras.layers.Dropout(rate=0.2),
tf.keras.layers.Dense(units=64, activation='relu'),
tf.keras.layers.Dropout(rate=0.2),
tf.keras.layers.Dense(units=1, activation='sigmoid')])# Compila el modelo
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])Con la tecnología de
Como hemos modificado los conjuntos para distintos usos, conviene volver a dividirlos:
# Split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=7)Con la tecnología de
Todo listo para entrenar el modelo:
# Extensión de TensorBoard%tensorboard --logdir logs/# Pasa el callback de TensorBoard
model.fit(X_train, y_train,
validation_data=(X_test, y_test),
batch_size=64,
epochs=10,
callbacks=[tensorboard_callback],
verbose=False)Con la tecnología de
<iframe
width="100%"
height="800"
src="http://localhost:6006"
frameborder="0"
allowfullscreen
></iframe><tensorflow.python.keras.callbacks.History at 0x7fc215b69400>Con la tecnología de
El panel de TensorBoard debería cargarse en tu Jupyter Notebook y podrás seguir las métricas de entrenamiento y validación.
10. TensorFlow para Swift
A pesar de su enorme éxito, hay algo que entristece de Python: es lento. Para ayudar a investigadores, practicantes e incluso principiantes, el equipo de TensorFlow ha desarrollado una versión para Swift. Aunque no está tan lista para producción como la de Python, tiene mucho potencial. Swift permite interacciones más de bajo nivel y módulos avanzados de compilación. Aquí encontrarás todo sobre la variante de TensorFlow para Swift. Te recomendamos también esta entrevista de Jeremy Howard con Josh Gordon, donde Jeremy comparte su visión al respecto.
¿Y ahora qué?
Has llegado al final del artículo. La belleza del deep learning está en su aplicación. Tu siguiente paso debería ser probar e integrar las ideas comentadas aquí. Esta actualización de TensorFlow es, sin duda, de las más completas y amigables para desarrolladores. Te animamos a ver esta lista de reproducción del Dev Summit de TensorFlow de este año, con novedades sobre TensorFlow lattice, TensorFlow probability, TensorFlow lite y más.
Si quieres reforzar tus conocimientos de deep learning, echa un vistazo a estos cursos:
Proyectos de machine learning para principiantes, estudiantes de último año y profesionales. La lista incluye proyectos guiados, tutoriales y código fuente de ejemplo.
Descubre todo lo que necesitas saber sobre los tipos de modelos de machine learning, incluyendo para qué se utilizan y ejemplos de cómo ponerlos en práctica.
Aprende a ajustar Llama-2 en Colab utilizando nuevas técnicas para superar las limitaciones de memoria y computación y hacer más accesibles los grandes modelos lingüísticos de código abierto.
Comprender y aplicar el optimizador Adam en Python. Aprende la intuición, las matemáticas y las aplicaciones prácticas del aprendizaje automático con PyTorch
Ya está disponible
TensorFlow 2.0 alpha. Este framework ha tenido un gran impacto en la comunidad de deep learning. Practicantes, investigadores y desarrolladores lo han adoptado como nunca. Es, sin duda, uno de los principales motores detrás del despegue de muchas de las aplicaciones con deep learning que vemos hoy. Dicho esto,TensorFlow 1.xtambién tenía sus contras (como muchos otros frameworks). Como dijo Martin Wicke (ingeniero de software del equipo deTensorFlow) durante el TF Dev Summit '19:Con todas las lecciones aprendidas de su amplia base de usuarios y de los issues en GitHub, el equipo de
TensorFlowlanzóTensorFlow 2.0 alphacon un buen número de cambios importantes para mejorar el rendimiento, la experiencia de uso y más. Te permite crear prototipos rápidos e incorpora muchas prácticas modernas de deep learning. En este artículo verás algunas de estas novedades con implementaciones concretas.Nota: las actualizaciones comentadas son, a juicio del autor, las más relevantes. Necesitarás experiencia previa con
TensorFlowyKeraspara seguir el artículo. Estos recursos pueden venirte bien si quieres refrescarTensorFlowyKeras:Instalación y un dataset de demostración
Para actualizar a
TensorFlow 2.0ejecuta esta línea en un Jupyter Notebook:!pip install tensorflow==2.0.0-alpha0La variante para GPU se instala igual (requiere tener CUDA previamente):
!pip install tensorflow-gpu==2.0.0-alpha0Puedes consultar más detalles del proceso de instalación aquí.
Algunas de las novedades que verás incluyen implementaciones de código. En esos casos necesitarás un dataset. En este artículo usaremos el dataset Adult del archivo UCI.
Este dataset plantea una clasificación binaria: predecir si una persona ganará más de 50.000 $ al año o no a partir de varios datos personales.
Hagamos un preprocesado básico y preparemos los splits en una proporción 80:20:
A estas alturas deberías tener un entorno funcional con
TensorFlow 2.0instalado y el dataset cargado en tu espacio de trabajo. Ya puedes pasar a las novedades.1. Eager execution por defecto
En
TensorFlow 2.0ya no necesitas crear una sesión y ejecutar el grafo computacional dentro de ella. La ejecución eager está activada por defecto en la versión 2.0 para que puedas construir y ejecutar tus modelos al instante. Si lo prefieres, puedes desactivarla así:tf.compat.v1.disable_eager_execution()(si has importadotensorflowcomotf).Aquí tienes una pequeña comparación en código que ilustra la diferencia:
2. tf.function y AutoGraph
Aunque la ejecución eager permite programación imperativa, para entrenamiento distribuido, optimización a gran escala y producción, la ejecución por grafos al estilo de
TensorFlow 1.xtiene ventajas. EnTensorFlow 2.0mantienes la ejecución basada en grafos, pero de forma más flexible. Se consigue contf.functionyAutoGraph.tf.functionte permite definir grafos deTensorFlowcon sintaxis de Python gracias aAutoGraph.AutoGraphsoporta buena parte del lenguaje Python, comoif,for,while,iteradores, etc. Hay limitaciones, eso sí. Aquí puedes ver la lista completa de compatibilidades disponibles. Abajo tienes un ejemplo que muestra lo sencillo que es definir un grafo deTensorFlowcon un simpledecorator.Fíjate en que no has tenido que crear sesiones ni placeholders para ejecutar
single_layer(). Esta es una de las ventajas detf.function. Por debajo, aplica las optimizaciones necesarias para que tu código vaya más rápido.3.
tf.variable_scopeya no es necesarioEn
TensorFlow 1.x, para usartf.layerscomo variables y reutilizarlas, debías usar el bloquetf.variable. EnTensorFlow 2.0ya no hace falta. Al estarkerascomo API de alto nivel central enTensorFlow 2.0, todas las capas creadas contf.layerspueden integrarse fácilmente en una definicióntf.keras.Sequential. El código se vuelve más legible y, además, puedes llevar control de variables y pérdidas.Un ejemplo:
En el ejemplo anterior pasas los datos de entrenamiento por el
modelpara obtener probabilidades crudas. Es solo una forward pass. Por supuesto, puedes entrenar el modelo:Puedes listar los parámetros entrenables del modelo, capa a capa, así:
4. Capas personalizadas, ahora mucho más fácil
En investigación y también en entornos industriales, a menudo necesitas escribir capas personalizadas para casos de uso concretos.
TensorFlow 2.0lo pone muy fácil para crear una capa a medida y combinarla con las existentes. También puedes personalizar la pasada hacia delante de tu modelo como quieras.Para crear una capa personalizada, lo más sencillo es extender la clase
Layerdetf.keras.layersy definirla. Crearás una capa propia y después definirás sus cálculos en la forward pass. Este es el resultado de ejecutarhelp(tf.keras.layers.Layer), donde verás qué debes especificar para lograrlo:Siguiendo esas indicaciones, vas a:
build()añadir los pesos de tu capacall()definir la forward pass encadenando la multiplicación de matrices yrelu()Puedes componer múltiples capas extendiendo la clase
Modeldetf.keras. Más información sobre cómo componer modelos aquí.5. Flexibilidad en el entrenamiento de modelos
TensorFlowpuede usar diferenciación automática para calcular los gradientes de la función de pérdida respecto a los parámetros del modelo.tf.GradientTapecrea un contexto de cinta queTensorFlowusa para registrar los gradientes de cada operación. Para entenderlo, definamos un modelo a bajo nivel extendiendotf.keras.Model.La topología de este modelo es exactamente la misma que definiste antes. Para entrenarlo con diferenciación automática, define la función de pérdida y el optimizador de forma explícita:
Ahora define las métricas para medir el rendimiento durante el entrenamiento: pérdida y accuracy del modelo.
tf.dataofrece utilidades para definir pipelines de entrada de datos. Es especialmente útil con grandes volúmenes de datos.Ahora define el generador que creará batches durante el entrenamiento.
Ya puedes entrenar el modelo con
tf.GradientTape. Primero define un método que entrene el modelo con los datos generados portf.data.DataSet. Envuelve los pasos de entrenamiento con el decoradortf.functionpara aprovechar su aceleración.Entrenamiento y validación del modelo
Usa los dos métodos anteriores para entrenar y validar el modelo durante 5 epochs.
Este ejemplo está inspirado en este ejemplo de los autores de
TensorFlow 2.0.6. TensorFlow Datasets
Un módulo aparte llamado
DataSetsse usa para operar con el modelo de forma elegante. Ya lo viste en el ejemplo anterior. En esta sección, verás cómo cargar MNIST justo como necesitas.Puedes instalar la librería
tensorflow_datasetsconpip. Una vez instalada, listo. Proporciona varias funciones útiles para construir con flexibilidad tu pipeline de datos. Puedes aprender más aquí y aquí. Ahora verás cómo montar un pipeline de entrada para cargar MNIST.Puedes ignorar el warning. Fíjate en lo bien que
tensorflow_datasetsgestiona el pipeline.Ahora puedes mostrar la primera imagen del lote cargado. Nota:
tensorflow_datasetsfunciona tanto en modo eager como con grafos.7. Política de precisión mixta automática
La política de precisión mixta fue propuesta por NVIDIA el año pasado. El artículo original está aquí. La idea es combinar media precisión (FP16) y precisión completa (FP32) para aprovechar lo mejor de ambas. Ha mostrado resultados espectaculares entrenando redes neuronales muy profundas (en tiempo y en puntuación).
Si trabajas en un entorno GPU con CUDA (por ejemplo, generación Volta o Tesla T4) y has instalado la variante GPU de
TensorFlow 2.0, puedes indicar aTensorFlowque entrene en precisión mixta así:os.environ['TF_ENABLE_AUTO_MIXED_PRECISION'] = '1'Esto convertirá automáticamente las operaciones del grafo según convenga. Verás un buen aumento de rendimiento. También puedes optimizar operaciones core de TensorFlow con precisión mixta. Consulta este artículo para saber más.
Ten en cuenta que esta función solo está soportada en el contenedor Docker de TensorFlow de NVIDIA. Para integrar entrenamiento de precisión mixta de forma nativa en tf.keras, te sugiero revisar este artículo. Gracias a Abhishek Thanki por señalarlo.
8. Entrenamiento distribuido
TensorFlow 2.0facilita muchísimo distribuir el entrenamiento en varias GPUs. Es especialmente útil en producción cuando hay que soportar cargas muy altas. Basta con meter el bloque de entrenamiento dentro de un bloquewith.Primero, define una estrategia de distribución así:
mirrored_strategy = tf.distribute.MirroredStrategy()La estrategia mirrored crea una réplica por GPU y las variables del modelo se reflejan por igual. Ahora puedes usarla de este modo:
Nota: este código solo será útil si tienes varias GPUs en un mismo sistema. Hay varias estrategias de distribución que puedes configurar. Más información aquí.
9. TensorBoard dentro de Jupyter Notebook
Probablemente, la parte más emocionante de esta actualización. Puedes visualizar el entrenamiento directamente en tu Jupyter Notebook con
TensorBoard. El nuevoTensorBoardviene cargado de funciones como perfiles de memoria, visualización de imágenes (incluida la matriz de confusión), grafo conceptual del modelo y mucho más. Más detalles aquí.En esta sección configurarás el entorno para que
TensorBoardse muestre dentro de Jupyter Notebook. Primero carga la extensióntensorboard.notebook:Ahora define el callback de
TensorBoardcon el módulotf.keras.callbacks.Reconstruye el modelo con la API
Sequentialdetf.keras:Como hemos modificado los conjuntos para distintos usos, conviene volver a dividirlos:
Todo listo para entrenar el modelo:
El panel de
TensorBoarddebería cargarse en tu Jupyter Notebook y podrás seguir las métricas de entrenamiento y validación.10. TensorFlow para Swift
A pesar de su enorme éxito, hay algo que entristece de Python: es lento. Para ayudar a investigadores, practicantes e incluso principiantes, el equipo de
TensorFlowha desarrollado una versión para Swift. Aunque no está tan lista para producción como la de Python, tiene mucho potencial. Swift permite interacciones más de bajo nivel y módulos avanzados de compilación. Aquí encontrarás todo sobre la variante de TensorFlow para Swift. Te recomendamos también esta entrevista de Jeremy Howard con Josh Gordon, donde Jeremy comparte su visión al respecto.¿Y ahora qué?
Has llegado al final del artículo. La belleza del deep learning está en su aplicación. Tu siguiente paso debería ser probar e integrar las ideas comentadas aquí. Esta actualización de
TensorFlowes, sin duda, de las más completas y amigables para desarrolladores. Te animamos a ver esta lista de reproducción del Dev Summit deTensorFlowde este año, con novedades sobreTensorFlow lattice,TensorFlow probability,TensorFlow litey más.Si quieres reforzar tus conocimientos de deep learning, echa un vistazo a estos cursos:
¡Feliz
eager_executing!