CoolFace
Apppublic

Tufan1/CVD-Predictor-Probablity

sourceHugging Faceapache-2.0updated 1y agoView on Hugging Face
0likes
app.py174 linesDownload Raw Back to root
1import streamlit as st2import torch3from transformers import AutoTokenizer, AutoModelForSequenceClassification4import re5from peft import PeftModel6from pydub import AudioSegment7import speech_recognition as sr8import io9from audio_recorder_streamlit import audio_recorder10 11# Load model and tokenizer from local fine-tuned directory12BASE_MODEL = "stanford-crfm/BioMedLM" #Huggingface13ADAPTER_ID = "Tufan1/BioMedLM-Cardio-Classifier-Fold1"14tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)15tokenizer.pad_token = tokenizer.eos_token16 17 18# Load base model as a sequence classification model19base_model = AutoModelForSequenceClassification.from_pretrained(20    BASE_MODEL,21    torch_dtype="float32",22    num_labels=1,23    low_cpu_mem_usage=True,24    device_map="cpu"25)26 27model = PeftModel.from_pretrained(28    base_model,29    ADAPTER_ID,30    device_map="cpu",31    adapter_name="cardio_adapter"32)33tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)34if tokenizer.pad_token is None:35    tokenizer.pad_token = tokenizer.eos_token36# Dictionaries to decode user inputs37gender_map = {1: "Female", 2: "Male"}38cholesterol_map = {1: "Normal", 2: "Elevated", 3: "Peak"}39glucose_map = {1: "Normal", 2: "High", 3: "Extreme"}40binary_map = {0: "No", 1: "Yes"}41 42def get_prediction(age, gender, height, weight, ap_hi, ap_lo,43                   cholesterol, glucose, smoke, alco, active):44    input_text = f"""Patient Record:45- Age: {age} years46- Gender: {gender_map[gender]}47- Height: {height} cm48- Weight: {weight} kg49- Systolic BP: {ap_hi} mmHg50- Diastolic BP: {ap_lo} mmHg51- Cholesterol Level: {cholesterol_map[cholesterol]}52- Glucose Level: {glucose_map[glucose]}53- Smokes: {binary_map[smoke]}54- Alcohol Intake: {binary_map[alco]}55- Physically Active: {binary_map[active]}"""56 57    inputs = tokenizer(input_text, return_tensors="pt", padding=True, truncation=True).to("cpu")58    model.eval()59    with torch.no_grad():60        outputs = model(**inputs)61        logits = outputs.logits.squeeze().item()62        prob = torch.sigmoid(torch.tensor(logits)).item()63 64    diagnosis = f"CVD Probability: {prob:.2%} โ€” {'๐Ÿ›‘ Cardiovascular Disease Detected' if prob > 0.7 else 'โœ… No Cardiovascular Disease'}"65    return diagnosis66 67def extract_details_from_text(text):68    age = int(re.search(r'(\d+)\s*year', text).group(1)) if re.search(r'(\d+)\s*year', text) else None69    gender = 2 if "man" in text.lower() else (1 if "female" in text.lower() else None)70    height = int(re.search(r'(\d+)\s*cm', text).group(1)) if re.search(r'(\d+)\s*cm', text) else None71    weight = int(re.search(r'(\d+)\s*kg', text).group(1)) if re.search(r'(\d+)\s*kg', text) else None72    bp_match = re.search(r'BP\s*(\d+)[/](\d+)', text)73    ap_hi, ap_lo = (int(bp_match.group(1)), int(bp_match.group(2))) if bp_match else (None, None)74    cholesterol = 3 if "peak" in text.lower() else 2 if "elevated" in text.lower() else 175    glucose = 3 if "extreme" in text.lower() else 2 if "high" in text.lower() else 176    smoke = 1 if "smoke" in text.lower() else 077    alco = 1 if "alcohol" in text.lower() else 078    active = 1 if "exercise" in text.lower() or "active" in text.lower() else 079    return age, gender, height, weight, ap_hi, ap_lo, cholesterol, glucose, smoke, alco, active80 81st.set_page_config(page_title="Cardiovascular Disease Predictor", layout="centered")82st.title("๐Ÿซ€ Cardiovascular Disease Predictor (LLM Powered)")83st.markdown("This tool uses a fine-tuned BioMedLM model to predict cardiovascular conditions from structured, text, or voice input.")84 85input_mode = st.radio("Choose input method:", ["Manual Input", "Text Phrase", "Audio Upload"])86 87if input_mode == "Manual Input":88    age = st.number_input("Age (years)", min_value=1, max_value=120)89    gender = st.selectbox("Gender", [("Female", 1), ("Male", 2)], format_func=lambda x: x[0])[1]90    height = st.number_input("Height (cm)", min_value=50, max_value=250)91    weight = st.number_input("Weight (kg)", min_value=10, max_value=200)92    ap_hi = st.number_input("Systolic BP", min_value=80, max_value=250)93    ap_lo = st.number_input("Diastolic BP", min_value=40, max_value=150)94    cholesterol = st.selectbox("Cholesterol", [("Normal", 1), ("Elevated", 2), ("Peak", 3)], format_func=lambda x: x[0])[1]95    glucose = st.selectbox("Glucose", [("Normal", 1), ("High", 2), ("Extreme", 3)], format_func=lambda x: x[0])[1]96    smoke = st.radio("Smoker?", [("No", 0), ("Yes", 1)], format_func=lambda x: x[0])[1]97    alco = st.radio("Alcohol Intake?", [("No", 0), ("Yes", 1)], format_func=lambda x: x[0])[1]98    active = st.radio("Physically Active?", [("No", 0), ("Yes", 1)], format_func=lambda x: x[0])[1]99 100    if st.button("Predict Diagnosis"):101        diagnosis = get_prediction(age, gender, height, weight, ap_hi, ap_lo,102                                   cholesterol, glucose, smoke, alco, active)103        st.success(f"๐Ÿฉบ **{diagnosis}**")104 105elif input_mode == "Text Phrase":106    phrase = st.text_area("Enter patient details in natural language:", height=200)107    if st.button("Extract & Predict"):108        try:109            values = extract_details_from_text(phrase)110            if all(v is not None for v in values):111                diagnosis = get_prediction(*values)112                st.success(f"๐Ÿฉบ **{diagnosis}**")113            else:114                st.warning("Couldn't extract all fields from the text. Please revise.")115        except Exception as e:116            st.error(f"Error: {e}")117 118elif input_mode == "Audio Upload":119    audio_input_mode = st.radio("Choose audio input type:", ["Upload Audio File", "Record Audio"])120 121    if audio_input_mode == "Upload Audio File":122        uploaded_file = st.file_uploader("Upload audio file (WAV, MP3, M4A, MPEG)", type=["wav", "mp3", "m4a", "mpeg"])123 124        if uploaded_file:125            st.audio(uploaded_file, format='audio/wav')126            audio = AudioSegment.from_file(uploaded_file)127            if audio and len(audio) > 0:128                wav_io = io.BytesIO()129                audio.export(wav_io, format="wav")130                wav_io.seek(0)131 132                recognizer = sr.Recognizer()133                with sr.AudioFile(wav_io) as source:134                    audio_data = recognizer.record(source)135 136                try:137                    text = recognizer.recognize_google(audio_data)138                    st.markdown(f"**Transcribed Text:** _{text}_")139                    values = extract_details_from_text(text)140                    if all(v is not None for v in values):141                        diagnosis = get_prediction(*values)142                        st.success(f"๐Ÿฉบ **{diagnosis}**")143                    else:144                        st.warning("Could not extract complete information from audio.")145                except Exception as e:146                    st.error(f"Audio processing error: {e}")147            else:148                st.error("Uploaded audio file is empty or not valid.")149 150    elif audio_input_mode == "Record Audio":151        audio = audio_recorder("Click to record", "Recording...")152 153        if audio and len(audio) > 0:154            st.audio(audio, format="audio/wav")155            wav_io = io.BytesIO(audio)156 157            recognizer = sr.Recognizer()158            with sr.AudioFile(wav_io) as source:159                audio_data = recognizer.record(source)160 161            try:162                text = recognizer.recognize_google(audio_data)163                st.markdown(f"**Transcribed Text:** _{text}_")164                values = extract_details_from_text(text)165                if all(v is not None for v in values):166                    diagnosis = get_prediction(*values)167                    st.success(f"๐Ÿฉบ **{diagnosis}**")168                else:169                    st.warning("Could not extract complete information from recorded audio.")170            except Exception as e:171                st.error(f"Recording processing error: {e}")172        else:173            st.error("No audio recorded or audio is empty.")174