Projects

Real/Bogus Transient Detection

A custom CuPy CNN and a PyTorch implementation for separating real astrophysical events from false detections in ZTF image cutouts.

PyTorch CuPy NumPy scikit-learn CNNs

The problem

Modern sky surveys produce more candidate events than people can inspect by hand. Some are real transients—objects such as supernovae or comets that change in brightness or position—but many are artifacts from instruments or image processing. The useful signal can be subtle inside a small, noisy cutout.

I used the braai paper by Duev et al. as the architectural starting point for studying this real/bogus classification task. My work is inspired by the paper rather than a strict reproduction: the data, split, hyperparameters, and frameworks differ, so the results are not directly comparable.

What the model sees

The dataset contains 38,368 labeled candidates from the University of Washington's ZTF Alert Archive. Each example contains three 63 × 63 cutouts: the new science image, a reference template, and their difference. About 18,000 examples are labeled real and 20,000 bogus.

That spatial arrangement matters. I compared CNNs that operate directly on the cutouts with Logistic Regression and Random Forest baselines that flatten every example into 11,907 unrelated pixel values.

Building the CNN twice

I first implemented the VGG6-style network at a low level with NumPy-compatible CuPy operations. Each convolution, pooling, dropout, and fully connected layer owns its forward and backward passes. Converting sliding image patches with im2col and accumulating their gradients with col2im turned convolution into matrix multiplication and reduced a projected 67-day CPU training run to about 35 minutes on an NVIDIA L4 GPU.

I then rebuilt the same architecture in PyTorch as a benchmark. The framework version trained in under three minutes on a T4 GPU. Writing both made the tradeoff concrete: the custom version exposed initialization, gradient flow, and memory management, while PyTorch made the same model far faster to express and run.

What the comparison showed

All four models were evaluated on the same held-out set of 9,592 examples. Both CNNs outperformed the flattened baselines, while the custom implementation stayed close to the PyTorch model despite its much longer inference time.

Model Accuracy ROC AUC
PyTorch CNN 82.61% 0.9105
CuPy CNN 80.17% 0.8902
Random Forest 77.50% 0.8551
Logistic Regression 66.17% 0.7113

The Random Forest was more competitive than I expected, but the CNN results reinforced why preserving spatial structure is useful for these image triplets.

What I learned

I began this as a machine-learning exercise and finished with a much better understanding of what sits beneath a framework call. Training stability depended on details such as He and Xavier initialization, early stopping, GPU memory cleanup, and the representation of convolution itself.

The project also changed how I read evaluation results. Accuracy was only one part of the comparison; recall, threshold behavior, inference time, and implementation complexity all affect whether a classifier is practical for a large sky survey. More than anything, implementing the architecture gave me a stronger appreciation for the decisions in the original braai work.