Model Analysis API
This module provides comprehensive model analysis capabilities for PyTorch models.
Core Functions
Classes
Function Details
analyze_model
- analyze_model(model, input_shape=None, detailed=True)
Analyze a PyTorch model and return detailed statistics.
Parameters:
model (torch.nn.Module): PyTorch model to analyze
input_shape (tuple, optional): Input tensor shape
detailed (bool, optional): Whether to include detailed layer analysis (default: True)
Returns: dict - Dictionary containing model analysis with keys:
basic_info (dict): Basic model information * total_parameters (int): Total number of parameters * trainable_parameters (int): Number of trainable parameters * total_layers (int): Total number of layers * device (str): Device the model is on * model_mode (str): Model mode (training/evaluation)
memory (dict): Memory usage information * parameters_mb (float): Parameter memory in MB * activations_mb (float): Activation memory in MB * input_mb (float): Input memory in MB * total_memory_mb (float): Total memory in MB
architecture (dict): Architecture analysis * depth (int): Network depth * conv_layers (int): Number of convolutional layers * linear_layers (int): Number of linear layers * norm_layers (int): Number of normalization layers * patterns (list): Detected architectural patterns
Raises:
ImportError: If PyTorch is not available
Example:
import torch.nn as nn from pytorch-graph import analyze_model model = nn.Sequential( nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 10) ) # Analyze model structure analysis = analyze_model(model, input_shape=(1, 784)) print(f"Total parameters: {analysis['basic_info']['total_parameters']:,}") print(f"Model size: {analysis['memory']['total_memory_mb']:.2f} MB")
profile_model
- profile_model(model, input_shape, device='cpu')
Profile a PyTorch model for performance analysis.
Parameters:
model (torch.nn.Module): PyTorch model to profile
input_shape (tuple): Input tensor shape
device (str, optional): Device to run profiling on (‘cpu’ or ‘cuda’, default: ‘cpu’)
Returns: dict - Profiling results dictionary with keys:
mean_time_ms (float): Mean inference time in milliseconds
std_time_ms (float): Standard deviation of inference time
min_time_ms (float): Minimum inference time in milliseconds
max_time_ms (float): Maximum inference time in milliseconds
fps (float): Frames per second (throughput)
memory_usage (dict): Memory usage statistics
execution_times (list): List of individual execution times
Raises:
ImportError: If PyTorch is not available
Example:
from pytorch-graph import profile_model profiling_results = profile_model( model=model, input_shape=(1, 784), device='cpu' ) print(f"Average inference time: {profiling_results['mean_time_ms']:.2f} ms") print(f"Throughput: {profiling_results['fps']:.1f} FPS")
extract_activations
- extract_activations(model, input_tensor, layer_names=None)
Extract intermediate activations from a PyTorch model.
Parameters:
model (torch.nn.Module): PyTorch model to extract activations from
input_tensor (torch.Tensor): Input tensor for forward pass
layer_names (list, optional): Specific layer names to extract (if None, extracts all)
Returns: dict - Dictionary of layer names to activation tensors
Raises:
ImportError: If PyTorch is not available
Example:
import torch from pytorch-graph import extract_activations input_tensor = torch.randn(1, 784) activations = extract_activations( model=model, input_tensor=input_tensor, layer_names=['0', '2'] # Extract from specific layers ) for layer_name, activation in activations.items(): print(f"{layer_name}: {activation.shape}")
ModelAnalyzer Class
- class ModelAnalyzer
Comprehensive model analysis and profiling class.
Methods:
- analyze(model, input_shape=None, detailed=True, device='auto')
Perform comprehensive analysis of the PyTorch model.
Parameters:
model (torch.nn.Module): PyTorch model to analyze
input_shape (tuple, optional): Input tensor shape
detailed (bool, optional): Whether to include detailed analysis (default: True)
device (str, optional): Device for analysis (‘auto’, ‘cpu’, ‘cuda’, default: ‘auto’)
Returns: dict - Dictionary containing comprehensive analysis
- profile_model(model, input_shape, device='cpu', num_runs=100)
Profile PyTorch model performance.
Parameters:
model (torch.nn.Module): PyTorch model to profile
input_shape (tuple): Input tensor shape
device (str, optional): Device for profiling (default: ‘cpu’)
num_runs (int, optional): Number of timing runs (default: 100)
Returns: dict - Dictionary with profiling results
- get_layer_info(model, input_shape=None)
Get detailed information about each layer in the model.
Parameters:
model (torch.nn.Module): PyTorch model
input_shape (tuple, optional): Input tensor shape
Returns: list - List of layer information dictionaries
- calculate_memory_usage(model, input_shape)
Calculate memory usage for the model.
Parameters:
model (torch.nn.Module): PyTorch model
input_shape (tuple): Input tensor shape
Returns: dict - Memory usage information
- detect_architecture_patterns(model)
Detect common architectural patterns in the model.
Parameters:
model (torch.nn.Module): PyTorch model
Returns: list - List of detected patterns
Examples
Basic Model Analysis
import torch.nn as nn
from pytorch-graph import analyze_model
model = nn.Sequential(
nn.Linear(784, 128),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(128, 64),
nn.ReLU(),
nn.Linear(64, 10)
)
# Analyze model structure
analysis = analyze_model(model, input_shape=(1, 784))
# Basic information
basic_info = analysis['basic_info']
print(f"Total parameters: {basic_info['total_parameters']:,}")
print(f"Trainable parameters: {basic_info['trainable_parameters']:,}")
print(f"Total layers: {basic_info['total_layers']}")
# Memory usage
memory_info = analysis['memory']
print(f"Model size: {memory_info['total_memory_mb']:.2f} MB")
# Architecture analysis
arch_info = analysis['architecture']
print(f"Network depth: {arch_info['depth']}")
print(f"Linear layers: {arch_info['linear_layers']}")
Performance Profiling
from pytorch-graph import profile_model
# Profile model performance
profiling_results = profile_model(
model=model,
input_shape=(1, 784),
device='cpu'
)
print(f"Average inference time: {profiling_results['mean_time_ms']:.2f} ms")
print(f"Standard deviation: {profiling_results['std_time_ms']:.2f} ms")
print(f"Min time: {profiling_results['min_time_ms']:.2f} ms")
print(f"Max time: {profiling_results['max_time_ms']:.2f} ms")
print(f"Throughput: {profiling_results['fps']:.1f} FPS")
Activation Extraction
import torch
from pytorch-graph import extract_activations
input_tensor = torch.randn(1, 784)
# Extract activations from all layers
all_activations = extract_activations(model, input_tensor)
for layer_name, activation in all_activations.items():
print(f"Layer {layer_name}: {activation.shape}")
# Extract from specific layers
specific_activations = extract_activations(
model=model,
input_tensor=input_tensor,
layer_names=['0', '3', '5'] # First, fourth, and sixth layers
)
Advanced Usage with ModelAnalyzer
from pytorch-graph import ModelAnalyzer
# Create analyzer
analyzer = ModelAnalyzer()
# Comprehensive analysis
analysis = analyzer.analyze(
model=model,
input_shape=(1, 784),
detailed=True,
device='auto'
)
# Get layer information
layer_info = analyzer.get_layer_info(model, input_shape=(1, 784))
for layer in layer_info:
print(f"Layer: {layer['name']}, Type: {layer['type']}, Parameters: {layer['parameters']}")
# Calculate memory usage
memory_usage = analyzer.calculate_memory_usage(model, input_shape=(1, 784))
print(f"Parameter memory: {memory_usage['parameters_mb']:.2f} MB")
print(f"Activation memory: {memory_usage['activations_mb']:.2f} MB")
# Detect patterns
patterns = analyzer.detect_architecture_patterns(model)
print(f"Detected patterns: {patterns}")
Model Comparison
def compare_models(models, input_shapes, names=None):
"""Compare multiple models."""
if names is None:
names = [f"Model_{i+1}" for i in range(len(models))]
results = {}
for name, (model, input_shape) in zip(names, zip(models, input_shapes)):
# Analyze model
analysis = analyze_model(model, input_shape=input_shape)
# Profile performance
profiling = profile_model(model, input_shape, device='cpu')
results[name] = {
'parameters': analysis['basic_info']['total_parameters'],
'model_size': analysis['memory']['total_memory_mb'],
'inference_time': profiling['mean_time_ms'],
'throughput': profiling['fps']
}
# Print comparison
print("Model Comparison:")
print("-" * 50)
for name, metrics in results.items():
print(f"{name}:")
print(f" Parameters: {metrics['parameters']:,}")
print(f" Model Size: {metrics['model_size']:.2f} MB")
print(f" Inference Time: {metrics['inference_time']:.2f} ms")
print(f" Throughput: {metrics['throughput']:.1f} FPS")
print()
return results
# Example usage
models = [mlp_model, cnn_model, resnet_model]
input_shapes = [(1, 784), (1, 3, 32, 32), (1, 3, 224, 224)]
names = ["MLP", "CNN", "ResNet"]
comparison_results = compare_models(models, input_shapes, names)
Memory Analysis
def analyze_memory_usage(model, input_shape):
"""Analyze memory usage patterns."""
analysis = analyze_model(model, input_shape=input_shape)
memory_info = analysis['memory']
print("Memory Analysis:")
print(f" Parameter memory: {memory_info['parameters_mb']:.2f} MB")
print(f" Activation memory: {memory_info['activations_mb']:.2f} MB")
print(f" Input memory: {memory_info['input_mb']:.2f} MB")
print(f" Total memory: {memory_info['total_memory_mb']:.2f} MB")
# Memory efficiency
param_ratio = memory_info['parameters_mb'] / memory_info['total_memory_mb']
activation_ratio = memory_info['activations_mb'] / memory_info['total_memory_mb']
print(f" Parameter ratio: {param_ratio:.1%}")
print(f" Activation ratio: {activation_ratio:.1%}")
return memory_info
# Analyze memory
memory_analysis = analyze_memory_usage(model, input_shape=(1, 784))
Layer-wise Analysis
def analyze_layers(model, input_shape):
"""Get detailed layer analysis."""
analyzer = ModelAnalyzer()
layer_info = analyzer.get_layer_info(model, input_shape)
print("Layer-wise Analysis:")
print("-" * 30)
for layer in layer_info:
print(f"\nLayer: {layer['name']}")
print(f" Type: {layer['type']}")
print(f" Parameters: {layer['parameters']:,}")
print(f" Input shape: {layer.get('input_shape', 'N/A')}")
print(f" Output shape: {layer.get('output_shape', 'N/A')}")
if 'memory_usage' in layer:
print(f" Memory: {layer['memory_usage']:.2f} MB")
return layer_info
# Analyze layers
layer_analysis = analyze_layers(model, input_shape=(1, 784))
Error Handling
The functions will raise appropriate exceptions for:
ImportError: If PyTorch is not available
RuntimeError: If model execution fails
ValueError: If invalid parameters are provided
TypeError: If model is not a PyTorch module
See Also
architecture_visualization - For architecture diagram generation
computational_graph_tracking - For computational graph analysis
Utilities API - For utility classes and functions