{"id":"tensorboard","name":"tensorboard","summary":"トレーニング指標の可視化、ヒストグラムによるモデルのデバッグ、実験の比較、モデルグラフの可視化、パフォーマンスのプロファイリング(GoogleのMLビジュアライゼーションツールキット)を使ったTensorBoardで行えます","body":"# TensorBoard: Visualization Toolkit for ML\n\n## When to Use This Skill\n\nUse TensorBoard when you need to:\n- **Visualize training metrics** like loss and accuracy over time\n- **Debug models** with histograms and distributions\n- **Compare experiments** across multiple runs\n- **Visualize model graphs** and architecture\n- **Project embeddings** to lower dimensions (t-SNE, PCA)\n- **Track hyperparameter** experiments\n- **Profile performance** and identify bottlenecks\n- **Visualize images and text** during training\n\n**Users**: 20M+ downloads/year | **GitHub Stars**: 27k+ | **License**: Apache 2.0\n\n## Installation\n\n```bash\n# Install TensorBoard\npip install tensorboard\n\n# PyTorch integration\npip install torch torchvision tensorboard\n\n# TensorFlow integration (TensorBoard included)\npip install tensorflow\n\n# Launch TensorBoard\ntensorboard --logdir=runs\n# Access at http://localhost:6006\n```\n\n## Quick Start\n\n### PyTorch\n\n```python\nfrom torch.utils.tensorboard import SummaryWriter\n\n# Create writer\nwriter = SummaryWriter('runs/experiment_1')\n\n# Training loop\nfor epoch in range(10):\n    train_loss = train_epoch()\n    val_acc = validate()\n\n    # Log metrics\n    writer.add_scalar('Loss/train', train_loss, epoch)\n    writer.add_scalar('Accuracy/val', val_acc, epoch)\n\n# Close writer\nwriter.close()\n\n# Launch: tensorboard --logdir=runs\n```\n\n### TensorFlow/Keras\n\n```python\nimport tensorflow as tf\n\n# Create callback\ntensorboard_callback = tf.keras.callbacks.TensorBoard(\n    log_dir='logs/fit',\n    histogram_freq=1\n)\n\n# Train model\nmodel.fit(\n    x_train, y_train,\n    epochs=10,\n    validation_data=(x_val, y_val),\n    callbacks=[tensorboard_callback]\n)\n\n# Launch: tensorboard --logdir=logs\n```\n\n## Core Concepts\n\n### 1. SummaryWriter (PyTorch)\n\n```python\nfrom torch.utils.tensorboard import SummaryWriter\n\n# Default directory: runs/CURRENT_DATETIME\nwriter = SummaryWriter()\n\n# Custom directory\nwriter = SummaryWriter('runs/experiment_1')\n\n# Custom comment (appended to default directory)\nwriter = SummaryWriter(comment='baseline')\n\n# Log data\nwriter.add_scalar('Loss/train', 0.5, step=0)\nwriter.add_scalar('Loss/train', 0.3, step=1)\n\n# Flush and close\nwriter.flush()\nwriter.close()\n```\n\n### 2. Logging Scalars\n\n```python\n# PyTorch\nfrom torch.utils.tensorboard import SummaryWriter\nwriter = SummaryWriter()\n\nfor epoch in range(100):\n    train_loss = train()\n    val_loss = validate()\n\n    # Log individual metrics\n    writer.add_scalar('Loss/train', train_loss, epoch)\n    writer.add_scalar('Loss/val', val_loss, epoch)\n    writer.add_scalar('Accuracy/train', train_acc, epoch)\n    writer.add_scalar('Accuracy/val', val_acc, epoch)\n\n    # Learning rate\n    lr = optimizer.param_groups[0]['lr']\n    writer.add_scalar('Learning_rate', lr, epoch)\n\nwriter.close()\n```\n\n```python\n# TensorFlow\nimport tensorflow as tf\n\ntrain_summary_writer = tf.summary.create_file_writer('logs/train')\nval_summary_writer = tf.summary.create_file_writer('logs/val')\n\nfor epoch in range(100):\n    with train_summary_writer.as_default():\n        tf.summary.scalar('loss', train_loss, step=epoch)\n        tf.summary.scalar('accuracy', train_acc, step=epoch)\n\n    with val_summary_writer.as_default():\n        tf.summary.scalar('loss', val_loss, step=epoch)\n        tf.summary.scalar('accuracy', val_acc, step=epoch)\n```\n\n### 3. Logging Multiple Scalars\n\n```python\n# PyTorch: Group related metrics\nwriter.add_scalars('Loss', {\n    'train': train_loss,\n    'validation': val_loss,\n    'test': test_loss\n}, epoch)\n\nwriter.add_scalars('Metrics', {\n    'accuracy': accuracy,\n    'precision': precision,\n    'recall': recall,\n    'f1': f1_score\n}, epoch)\n```\n\n### 4. Logging Images\n\n```python\n# PyTorch\nimport torch\nfrom torchvision.utils import make_grid\n\n# Single image\nwriter.add_image('Input/sample', img_tensor, epoch)\n\n# Multiple images as grid\nimg_grid = make_grid(images[:64], nrow=8)\nwriter.add_image('Batch/inputs', img_grid, epoch)\n\n# Predictions visualization\npred_grid = make_grid(predictions[:16], nrow=4)\nwriter.add_image('Predictions', pred_grid, epoch)\n```\n\n```python\n# TensorFlow\nimport tensorflow as tf\n\nwith file_writer.as_default():\n    # Encode images as PNG\n    tf.summary.image('Training samples', images, step=epoch, max_outputs=25)\n```\n\n### 5. Logging Histograms\n\n```python\n# PyTorch: Track weight distributions\nfor name, param in model.named_parameters():\n    writer.add_histogram(name, param, epoch)\n\n    # Track gradients\n    if param.grad is not None:\n        writer.add_histogram(f'{name}.grad', param.grad, epoch)\n\n# Track activations\nwriter.add_histogram('Activations/relu1', activations, epoch)\n```\n\n```python\n# TensorFlow\nwith file_writer.as_default():\n    tf.summary.histogram('weights/layer1', layer1.kernel, step=epoch)\n    tf.summary.histogram('activations/relu1', activations, step=epoch)\n```\n\n### 6. Logging Model Graph\n\n```python\n# PyTorch\nimport torch\n\nmodel = MyModel()\ndummy_input = torch.randn(1, 3, 224, 224)\n\nwriter.add_graph(model, dummy_input)\nwriter.close()\n```\n\n```python\n# TensorFlow (automatic with Keras)\ntensorboard_callback = tf.keras.callbacks.TensorBoard(\n    log_dir='logs',\n    write_graph=True\n)\n\nmodel.fit(x, y, callbacks=[tensorboard_callback])\n```\n\n## Advanced Features\n\n### Embedding Projector\n\nVisualize high-dimensional data (embeddings, features) in 2D/3D.\n\n```python\nimport torch\nfrom torch.utils.tensorboard import SummaryWriter\n\n# Get embeddings (e.g., word embeddings, image features)\nembeddings = model.get_embeddings(data)  # Shape: (N, embedding_dim)\n\n# Metadata (labels for each point)\nmetadata = ['class_1', 'class_2', 'class_1', ...]\n\n# Images (optional, for image embeddings)\nlabel_images = torch.stack([img1, img2, img3, ...])\n\n# Log to TensorBoard\nwriter.add_embedding(\n    embeddings,\n    metadata=metadata,\n    label_img=label_images,\n    global_step=epoch\n)\n```\n\n**In TensorBoard:**\n- Navigate to \"Projector\" tab\n- Choose PCA, t-SNE, or UMAP visualization\n- Search, filter, and explore clusters\n\n### Hyperparameter Tuning\n\n```python\nfrom torch.utils.tensorboard import SummaryWriter\n\n# Try different hyperparameters\nfor lr in [0.001, 0.01, 0.1]:\n    for batch_size in [16, 32, 64]:\n        # Create unique run directory\n        writer = SummaryWriter(f'runs/lr{lr}_bs{batch_size}')\n\n        # Log hyperparameters\n        writer.add_hparams(\n            {'lr': lr, 'batch_size': batch_size},\n            {'hparam/accuracy': final_acc, 'hparam/loss': final_loss}\n        )\n\n        # Train and log\n        for epoch in range(10):\n            loss = train(lr, batch_size)\n            writer.add_scalar('Loss/train', loss, epoch)\n\n        writer.close()\n\n# Compare in TensorBoard's \"HParams\" tab\n```\n\n### Text Logging\n\n```python\n# PyTorch: Log text (e.g., model predictions, summaries)\nwriter.add_text('Predictions', f'Epoch {epoch}: {predictions}', epoch)\nwriter.add_text('Config', str(config), 0)\n\n# Log markdown tables\nmarkdown_table = \"\"\"\n| Metric | Value |\n|--------|-------|\n| Accuracy | 0.95 |\n| F1 Score | 0.93 |\n\"\"\"\nwriter.add_text('Results', markdown_table, epoch)\n```\n\n### PR Curves\n\nPrecision-Recall curves for classification.\n\n```python\nfrom torch.utils.tensorboard import SummaryWriter\n\n# Get predictions and labels\npredictions = model(test_data)  # Shape: (N, num_classes)\nlabels = test_labels  # Shape: (N,)\n\n# Log PR curve for each class\nfor i in range(num_classes):\n    writer.add_pr_curve(\n        f'PR_curve/class_{i}',\n        labels == i,\n        predictions[:, i],\n        global_step=epoch\n    )\n```\n\n## Integration Examples\n\n### PyTorch Training Loop\n\n```python\nimport torch\nimport torch.nn as nn\nfrom torch.utils.tensorboard import SummaryWriter\n\n# Setup\nwriter = SummaryWriter('runs/resnet_experiment')\nmodel = ResNet50()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001)\ncriterion = nn.CrossEntropyLoss()\n\n# Log model graph\ndummy_input = torch.randn(1, 3, 224, 224)\nwriter.add_graph(model, dummy_input)\n\n# Training loop\nfor epoch in range(50):\n    model.train()\n    train_loss = 0.0\n    train_correct = 0\n\n    for batch_idx, (data, target) in enumerate(train_loader):\n        optimizer.zero_grad()\n        output = model(data)\n        loss = criterion(output, target)\n        loss.backward()\n        optimizer.step()\n\n        train_loss += loss.item()\n        pred = output.argmax(dim=1)\n        train_correct += pred.eq(target).sum().item()\n\n        # Log batch metrics (every 100 batches)\n        if batch_idx % 100 == 0:\n            global_step = epoch * len(train_loader) + batch_idx\n            writer.add_scalar('Loss/train_batch', loss.item(), global_step)\n\n    # Epoch metrics\n    train_loss /= len(train_loader)\n    train_acc = train_correct / len(train_loader.dataset)\n\n    # Validation\n    model.eval()\n    val_loss = 0.0\n    val_correct = 0\n\n    with torch.no_grad():\n        for data, target in val_loader:\n            output = model(data)\n            val_loss += criterion(output, target).item()\n            pred = output.argmax(dim=1)\n            val_correct += pred.eq(target).sum().item()\n\n    val_loss /= len(val_loader)\n    val_acc = val_correct / len(val_loader.dataset)\n\n    # Log epoch metrics\n    writer.add_scalars('Loss', {'train': train_loss, 'val': val_loss}, epoch)\n    writer.add_scalars('Accuracy', {'train': train_acc, 'val': val_acc}, epoch)\n\n    # Log learning rate\n    writer.add_scalar('Learning_rate', optimizer.param_groups[0]['lr'], epoch)\n\n    # Log histograms (every 5 epochs)\n    if epoch % 5 == 0:\n        for name, param in model.named_parameters():\n            writer.add_histogram(name, param, epoch)\n\n    # Log sample predictions\n    if epoch % 10 == 0:\n        sample_images = data[:8]\n        writer.add_image('Sample_inputs', make_grid(sample_images), epoch)\n\nwriter.close()\n```\n\n### TensorFlow/Keras Training\n\n```python\nimport tensorflow as tf\n\n# Define model\nmodel = tf.keras.models.Sequential([\n    tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),\n    tf.keras.layers.MaxPooling2D(),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(128, activation='relu'),\n    tf.keras.layers.Dense(10, activation='softmax')\n])\n\nmodel.compile(\n    optimizer='adam',\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)\n\n# TensorBoard callback\ntensorboard_callback = tf.keras.callbacks.TensorBoard(\n    log_dir='logs/fit',\n    histogram_freq=1,          # Log histograms every epoch\n    write_graph=True,          # Visualize model graph\n    write_images=True,         # Visualize weights as images\n    update_freq='epoch',       # Log metrics every epoch\n    profile_batch='500,520',   # Profile batches 500-520\n    embeddings_freq=1          # Log embeddings every epoch\n)\n\n# Train\nmodel.fit(\n    x_train, y_train,\n    epochs=10,\n    validation_data=(x_val, y_val),\n    callbacks=[tensorboard_callback]\n)\n```\n\n## Comparing Experiments\n\n### Multiple Runs\n\n```bash\n# Run experiments with different configs\npython train.py --lr 0.001 --logdir runs/exp1\npython train.py --lr 0.01 --logdir runs/exp2\npython train.py --lr 0.1 --logdir runs/exp3\n\n# View all runs together\ntensorboard --logdir=runs\n```\n\n**In TensorBoard:**\n- All runs appear in the same dashboard\n- Toggle runs on/off for comparison\n- Use regex to filter run names\n- Overlay charts to compare metrics\n\n### Organizing Experiments\n\n```python\n# Hierarchical organization\nruns/\n├── baseline/\n│   ├── run_1/\n│   └── run_2/\n├── improved/\n│   ├── run_1/\n│   └── run_2/\n└── final/\n    └── run_1/\n\n# Log with hierarchy\nwriter = SummaryWriter('runs/baseline/run_1')\n```\n\n## Best Practices\n\n### 1. Use Descriptive Run Names\n\n```python\n# ✅ Good: Descriptive names\nfrom datetime import datetime\ntimestamp = datetime.now().strftime('%Y%m%d_%H%M%S')\nwriter = SummaryWriter(f'runs/resnet50_lr0.001_bs32_{timestamp}')\n\n# ❌ Bad: Auto-generated names\nwriter = SummaryWriter()  # Creates runs/Jan01_12-34-56_hostname\n```\n\n### 2. Group Related Metrics\n\n```python\n# ✅ Good: Grouped metrics\nwriter.add_scalar('Loss/train', train_loss, step)\nwriter.add_scalar('Loss/val', val_loss, step)\nwriter.add_scalar('Accuracy/train', train_acc, step)\nwriter.add_scalar('Accuracy/val', val_acc, step)\n\n# ❌ Bad: Flat namespace\nwriter.add_scalar('train_loss', train_loss, step)\nwriter.add_scalar('val_loss', val_loss, step)\n```\n\n### 3. Log Regularly but Not Too Often\n\n```python\n# ✅ Good: Log epoch metrics always, batch metrics occasionally\nfor epoch in range(100):\n    for batch_idx, (data, target) in enumerate(train_loader):\n        loss = train_step(data, target)\n\n        # Log every 100 batches\n        if batch_idx % 100 == 0:\n            writer.add_scalar('Loss/batch', loss, global_step)\n\n    # Always log epoch metrics\n    writer.add_scalar('Loss/epoch', epoch_loss, epoch)\n\n# ❌ Bad: Log every batch (creates huge log files)\nfor batch in train_loader:\n    writer.add_scalar('Loss', loss, step)  # Too frequent\n```\n\n### 4. Close Writer When Done\n\n```python\n# ✅ Good: Use context manager\nwith SummaryWriter('runs/exp1') as writer:\n    for epoch in range(10):\n        writer.add_scalar('Loss', loss, epoch)\n# Automatically closes\n\n# Or manually\nwriter = SummaryWriter('runs/exp1')\n# ... logging ...\nwriter.close()\n```\n\n### 5. Use Separate Writers for Train/Val\n\n```python\n# ✅ Good: Separate log directories\ntrain_writer = SummaryWriter('runs/exp1/train')\nval_writer = SummaryWriter('runs/exp1/val')\n\ntrain_writer.add_scalar('loss', train_loss, epoch)\nval_writer.add_scalar('loss', val_loss, epoch)\n```\n\n## Performance Profiling\n\n### TensorFlow Profiler\n\n```python\n# Enable profiling\ntensorboard_callback = tf.keras.callbacks.TensorBoard(\n    log_dir='logs',\n    profile_batch='10,20'  # Profile batches 10-20\n)\n\nmodel.fit(x, y, callbacks=[tensorboard_callback])\n\n# View in TensorBoard Profile tab\n# Shows: GPU utilization, kernel stats, memory usage, bottlenecks\n```\n\n### PyTorch Profiler\n\n```python\nimport torch.profiler as profiler\n\nwith profiler.profile(\n    activities=[\n        profiler.ProfilerActivity.CPU,\n        profiler.ProfilerActivity.CUDA\n    ],\n    on_trace_ready=torch.profiler.tensorboard_trace_handler('./runs/profiler'),\n    record_shapes=True,\n    with_stack=True\n) as prof:\n    for batch in train_loader:\n        loss = train_step(batch)\n        prof.step()\n\n# View in TensorBoard Profile tab\n```\n\n## Resources\n\n- **Documentation**: https://www.tensorflow.org/tensorboard\n- **PyTorch Integration**: https://pytorch.org/docs/stable/tensorboard.html\n- **GitHub**: https://github.com/tensorflow/tensorboard (27k+ stars)\n- **TensorBoard.dev**: https://tensorboard.dev (share experiments publicly)\n\n## See Also\n\n- `references/visualization.md` - Comprehensive visualization guide\n- `references/profiling.md` - Performance profiling patterns\n- `references/integrations.md` - Framework-specific integration examples","author":"@Orchestra-Research","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/Orchestra-Research/AI-Research-SKILLs/tree/main/13-mlops/tensorboard","license":"MIT","category":"coding","lang":"en","tokens":3708,"stars":0,"calls30d":2,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/integrations.md","size":16205,"sha256":"a647d47e9589eb7abbbcb494fc2c8f21c2b8cab1fee3a59e30cab4b81014cd4a"},{"path":"references/profiling.md","size":13337,"sha256":"1471302d589c00c3bd9d0247008d732e4f446842692b2dc4587ec8278acd33d8"},{"path":"references/visualization.md","size":14897,"sha256":"0e5ef61808dc0bb1d3820a0695aa86a4af6659f1ba2324204953b84dda6f3815"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[{"code":"code.eval","kind":"dangerous-code","where":"SKILL.md:382","excerpt":"eval(","message":"evaluates code at runtime","severity":"warn"},{"code":"code.eval","kind":"dangerous-code","where":"references/profiling.md:76","excerpt":"eval(","message":"evaluates code at runtime","severity":"warn"},{"code":"code.eval","kind":"dangerous-code","where":"references/visualization.md:318","excerpt":"eval(","message":"evaluates code at runtime","severity":"warn"}],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["developer.nvidia.com","docs.fast.ai","huggingface.co","pytorch-lightning.readthedocs.io","pytorch.org","tensorboard.dev","www.tensorflow.org"]}}