DOROTHY home

Reference / API reference / dorothy / dorothy.analysis / dorothy.analysis.saliency

dorothy.analysis.saliency

Gradient and ablation saliency of the predictions to the input spectrum.

SaliencyAnalyzer takes the Jacobian of the predicted means and scatters with respect to the input and weights it by the Fisher information. AblationSaliencyAnalyzer masks blocks of the spectrum and measures the change of the predictions. Both analyse one spectrum, as the model sees it (preprocessed, in normalized units), with the first output head of a MultiHeadMLP and no label errors.

Examples

>>> from dorothy.inference import Predictor
>>> from dorothy.analysis import SaliencyAnalyzer, plot_parameter_saliency
>>>
>>> predictor = Predictor.load("outputs/variant5/checkpoint")
>>> analyzer = SaliencyAnalyzer(predictor.model, device="cuda")
>>>
>>> result = analyzer.compute_saliency(X, wavelength, survey="boss")
>>> fig = plot_parameter_saliency(result, "teff", output_path="teff_saliency.png")

Functions

plot_ablation_parameter_saliency(result, ...)

Plot the ablation saliency of one parameter along the spectrum.

plot_ablation_saliency_heatmap(result[, ...])

Plot the ablation saliency of all parameters as heatmaps.

plot_parameter_saliency(result, param_name)

Plot the gradient saliency of one parameter along the spectrum.

plot_saliency_heatmap(result[, output_path, ...])

Plot the gradient saliency of all parameters as heatmaps.

Classes

AblationSaliencyAnalyzer(model[, device, ...])

Ablation saliency of the predictions to the input spectrum.

AblationSaliencyResult(survey, wavelength, ...)

Result of AblationSaliencyAnalyzer.compute_saliency.

SaliencyAnalyzer(model[, device, ...])

Gradient saliency of the predictions to the input spectrum.

SaliencyResult(survey, wavelength, spectrum, ...)

Result of SaliencyAnalyzer.compute_saliency.

class dorothy.analysis.saliency.SaliencyResult(survey, wavelength, spectrum, spectrum_error, mask, jacobian_mean_flux, jacobian_mean_error, jacobian_sigma_flux, jacobian_sigma_error, predictions, uncertainties, fisher_importance_per_param, fisher_importance, parameter_names, gaia_id=None, ra=None, dec=None)[source]

Bases: object

Result of SaliencyAnalyzer.compute_saliency.

Predictions, scatters and Jacobians are in normalized units, with the input as the model sees it. The Jacobians and the Fisher importance are zero at masked pixels.

survey

Survey of the spectrum, “unknown” if not given.

wavelength

Wavelength grid in Å, shape (N,).

spectrum

Flux channel of the input, shape (N,).

spectrum_error

Error channel of the input, shape (N,): the precision encoding ρ when data.precision_encoding is set, else σ.

mask

True where the pixel is valid, shape (N,).

jacobian_mean_flux

Gradient of the predicted means w.r.t. flux, shape (n_params, N).

jacobian_mean_error

Gradient of the means w.r.t. the error channel, shape (n_params, N).

jacobian_sigma_flux

Gradient of the predicted scatter σ w.r.t. flux, shape (n_params, N). σ is losses.predicted_scatter, so the gradient is zero where ln s is clamped.

jacobian_sigma_error

Gradient of σ w.r.t. the error channel, shape (n_params, N).

predictions

Predicted means, shape (n_params,).

uncertainties

Predicted scatters σ, shape (n_params,).

fisher_importance_per_param

Fisher importance of each parameter, shape (n_params, N).

fisher_importance

Sum of fisher_importance_per_param over the parameters, shape (N,).

parameter_names

Parameter names, length n_params.

gaia_id

Gaia DR3 source ID, if given.

ra

Right ascension in degrees, if given.

dec

Declination in degrees, if given.

get_param_index(param_name)[source]

Index of a parameter in the parameter arrays.

Parameters:

param_name (str) – Parameter name, such as “teff”.

Returns:

The index.

Raises:

ValueError – If param_name is not in parameter_names.

Return type:

int

