# POC PyTorch baselines

Run the completed real-input smoke suite from the workspace root:

```sh
.venv/bin/python 전처리/run_experiments.py --smoke
.venv/bin/python 전처리/run_experiments.py --visualize
.venv/bin/python 전처리/run_experiments.py --model-dashboard
.venv/bin/python 전처리/run_experiments.py --attributions
.venv/bin/python 전처리/run_experiments.py --compare-cad-predictions
.venv/bin/python -m models.runner --all
.venv/bin/python -m py_compile models/*.py 전처리/run_experiments.py
.venv/bin/python -c 'from models import test_baselines as t; [getattr(t,n)() for n in dir(t) if n.startswith("test_")]'
```

`results/models/report.json` contains actual prepared input paths, tensor shapes, parameter counts, bounded-CPU forward/backward latency, finite-output/gradient pass flags, and separate synthetic checkpoint paths. It reports no real accuracy: all AC28 `training_valid` masks are false.

The [model input/fusion dashboard](../results/models/dashboard/index.html) shows the prepared visual input, XLS process branch, fusion point, output domain and actual execution result for every model family. It labels geometry-only baselines and proposed process-fusion extensions separately.

`--attributions` writes [prepared-sample local response diagnostics](../results/models/attributions/index.html). These are absolute input-times-gradient maps of mean raw outputs from the named diagnostic checkpoints at run 18h01. They are not causal feature importance or validated-prediction explanations; every artifact is `production_valid=false`.

The [common-CAD prediction comparison](../results/models/cad_predictions/index.html) weak-trains every feasible architecture on run 18h01, transfers each native output back to the 11,956-node CAD using stored correspondences where available, and reports training AP/IoU/Dice plus mapping coverage. It is a representation/fit diagnostic, not held-out model selection.

`--prepare` and `--all` run the graph, B-Rep, and representation preparation CLIs, then rebuild the colocated processed-data galleries through `전처리/visualize_processed.py`. `--visualize` rebuilds only those galleries; it does not prepare data or train/run models.

Implemented families are 2D CNN/U-Net with process FiLM, dense 3D U-Net with process FiLM, PointNet, DGCNN with dynamic feature-space kNN, MeshGraphNet-style edge-conditioned/global-process GNN, UV-Net-style face-grid plus actual face adjacency, FNO2d (positive and negative low Fourier modes), a tabular MLP surrogate, and a synthetic-only sklearn GP constrained expected-improvement example.

The intended production candidate is also executed with three node heads plus a graph-level defect-type head: `STEP graph + XLS process → defect-risk logit + signed normal deformation + deformation magnitude` on every CAD node, with one type-logit vector per run. During training, the fused `all_merge_pointcloud_full.ply` supplies registered deformation supervision and the defect CSV supplies annotations. T1/T2/TOP component scans are registration/coverage QA, not independent samples. Current paired targets remain disabled for validated learning because registration and defect extent are not validated.

The requested diagnostic weak-label fit is available only through an explicit opt-in:

```sh
.venv/bin/python 전처리/run_experiments.py --train-weak-gnn
```

It runs a two-sample weak-label training diagnostic and writes a [training gallery](../results/models/weak_gnn/index.html), JSON report and non-production checkpoint. The node heads predict risk, signed normal deformation and deformation magnitude. A graph-level defect-type head is present, but it cannot be trained from these files because both runs contain only `찍힘`; at least two defect classes plus reviewed OK examples and held-out parts are needed. The current hard physical consistency rule is `magnitude ≥ |signed normal deformation|`; graph smoothness is a soft spatial prior rather than a governing-equation constraint.

The sparse entry is a true optional MinkowskiEngine encoder/downsample/bottleneck/up-convolution/skip U-Net. `cad_surface_sparse_32.npz` is adapted explicitly from unique `int32 [N,3]` voxel coordinates to Minkowski `int32 [N,4]` `[batch,x,y,z]` coordinates, with normalized stored features and their masks concatenated. If the optional backend is installed, the runner performs real sparse forward/backward execution and verifies that the decoder output coordinate set matches the input voxel set before calculating its synthetic objective. If MinkowskiEngine is absent, it is reported as `unavailable_optional_backend`; no dense tensor is called sparse. A loaded backend that fails execution is separately reported as `optional_backend_runtime_error`.

Adapters use only explicit prepared keys: image `x/feature_valid/feature_names`, dense voxel `x/feature_valid`, point `x/feature_valid`, graph `x/feature_valid/edge_index/edge_attr`, B-Rep `pos_mm/normal/curvature/trim_valid/normal_valid/curvature_valid/edge_index`, and tabular process-plus-geometry `x/feature_valid`. Unknown values are zero-imputed only together with appended masks. Input-only smoke normalization is fixed and unit-aware, not fit from held-out data: mm coordinates/depth/edge lengths share 1000 mm, area 1e6 mm², °C/seconds/m·s⁻¹ use fixed 500/100/1000 references, inverse-mm curvature uses physical-scale signed log, and native scan coordinates use one common scanner-frame scale rather than per-axis scaling.

Scan image/voxel/point inputs are post-scan inspection representations. CAD/process graph, B-Rep, and tabular inputs are only pre-process predictive candidates once independent externally validated outcomes exist. Current CAD surface voxels are not a filled solid; FNO has no paired thermal/field target and is therefore only an architecture smoke. The graph report tests permutation equivariance, two actual process conditions, all seven full topologies with the same weights, and a recomputed procedural geometry perturbation. These are architecture checks—not CAD-revision transfer or process-effect validation.

## Training contract

`python -m models.runner --train validated.npz` permits training only when the NPZ contains `x`, `feature_valid` of exactly the same shape, `y`, `training_valid` of exactly the same target shape, `group_id`, and `label_status == "externally_validated"` for every sample. It refuses empty masks, nonfinite valid fields/labels, missing metadata, one-group/random point splits, and invalid labels. Feature scaling is fit only on training groups and ignores masked values; masks are appended to the model input. Held-out masked MSE is emitted only for valid held-out labels.
