BiTAge#
Index#
Let’s first import some packages:
[1]:
import os
import inspect
import shutil
import json
import torch
import pandas as pd
import pyaging as pya
Instantiate model class#
[2]:
def print_entire_class(cls):
source = inspect.getsource(cls)
print(source)
print_entire_class(pya.models.BiTAge)
class BiTAge(pyagingModel):
def __init__(self):
super().__init__()
def preprocess(self, x):
"""
Binarizes an array based on the median of each row, excluding zeros.
"""
# Create a mask for non-zero elements
non_zero_mask = x != 0
# Apply mask, calculate median for each row, and binarize data
for i in range(x.size(0)):
non_zero_elements = x[i][non_zero_mask[i]]
if non_zero_elements.nelement() > 0:
median_value = non_zero_elements.median()
x[i] = (x[i] > median_value).float()
else:
# Handle the case where all elements are zero
x[i] = torch.zeros_like(x[i])
return x
def postprocess(self, x):
return x
[3]:
model = pya.models.BiTAge()
Define clock metadata#
[4]:
model.metadata["clock_name"] = 'bitage'
model.metadata["data_type"] = 'transcriptomics'
model.metadata["species"] = 'C elegans'
model.metadata["year"] = 2021
model.metadata["approved_by_author"] = '✅'
model.metadata["citation"] = "Meyer, David H., and Björn Schumacher. \"BiT age: A transcriptome‐based aging clock near the theoretical limit of accuracy.\" Aging cell 20.3 (2021): e13320."
model.metadata["doi"] = 'https://doi.org/10.1111/acel.13320'
model.metadata["research_only"] = None
model.metadata["notes"] = None
Download clock dependencies#
Download GitHub repository#
[5]:
github_url = "https://github.com/Meyer-DH/AgingClock.git"
github_folder_name = github_url.split('/')[-1].split('.')[0]
os.system(f"git clone {github_url}")
[5]:
0
Load features#
From CSV file#
[6]:
model.features = pd.read_csv('AgingClock/Data/Predictor_Genes.csv')['WormBaseID'].tolist()
Load weights into base model#
From CSV file#
[7]:
weights = pd.read_csv('AgingClock/Data/Predictor_Genes.csv')['ElasticNet_Coef'].tolist()
weights = torch.tensor(weights).unsqueeze(0).float()
intercept = torch.tensor([103.54631743289005]).float()
Linear model#
[8]:
base_model = pya.models.LinearModel(input_dim=len(model.features))
base_model.linear.weight.data = weights.float()
base_model.linear.bias.data = intercept.float()
model.base_model = base_model
Load reference values#
[9]:
model.reference_values = None
Load preprocess and postprocess objects#
[10]:
model.preprocess_name = "binarize"
model.preprocess_dependencies = None
[11]:
model.postprocess_name = None
model.postprocess_dependencies = None
Check all clock parameters#
[12]:
pya.utils.print_model_details(model)
%==================================== Model Details ====================================%
Model Attributes:
training: True
metadata: {'approved_by_author': '✅',
'citation': 'Meyer, David H., and Björn Schumacher. "BiT age: A '
'transcriptome‐based aging clock near the theoretical limit of '
'accuracy." Aging cell 20.3 (2021): e13320.',
'clock_name': 'bitage',
'data_type': 'transcriptomics',
'doi': 'https://doi.org/10.1111/acel.13320',
'notes': None,
'research_only': None,
'species': 'C elegans',
'version': None,
'year': 2021}
reference_values: None
preprocess_name: 'binarize'
preprocess_dependencies: None
postprocess_name: None
postprocess_dependencies: None
features: ['WBGene00012747', 'WBGene00011554', 'WBGene00002259', 'WBGene00018196', 'WBGene00017813', 'WBGene00020516', 'WBGene00008357', 'WBGene00019885', 'WBGene00016717', 'WBGene00017841', 'WBGene00018645', 'WBGene00021321', 'WBGene00000609', 'WBGene00045399', 'WBGene00012840', 'WBGene00011753', 'WBGene00003562', 'WBGene00010924', 'WBGene00018257', 'WBGene00001694', 'WBGene00000669', 'WBGene00008708', 'WBGene00016423', 'WBGene00019184', 'WBGene00013548', 'WBGene00008341', 'WBGene00016394', 'WBGene00001758', 'WBGene00000778', 'WBGene00017501']... [Total elements: 576]
base_model_features: None
%==================================== Model Details ====================================%
Model Structure:
base_model: LinearModel(
(linear): Linear(in_features=576, out_features=1, bias=True)
)
%==================================== Model Details ====================================%
Model Parameters and Weights:
base_model.linear.weight: [-3.9183850288391113, -3.661531448364258, -3.4419755935668945, -3.357285976409912, -3.152588367462158, -3.142742395401001, -3.1411612033843994, -3.1204745769500732, -3.048347234725952, -2.9659650325775146, -2.9609527587890625, -2.9258642196655273, -2.9174859523773193, -2.9001877307891846, -2.8675224781036377, -2.8590519428253174, -2.8371870517730713, -2.803004264831543, -2.7863166332244873, -2.726417064666748, -2.7252001762390137, -2.7046279907226562, -2.642418622970581, -2.6392977237701416, -2.631728172302246, -2.6270203590393066, -2.6188695430755615, -2.6094517707824707, -2.595085620880127, -2.590425968170166]... [Tensor of shape torch.Size([1, 576])]
base_model.linear.bias: tensor([103.5463])
%==================================== Model Details ====================================%
Basic test#
[13]:
torch.manual_seed(42)
input = torch.randn(10, len(model.features), dtype=float)
model.eval()
model.to(float)
pred = model(input)
pred
[13]:
tensor([[111.5220],
[148.4960],
[120.4686],
[119.6525],
[130.4869],
[131.7758],
[175.6584],
[139.2055],
[131.0180],
[136.8147]], dtype=torch.float64, grad_fn=<AddmmBackward0>)
Save torch model#
[14]:
torch.save(model, f"../weights/{model.metadata['clock_name']}.pt")
Clear directory#
[15]:
# Function to remove a folder and all its contents
def remove_folder(path):
try:
shutil.rmtree(path)
print(f"Deleted folder: {path}")
except Exception as e:
print(f"Error deleting folder {path}: {e}")
# Get a list of all files and folders in the current directory
all_items = os.listdir('.')
# Loop through the items
for item in all_items:
# Check if it's a file and does not end with .ipynb
if os.path.isfile(item) and not item.endswith('.ipynb'):
os.remove(item)
print(f"Deleted file: {item}")
# Check if it's a folder
elif os.path.isdir(item):
remove_folder(item)
Deleted folder: AgingClock