Two Approaches for Plotting Loss Curves in Caffe

Introduction

When training deep learning models with Caffe, visualizing the training progress through loss curves is essential for monitoring model convergence. This article presents two practical approaches for generating training visualizations.

Method 1: Custom Python Script for Headless Servers

The following implementation is specifically designed for server environments without a graphical desktop. All file paths in the solver configuration must be absolute paths.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib
matplotlib.use('Agg')
import sys
import numpy as np
import matplotlib.pyplot as plt

caffe_root = '/opt/caffe/'
sys.path.insert(0, caffe_root + 'python')
import caffe

caffe.set_mode_cpu()
solver = caffe.SGDSolver('/opt/caffe/examples/mnist/lenet_solver.prototxt')

# Configuration parameters
max_iterations = 2000
log_interval = 50
evaluation_interval = 500
evaluation_iterations = 100

# Initialize arrays for metrics
training_loss = np.zeros(int(np.ceil(max_iterations * 1.0 / log_interval)))
validation_loss = np.zeros(int(np.ceil(max_iterations * 1.0 / evaluation_interval)))
validation_accuracy = np.zeros(int(np.ceil(max_iterations * 1.0 / evaluation_interval)))

solver.step(1)
cumulative_train_loss = 0.0
cumulative_val_loss = 0.0
cumulative_accuracy = 0.0

for iteration in range(max_iterations):
    solver.step(1)
    cumulative_train_loss += solver.net.blobs['loss'].data
    
    if iteration % log_interval == 0:
        training_loss[iteration // log_interval] = cumulative_train_loss / log_interval
        cumulative_train_loss = 0.0
    
    if iteration % evaluation_interval == 0:
        for eval_iter in range(evaluation_iterations):
            solver.test_nets[0].forward()
            cumulative_val_loss += solver.test_nets[0].blobs['loss'].data
            cumulative_accuracy += solver.test_nets[0].blobs['accuracy'].data
        
        validation_loss[iteration // evaluation_interval] = cumulative_val_loss / evaluation_iterations
        validation_accuracy[iteration // evaluation_interval] = cumulative_accuracy / evaluation_iterations
        cumulative_val_loss = 0.0
        cumulative_accuracy = 0.0

# Generate visualization
plt.figure(figsize=(10, 6))
plt.plot(log_interval * np.arange(len(training_loss)), training_loss, 'g-', label='Training Loss')
plt.plot(evaluation_interval * np.arange(len(validation_loss)), validation_loss, 'y-', label='Validation Loss')
plt.plot(evaluation_interval * np.arange(len(validation_accuracy)), validation_accuracy, 'r-', label='Validation Accuracy')

plt.xlabel('Iteration')
plt.ylabel('Loss / Accuracy')
plt.legend()
plt.grid(True, alpha=0.3)
plt.savefig('/opt/caffe/examples/mnist/training_curves.png', dpi=150)
print("Training curves saved successfully")

Note: If you encounter a TypeError: 'numpy.float64' object cannot be interpreted as an index error, downgrade NumPy to version 1.11.0:

sudo pip install -U numpy==1.11.0

Method 2: Dual Axis Plotting with Matplotlib

This approach uses twinx() to display loss and accuracy on different y-axes within a single plot. Note that this method requires a desktop enviroment.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import sys

caffe_root = '/opt/caffe/'
sys.path.insert(0, caffe_root + 'python')
import caffe

caffe.set_mode_cpu()
solver = caffe.SGDSolver('/opt/caffe/examples/mnist/lenet_solver.prototxt')

# Training parameters
total_iterations = 2000
validation_interval = 250

# Pre-allocate arrays
training_losses = np.zeros(total_iterations)
validation_accuracies = np.zeros(int(np.ceil(total_iterations / validation_interval)))

# Main training loop
for iteration in range(total_iterations):
    solver.step(1)
    training_losses[iteration] = solver.net.blobs['loss'].data
    
    if iteration % validation_interval == 0:
        accuracy = solver.test_nets[0].blobs['accuracy'].data
        validation_accuracies[iteration // validation_interval] = accuracy
        print(f'Iteration {iteration}: Validation Accuracy = {accuracy:.4f}')

# Create dual-axis plot
fig, primary_axis = plt.subplots()
secondary_axis = primary_axis.twinx()

primary_axis.plot(np.arange(total_iterations), training_losses, 'b-', alpha=0.7, label='Training Loss')
secondary_axis.plot(
    validation_interval * np.arange(len(validation_accuracies)),
    validation_accuracies,
    'r-',
    linewidth=2,
    label='Validation Accuracy'
)

primary_axis.set_xlabel('Iteration')
primary_axis.set_ylabel('Training Loss', color='blue')
secondary_axis.set_ylabel('Validation Accuracy', color='red')
primary_axis.tick_params(axis='y', labelcolor='blue')
secondary_axis.tick_params(axis='y', labelcolor='red')

plt.title('Training Progress Visualization')
fig.legend(loc='upper right', bbox_to_anchor=(0.88, 0.88))
plt.tight_layout()
plt.show()

Method 3: Caffe's Built-in Logging Tools

Caffe provides auxiliary scripts for generating training logs and visualizations:

#!/bin/bash
# Generate timestamped log file
LOG_DIR="/opt/caffe/examples/mnist"
TIMESTAMP=$(date +%Y-%m-%d-%H-%M)
LOG_FILE="${LOG_DIR}/training_${TIMESTAMP}.log"

# Run training and capture output
cd /opt/caffe
./build/tools/caffe train --solver=examples/mnist/lenet_solver.prototxt 2>&1 | tee $LOG_FILE

Copy the required parsing scripts to your log directory:

cp /opt/caffe/tools/extra/parse_log.sh /opt/caffe/tools/extra/extract_seconds.py \
   /opt/caffe/tools/extra/plot_training_log.py.example /path/to/log/directory/

Generate the visualization plot:

python plot_training_log.py 6 training_plot.png training_log.log

Limitation: The built-in plotting tool has known accuracy issues with data processing, and certain parameter renges (4-7) may not function correctly.

Running Training in Background

For long-running training sessions via SSH, use the following command to ensure training continues even after disconnecting:

nohup python train_script.py > nohup_output.log 2>&1 &

This approach is particularly useful for extended training runs where connection stability cannot be guaranteed.

Tags: caffe deep-learning neural-network python matplotlib

Posted on Fri, 31 Jul 2026 16:19:59 +0000 by goldilok