Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
2f9644a
Enable training a new head
Mar 23, 2026
39ca964
add running instructions
Mar 23, 2026
7843b08
Two headed model template
Mar 30, 2026
912cf78
Replace tracks by heads
Mar 30, 2026
e88a7b3
ASAP 4 Cell lines
Apr 14, 2026
3cfce94
plots
Apr 20, 2026
08d3724
13 head train.py
May 2, 2026
58b8759
Merge branch 'multi-head' into linear_probing_multihead
May 2, 2026
ffd98b0
Change task.py for linear probing on multihead
May 2, 2026
58036c1
13 head train.py
May 2, 2026
4a8c793
Fix Cuda OOM on eval
May 7, 2026
935c2e0
13head experiment name + fix datasets
May 8, 2026
8532ce4
Fix num_heads
May 8, 2026
0f8627e
Merge branch 'two-headed-model' into linear_probing_multihead
May 9, 2026
389b049
Fix num heads
May 10, 2026
cfdf723
Fix types
May 10, 2026
d500e73
Fix criterion, model initialisation
May 10, 2026
307dba3
helper functions, remove them
May 12, 2026
d5652ea
Time epochs, fix early stopping, plot lp
May 17, 2026
cc265ea
Fine tuning
Jun 1, 2026
d994c5e
Remove local plotting and tutorial files from repository
Jun 30, 2026
2eaff9b
Update docstrings
Jun 30, 2026
c8a6ca5
Restore tutorials/train.py from main
Jun 30, 2026
3c58aa3
Merge branch 'main' into finetuning
Jun 30, 2026
7dae871
Add target head to predict_snv_atac
Aug 7, 2026
ccbbf1d
restore correct optimizer
alankuznicki Aug 6, 2026
46d2834
functions
alankuznicki Aug 6, 2026
5de8c9a
update jt function names
alankuznicki Aug 6, 2026
4c19ea6
added progressive training from scratch
alankuznicki Aug 6, 2026
6a97a26
added progressive extension of models
alankuznicki Aug 6, 2026
b1bbad6
add validation on new heads in task.py
alankuznicki Aug 6, 2026
762c18b
val on new heads in trainer.py
alankuznicki Aug 6, 2026
d3e6598
clauded num_workers to nonzero
alankuznicki Aug 7, 2026
ed96b45
memmap
alankuznicki Aug 7, 2026
a305c58
de-duplicated chromosome windows
alankuznicki Aug 7, 2026
3c04238
added comments on potential future issues
alankuznicki Aug 7, 2026
bb3f5f9
Revert "added comments on potential future issues"
alankuznicki Aug 11, 2026
370d64f
Revert "de-duplicated chromosome windows"
alankuznicki Aug 11, 2026
ab91bef
Revert "memmap"
alankuznicki Aug 11, 2026
3ccb706
Revert "clauded num_workers to nonzero"
alankuznicki Aug 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ generated/**
wandb/**
*/.DS_Store
.idea
*.png

/data
/checkpoint
/logs
/plots
/archive/imgs/
/tmp


# Created by https://www.gitignore.io/api/macos,python,R,linux,vim,emacs,visualstudiocode,intellij
Expand Down
5 changes: 4 additions & 1 deletion src/asap/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
from .dataset import training_datasets, peak_dataset, wg_dataset, robustness_peak_dataset, robustness_wg_dataset
from .task import train_model, eval_model, eval_robustness, export_predictions, predict_snv_atac


from .task import train_model, eval_model, eval_robustness, export_predictions, predict_snv_atac, train_new_head_lp, train_new_head_ft, train_multiheaded_model, eval_multihead_model, train_multiheaded_model_progressively, extend_multiheaded_model_progressively

8 changes: 5 additions & 3 deletions src/asap/dataloader/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ def __init__(
):
super().__init__()
self.genome = genome
if signal_files is not None:
self.signal_files = [signal_files]
else:
if signal_files is None:
self.signal_files = None
elif type(signal_files) is list:
self.signal_files = signal_files
else:
self.signal_files = [signal_files]

