Kelmoir's picture
Various small documentation updates
022b0d1 verified
Raw
History Blame Contribute Delete
5.65 kB
import gradio as gr
import torch
import pandas as pd
from transformers import AutoModelForSequenceClassification, BertTokenizerFast
#Setting up the model
model_save_path = "Kelmoir/2026-02-14_CAFA6_classification_Rostlab_prot_bert_v1"
model = AutoModelForSequenceClassification.from_pretrained(model_save_path)
tokenizer = BertTokenizerFast.from_pretrained("Rostlab/prot_bert",
do_lower_case=False)
# Setting up the computation device - cuda or CPU
device = "cuda" if torch.cuda.is_available() else "cpu"
# Get the id2label
id2label = model.config.id2label
model.to(device)
def prepare_for_tokenization(input_prot_seq: str)-> str:
"""
This function shall insert a [SPACE] between each protein sequence item, and returns the resulting string,
also, uppercases the sting and replaces unlike proteins
A maximum length of 1024 is enforced as was used for model training
"""
if len(input_prot_seq) > 1024:
input_prot_seq = input_prot_seq[:1024]
input_prot_seq = input_prot_seq.strip().upper().replace(r"[UZOB]", "X")
spaces = " "*len(input_prot_seq)
# Source - https://stackoverflow.com/a
# Posted by Ma0, modified by community. See post 'Timeline' for change history
# Retrieved 2026-01-12, License - CC BY-SA 3.0
return ''.join(map(''.join, zip(input_prot_seq, spaces))).strip() # kudos @Coldspeed
def process_result(logits, threshold=0.6, top_n=10):
"""
This function will take in a single protein logit prediction and turns it into alist of predicted GO-terms
Args:
**logits** a single Logit array
**threshold** A float value between 0 and 1. Only GO-terms with a score higher than this value will be considered.
**top_n** An integer value. If no GO-terms are above the threshold, the top_n GO-terms will be returned.
Ensure, that the length is equal
"""
all_results = []
# Convert logits to probabilities using sigmoid
probabilities = torch.sigmoid(logits).squeeze()
# Get indices of GO terms above threshold
above_threshold_indices = torch.where(probabilities > threshold)[0]
# If no terms above threshold, take the top_n terms
if len(above_threshold_indices) == 0:
top_n_values, top_n_indices = torch.topk(probabilities, k=min(top_n, len(probabilities)))
selected_indices = top_n_indices
selected_probabilities = top_n_values
else:
selected_indices = above_threshold_indices
selected_probabilities = probabilities[above_threshold_indices]
# Sort selected terms by probability in descending order
sorted_probabilities, sort_indices = torch.sort(selected_probabilities, descending=True)
sorted_indices = selected_indices[sort_indices]
for idx, prob in zip(sorted_indices, sorted_probabilities):
go_term = id2label[idx.item()]
score = prob.item()
all_results.append([go_term, f"{score:.3f}"]) # Format score to 3 decimal places
results_df = pd.DataFrame(all_results)
# The request specifies 3 columns, all string, no headers, no index
return results_df
def predict_on_input(input: str, threshold:float):
model.eval()
with torch.inference_mode():
tokenized = tokenizer(prepare_for_tokenization(input),
return_tensors="pt").to(device)
output_logits = model(**tokenized)
output_table = process_result(output_logits.logits,
threshold=threshold)
return output_table
description = """
This is a demo project to showcase my attempts at predicting the protein functions - known as GO-terms based of the protein amino acid string.
This is essentially the scope of the CAFA 6 challenge that was hosted on Kaggle - https://www.kaggle.com/competitions/cafa-6-protein-function-prediction/overview
This demo takes in a single protein sequence, and will then predict the corresonding GO-terms based of that, and display the score.
Right now, no further post-processing or frills are available.
The model used to perform the predictions is a fine tuned ProtBERT Model. See: https://huggingface.co/Rostlab/prot_bert
And finally, the model isn't to good right now, there is much more experimentation ahead. For instance, the example was reported with the following GO-terms:
- GO:1990837
- GO:0005515
"""
demo = gr.Interface(
fn = predict_on_input,
inputs = [
gr.Textbox(value="MHHRMNEMNLSPVGMEQLTSSSVSNALPVSGSHLGLAASPTHSAIPAPGLPVAIPNLGPSLSSLPSALSLMLPMGIGDRGVMCGLPERNYTLPPPPYPHLESSYFRTILPGILSYLADRPPPQYIHPNSINVDGNTALSITNNPSALDPYQSNGNVGLEPGIVSIDSRSVNTHGAQSLHPSDGHEVALDTAITMENVSRVTSPISTDGMAEELTMDGVAGEHSQIPNGSRSHEPLSVDSVSNNLAADAVGHGGVIPMHGNGLELPVVMETDHIASRVNGMSDSALSDSIHTVAMSTNSVSVALSTSHNLASLESVSLHEVGLSLEPVAVSSITQEVAMGTGHVDVSSDSLSFVSPSLQMEDSNSNKENMATLFTIWCTLCDRAYPSDCPEHGPVTFVPDTPIESRARLSLPKQLVLRQSIVGAEVGVWTGETIPVRTCFGPLIGQQSHSMEVAEWTDKAVNHIWKIYHNGVLEFCIITTDENECNWMMFVRKARNREEQNLVAYPHDGKIFFCTSQDIPPENELLFYYSRDYAQQIGVPEHPDVHLCNCGKECNSYTEFKAHLTSHIHNHLPTQGHSGSHGPSHSKERKWKCSMCPQAFISPSKLHVHFMGHMGMKPHKCDFCSKAFSDPSNLRTHLKIHTGQKNYRCTLCDKSFTQKAHLESHMVIHTGEKNLKCDYCDKLFMRRQDLKQHVLIHTQERQIKCPKCDKLFLRTNHLKKHLNSHEGKRDYVCEKCTKAYLTKYHLTRHLKTCKGPTSSSSAPEEEEEDDSEEEDLADSVGTEDCRINSAVYSADESLSAHK",
label="Protein sequence",
show_label=True),
gr.Slider(minimum = -1,
maximum = 1,
step= 0.01,
value=0.25,
label="Prediction threshold",
show_label=True)
],
outputs = [
gr.Dataframe(label="Outpt table of Go-terms",
show_label=True)
],
description = description,
title ="CAFA ProtBERT prediction demo V1",
)
#demo.launch(debug=True)
demo.launch()