tutorial - ¿Una forma sencilla de visualizar un gráfico TensorFlow en Jupyter?
tensorflow tutorial español (7)
La forma oficial de visualizar un gráfico TensorFlow es con TensorBoard, pero a veces solo quiero un vistazo rápido al gráfico cuando estoy trabajando en Jupyter.
¿Existe una solución rápida, idealmente basada en herramientas TensorFlow, o paquetes estándar de SciPy (como matplotlib), pero si es necesario basado en bibliotecas de terceros?
Aquí hay una receta que copié de uno de los cuadernos de sueños profundos de Alex Mordvintsev en algún momento
from IPython.display import clear_output, Image, display, HTML
import numpy as np
def strip_consts(graph_def, max_const_size=32):
"""Strip large constant values from graph_def."""
strip_def = tf.GraphDef()
for n0 in graph_def.node:
n = strip_def.node.add()
n.MergeFrom(n0)
if n.op == ''Const'':
tensor = n.attr[''value''].tensor
size = len(tensor.tensor_content)
if size > max_const_size:
tensor.tensor_content = "<stripped %d bytes>"%size
return strip_def
def show_graph(graph_def, max_const_size=32):
"""Visualize TensorFlow graph."""
if hasattr(graph_def, ''as_graph_def''):
graph_def = graph_def.as_graph_def()
strip_def = strip_consts(graph_def, max_const_size=max_const_size)
code = """
<script>
function load() {{
document.getElementById("{id}").pbtxt = {data};
}}
</script>
<link rel="import" href="https://tensorboard.appspot.com/tf-graph-basic.build.html" onload=load()>
<div style="height:600px">
<tf-graph-basic id="{id}"></tf-graph-basic>
</div>
""".format(data=repr(str(strip_def)), id=''graph''+str(np.random.rand()))
iframe = """
<iframe seamless style="width:1200px;height:620px;border:0" srcdoc="{}"></iframe>
""".format(code.replace(''"'', ''"''))
display(HTML(iframe))
Luego para visualizar el gráfico actual
show_graph(tf.get_default_graph().as_graph_def())
Si su gráfico se guarda como pbtxt, podría hacer
gdef = tf.GraphDef()
from google.protobuf import text_format
text_format.Merge(open("tf_persistent.pbtxt").read(), gdef)
show_graph(gdef)
Verás algo como esto
Escribí un simple ayudante que inicia un tensorboard desde el cuaderno jupyter. Simplemente agregue esta función en algún lugar en la parte superior de su computadora portátil
def TB(cleanup=False):
import webbrowser
webbrowser.open(''http://127.0.1.1:6006'')
!tensorboard --logdir="logs"
if cleanup:
!rm -R logs/
Y luego ejecútelo
TB()
siempre que genere sus resúmenes.
En lugar de abrir un gráfico en la misma ventana de jupyter:
- comienza un tensorboard
- abre una nueva pestaña con tensorboard
- navegar a esta pestaña
Una vez que haya terminado con la exploración, simplemente haga clic en la pestaña y deje de interrumpir el núcleo.
Si desea limpiar su directorio de registro, después de la ejecución, simplemente ejecute
TB(1)
Escribí una extensión de Jupyter para la integración de tensorboard. Puede:
- Inicie el tensorboard simplemente haciendo clic en un botón en Jupyter
- Gestionar múltiples instancias de tensorboard.
- Integración perfecta con la interfaz Jupyter.
Una versión gratuita de Tensorboard / iframes de esta visualización que ciertamente se abarrota rápidamente puede
import pydot
from itertools import chain
def tf_graph_to_dot(in_graph):
dot = pydot.Dot()
dot.set(''rankdir'', ''LR'')
dot.set(''concentrate'', True)
dot.set_node_defaults(shape=''record'')
all_ops = in_graph.get_operations()
all_tens_dict = {k: i for i,k in enumerate(set(chain(*[c_op.outputs for c_op in all_ops])))}
for c_node in all_tens_dict.keys():
node = pydot.Node(c_node.name)#, label=label)
dot.add_node(node)
for c_op in all_ops:
for c_output in c_op.outputs:
for c_input in c_op.inputs:
dot.add_edge(pydot.Edge(c_input.name, c_output.name))
return dot
que luego puede ser seguido por
from IPython.display import SVG
# Define model
tf_graph_to_dot(graph).write_svg(''simple_tf.svg'')
SVG(''simple_tf.svg'')
para representar el gráfico como registros en un archivo SVG estático
TensorBoard Visualizar nodos - Gráfico de arquitectura
<img src="https://www.tensorflow.org/images/graph_vis_animation.gif" width=1300 height=680>
TensorFlow 2.0
ahora admite
TensorBoard
en
Jupyter
mediante comandos mágicos (por ejemplo,
%tensorboard --logdir logs/train
).
Aquí hay un
link
a tutoriales y ejemplos.
[EDICIONES 1, 2]
Como @MiniQuark mencionó en un comentario, primero debemos cargar la extensión (
%load_ext tensorboard.notebook
).
A continuación se presentan ejemplos de uso para usar el
modo gráfico
,
@tf.function
y
tf.keras
(en
tensorflow==2.0.0-alpha0
):
1. Ejemplo usando el
modo gráfico
en TF2 (a través de
tf.compat.v1.disable_eager_execution()
)
%load_ext tensorboard.notebook
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
from tensorflow.python.ops.array_ops import placeholder
from tensorflow.python.training.gradient_descent import GradientDescentOptimizer
from tensorflow.python.summary.writer.writer import FileWriter
with tf.name_scope(''inputs''):
x = placeholder(tf.float32, shape=[None, 2], name=''x'')
y = placeholder(tf.int32, shape=[None], name=''y'')
with tf.name_scope(''logits''):
layer = tf.keras.layers.Dense(units=2)
logits = layer(x)
with tf.name_scope(''loss''):
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)
loss_op = tf.reduce_mean(xentropy)
with tf.name_scope(''optimizer''):
optimizer = GradientDescentOptimizer(0.01)
train_op = optimizer.minimize(loss_op)
FileWriter(''logs/train'', graph=train_op.graph).close()
%tensorboard --logdir logs/train
2. Mismo ejemplo que el anterior pero ahora usando el decorador
@tf.function
para pases hacia adelante y hacia atrás y sin deshabilitar la ejecución ansiosa:
%load_ext tensorboard.notebook
import tensorflow as tf
import numpy as np
logdir = ''logs/''
writer = tf.summary.create_file_writer(logdir)
tf.summary.trace_on(graph=True, profiler=True)
@tf.function
def forward_and_backward(x, y, w, b, lr=tf.constant(0.01)):
with tf.name_scope(''logits''):
logits = tf.matmul(x, w) + b
with tf.name_scope(''loss''):
loss_fn = tf.nn.sparse_softmax_cross_entropy_with_logits(
labels=y, logits=logits)
reduced = tf.reduce_sum(loss_fn)
with tf.name_scope(''optimizer''):
grads = tf.gradients(reduced, [w, b])
_ = [x.assign(x - g*lr) for g, x in zip(grads, [w, b])]
return reduced
# inputs
x = tf.convert_to_tensor(np.ones([1, 2]), dtype=tf.float32)
y = tf.convert_to_tensor(np.array([1]))
# params
w = tf.Variable(tf.random.normal([2, 2]), dtype=tf.float32)
b = tf.Variable(tf.zeros([1, 2]), dtype=tf.float32)
loss_val = forward_and_backward(x, y, w, b)
with writer.as_default():
tf.summary.trace_export(
name=''NN'',
step=0,
profiler_outdir=logdir)
%tensorboard --logdir logs/
3. Usando la API
tf.keras
:
%load_ext tensorboard.notebook
import tensorflow as tf
import numpy as np
x_train = [np.ones((1, 2))]
y_train = [np.ones(1)]
model = tf.keras.models.Sequential([tf.keras.layers.Dense(2, input_shape=(2, ))])
model.compile(
optimizer=''sgd'',
loss=''sparse_categorical_crossentropy'',
metrics=[''accuracy''])
logdir = "logs/"
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=logdir)
model.fit(x_train,
y_train,
batch_size=1,
epochs=1,
callbacks=[tensorboard_callback])
%tensorboard --logdir logs/
Estos ejemplos producirán algo como esto debajo de la celda:
Código
def tb(logdir="logs", port=6006, open_tab=True, sleep=2):
import subprocess
proc = subprocess.Popen(
"tensorboard --logdir={0} --port={1}".format(logdir, port), shell=True)
if open_tab:
import time
time.sleep(sleep)
import webbrowser
webbrowser.open("http://127.0.0.1:{}/".format(port))
return proc
Uso
tb() # Starts a TensorBoard server on the logs directory, on port 6006
# and opens a new tab in your browser to use it.
tb("logs2", 6007) # Starts a second server on the logs2 directory, on port 6007,
# and opens a new tab to use it.
El inicio de un servidor no bloquea a Jupyter (excepto durante 2 segundos para garantizar que el servidor tenga tiempo para iniciarse antes de abrir una pestaña). Todos los servidores de TensorBoard se detendrán cuando interrumpa el núcleo.
Uso avanzado
Si desea más control, puede matar los servidores mediante programación de esta manera:
server1 = tb()
server2 = tb("logs2", 6007)
# and later...
server1.kill() # stops the first server
server2.kill() # stops the second server
Puede configurar
open_tab=False
si no desea que se abran nuevas pestañas.
También puede establecer la
sleep
en algún otro valor si 2 segundos es demasiado o no es suficiente en su sistema.
Si prefiere pausar Jupyter mientras TensorBoard se está ejecutando, puede llamar al método
wait()
cualquier servidor.
Esto bloqueará a Jupyter hasta que interrumpa el kernel, lo que detendrá este servidor y todos los demás.
server1.wait()
Prerrequisitos
Esta solución supone que ha instalado TensorBoard (p. Ej., Utilizando
pip install tensorboard
) y que está disponible en el entorno en el que inició Jupyter.
Reconocimiento
Esta respuesta fue inspirada por la respuesta de @ SalvadorDali. Su solución es agradable y simple, pero quería poder iniciar múltiples instancias de tensorboard sin bloquear Jupyter. Además, prefiero no eliminar los directorios de registro. En cambio, inicio tensorboard en el directorio de registro raíz, y cada ejecución de TensorFlow se registra en un subdirectorio diferente.