class dorothy.analysis.saliency.AblationSaliencyResult(survey, wavelength, spectrum, spectrum_error, mask, block_size, delta_mu, delta_mu_total, delta_sigma, delta_sigma_total, fisher_weighted, fisher_weighted_total, predictions, uncertainties, parameter_names, gaia_id=None, ra=None, dec=None)[source]

Bases: object

Result of AblationSaliencyAnalyzer.compute_saliency.

A block of the spectrum is ablated by setting its pixels to zero in the flux, error and mask channels. The value at a pixel is the mean over the ablated blocks that cover it, and zero at masked pixels. Ablation changes flux and error together, so the result has no separate maps for them.

The changes are signed like gradients. A positive delta_mu means that ablating the region raised the prediction, so the region was lowering it. Predictions and scatters are in normalized units.

survey

Survey of the spectrum, “unknown” if not given.

wavelength

Wavelength grid in Å, shape (N,).

spectrum

Flux channel of the input, shape (N,).

spectrum_error

Error channel of the input, shape (N,): the precision encoding ρ when data.precision_encoding is set, else σ.

mask

True where the pixel is valid, shape (N,).

block_size

Block size in pixels. With the training distribution, the list of block sizes, one per grid point and with repeats; the maps are the mean over them.

delta_mu

Change of the predicted mean, μ_ablated - μ₀, shape (n_params, N).

delta_mu_total

Sum of delta_mu over the parameters, shape (N,).

delta_sigma

Change of the predicted scatter, σ_ablated - σ₀, shape (n_params, N). Positive means that the region lowered σ.

delta_sigma_total

Sum of delta_sigma over the parameters, shape (N,).

fisher_weighted

((Δμ)² + 2 (Δσ)²) / σ₀², unsigned, shape (n_params, N).

fisher_weighted_total

Sum of fisher_weighted over the parameters, shape (N,).

predictions

Baseline predicted means μ₀, shape (n_params,).

uncertainties

Baseline predicted scatters σ₀, shape (n_params,).

parameter_names

Parameter names, length n_params.

gaia_id

Gaia DR3 source ID, if given.

ra

Right ascension in degrees, if given.

dec

Declination in degrees, if given.

get_param_index(param_name)[source]

Index of a parameter in the parameter arrays.

Parameters:

param_name (str) – Parameter name, such as “teff”.

Returns:

The index.

Raises:

ValueError – If param_name is not in parameter_names.

Return type:

int

class dorothy.analysis.saliency.SaliencyAnalyzer(model, device='auto', scatter_floor=0.01, parameter_names=None)[source]

Bases: object

Gradient saliency of the predictions to the input spectrum.

The Jacobian holds the derivatives of the predicted means μ_p and scatters σ_p with respect to the flux and error channels. The Fisher information of N(μ, σ²) is 1/σ² for μ and 2/σ² for σ, so the importance of pixel i for parameter p is:

I_p(i) = [(∂μ_p/∂flux_i)² + (∂μ_p/∂err_i)²
          + 2 (∂σ_p/∂flux_i)² + 2 (∂σ_p/∂err_i)²] / σ_p²

The model uses the first output head of a MultiHeadMLP, without label errors.

model

The model, on device and in eval mode.

device

Device of the computation.

scatter_floor

Scatter floor s_0 of losses.predicted_scatter.

parameter_names

Parameter names.

compute_saliency(X, wavelength, survey=None, gaia_id=None, ra=None, dec=None)[source]

Compute the saliency of one spectrum.

One forward pass and one batched backward pass over the 2 * n_params outputs.

Parameters:
  • X (torch.Tensor) – Model input, shape (3, N): [flux, error, mask], with the preprocessing of training. A pixel is valid where the mask is above 0.5; masked pixels may hold any value, including NaN.

  • wavelength (NDArray[np.float32]) – Wavelength in Å, shape (N,).

  • survey (str | None) – Survey of the spectrum, required for a MultiHeadMLP with several surveys.

  • gaia_id (int | None) – Gaia DR3 source ID, stored in the result.

  • ra (float | None) – Right ascension in degrees, stored in the result.

  • dec (float | None) – Declination in degrees, stored in the result.

Returns:

