PyHessian Documentation

repository·master·Indexed 21 days ago

https://github.com/amirgholami/pyhessian

A PyTorch library for Hessian-based analysis of neural network models. It provides tools to compute eigenvalues, the Hessian trace, and Eigenvalue Spectral Density (ESD) using randomized linear algebra, such as Hutchinson's method and the Stochastic Lanczos algorithm, enabling analysis of loss landscape flatness without explicitly forming the full Hessian matrix.

Tokens
1.8K
Snippets
8
Records
10
Agent score
24%

What's inside PyHessian

  1. Train a model for Hessian analysis

    master

    PyHessian requires a pre-trained neural network model. You can use the provided training.py script to train a ResNet20 model on the Cifar-10 dataset.

    Note: Ensure you set CUDA_VISIBLE_DEVICES if using a GPU.

    export CUDA_VISIBLE_DEVICES=0; python training.py [--batch-size] [--test-batch-size] [--epochs] [--lr] [--lr-decay] [--lr-decay-epoch] [--seed] [--weight-decay] [--batch-norm] [--residual] [--cuda] [--saving-folder]
  2. Perform Hessian analysis on a model checkpoint

    master

    Once a model checkpoint is saved, use example_pyhessian_analysis.py to compute the top eigenvalue, the trace of the Hessian, and the Eigenvalue Spectral Density (ESD). The output density plot is saved as example.pdf.

    export CUDA_VISIBLE_DEVICES=0; python example_pyhessian_analysis.py [--mini-hessian-batch-size] [--hessian-batch-size] [--seed] [--batch-norm] [--residual] [--cuda] [--resume]
  3. Analyze loss landscape flatness using Hessian eigenvectors

    master

    You can visualize the loss landscape by perturbing model parameters along specific directions. Using the top Hessian eigenvector provides a more informative view of the landscape's curvature than random directions.

    Workflow:

    1. Compute the top eigenvector using hessian_comp.eigenvalues().
    2. Perturb the model parameters along that direction using a scalar $\lambda$.
    3. Measure the loss at each perturbation point.

    Note: When perturbing, ensure you use a copy of the model to avoid modifying the original weights permanently.

    # 1. Get top eigenvector
    top_eigenvalues, top_eigenvector = hessian_comp.eigenvalues()
    
    # 2. Define perturbation range
    lams = np.linspace(-0.5, 0.5, 21).astype(np.float32)
    
    # 3. Perturb and measure loss
    loss_list = []
    model_perb = copy_of_model
    
    for lam in lams:
        # Perturb model_perb along top_eigenvector[0] by amount 'lam'
        model_perb = get_params(model, model_perb, top_eigenvector[0], lam)
        loss_list.append(criterion(model_perb(inputs), targets).item())
  4. Reference: training.py CLI arguments

    master

    Arguments for the training.py script:

    ArgumentDescription
    --batch-sizetraining batch size (default: 128)
    --test-batch-sizetesting batch size (default: 256)
    --epochstotal number of training epochs (default: 180)
    --lrinitial learning rate (default: 0.1)
    --lr-decaylearning rate decay ratio (default: 0.1)
    --lr-decay-epochepoch for the learning rate decaying (default: 80, 120)
    --seedused to reproduce the results (default: 1)
    --weight-decayweight decay value (default: 5e-4)
    --batch-normdo we need batch norm in ResNet or not (default: True)
    --residualdo we need residual connection or not (default: True)
    --cudado we use gpu or not (default: True)
    --saving-foldersaving path of the final checkpoint (default: checkpoints/)
  5. Reference: example_pyhessian_analysis.py CLI arguments

    master

    Arguments for the example_pyhessian_analysis.py script:

    ArgumentDescription
    --mini-hessian-batch-sizemini hessian batch size (default: 200)
    --hessian-batch-sizehessian batch size (default: 200)
    --seedused to reproduce the results (default: 1)
    --batch-normdo we need batch norm in ResNet or not (default: True)
    --residualdo we need residual connection or not (default: True)
    --cudado we use gpu or not (default: True)
    --resumeresume path of the checkpoint (default: none, must be filled by user)
  6. Compute Hessian trace and density

    master

    The hessian module provides methods to approximate the Hessian's trace and its eigenvalue spectrum density using randomized linear algebra (e.g., Hutchinson's method and Stochastic Lanczos algorithm).

    • trace(): Returns an approximation of the Hessian trace.
    • density(): Returns the eigenvalue spectrum density, useful for analyzing the flatness of the loss landscape.
    # Assuming hessian_comp is an instance of the hessian module
    
    # Get the trace
    trace = hessian_comp.trace()
    print(f"Trace: {np.mean(trace)}")
    
    # Get eigenvalue spectrum density
    density_eigen, density_weight = hessian_comp.density()
  7. Normalize parameter vectors for perturbation

    master

    When perturbing model parameters along a direction (like a random vector or a gradient vector), use pyhessian.utils.normalization to ensure the direction vector is properly scaled.

    from pyhessian.utils import normalization
    
    # Example: Normalizing a list of parameter tensors
    v = [torch.randn_like(p) for p in model.parameters()]
    v = normalization(v)
  8. Compute Neural Network Hessian eigenvalues

    master

    Use the hessian function to create a Hessian computation module for a PyTorch model. This module allows you to compute eigenvalues and eigenvectors without explicitly forming the full Hessian matrix, making it efficient for large neural networks.

    To use it:

    1. Ensure your model is in .eval() mode to disable running statistics updates.
    2. Define your loss function (e.g., torch.nn.CrossEntropyLoss()).
    3. Provide a data tuple (inputs, targets).
    4. Set cuda=True for faster computation if a GPU is available.
    from pyhessian import hessian
    
    # Setup
    model.eval()
    criterion = torch.nn.CrossEntropyLoss()
    # inputs, targets should be tensors
    
    # Create the module
    hessian_comp = hessian(model, criterion, data=(inputs, targets), cuda=True)
    
    # Compute top N eigenvalues and eigenvectors
    top_eigenvalues, top_eigenvector = hessian_comp.eigenvalues(top_n=2)