|
|
|
import gradio as gr |
|
import torch |
|
import torchvision |
|
import torch.nn as nn |
|
import torch.nn.functional as F |
|
import torch.optim as optim |
|
from torchvision import transforms |
|
from PIL import Image |
|
import pandas as pd |
|
import joblib,os |
|
|
|
from sklearn.preprocessing import MinMaxScaler,LabelEncoder |
|
|
|
n_tab_features = 8 |
|
num_classes = 11 |
|
n_pain_cls = 4 |
|
n_hidden = 128 |
|
|
|
project = os.getcwd() |
|
scaler = MinMaxScaler(feature_range=(0,1)) |
|
encoder = LabelEncoder() |
|
|
|
fun_tran= lambda x: [int(y) if y!=1 else 0 for y in np.exp( 5*np.log( [k if k>0 else 1 for k in x.flatten()] ) ) ] |
|
|
|
|
|
class DosagePredictionModel(nn.Module): |
|
def __init__(self, n_tab_features, n_pain_cls): |
|
super(DosagePredictionModel, self).__init__() |
|
self.fc1 = nn.Linear(n_tab_features, n_hidden) |
|
self.fc2 = nn.Linear(n_hidden, n_hidden) |
|
self.fc3 = nn.Linear(n_hidden, n_hidden//2) |
|
self.fc4 = nn.Linear(n_hidden//2, n_hidden//2) |
|
self.bn5 = nn.BatchNorm1d(n_hidden//2) |
|
self.fc6 = nn.Linear(n_hidden//2, num_classes) |
|
self.fc7 = nn.Linear(n_hidden//2, n_pain_cls) |
|
self.fc8 = nn.Linear(n_hidden//2, 1) |
|
|
|
|
|
def forward(self, x, regression_targets=None,classification_targets=None, pain_cls_tgt=None ): |
|
x = torch.relu(self.fc1(x)) |
|
x = torch.relu(self.fc2(x)) |
|
x = torch.relu(self.fc3(x)) |
|
x = torch.relu(self.fc4(x)) |
|
x = self.bn5(x) |
|
|
|
regression_output = self.fc8(x) |
|
regression_y = regression_output |
|
|
|
|
|
output_classification = self.fc6(x) |
|
output_classification = torch.softmax(output_classification,dim=1) |
|
pred_cls_y = torch.argmax(output_classification, dim = 1) |
|
|
|
|
|
pain_output_cls = self.fc7(x) |
|
pain_output_cls = torch.softmax(pain_output_cls,dim=1) |
|
pred_pain_cls_y = torch.argmax(pain_output_cls, dim = 1) |
|
|
|
if (classification_targets is None) or (regression_targets is None) or (pain_cls_tgt is None): |
|
|
|
loss, regression_loss, med_cls_loss, pain_cls_loss = None, None, None, None |
|
else: |
|
loss_fn = nn.SmoothL1Loss() |
|
regression_loss = loss_fn(regression_output, regression_targets.view(-1,1)) |
|
|
|
med_cls_loss = nn.CrossEntropyLoss()(output_classification, classification_targets ) |
|
|
|
pain_cls_loss = nn.CrossEntropyLoss()(pain_output_cls, pain_cls_tgt ) |
|
|
|
weight_dosage, weight_med_cls = 0.2, 0.4 |
|
loss = weight_dosage * regression_loss + weight_med_cls * med_cls_loss + (1-(weight_dosage+weight_med_cls))*pain_cls_loss |
|
return loss,regression_loss,med_cls_loss,pain_cls_loss, regression_y, pred_cls_y, pred_pain_cls_y |
|
|
|
|
|
|
|
model = DosagePredictionModel(n_tab_features, n_pain_cls) |
|
|
|
|
|
model.load_state_dict(torch.load("med_dos_pain_1.pt")) |
|
|
|
|
|
model.eval() |
|
|
|
|
|
medicines = ["Aspirin", "Lisinopril", "Metoprolol", "Hydrochlorothiazide"] |
|
dense_features = ['Weight_in_Kgs','Heart_rate','pulse_rate','Systolic_BP','Diastolic_BP','BIS_Value','SPO2'] |
|
sparse_features = ['Pain_Position'] |
|
|
|
|
|
def get_medicine_name(pred_medicine_class, pred_pain_cls): |
|
med_encoder = joblib.load(project+'/cat_encoder.joblib') |
|
pred_medicine_name = med_encoder.inverse_transform(pred_medicine_class) |
|
|
|
pain_level_enc= joblib.load(project+'/cat_dos_level_encoder.joblib') |
|
pred_dos_level_nm = pain_level_enc.inverse_transform(pred_pain_cls) |
|
|
|
|
|
return pred_medicine_name, pred_dos_level_nm |
|
|
|
|
|
def get_model_input(Weight_in_Kgs, Heart_rate, pulse_rate, Systolic_BP, Diastolic_BP, BIS_Value, SPO2, Pain_Position): |
|
values = [[Weight_in_Kgs, Heart_rate, pulse_rate, Systolic_BP, Diastolic_BP, BIS_Value, SPO2]] |
|
cat_values = [[Pain_Position]] |
|
all_values = [[Weight_in_Kgs, Heart_rate, pulse_rate, Systolic_BP, Diastolic_BP, BIS_Value, SPO2,Pain_Position]] |
|
temp = pd.DataFrame(all_values, columns= dense_features + sparse_features) |
|
|
|
|
|
scaler = joblib.load(project+'/scaler.joblib') |
|
temp[dense_features] = scaler.transform( temp[dense_features] ) |
|
|
|
|
|
|
|
painpos_encoder = joblib.load(project+'/cat_pain_level_encoder.joblib') |
|
temp[sparse_features] = painpos_encoder.transform( cat_values[0] ) |
|
|
|
|
|
input = torch.tensor(temp.to_numpy()).float() |
|
|
|
|
|
return input |
|
|
|
|
|
def predict(Weight_in_Kgs, Heart_rate, pulse_rate, Systolic_BP, Diastolic_BP, BIS_Value, SPO2, Pain_Position): |
|
|
|
X = get_model_input(Weight_in_Kgs, Heart_rate, pulse_rate, Systolic_BP, Diastolic_BP, BIS_Value, SPO2, Pain_Position) |
|
|
|
|
|
_, _, _, _, pred_dosage, pred_medicine_class, pred_pain_cls = model(X) |
|
|
|
medicine, dosage_level_nm = get_medicine_name(pred_medicine_class, pred_pain_cls) |
|
if Pain_Position =='No Pain': |
|
medicine, dosage_level_nm = 'NA', 'NA' |
|
|
|
return "The predicted medicine for you is: " + medicine[0], dosage_level_nm[0] |
|
|
|
Weight_in_Kgs, Heart_rate, pulse_rate, Systolic_BP = 75.3, 85.7, 84, 141 |
|
Diastolic_BP, BIS_Value, SPO2, Pain_Position = 92, 80, 90, 'Lower Back' |
|
predict(Weight_in_Kgs, Heart_rate, pulse_rate, Systolic_BP, Diastolic_BP, BIS_Value, SPO2, Pain_Position) |
|
|
|
interface = gr.Interface( |
|
fn=predict, |
|
inputs=[gr.inputs.Slider(minimum=40,maximum=120,step=1,label="Weight in Kgs"), |
|
gr.inputs.Slider(minimum=40,maximum=105,step=1,label="Heart rate"), |
|
gr.inputs.Slider(minimum=60,maximum=100,step=1,label="Pulse rate"), |
|
gr.inputs.Slider(minimum=115,maximum=142,step=1,label="Systolic BP"), |
|
gr.inputs.Slider(minimum=70,maximum=93,step=1,label="Diastolic BP"), |
|
gr.inputs.Slider(minimum=30,maximum=100,step=1,label="BIS Value"), |
|
gr.inputs.Slider(minimum=71,maximum=100,step=1,label="SPO2"), |
|
gr.inputs.Dropdown(['Lower Back', 'Shoulder ', 'Abdomine', 'Muscle', 'Neck', |
|
'Fybromialgia', 'Knee Joint', 'Joint pain', 'Shoulder', 'No Pain'], label="Pain Position", default="Lower Back") ], |
|
outputs=[gr.outputs.Textbox(label="Medicine"),gr.outputs.Textbox(label="Dosage Level")] ) |
|
|
|
|
|
interface.launch() |