The Jacobians, predictions and Fisher importance.

Return type:

SaliencyResult

class dorothy.analysis.saliency.AblationSaliencyAnalyzer(model, device='auto', scatter_floor=0.01, parameter_names=None, batch_size=64)[source]

Bases: object

Ablation saliency of the predictions to the input spectrum.

A window of block_size pixels slides over the spectrum in steps of one pixel. Each window is zeroed in the flux, error and mask channels. Three maps follow:

  1. Delta-mu: the signed change of the predicted means.

  2. Delta-sigma: the signed change of the predicted scatters.

  3. Fisher-weighted: ((delta_mu)^2 + 2 (delta_sigma)^2) / sigma_0^2, the Fisher quadratic form of N(mu, sigma^2) that gradient saliency uses.

The model uses the first output head of a MultiHeadMLP, without label errors.

When the spectrum reaches the output only through the model’s first nn.Linear layer, the analyzer temporarily replaces that layer’s forward method during a run. Do not call the model from another thread meanwhile.

model

The model, on device and in eval mode.

device

Device of the computation.

scatter_floor

Scatter floor s_0 of losses.predicted_scatter.

parameter_names

Parameter names.

batch_size

Number of ablated spectra per forward pass.

compute_saliency(X, wavelength, survey=None, block_size=None, use_training_distribution=False, n_block_sizes=21, f_min=None, f_max=0.5, gaia_id=None, ra=None, dec=None)[source]

Compute the ablation saliency of one spectrum.

Each block size needs N - block_size + 1 forward passes, in batches of batch_size.

Parameters:
  • X (torch.Tensor) – Model input, shape (3, N): [flux, error, mask], with the preprocessing of training. A pixel is valid where the mask is above 0.5; masked pixels may hold any value, including NaN.

  • wavelength (NDArray[np.float32]) – Wavelength in Å, shape (N,).

  • survey (str | None) – Survey of the spectrum, required for a MultiHeadMLP with several surveys.

  • block_size (int | None) – Block size in pixels; None means 5. A block longer than N gives zero maps.

  • use_training_distribution (bool) – If True, ignore block_size and average the maps of n_block_sizes block sizes ceil(N * f), with f evenly spaced in log f from f_min to f_max (the log-uniform sizes of the training input masking), each with equal weight.

  • n_block_sizes (int) – Number of block sizes with the training distribution.

  • f_min (float | None) – Smallest block fraction f with the training distribution; None means 1/N.

  • f_max (float) – Largest block fraction f with the training distribution.

  • gaia_id (int | None) – Gaia DR3 source ID, stored in the result.

  • ra (float | None) – Right ascension in degrees, stored in the result.

  • dec (float | None) – Declination in degrees, stored in the result.

Returns:

The per-pixel changes of the predictions and the Fisher-weighted importance.

Return type:

AblationSaliencyResult

dorothy.analysis.saliency.plot_parameter_saliency(result, param_name, output_path=None, figsize=(14, 14), cmap='RdBu', cmap_fisher='Purples', normalizer=None, label_values=None, label_errors=None)[source]

Plot the gradient saliency of one parameter along the spectrum.

Three stacked panels show the sensitivity of the mean (∂μ/∂x), the sensitivity of the scatter (∂σ/∂x) and the Fisher importance of the parameter. Each panel has the flux spectrum above the error spectrum, coloured by the panel’s quantity at each pixel. Masked wavelengths are grey. The colour scales span the 99th percentile of the valid pixels.

Parameters:
  • result (SaliencyResult) – Result of SaliencyAnalyzer.compute_saliency.

  • param_name (str) – Parameter to plot, such as “teff”.

  • output_path (Path | str | None) – File to save the figure to; None saves nothing.

  • figsize (tuple[float, float]) – Figure size (width, height) in inches.

  • cmap (str) – Colormap of the sensitivity panels (red is negative, blue positive for the default).

  • cmap_fisher (str) – Colormap of the Fisher panel.

  • normalizer (LabelNormalizer | None) – If given, the title shows the prediction in physical units; otherwise in normalized units.

  • label_values (NDArray[np.float32] | None) – Catalogue labels in physical units, shape (n_params,), shown in the title.

  • label_errors (NDArray[np.float32] | None) – Label errors in physical units, shape (n_params,), shown with label_values.

