pycsamt.ai.inversion.inv3d#

GCNInverter3D — graph-convolutional 3-D MT spatial inversion.

Exploits inter-station spatial relationships by representing the survey network as a graph whose adjacency encodes station proximity. Each node receives features from its neighbours via Kipf & Welling (2017) spectral graph convolutions before predicting a per-station 1-D subsurface model, yielding a spatially consistent 3-D resistivity image.

Input / output convention#

  • Input X: ndarray (n_samples, n_stations, n_features) or (n_stations, n_features) for a single survey. Typical features: [log10(rho_a_f1), phi_f1, …, log10(rho_a_fK), phi_fK] giving n_features = 2 × K.

  • Target y: ndarray (n_samples, n_stations, 2*n_layers-1) — per-station model parameters (log10(ρ) for each layer concatenated with log10(thickness) for each interface).

  • Adjacency A: ndarray (n_stations, n_stations) — symmetric normalised adjacency \(\tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2}\). Build from station coordinates with build_adjacency().

Message-passing rule (Kipf & Welling 2017)#

\[H^{(l+1)} = \sigma\!\bigl( \tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2}\, H^{(l)} W^{(l)}\bigr)\]

where \(\tilde{A} = A + I\) (self-loops) and \(\tilde{D}_{ii} = \sum_j \tilde{A}_{ij}\).

References

Example

>>> import numpy as np
>>> from pycsamt.ai.nets.gcn import build_adjacency
>>> from pycsamt.ai.inversion.inv3d import GCNInverter3D
>>> rng = np.random.default_rng(0)
>>> coords = rng.uniform(0, 10_000, (30, 2))
>>> A = build_adjacency(coords, radius=3_000)
>>> X = rng.standard_normal((200, 30, 40)).astype("f4")
>>> y = rng.standard_normal((200, 30, 9)).astype("f4")
>>> inv = GCNInverter3D(n_features=40, n_layers=5)
>>> inv.fit(X, y, adjacency=A, epochs=5, verbose=False)
GCNInverter3D(n_features=40, n_layers=5, ..., n_stations=30, fitted)

Classes

GCNInverter3D([n_features, n_layers, ...])

Graph-convolutional 3-D MT inversion estimator.

class pycsamt.ai.inversion.inv3d.GCNInverter3D(n_features=40, n_layers=5, hidden=(256, 128, 64), dropout=0.1, device=None, **net_kwargs)[source]#

Bases: BaseEMNet

Graph-convolutional 3-D MT inversion estimator.

Models the spatial context of a multi-station survey as a graph and applies spectral GCN message-passing before regressing per-station 1-D subsurface models. The result is a spatially coherent 3-D resistivity volume without any external graph library dependency.

Parameters:
  • n_features (int, default 40) – Per-station input feature dimension. A typical choice is 2 × n_freqs (log10(ρ_a) + phase at each frequency).

  • n_layers (int, default 5) – Number of depth layers per station. Output size per station is 2 * n_layers - 1 (n_layers log10(ρ) + (n_layers-1) log10(h)).

  • hidden (sequence of int, default (256, 128, 64)) – Width of each GCN message-passing layer.

  • dropout (float, default 0.1) – Dropout probability applied between GCN layers during training.

  • device (str or None) – Compute device ('cpu', 'cuda', 'gpu:0', …). None auto-detects.

  • **net_kwargs – Extra keyword arguments forwarded to GCNNet.

fit(X, y=None, adjacency=None, *, coords=None, radius=5000.0, epochs=100, batch_size=16, lr=0.001, patience=15, val_frac=0.15, grad_clip=1.0, seed=None, verbose=True)[source]#

Train the 3-D GCN inversion network.

Parameters:
  • X (ndarray (n_samples, n_stations, n_features) or) – (n_stations, n_features) Per-station MT feature matrices.

  • y (ndarray (n_samples, n_stations, 2*n_layers-1) or) – (n_stations, 2*n_layers-1) Target per-station model parameters (log10 scale recommended).

  • adjacency (ndarray (n_stations, n_stations), optional) – Pre-computed normalised adjacency matrix. If None, coords and radius must be provided.

  • coords (ndarray (n_stations, 2), optional) – Station (x, y) positions used to build the adjacency when adjacency is not given.

  • radius (float) – Maximum inter-station edge distance in the same units as coords; ignored when adjacency is supplied.

  • epochs (int) – Standard training hyper-parameters.

  • batch_size (int) – Standard training hyper-parameters.

  • lr (float) – Standard training hyper-parameters.

  • patience (int) – Standard training hyper-parameters.

  • val_frac (float) – Standard training hyper-parameters.

  • grad_clip (float | None) – Standard training hyper-parameters.

  • seed (int | None) – Standard training hyper-parameters.

  • verbose (bool) – Standard training hyper-parameters.

Return type:

self

predict(X, adjacency=None, *, coords=None, radius=5000.0, as_log_rho=True)[source]#

Predict per-station subsurface models.

Parameters:
  • X (ndarray (n_stations, n_features) or) – (n_samples, n_stations, n_features)

  • adjacency (ndarray (n_stations, n_stations), optional) – If None, uses the adjacency stored from fit().

  • coords (ndarray (n_stations, 2), optional) – Build adjacency from coordinates when adjacency is absent.

  • radius (float) – Edge radius (used only when coords is supplied).

  • as_log_rho (bool) – Return log10(ρ) when True; linear-scale ρ otherwise.

Returns:

y_pred

Return type:

ndarray (n_stations, n_out) or (n_samples, n_stations, n_out)

predict_with_uncertainty(X, adjacency=None, *, coords=None, radius=5000.0, n_mc=30)[source]#

MC-dropout uncertainty estimate for 3-D predictions.

Runs n_mc stochastic forward passes with dropout active and returns the mean and pointwise standard deviation.

Parameters:
  • X (ndarray (..., n_stations, n_features))

  • adjacency (ndarray, optional)

  • coords (ndarray, optional)

  • radius (float)

  • n_mc (int) – Number of Monte-Carlo dropout samples.

Returns:

  • mean (ndarray — same shape as predict() output)

  • std (ndarray — same shape)

Return type:

tuple[ndarray, ndarray]