Tutorial 4: Export, Save & Integration Workflows#
Estimated time: 25 minutes
Learn how to save visualizations in different formats, integrate them into ML workflows, and batch process model visualizations.
Overview#
In this tutorial, you’ll learn how to:
Save visualizations in multiple file formats (PNG, SVG, PDF)
Optimize output quality and file size
Integrate visualizations into training pipelines
Batch process multiple models
Reproduce visualizations reliably
File Format Options#
visualkeras generates PIL Image objects that can be saved in any format PIL supports.
PNG — Best for web and general use
import visualkeras
from tensorflow import keras
model = keras.Sequential([
keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Flatten(),
keras.layers.Dense(10, activation='softmax')
])
# PNG with default quality
image = visualkeras.show(model, mode='layered')
image.save('model_architecture.png')
# For higher quality PNG with better compression
image.save('model_architecture_hq.png', quality=95, optimize=True)
SVG — Best for scalable, editable diagrams
SVG (Scalable Vector Graphics) output is useful when you need to edit the visualization later or want unlimited scaling without quality loss:
# Convert PIL Image to SVG using cairosvg (install: pip install cairosvg)
import io
from PIL import Image
image = visualkeras.show(model, mode='layered')
# Save as PNG first, then convert to SVG
png_buffer = io.BytesIO()
image.save(png_buffer, format='PNG')
png_buffer.seek(0)
# Or use external tools: convert model.png model.svg (ImageMagick)
image.save('model_architecture.png')
# Then: $ convert model_architecture.png model_architecture.svg
PDF — Best for documents and printing
# PDF output for papers and documents
image = visualkeras.show(model, mode='layered', preset='presentation')
image.save('model_architecture.pdf')
# For print-ready PDF with high DPI
# PIL doesn't support DPI in PDF directly, but you can resize
width, height = image.size
# Create high-DPI version (300 DPI)
dpi_scale = 2 # 2x for 300 DPI equivalent
hires_image = image.resize(
(width * dpi_scale, height * dpi_scale),
Image.Resampling.LANCZOS
)
hires_image.save('model_architecture_print.pdf')
Quality and Size Optimization#
Different use cases need different quality levels:
import visualkeras
# 1. Web use — optimize for small file size
image = visualkeras.show(model, mode='layered')
image.save('web_small.png', optimize=True) # ~100-300 KB
# 2. presentation — balance quality and size
image = visualkeras.show(model, mode='layered', preset='presentation')
image.save('presentation.png') # ~500 KB - 2 MB
# 3. Publication — maximum quality
image = visualkeras.show(model, mode='layered', preset='presentation')
image.save('publication.png', quality=95) # ~3-5 MB
# 4. Very large models — use compact preset
image = visualkeras.show(model, mode='layered', preset='compact')
image.save('compact.png', optimize=True) # Smaller & fits on screen
Saving Visualizations During Training#
Automatically save model visualizations at key checkpoints:
import os
import visualkeras
from tensorflow import keras
import tensorflow as tf
# Create output directory
os.makedirs('model_checkpoints', exist_ok=True)
# Custom callback to visualize model at checkpoints
class VisualizationCallback(keras.callbacks.Callback):
def __init__(self, save_dir='model_checkpoints'):
super().__init__()
self.save_dir = save_dir
def on_train_begin(self, logs=None):
# Save initial architecture
try:
image = visualkeras.show(self.model, mode='layered')
path = os.path.join(self.save_dir, 'initial_architecture.png')
image.save(path)
print(f"Saved initial architecture to {path}")
except Exception as e:
print(f"Could not visualize model: {e}")
def on_epoch_end(self, epoch, logs=None):
# Optionally save every N epochs
if (epoch + 1) % 10 == 0:
try:
image = visualkeras.show(self.model, mode='graph')
path = os.path.join(self.save_dir, f'architecture_epoch_{epoch+1}.png')
image.save(path)
print(f"Saved epoch {epoch+1} visualization")
except Exception:
pass # Skip if visualization fails
# Use the callback
model = keras.Sequential([...])
callback = VisualizationCallback()
model.fit(
x_train, y_train,
epochs=100,
callbacks=[callback],
)
Batch Processing Multiple Models#
Visualize entire model families consistently:
import visualkeras
from pathlib import Path
# Define model configurations
model_configs = [
{'name': 'small', 'filters': 32},
{'name': 'medium', 'filters': 64},
{'name': 'large', 'filters': 128},
]
# Output directory
output_dir = Path('model_visualizations')
output_dir.mkdir(exist_ok=True)
# Build and visualize each model
for config in model_configs:
model = keras.Sequential([
keras.layers.Conv2D(config['filters'], (3, 3),
activation='relu',
input_shape=(224, 224, 3)),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Conv2D(config['filters']*2, (3, 3),
activation='relu'),
keras.layers.Flatten(),
keras.layers.Dense(1000, activation='relu'),
keras.layers.Dense(10, activation='softmax'),
])
# Use consistent styling across all models
color_map = {
keras.layers.Conv2D: {'fill': '#3498db', 'outline': '#2980b9'},
keras.layers.MaxPooling2D: {'fill': '#2ecc71', 'outline': '#27ae60'},
keras.layers.Dense: {'fill': '#e74c3c', 'outline': '#c0392b'},
keras.layers.Flatten: {'fill': '#f39c12', 'outline': '#d68910'},
}
# Visualize with consistent options
image = visualkeras.show(
model,
mode='layered',
preset='presentation',
color_map=color_map
)
# Save with consistent naming
output_path = output_dir / f'{config["name"]}_architecture.png'
image.save(output_path, optimize=True)
print(f"✓ Saved {config['name']} model to {output_path}")
print(f"\nAll models saved to {output_dir}/")
Integration with Jupyter Notebooks#
Display visualizations directly in notebooks:
import visualkeras
from IPython.display import Image as IPImage, display
model = keras.Sequential([...])
# Method 1: Direct display (simplest)
image = visualkeras.show(model, mode='layered')
display(image)
# Method 2: Save and display via IPython
image.save('temp_model.png')
display(IPImage('temp_model.png'))
# Method 3: Multiple visualizations side-by-side
from IPython.display import HTML
import base64
import io
def image_to_base64(pil_image):
buffer = io.BytesIO()
pil_image.save(buffer, format='PNG')
buffer.seek(0)
return base64.b64encode(buffer.getvalue()).decode()
mode1 = visualkeras.show(model, mode='layered')
mode2 = visualkeras.show(model, mode='graph')
html = f"""
<div style="display: flex; gap: 20px;">
<div><h3>Layered View</h3><img src="data:image/png;base64,{image_to_base64(mode1)}"></div>
<div><h3>Graph View</h3><img src="data:image/png;base64,{image_to_base64(mode2)}"></div>
</div>
"""
display(HTML(html))
Reproducible Visualization Configurations#
Store and reuse visualization configurations:
import json
import visualkeras
from visualkeras.options import LayeredOptions
# Define a reusable configuration
paper_config = {
'mode': 'layered',
'preset': 'presentation',
'color_map': {
'Conv2D': {'fill': '#1f77b4', 'outline': '#0d47a1'},
'MaxPooling2D': {'fill': '#2ca02c', 'outline': '#1b5e20'},
'Dense': {'fill': '#d62728', 'outline': '#b71c1c'},
},
'padding': 20,
'spacing': 15,
}
# Save configuration
with open('paper_style.json', 'w') as f:
json.dump(paper_config, f, indent=2)
# Load and apply configuration
with open('paper_style.json', 'r') as f:
config = json.load(f)
image = visualkeras.show(model, **config)
image.save('paper_figure.png')
# Share configurations with team members
# They can load and use the same style:
# $ git clone repo
# $ python apply_style.py
Integration with Documentation Generators#
Automatically update documentation with current model architecture:
# docs/generate_archtecture_docs.py
import visualkeras
from pathlib import Path
import sys
# Add model path to sys.path
sys.path.insert(0, str(Path(__file__).parent.parent))
# Import your models
from models import create_encoder, create_decoder, create_full_model
# Generate documentation
doc_output = Path(__file__).parent / 'generated'
doc_output.mkdir(exist_ok=True)
models = {
'encoder': create_encoder(),
'decoder': create_decoder(),
'full_model': create_full_model(),
}
for name, model in models.items():
image = visualkeras.show(model, mode='graph', preset='presentation')
image.save(doc_output / f'{name}_architecture.png')
print(f"Generated {name}_architecture.png")
# Run as: python docs/generate_architecture_docs.py
# Then commit generated images to docs/generated/
Best Practices#
Use presets for consistency - Use
preset='presentation'for papers and documentation - Usepreset='compact'for web and tight spaces - Define custom presets for team standardsStore configurations in version control - Save color maps and options in JSON - Share across team members - Track changes to visualization standards
Batch before shipping - Generate all visualizations together - Use consistent styling across all images - Version images with your model releases
Automate visualization generation - Use callbacks during training - Generate in CI/CD pipelines - Update documentation automatically
Summary#
You’ve learned how to:
Export visualizations in multiple formats (PNG, SVG, PDF)
Optimize quality and file size for different use cases
Integrate visualizations into training workflows
Batch process multiple models consistently
Reproduce visualizations with configuration files
Automate documentation generation
Next, explore how to fix visualization issues and debug your models using visualkeras parameters in Tutorial 5: Debugging Visualizations with Parameters.