Returns:

The Matplotlib figure. The caller closes it.

Raises:

ValueError – If param_name is unknown or result.mask has no valid pixel.

Return type:

Figure

dorothy.analysis.saliency.plot_saliency_heatmap(result, output_path=None, figsize=(16, 14), cmap_gradient='RdBu', cmap_fisher='Purples')[source]

Plot the gradient saliency of all parameters as heatmaps.

Three stacked panels show ∂μ/∂x, ∂σ/∂x and the Fisher importance. Each has two rows per parameter (flux and error channel) and one column per pixel. Masked wavelengths are grey. Each parameter’s two rows are divided by their largest absolute value over the valid pixels: the sensitivity panels span [-1, 1] and the Fisher panel [0, 1]. The Fisher rows of a parameter are the flux and error terms of its importance.

Parameters:
  • result (SaliencyResult) – Result of SaliencyAnalyzer.compute_saliency.

  • output_path (Path | str | None) – File to save the figure to; None saves nothing.

  • figsize (tuple[float, float]) – Figure size (width, height) in inches.

  • cmap_gradient (str) – Colormap of the sensitivity panels (red is negative, blue positive for the default).

  • cmap_fisher (str) – Colormap of the Fisher panel.

Returns:

The Matplotlib figure. The caller closes it.

Raises:

ValueError – If result.mask has no valid pixel.

Return type:

Figure

dorothy.analysis.saliency.plot_ablation_parameter_saliency(result, param_name, output_path=None, figsize=(14, 14), cmap='RdBu', cmap_fisher='Purples', normalizer=None, label_values=None, label_errors=None)[source]

Plot the ablation saliency of one parameter along the spectrum.

The layout is that of plot_parameter_saliency. The three panels show Δμ, Δσ and the Fisher-weighted change of the parameter. Ablation changes flux and error together, so the flux and error spectra of a panel have the same colours. A positive Δμ means that ablating the region raised the prediction.

Parameters:
  • result (AblationSaliencyResult) – Result of AblationSaliencyAnalyzer.compute_saliency.

  • param_name (str) – Parameter to plot, such as “teff”.

  • output_path (Path | str | None) – File to save the figure to; None saves nothing.

  • figsize (tuple[float, float]) – Figure size (width, height) in inches.

  • cmap (str) – Colormap of the signed panels.

  • cmap_fisher (str) – Colormap of the Fisher panel.

  • normalizer (LabelNormalizer | None) – If given, the title shows the prediction in physical units; otherwise in normalized units.

  • label_values (NDArray[np.float32] | None) – Catalogue labels in physical units, shape (n_params,), shown in the title.

  • label_errors (NDArray[np.float32] | None) – Label errors in physical units, shape (n_params,), shown with label_values.

Returns:

The Matplotlib figure. The caller closes it.

Raises:

ValueError – If param_name is unknown or result.mask has no valid pixel.

Return type:

Figure

dorothy.analysis.saliency.plot_ablation_saliency_heatmap(result, output_path=None, figsize=(16, 14), cmap_signed='RdBu', cmap_fisher='Purples')[source]

Plot the ablation saliency of all parameters as heatmaps.

The layout is that of plot_saliency_heatmap. The three panels show Δμ, Δσ and the Fisher-weighted change. Ablation changes flux and error together, so the two rows of a parameter are equal. Each parameter is divided by its largest absolute value over the valid pixels: the signed panels span [-1, 1] and the Fisher panel [0, 1].

Parameters:
  • result (AblationSaliencyResult) – Result of AblationSaliencyAnalyzer.compute_saliency.

  • output_path (Path | str | None) – File to save the figure to; None saves nothing.

  • figsize (tuple[float, float]) – Figure size (width, height) in inches.

  • cmap_signed (str) – Colormap of the signed panels.

  • cmap_fisher (str) – Colormap of the Fisher panel.

Returns:

The Matplotlib figure. The caller closes it.

Raises:

ValueError – If result.mask has no valid pixel.

Return type:

Figure