# if we randomly shift to augment the data
self.random_shift = random_shift
Expand Down
26 changes: 16 additions & 10 deletions src/asap/models/convnext_dcnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
'kernel2': 1,
'dropout': 0.3,
'final_dropout': 0.05,
'use_map': False
'use_map': False,
'num_heads': 1,
}


Expand Down Expand Up @@ -50,7 +51,8 @@ def __init__(self, **kwargs) -> None:
kernel1=config['kernel1'],
kernel2=config['kernel2'],
dropout=config['dropout'],
final_dropout=config['final_dropout'])
final_dropout=config['final_dropout'],
num_heads=config['num_heads'])

def forward(self, x:torch.Tensor, return_unmap=False) -> torch.Tensor:
x = torch.transpose(x, dim0=-1, dim1=-2)
Expand All @@ -70,7 +72,7 @@ class BasenjiCoreBlock(nn.Module):
def __init__(self, nr_tracks: int, window: int, filters_in,
nr_res_blocks: int = 11, rate_mult: float = 1.5, bin_size: int = 100, filters1: int = 128,
filters3: int = None, kernel1: int = 3, kernel2: int = 1, dropout: float = 0.3,
final_dropout: float = 0.05):
final_dropout: float = 0.05, num_heads=1):
super().__init__()
if not filters3:
filters3 = window
Expand All @@ -93,10 +95,11 @@ def __init__(self, nr_tracks: int, window: int, filters_in,
pool_size = bin_size // 2
self.pool = nn.AvgPool1d(kernel_size=pool_size, stride=pool_size)

self.linear_out = nn.Linear(
in_features=filters3,
out_features=nr_tracks,
)
print("creating output layer with tracks:", num_heads)
self.heads = nn.ModuleList([
nn.Linear(filters3, nr_tracks)
for _ in range(num_heads)
])
self.activation = nn.Softplus()

def forward(self, x:torch.Tensor) -> torch.Tensor:
Expand All @@ -115,9 +118,12 @@ def forward(self, x:torch.Tensor) -> torch.Tensor:
x = self.final_dropout(x)
x = self.pool(x)
x = torch.transpose(x, -2, -1)
x = self.linear_out(x)
x = self.activation(x)
return x
outputs = []
for head in self.heads:
out = head(x)
out = self.activation(out)
outputs.append(out)
return outputs


class ConvBlock(nn.Module):
Expand Down
6 changes: 3 additions & 3 deletions src/asap/snv/predict.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def _idx_to_ohe(idx: np.ndarray) -> np.ndarray:
one_hot_encoded = eye[idx]
return one_hot_encoded

def add_predictions(snv: pd.DataFrame, chroms: List[int], bw_file: str, model: nn.Module, genome: str, margin_size: int, window_size: int, bin_size: int, device: torch.device) -> None:
def add_predictions(snv: pd.DataFrame, chroms: List[int], bw_file: str, model: nn.Module, genome: str, margin_size: int, window_size: int, bin_size: int, device: torch.device, target_head=0) -> None:
# Ensure output columns exist
output_columns = ['signal_true', 'signal_pred_ref', 'signal_pred_alt']
for col in output_columns:
Expand Down Expand Up @@ -56,8 +56,8 @@ def add_predictions(snv: pd.DataFrame, chroms: List[int], bw_file: str, model: n
x = _idx_to_ohe(x).astype(np.float32)
x_var = _idx_to_ohe(x_var).astype(np.float32)

ref_pred = model(torch.from_numpy(x).to(device))
var_pred = model(torch.from_numpy(x_var).to(device))
ref_pred = model(torch.from_numpy(x).to(device))[target_head]
var_pred = model(torch.from_numpy(x_var).to(device))[target_head]
for (i, _), true, ref, var in zip(chr_df_i.iterrows(), y, ref_pred.cpu().detach().numpy(), var_pred.cpu().detach().numpy()):
snv.loc[i, 'signal_true'] = json.dumps(true.flatten().tolist())
snv.loc[i, 'signal_pred_ref'] = json.dumps(ref.tolist())
Expand Down
Loading