VisualDL: Visualization Tool for Deep Learning Experiments

Introduction

VisualDL is a visualization tool designed for deep learning tasks, featuring scalar trends, parameter distributions, model structures, and image visualization. It enables “what you see is what you get”—allowing you to observe training processes, analyze models, and improve convergence.

Key Features:

  1. Scalar: Trend graphs for training/test errors
  2. Image: Visualization for convolutional layers/parameters
  3. Histogram: Parameter distribution and trend analysis
  4. Graph: Model structure visualization

Images from VisualDL GitHub

Installation

System: Ubuntu (Mac similar)

1. Install via pip

pip3 install --upgrade visualdl

Test Installation:

# Download sample log
vdl_create_scratch_log

# Start VisualDL server
visualdl --logdir=scratch_log/ --port=8080

Troubleshooting: If you encounter a protobuf version error:

# Upgrade protobuf
pip3 install protobuf -U

Open http://127.0.0.1:8080 in your browser to access the dashboard.

2. Install from Source

# Dependencies
apt install npm nodejs-legacy cmake unzip

# Clone repo
git clone https://github.com/PaddlePaddle/VisualDL.git
cd VisualDL

# Build wheel
python3 setup.py bdist_wheel

# Install wheel
pip3 install --upgrade dist/visualdl-*.whl

Basic Usage

Example Code: test_visualdl.py

from visualdl import LogWriter

# Initialize log writer (sync every 1000 writes)
logw = LogWriter("./random_log", sync_cycle=10000)

# Create scalar records for train/test
with logw.mode('train') as logger:
    scalar_train = logger.scalar("scratch/scalar")

with logw.mode('test') as logger:
    scalar_test = logger.scalar("scratch/scalar")

# Generate dummy data
for step in range(1000):
    scalar_train.add_record(step, step * 1. / 1000)
    scalar_test.add_record(step, 1. - step * 1. / 1000)

Run & Visualize:

# Start VisualDL
visualdl --logdir=random_log/ --port=8080

Open http://127.0.0.1:8080 to view the generated graphs.

Using VisualDL with PaddlePaddle

Step 1: Define MobileNet V2 Model

# mobilenet_v2.py
import paddle.fluid as fluid

def conv_bn_layer(input, num_filters, filter_size, stride, padding, num_groups=1, if_act=True):
    conv = fluid.layers.conv2d(
        input=input, num_filters=num_filters, filter_size=filter_size,
        stride=stride, padding=padding, groups=num_groups, bias_attr=False
    )
    bn = fluid.layers.batch_norm(input=conv)
    return fluid.layers.relu6(bn) if if_act else bn

def inverted_residual_unit(...):
    # Implement bottleneck layers as per MobileNet V2 specs
    ...

def net(input, class_dim=10):
    # Build model architecture
    ...
    return fluid.layers.fc(input=feature, size=class_dim, act='softmax')

Step 2: Training with VisualDL Logging

# train.py
import paddle.fluid as fluid
from visualdl import LogWriter
import mobilenet_v2

# Initialize VisualDL logger
log_writer = LogWriter(dir='log/', sync_cycle=10)

# Define logging components
with log_writer.mode('train') as writer:
    train_cost = writer.scalar('cost')
    train_acc = writer.scalar('accuracy')
    weight_hist = writer.histogram('weights', num_buckets=50)

with log_writer.mode('test') as writer:
    test_cost = writer.scalar('cost')
    test_acc = writer.scalar('accuracy')

# Model definition
image = fluid.layers.data(name='image', shape=[3, 32, 32], dtype='float32')
label = fluid.layers.data(name='label', shape=[1], dtype='int64')
model = mobilenet_v2.net(image, 10)

# Loss and optimizer
cost = fluid.layers.cross_entropy(input=model, label=label)
avg_cost = fluid.layers.mean(cost)
acc = fluid.layers.accuracy(input=model, label=label)

# Training loop
train_reader = paddle.batch(cifar.train10(), batch_size=32)
test_reader = paddle.batch(cifar.test10(), batch_size=32)

exe = fluid.Executor(fluid.CUDAPlace(0))
exe.run(fluid.default_startup_program())

for pass_id in range(10):
    for batch_id, data in enumerate(train_reader()):
        train_cost_val, train_acc_val, params = exe.run(
            program=fluid.default_main_program(),
            feed=fluid.DataFeeder(place=fluid.CUDAPlace(0), feed_list=[image, label]).feed(data),
            fetch_list=[avg_cost, acc, fluid.default_startup_program().global_block().all_parameters()[0].name]
        )
        train_cost.add_record(batch_id, train_cost_val[0])
        train_acc.add_record(batch_id, train_acc_val[0])
        weight_hist.add_record(batch_id, params.flatten())
        if batch_id % 100 == 0:
            print(f"Pass {pass_id}, Batch {batch_id}, Cost: {train_cost_val[0]:.4f}")

Start Training:

visualdl --logdir=log/ --port=8080

Visualization Dashboard

Key Metrics:

  1. Training/Test Loss: Track convergence
  2. Accuracy Trends: Identify overfitting
  3. Weight Histograms: Monitor parameter stability
  4. Model Structure: Verify architecture correctness

Example Screenshots:
- Loss Curves: Shows training loss decreasing while test loss plateaus (overfitting risk)
- Histogram: Weight distribution stabilizes after 5 epochs
- Model Graph: Confirm MobileNet V2 layers are correctly formed

Reference

  1. VisualDL GitHub
  2. PaddlePaddle Official Docs
  3. VisualDL User Guide

Previous: Transfer Learning with PaddlePaddle

Next: Custom Image Dataset Recognition

Xiaoye