Downloads · 30 days
80
26% of all-time downloads
Kentucky-Open-Science/DALE-CT-2S
DALE-CT-2S is a image feature extraction model from Kentucky-Open-Science. Use it for the image feature extraction task on the model card, and read the license before you ship it in a product. It is set up for timm. The card lists the license as cc-by-nc-sa-4.0.
Authors: Evan W. Damron (ORCID 0009-0009-1104-3202) · Mahmut S. Gokmen · Mitchell A. Klusty · Caroline N. Leach · Emily B. Collier · V. K. Cody Bumgardner — Institute for Biomedical Informatics Center for Applied AI (…
Downloads · 30 days
80
26% of all-time downloads
All-time downloads
312
Public
Parameters
304M
1.2 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors1.2 GB · 100%
From the Hugging Face model README
Authors: Evan W. Damron (ORCID 0009-0009-1104-3202) · Mahmut S. Gokmen · Mitchell A. Klusty · Caroline N. Leach · Emily B. Collier · V. K. Cody Bumgardner — Institute for Biomedical Informatics Center for Applied AI (IBI-CAAI), University of Kentucky
This repository hosts the backbone weights for DALE-CT-2S (Depth-Aware Latent-Euclidean Computed Tomography), a foundational Vision Transformer (ViT-Large) trained on Chest CT scans using the strictly non-predictive Latent-Euclidean Joint-Embedding Predictive Architecture (LeJEPA) framework.
This 2S model improves upon the 1S variant by introducing a native 512px architecture, a refined patch size (16), and a more sophisticated dual-source (2S) dense auxiliary supervision objective that balances macroscopic and fine-grained pathology tracking using both TotalSegmentator and ReXGroundingCT targets.
This model was developed by the Institute for Biomedical Informatics Center for Applied AI (IBI-CAAI) at the University of Kentucky to serve as a robust feature extractor for downstream medical imaging tasks, including segmentation, multi-instance learning (MIL), and anomaly detection.
Note: This model was originally published as Guided-Chest-CT-LeJEPA-2S. The name has been formally updated to DALE-CT-2S.
import timm
model = timm.create_model("hf-hub:Kentucky-Open-Science/DALE-CT-2S", pretrained=True)
model.eval()
Inputs must be Hounsfield-Unit slices preprocessed exactly as during training (clipping + z-score; see the full example below).
All numbers are our own head-to-head measurements: every model (including the public 3D baselines in the paper) is probed under one linear-probing MIL protocol on shared splits (CT-RATE n = 992 test scans; RAD-ChestCT n = 360). See the paper for the full protocol and confidence intervals.
| Model | CT-RATE Macro AUROC | RAD-ChestCT AUROC (frozen / retrained probe) | Role |
|---|---|---|---|
| DALE-CT-2S | 0.8247 | 0.6252 / 0.7389 | Best in-domain (CT-RATE) |
| DALE-CT-1S-v2 | 0.8098 | 0.6284 / 0.7334 | Anatomical (TotalSegmentator) dense supervision only |
| DALE-CT-0 | 0.8057 | 0.5946 / 0.7477 | Pure self-supervised, CT-RATE |
| Finetuned DINOv2 | 0.7953 | 0.6252 / 0.7550 | Continual-pretraining baseline — strongest dense (patch-level) features |
Paper: DALE-CT: Depth-Aware 2D Slice Encoders Learn an Anatomical World Model of Chest CT · Code: Kentucky-Open-Science/DALE-CT · Benchmark: Kentucky-Open-Science/chest-ct-foundation-model-benchmark
vit_large_patch14_dinov2 (via timm). Note: This model was randomly initialized and trained entirely from scratch with modified architecture arguments.512x512 resolution. The architecture supports variable input sizes dynamically, provided the height and width are divisible by the patch size (16).This model is intended for research purposes in the field of medical imaging and radiology.
[-997.0, 888.0]. These values correspond to the 0.5% and 99.5% pixel intensities of the foreground voxels calculated on a subset of the CT-RATE dataset. The clipped values were mapped to a [0, 1] range, followed by Z-score normalization utilizing a dataset mean of -142.39 and standard deviation of 360.97.bf16 mixed precision.3.0e-04 (decaying to 3.0e-05), and a 5,000-step warmup.The total loss combines the self-supervised spatial invariance objective with a dense auxiliary head: $$\mathcal{L}{\text{Total}}=\mathcal{L}{\text{LeJEPA}}+\lambda_{\text{aux}}\mathcal{L}{\text{Aux}}$$ where \(\lambda{\text{aux}}=0.1\).
The model utilizes a strictly non-predictive architecture that combines a spatial invariance loss with Sketched Isotropic Gaussian Regularization (SIGReg): $$\mathcal{L}{\text{LeJEPA}}=(1-\lambda)\mathcal{L}{\text{invariance}}+\lambda\mathcal{L}_{\text{SIGReg}}$$ where \(\lambda=0.02\). The SIGReg formulation projects embeddings onto a set of random 1D directions to enforce normality via empirical characteristic functions, completely avoiding traditional architectural heuristics like predictor networks.
The auxiliary loss evaluates soft, fractional labels describing the proportional composition of anatomy/pathology within a crop. It is split between macroscopic and fine-grained views, and further divided between TotalSegmentator (TS) and ReX predictions: $$\mathcal{L}{\text{Aux}}=0.5\cdot\mathcal{L}{\text{Global}}+0.5\cdot\mathcal{L}_{\text{Patch}}$$ Because ReX labels represent sparse abnormalities, their loss is strictly masked to prevent penalizing the model on unverified scans.
A specialized, GPU-accelerated augmentation pipeline generated the multi-crop views required for the invariant architecture.
1. Spatial & Guided Cropping
2. Intensity & Noise Augmentations
Because CT scans require strict Hounsfield Unit (HU) windowing and normalization to match the training distribution, you must apply the specific preprocessing logic below. Note: With 2S's native 512px architecture, standard CT slices (512x512) no longer require dynamic padding.
import torch
import numpy as np
import timm
from huggingface_hub import hf_hub_download
from safetensors.torch import load_file
class CTInferenceTransform:
"""
Applies the exact HU windowing and Z-score normalization used during DALE-CT 2S training.
Assumes standard 512x512 CT slice inputs.
"""
def __init__(self):
self.clip_min = -997.0
self.clip_max = 888.0
self.mean_hu = -142.39
self.std_hu = 360.97
# Calculate 0-1 scaled mean and std
range_val = self.clip_max - self.clip_min
self.norm_mean = (self.mean_hu - self.clip_min) / range_val
self.norm_std = self.std_hu / range_val
def __call__(self, volume):
# Expects a 2D numpy array or torch tensor (H, W) in Hounsfield Units
if isinstance(volume, np.ndarray):
volume = torch.from_numpy(volume).float()
if volume.ndim == 2:
volume = volume.unsqueeze(0) # Add channel dim: (1, H, W)
# 1. Clamp HU values and map strictly to [0, 1]
volume = torch.clamp(volume, self.clip_min, self.clip_max)
range_val = self.clip_max - self.clip_min
volume = (volume - self.clip_min) / range_val
# 2. Z-score standardization
volume = (volume - self.norm_mean) / self.norm_std
# Returns (1, 1, H, W). For batched inference, stack these along dim=0.
return volume.unsqueeze(0)
def load_ct_model(repo_id="Kentucky-Open-Science/DALE-CT-2S"):
"""
Downloads and initializes the ViT-Large backbone using timm and safetensors.
"""
# 1. Initialize the base architecture with 2S overrides (patch_size=16, img_size=512)
model = timm.create_model(
"vit_large_patch14_dinov2",
pretrained=False,
num_classes=0,
in_chans=1,
patch_size=16,
img_size=512,
dynamic_img_size=True
)
# 2. Download and load the custom safetensors weights
model_path = hf_hub_download(repo_id=repo_id, filename="model.safetensors")
state_dict = load_file(model_path)
model.load_state_dict(state_dict, strict=False)
model.eval()
return model
if __name__ == "__main__":
# Initialize the transform and the model
transform = CTInferenceTransform()
model = load_ct_model()
# Simulate a raw CT slice (Replace this with an actual NIfTI/DICOM load in Hounsfield Units)
raw_ct_slice = np.random.uniform(-1000, 1000, size=(512, 512))
# Process the image to ensure correct normalization
input_tensor = transform(raw_ct_slice)
# Extract embeddings
with torch.no_grad():
# Option A: Get the single pooled global feature for the entire slice
global_feature = model(input_tensor)
# Option B: Get the unpooled, dense spatial patch tokens (for fine-grained tasks like Segmentation)
patch_tokens = model.forward_features(input_tensor)
print(f"Input tensor shape: {input_tensor.shape}")
print(f"Extracted features shape: {global_feature.shape}")
print(f"Dense patch tokens shape: {patch_tokens.shape}")