Instructions to use kjfk/galaxy-bar-detection-resnet50 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Keras
How to use kjfk/galaxy-bar-detection-resnet50 with Keras:
# !pip install -U keras tensorflow huggingface_hub # Keras needs TensorFlow installed to read "hf://" paths, so the tensorflow backend is selected here; # "jax" and "torch" also work for computation once TensorFlow is installed. import os os.environ["KERAS_BACKEND"] = "tensorflow" import keras model = keras.saving.load_model("hf://kjfk/galaxy-bar-detection-resnet50") - Notebooks
- Google Colab
- Kaggle
Galaxy Bar Detection β ResNet50 (IITK Astronomy Project)
A CNN that measures stellar bar strength in simulated disc galaxies from a single image β and classifies barred vs unbarred as a by-product.
β Final model: regression_resnet50.weights.h5
Regresses the physical A2/A0 Fourier bar-strength directly from a 224Γ224 grayscale stellar-density image. Classification = predicted A2/A0 β₯ 0.19.
| Metric (450-image test set, held-out snapshots) | Value |
|---|---|
| Classification accuracy | 96.0% |
| ROC AUC | 0.981 |
| Bar recall | 92.0% |
| Strength error (MAE) | 0.022 in A2/A0 units (range 0β0.28) |
| Face-on (0Β°) accuracy / MAE | 100% / 0.014 |
It reproduces the physics across the whole simulation
Run over 182 snapshots spanning the simulation, the CNN's predictions track the
independently-computed A2/A0 curve through the entire bar-formation history β
MAE 0.0144 β from images alone (bar_evolution.png).
It generalises beyond its training range
Trained only on inclinations β€ 40Β°, evaluated 0β90Β° on held-out snapshots
(tilt_breakdown.png):
| Inclination | 0Β° | 20Β° | 40Β° | 50Β° | 60Β° | 70β80Β° | 90Β° |
|---|---|---|---|---|---|---|---|
| Accuracy | 100% | 89% | 89% | 89% | 78% | ~70% | 82% |
Performance holds at 50Β° (never trained there) and degrades gracefully toward edge-on, where a bar is physically hidden by projection.
The key finding: reframing beat data
The binary classifier trained on the same images scored 86.4%. Switching the
target from a bar/no-bar label to the continuous A2/A0 value took it to
96.0%. An ablation isolates the cause (ablation_attribution.png):
| Setup | Same 450-image test |
|---|---|
| Binary classification, v3 data | 86.4% |
| Regression, identical v3 data | 95.6% |
| Regression + 1,500 extra mid-strength images | 96.0% |
+9.2 points came from the reframing alone; the extra data added +0.4 (within noise). Binary labels forced the discarding of "mid-strength" galaxies (0.10 < A2/A0 < 0.22) β exactly the region containing the 0.19 decision boundary β leaving the classifier blind where it most needed to see. Regression removes the need to discard anything and supervises the full continuum.
Loading (weights-only β a Keras full-model serialization bug)
from tensorflow import keras
from tensorflow.keras import layers
base = keras.applications.ResNet50(weights=None, include_top=False, input_shape=(224,224,3))
inp = keras.Input((224,224,3))
x = keras.Sequential([layers.Identity()])(inp) # placeholder (augmentation at train time)
x = keras.applications.resnet50.preprocess_input(x)
x = base(x, training=False)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.3)(x)
out = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inp, out)
model.load_weights("regression_resnet50.weights.h5")
# prediction * 0.30 = A2/A0 ; >= 0.19 means "barred"
Input spec (must match exactly, or predictions are invalid): 224Γ224
stellar-density map, log10 clipped to 1e7β1e9 then normalised 0β1, grayscale
replicated to 3 channels, 40 kpc field of view, galaxy centred and face-on
aligned before tilting.
Training
ResNet50 (ImageNet) two-phase transfer learning: freeze backbone + train head (8 epochs, lr 1e-3), then unfreeze and fine-tune (β€18 epochs, lr 1e-5, early stopping on val MAE). Huber loss, random rotation/flip/translation augmentation. Splits are by simulation snapshot, never by image, so no galaxy appears in both training and test. Verified no overfitting: train MAE β test MAE.
Labels are physical, not manual
Every image inherits the A2/A0 bar strength computed from the N-body particle data of its source snapshot (GADGET simulation, 502 snapshots) β no human labelling anywhere in the pipeline.
Earlier binary models (the journey)
bar_resnet50_v{1,2,3}.keras β v1 76.5% (tilts to 60Β°, label noise from
invisible bars) β v2 86.8% (tilt capped at 40Β°) β v3 86.4% (AUC 0.944). Adding
test-time augmentation + 3-seed ensembling reached 91.8%. A morpho-kinematic
variant (velocity + dispersion channels) was tested and did not help
(83.3%) β morphology alone suffices at β€40Β°. Across architectures on the
regression task: ResNet50 96.0% β« ConvNeXt-Tiny 91.6% β« EfficientNetV2-B0 84.0%;
ensembling diluted the strongest model rather than improving it.
Limitations
One simulated galaxy observed at many epochs β generalisation to other galaxies is untested. Sim-to-real transfer (telescope noise, PSF, foreground stars) is also untested. Valid domain: inclinations β² 50Β°, images built with the exact render recipe above.
Code, dataset pipeline, all 15 figures and full analysis: https://github.com/GuptaOum/IITK_astronomy_project
- Downloads last month
- 97