NetVLAD

repository·master·Indexed 20 days ago

https://github.com/relja/netvlad

A MATLAB implementation of a CNN architecture for weakly supervised place recognition. It includes tools for training NetVLAD layers, performing feature extraction via computeRepresentation and serialAllFeats, and evaluating models on standard place recognition datasets using Recall@N metrics. Requires relja_matlab (v1.02+) and MatConvNet (v1.0-beta18+), with optional acceleration via Yael_matlab.

Tokens
3K
Snippets
7
Records
11
Agent score
20%

What's inside NetVLAD

  1. Handle NetVLAD output vectors for Product Quantization

    master

    The NetVLAD layer produces a vector of dimension (K*D)x1, where K is the number of cluster centers and D is the input descriptor dimensionality. The default flattening stores values such that the first cluster center's values are at indices [1:K:end].

    If you intend to use Product Quantization (PQ), you should reshape the vector so that values associated with the same cluster center are grouped in contiguous blocks of size D. Use the following transformation:

    % Reshape to group cluster center values together
    netvladForPQ = reshape( reshape(netvlad, [K, D])', [K*D, 1] );
    netvladForPQ = reshape( reshape(netvlad, [K, D])', [K*D, 1] );
  2. Train NetVLAD networks from scratch

    master

    To train a NetVLAD network using weakly supervised learning:

    1. Prepare Data: Load your training and validation datasets (e.g., using dbTokyoTimeMachine('train')).
    2. Execute Training: Call trainWeakly with your dataset objects and desired hyperparameters.
    3. Select Best Model: Training periodically saves checkpoints. Use pickBestNet(sessionID) to retrieve the network that performed best on the validation set.
    4. Dimensionality Reduction: For optimal performance, apply PCA and whitening to the best network using addPCA.

    Important trainWeakly Parameters

    • netID: Name of the network architecture (caffe for AlexNet, vd16 for VGG-16).
    • layerName: The last convolutional layer to crop (e.g., conv5_3 for VGG-16).
    • backPropToLayer: The layer down to which learning is performed.
    • method: Aggregation method (e.g., vlad_preL2_intra, max, avg).
    • learningRate: SGD learning rate.
    • useGPU: Boolean to enable/disable GPU acceleration.
    % 1. Setup
    setup;
    
    % 2. Load Data
    dbTrain= dbTokyoTimeMachine('train');
    dbVal= dbTokyoTimeMachine('val');
    
    % 3. Train
    sessionID= trainWeakly(dbTrain, dbVal, ...
        'netID', 'vd16', 'layerName', 'conv5_3', 'backPropToLayer', 'conv5_1', ...
        'method', 'vlad_preL2_intra', ...
        'learningRate', 0.0001, ...
        'doDraw', true);
    
    % 4. Pick best and add PCA
    [~, bestNet]= pickBestNet(sessionID);
    finalNet= addPCA(bestNet, dbTrain, 'doWhite', true, 'pcaDim', 4096);
  3. Use and test pre-trained NetVLAD networks

    master

    To use a pre-trained network for place recognition, follow these steps:

    1. Initialize Paths: Run setup; to set MATLAB paths.
    2. Load Network: Load the .mat file using localPaths() to resolve the directory. If using an older model (v1.01 or below), wrap the network with relja_simplenn_tidy(net) to upgrade it.
    3. Single Image Inference: Use computeRepresentation(net, im) on a normalized image.
    4. Batch Inference: For large sets of images, use serialAllFeats. This is significantly faster as it uses batches and minimizes GPU transfers.
      • Note on Batch Size: If images have different resolutions (common in place recognition datasets), set 'batchSize', 1 to avoid errors.
    5. Evaluation: To measure performance (e.g., Recall@N) on a dataset, use testFromFn with the database and query feature files.
    setup;
    
    % Load network
    netID= 'vd16_tokyoTM_conv5_3_vlad_preL2_intra_white';
    paths= localPaths();
    load( sprintf('%s%s.mat', paths.ourCNNs, netID), 'net' );
    net= relja_simplenn_tidy(net);
    
    % Single image
    im= vl_imreadjpeg({which('football.jpg')}); im= im{1};
    feats= computeRepresentation(net, im);
    
    % Batch processing
    serialAllFeats(net, imPath, imageFns, outputFn, 'batchSize', 10);
    
    % Testing Recall@N
    [recall, ~, ~, opts]= testFromFn(dbTest, dbFeatFn, qFeatFn);
    plot(opts.recallNs, recall, 'ro-');
  4. Install and configure NetVLAD dependencies

    master

    NetVLAD is written in MATLAB and requires several libraries to function.

    Required Dependencies

    1. relja_matlab: version 1.02 or above.
    2. MatConvNet: version 1.0-beta18 or above.
    • Yael_matlab: Highly recommended for speed (tested with version 438). Note that Yael is used for acceleration but is not used for the feature extraction (feed-forward pass) itself.

    Configuration

    To configure the library paths for dependencies, datasets, and pretrained models:

    1. Locate localPaths.m.setup in the repository.
    2. Copy it to a new file named localPaths.m.
    3. Edit the variables within localPaths.m to point to your specific dependency and data locations.
    # No specific command provided, but the workflow is:
    cp localPaths.m.setup localPaths.m
    # Then edit localPaths.m
  5. Avoid file corruption when running multiple training sessions

    master

    If you run multiple training processes with the same combination of dbTrain, netID, layerName, and method, they will attempt to write to the same initial image representation files (dbCheckpoint0, qCheckpoint0, dbCheckpoint0val, qCheckpoint0val), causing corruption.

    To run concurrent trainings with the same settings, use one of these methods:

    1. Wait for the first process to finish computing the 4 checkpoint files before starting the next.
    2. Manually set different paths for dbCheckpoint0, qCheckpoint0, dbCheckpoint0val, and qCheckpoint0val for each run.
    3. Recommended: Set a unique checkpoint0suffix for each run. This automatically generates unique filenames for the 4 checkpoint files.
  6. Read NetVLAD binary feature files in MATLAB

    master

    The serialAllFeats function saves image representations as single 32-bit floats. For a file containing numImages with D-dimensional representations, the file size is D * numImages * 4 bytes.

    To read these files into MATLAB, use fread with the following configuration:

    % D: dimensionality, numImages: number of images, featFn: filename
    feats = fread( fopen(featFn, 'rb'), [D, numImages], 'float32=>single');
    feats = fread( fopen(featFn, 'rb'), [D, numImages], 'float32=>single');
  7. Load and plot training results

    master

    Training periodically saves .mat files containing the network, options, and performance metrics. To load and visualize the training curves (like validation recall@N), use the following pattern:

    % Load the saved data
    load('0fd5_ep000020_latest.mat', 'obj', 'opts', 'auxData');
    
    % Plot the results
    plotResults(obj, opts, auxData);

    Key Curves in plotResults:

    • Top Left: Dynamic loss (smoothed triplet ranking loss on training batches).
    • Bottom Left: Loss evaluated on training and validation sets using random samples.
    • Right: Recall@N for training (t.N) and validation (v.N) sets. This is the most important metric.
    load('0fd5_ep000020_latest.mat', 'obj', 'opts', 'auxData');
    plotResults(obj, opts, auxData);
  8. Perform detailed Tokyo 24/7 dataset testing

    master

    To get detailed recall results for specific time-of-day subsets in the Tokyo 24/7 dataset (daytime, sunset, nighttime), use testFromFn to retrieve all recalls, then index the resulting array.

    In Tokyo 24/7, queries are organized such that (iQuery mod 3) determines the type: 1 is daytime, 2 is sunset, and 0 is nighttime.

    % 1. Run the test to get all recalls
    [recall, ~, allRecalls, opts] = testFromFn(dbTest, dbFeatFn, qFeatFn);
    
    % 2. Calculate mean recall for all queries
    recalls = mean(allRecalls, 1)';
    
    % 3. Calculate specific subset recalls
    recallDay = mean(allRecalls(1:3:end, :), 1)';
    recallSunsetNight = mean(allRecalls([2:3:end, 3:3:end], :), 1)';
    [recall, ~, allRecalls, opts] = testFromFn(dbTest, dbFeatFn, qFeatFn);
    recalls = mean(allRecalls, 1)';
    recallDay = mean(allRecalls(1:3:end, :), 1)';
    recallSunsetNight = mean(allRecalls([2:3:end, 3:3:end], :), 1)';
  9. Configure training parameters for `trainWeakly`

    master

    The trainWeakly function accepts several categories of parameters to control the weakly supervised training process.

    Main Parameters

    • netID: Network name (caffe for AlexNet, vd16 for VGG-16).
    • layerName: The layer to crop the initial network at (e.g., conv5 for caffe, conv5_3 for vd16).
    • method: Aggregation method. Defaults to vlad_preL2_intra. Other options: max (max pooling), avg (average pooling), or vlad_preL2 (disables intra-normalization).
    • margin: Loss margin parameter.
    • useGPU: Boolean to enable/disable GPU.
    • sessionID: Unique string for the run (avoid slashes/non-alphanumeric characters).
    • computeBatchSize: Batch size for computing image representations (affects speed, not training behavior).
    • compFeatsFrequency: Frequency (in training tuples) to recompute cached image representations.

    SGD Parameters

    • learningRate, batchSize, momentum, weightDecay, nEpoch: Standard SGD parameters. Note that batchSize refers to the number of training tuples (each tuple contains a query, a positive, and negatives).
    • lrDownFactor, lrDownFreq: Learning rate decay schedule.
    • backPropToLayer: Specifies the layer down to which learning is performed (name or number).
    • fixLayers: Cell array of layers to keep frozen (use backPropToLayer instead for most cases).

    Other Parameters

    • doDraw: Plot performance curves during training.
    • saveFrequency: Frequency of saving the network and data.
    • recallNs: Array of N values for recall measurement.
    • test0: If true, tests the network before training (off-the-shelf mode).
    • nTestRankSample: Number of tuples used for loss computation during testing.
    • nTestSample: Upper limit on queries used for testing (set to $\infty$ to use all).
    • nNegChoice: Number of negatives sampled per tuple per epoch.
    • nNegCache: Number of hardest negatives to remember for the next epoch.
    • nNegCap: Total number of hardest negatives kept in the training tuple.
    • excludeVeryHard: If true, ignores negatives closer than the closest potential positive.
    • startEpoch: Restart training from a specific epoch (requires matching sessionID).
  10. Reference: `trainWeakly` function arguments

    master

    The trainWeakly function is the core entry point for weakly supervised training.

    ParameterDescription
    netIDThe name of the network (caffe for AlexNet, vd16 for VGG-16)
    layerNameWhich layer to crop the initial network at (e.g., conv5 for caffe, conv5_3 for vd16)
    backPropToLayerDown to which layer to perform the learning. If omitted, the entire network is trained
    methodAggregation method: vlad_preL2_intra (default), max, avg, or other variants like vlad_preL2
    learningRateThe learning rate for SGD
    useGPUBoolean to use GPU or CPU
    doDrawBoolean to plot performance curves during training

    Other SGD and method-specific parameters (batch size, momentum, weight decay, margin size, etc.) are detailed in trainWeakly.m.

  11. Reference: `serialAllFeats` function arguments

    master

    The serialAllFeats function computes image representations for a collection of images efficiently using batches.

    ParameterDescription
    netThe trained network object
    imPathPath to the directory containing images
    imageFnsCell array of image filenames relative to imPath
    outputFnFilename/path where binary representations (single 4-byte floats) will be saved
    'batchSize'Number of images per forward pass. Note: Set to 1 if images have varying resolutions.