add req
Browse files- app.py +61 -11
- flagged/log.csv +3 -0
- models/__pycache__/inception.cpython-38.pyc +0 -0
- models/__pycache__/inception.cpython-39.pyc +0 -0
- requirements.txt +6 -0
- sample_data/ath_001_1fwuysgx07e80a63e85e4405cb9ef432ca21b8096bc5d2de.dat +0 -0
- sample_data/ath_001_2ztxkdc11326385fdd37d229683c95ce9ac5e9768817f96f.hea +16 -0
- sample_data/ath_001_ewabg1uc1326385fdd37d229683c95ce9ac5e9768817f96f.hea +16 -0
- sample_data/ath_001_f17hino207e80a63e85e4405cb9ef432ca21b8096bc5d2de.dat +0 -0
- sample_data/ath_001_rh_j77511326385fdd37d229683c95ce9ac5e9768817f96f.hea +16 -0
- sample_data/ath_001_zxgouf9007e80a63e85e4405cb9ef432ca21b8096bc5d2de.dat +0 -0
- test.ipynb +190 -0
app.py
CHANGED
@@ -1,15 +1,28 @@
|
|
1 |
import os
|
2 |
import wfdb
|
|
|
3 |
import numpy as np
|
4 |
import gradio as gr
|
5 |
from models.inception import *
|
|
|
6 |
|
7 |
|
8 |
-
def load_data():
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
def load_model(sample_frequency,recording_time, num_leads):
|
15 |
cwd = os.getcwd()
|
@@ -19,14 +32,51 @@ def load_model(sample_frequency,recording_time, num_leads):
|
|
19 |
return model
|
20 |
|
21 |
|
22 |
-
def run(
|
23 |
SAMPLE_FREQUENCY = 100
|
24 |
TIME = 10
|
25 |
NUM_LEADS = 1
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
model = load_model(sample_frequency=SAMPLE_FREQUENCY,recording_time=TIME,num_leads=NUM_LEADS)
|
28 |
-
predicion = model.predict(
|
29 |
-
return predicion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
-
iface = gr.Interface(fn=run, inputs="text", outputs="text")
|
32 |
-
iface.launch()
|
|
|
1 |
import os
|
2 |
import wfdb
|
3 |
+
import shutil
|
4 |
import numpy as np
|
5 |
import gradio as gr
|
6 |
from models.inception import *
|
7 |
+
from scipy.signal import resample
|
8 |
|
9 |
|
10 |
+
def load_data(sample_data):
|
11 |
+
ecg, meta_data = wfdb.rdsamp(sample_data)
|
12 |
+
lead_I = ecg[:,0]
|
13 |
+
sample_frequency = meta_data["fs"]
|
14 |
+
return lead_I, sample_frequency
|
15 |
+
|
16 |
+
def preprocess_ecg(ecg,fs):
|
17 |
+
if fs != 100:
|
18 |
+
ecg = resample(ecg, int(len(ecg)*(100/fs)))
|
19 |
+
else:
|
20 |
+
pass
|
21 |
+
if len(ecg) > 1000:
|
22 |
+
ecg = ecg[:1000]
|
23 |
+
else:
|
24 |
+
pass
|
25 |
+
return ecg
|
26 |
|
27 |
def load_model(sample_frequency,recording_time, num_leads):
|
28 |
cwd = os.getcwd()
|
|
|
32 |
return model
|
33 |
|
34 |
|
35 |
+
def run(header_file, data_file):
|
36 |
SAMPLE_FREQUENCY = 100
|
37 |
TIME = 10
|
38 |
NUM_LEADS = 1
|
39 |
+
demo_dir = f"{CWD}/sample_data"
|
40 |
+
_, hdr_basename = os.path.split(header_file.name)
|
41 |
+
_, data_basename = os.path.split(data_file.name)
|
42 |
+
shutil.copyfile(data_file.name, f"{demo_dir}/{data_basename}")
|
43 |
+
shutil.copyfile(header_file.name, f"{demo_dir}/{hdr_basename}")
|
44 |
+
data, fs = load_data(f"{demo_dir}/{hdr_basename.split('.')[0]}")
|
45 |
+
ecg = preprocess_ecg(data,fs)
|
46 |
model = load_model(sample_frequency=SAMPLE_FREQUENCY,recording_time=TIME,num_leads=NUM_LEADS)
|
47 |
+
predicion = model.predict(np.expand_dims(ecg,0)).ravel()[0]
|
48 |
+
return str(round(predicion,1))
|
49 |
+
|
50 |
+
# Give credit to https://huggingface.co/spaces/Tej3/ECG_Classification/blob/main/app.py for interface
|
51 |
+
|
52 |
+
CWD = os.getcwd()
|
53 |
+
|
54 |
+
with gr.Blocks() as demo:
|
55 |
+
#with gr.Row():
|
56 |
+
# pred_type = gr.Radio(['Age', 'Gender'], label= "Select Model")
|
57 |
+
with gr.Row():
|
58 |
+
with gr.Column(scale=1):
|
59 |
+
header_file = gr.File(label = "header_file", file_types=[".hea"],)
|
60 |
+
data_file = gr.File(label = "data_file", file_types=[".dat"])
|
61 |
+
with gr.Column(scale=1):
|
62 |
+
output_age = gr.Textbox(label = "Predicted age")
|
63 |
+
#output_gender = gr.Textbox(label = "Predicted gender")
|
64 |
+
#with gr.Row():
|
65 |
+
# ecg_graph = gr.Plot(label = "ECG Signal Visualisation")
|
66 |
+
with gr.Row():
|
67 |
+
predict_btn = gr.Button("Predict")
|
68 |
+
predict_btn.click(fn= run, inputs = [#pred_type,
|
69 |
+
header_file, data_file], outputs=[output_age])
|
70 |
+
with gr.Row():
|
71 |
+
gr.Examples(examples=[[f"{CWD}/sample_data/ath_001.hea", f"{CWD}/sample_data/ath_001.dat"],\
|
72 |
+
# [f"{CWD}/demo_data/test/00008_lr.hea", f"{CWD}/demo_data/test/00008_lr.dat", "sinusrhythmus linkstyp qrs(t) abnormal inferiorer infarkt alter unbest."], \
|
73 |
+
# [f"{CWD}/demo_data/test/00045_lr.hea", f"{CWD}/demo_data/test/00045_lr.dat", "sinusrhythmus unvollstÄndiger rechtsschenkelblock sonst normales ekg"],\
|
74 |
+
# [f"{CWD}/demo_data/test/00257_lr.hea", f"{CWD}/demo_data/test/00257_lr.dat", "premature atrial contraction(s). sinus rhythm. left atrial enlargement. qs complexes in v2. st segments are slightly elevated in v2,3. st segments are depressed in i, avl. t waves are low or flat in i, v5,6 and inverted in avl. consistent with ischaemic h"],\
|
75 |
+
],
|
76 |
+
inputs = [header_file, data_file])
|
77 |
+
#
|
78 |
+
if __name__ == "__main__":
|
79 |
+
demo.launch()
|
80 |
|
81 |
+
#iface = gr.Interface(fn=run, inputs="text", outputs="text")
|
82 |
+
#iface.launch()
|
flagged/log.csv
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
ecg,output,flag,username,timestamp
|
2 |
+
1,,,,2024-01-13 13:13:14.648011
|
3 |
+
1,,,,2024-01-13 13:13:16.151475
|
models/__pycache__/inception.cpython-38.pyc
ADDED
Binary file (2.59 kB). View file
|
|
models/__pycache__/inception.cpython-39.pyc
ADDED
Binary file (2.58 kB). View file
|
|
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio==3.25.0
|
2 |
+
numpy==1.24.2
|
3 |
+
tqdm==4.64.1
|
4 |
+
wfdb==4.1.0
|
5 |
+
scipy==1.7.3
|
6 |
+
tensorflow=2.8.0
|
sample_data/ath_001_1fwuysgx07e80a63e85e4405cb9ef432ca21b8096bc5d2de.dat
ADDED
Binary file (120 kB). View file
|
|
sample_data/ath_001_2ztxkdc11326385fdd37d229683c95ce9ac5e9768817f96f.hea
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
ath_001 12 500 5000
|
2 |
+
ath_001.dat 16 50000/mV 16 0 10251 49595 0 I
|
3 |
+
ath_001.dat 16 50000/mV 16 0 -1096 35223 0 II
|
4 |
+
ath_001.dat 16 50000/mV 16 0 -10267 60826 0 III
|
5 |
+
ath_001.dat 16 50000/mV 16 0 -3724 3505 0 AVR
|
6 |
+
ath_001.dat 16 50000/mV 16 0 9391 26379 0 AVL
|
7 |
+
ath_001.dat 16 50000/mV 16 0 -5395 57481 0 AVF
|
8 |
+
ath_001.dat 16 50000/mV 16 0 13580 61759 0 V1
|
9 |
+
ath_001.dat 16 50000/mV 16 0 11410 33501 0 V2
|
10 |
+
ath_001.dat 16 50000/mV 16 0 14721 52508 0 V3
|
11 |
+
ath_001.dat 16 50000/mV 16 0 16103 51083 0 V4
|
12 |
+
ath_001.dat 16 50000/mV 16 0 6662 44197 0 V5
|
13 |
+
ath_001.dat 16 50000/mV 16 0 -3806 11333 0 V6
|
14 |
+
#SL12: Sinus bradycardia with marked sinus arrhythmia, Right axis deviation, Borderline ECG
|
15 |
+
#C: Sinus arrhythmia, Normal ECG
|
16 |
+
|
sample_data/ath_001_ewabg1uc1326385fdd37d229683c95ce9ac5e9768817f96f.hea
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
ath_001 12 500 5000
|
2 |
+
ath_001.dat 16 50000/mV 16 0 10251 49595 0 I
|
3 |
+
ath_001.dat 16 50000/mV 16 0 -1096 35223 0 II
|
4 |
+
ath_001.dat 16 50000/mV 16 0 -10267 60826 0 III
|
5 |
+
ath_001.dat 16 50000/mV 16 0 -3724 3505 0 AVR
|
6 |
+
ath_001.dat 16 50000/mV 16 0 9391 26379 0 AVL
|
7 |
+
ath_001.dat 16 50000/mV 16 0 -5395 57481 0 AVF
|
8 |
+
ath_001.dat 16 50000/mV 16 0 13580 61759 0 V1
|
9 |
+
ath_001.dat 16 50000/mV 16 0 11410 33501 0 V2
|
10 |
+
ath_001.dat 16 50000/mV 16 0 14721 52508 0 V3
|
11 |
+
ath_001.dat 16 50000/mV 16 0 16103 51083 0 V4
|
12 |
+
ath_001.dat 16 50000/mV 16 0 6662 44197 0 V5
|
13 |
+
ath_001.dat 16 50000/mV 16 0 -3806 11333 0 V6
|
14 |
+
#SL12: Sinus bradycardia with marked sinus arrhythmia, Right axis deviation, Borderline ECG
|
15 |
+
#C: Sinus arrhythmia, Normal ECG
|
16 |
+
|
sample_data/ath_001_f17hino207e80a63e85e4405cb9ef432ca21b8096bc5d2de.dat
ADDED
Binary file (120 kB). View file
|
|
sample_data/ath_001_rh_j77511326385fdd37d229683c95ce9ac5e9768817f96f.hea
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
ath_001 12 500 5000
|
2 |
+
ath_001.dat 16 50000/mV 16 0 10251 49595 0 I
|
3 |
+
ath_001.dat 16 50000/mV 16 0 -1096 35223 0 II
|
4 |
+
ath_001.dat 16 50000/mV 16 0 -10267 60826 0 III
|
5 |
+
ath_001.dat 16 50000/mV 16 0 -3724 3505 0 AVR
|
6 |
+
ath_001.dat 16 50000/mV 16 0 9391 26379 0 AVL
|
7 |
+
ath_001.dat 16 50000/mV 16 0 -5395 57481 0 AVF
|
8 |
+
ath_001.dat 16 50000/mV 16 0 13580 61759 0 V1
|
9 |
+
ath_001.dat 16 50000/mV 16 0 11410 33501 0 V2
|
10 |
+
ath_001.dat 16 50000/mV 16 0 14721 52508 0 V3
|
11 |
+
ath_001.dat 16 50000/mV 16 0 16103 51083 0 V4
|
12 |
+
ath_001.dat 16 50000/mV 16 0 6662 44197 0 V5
|
13 |
+
ath_001.dat 16 50000/mV 16 0 -3806 11333 0 V6
|
14 |
+
#SL12: Sinus bradycardia with marked sinus arrhythmia, Right axis deviation, Borderline ECG
|
15 |
+
#C: Sinus arrhythmia, Normal ECG
|
16 |
+
|
sample_data/ath_001_zxgouf9007e80a63e85e4405cb9ef432ca21b8096bc5d2de.dat
ADDED
Binary file (120 kB). View file
|
|
test.ipynb
ADDED
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 41,
|
6 |
+
"metadata": {},
|
7 |
+
"outputs": [],
|
8 |
+
"source": [
|
9 |
+
"import os\n",
|
10 |
+
"import wfdb\n",
|
11 |
+
"import numpy as np\n",
|
12 |
+
"import gradio as gr\n",
|
13 |
+
"from models.inception import *\n",
|
14 |
+
"from scipy.signal import resample\n",
|
15 |
+
"\n",
|
16 |
+
"\n",
|
17 |
+
"def load_data():\n",
|
18 |
+
" cwd = os.getcwd()\n",
|
19 |
+
" sample_data = f\"{cwd}/sample_data/ath_001\"\n",
|
20 |
+
" ecg, meta_data = wfdb.rdsamp(sample_data)\n",
|
21 |
+
" lead_I = ecg[:,0]\n",
|
22 |
+
" sample_frequency = meta_data[\"fs\"]\n",
|
23 |
+
" return lead_I, sample_frequency\n",
|
24 |
+
"\n",
|
25 |
+
"def preprocess_ecg(ecg,fs):\n",
|
26 |
+
" if fs != 500:\n",
|
27 |
+
" ecg = resample(ecg, int(len(ecg)*(500/fs)))\n",
|
28 |
+
" else:\n",
|
29 |
+
" pass\n",
|
30 |
+
" if len(ecg) > 5000:\n",
|
31 |
+
" ecg = ecg[:5000]\n",
|
32 |
+
" else:\n",
|
33 |
+
" pass\n",
|
34 |
+
" return ecg\n",
|
35 |
+
"\n",
|
36 |
+
"def load_model(sample_frequency,recording_time, num_leads):\n",
|
37 |
+
" cwd = os.getcwd()\n",
|
38 |
+
" weights = f\"{cwd}/models/weights/model_weights_leadI.h5\"\n",
|
39 |
+
" model = build_model((sample_frequency * recording_time, num_leads), 1)\n",
|
40 |
+
" model.load_weights(weights)\n",
|
41 |
+
" return model\n",
|
42 |
+
"\n",
|
43 |
+
"\n",
|
44 |
+
"def run(ecg):\n",
|
45 |
+
" SAMPLE_FREQUENCY = 100\n",
|
46 |
+
" TIME = 10\n",
|
47 |
+
" NUM_LEADS = 1\n",
|
48 |
+
" data, fs = load_data()\n",
|
49 |
+
" model = load_model(sample_frequency=SAMPLE_FREQUENCY,recording_time=TIME,num_leads=NUM_LEADS)\n",
|
50 |
+
" predicion = model.predict(data)\n",
|
51 |
+
" return str(predicion)"
|
52 |
+
]
|
53 |
+
},
|
54 |
+
{
|
55 |
+
"cell_type": "code",
|
56 |
+
"execution_count": 42,
|
57 |
+
"metadata": {},
|
58 |
+
"outputs": [],
|
59 |
+
"source": [
|
60 |
+
"data, fs = load_data()"
|
61 |
+
]
|
62 |
+
},
|
63 |
+
{
|
64 |
+
"cell_type": "code",
|
65 |
+
"execution_count": 43,
|
66 |
+
"metadata": {},
|
67 |
+
"outputs": [
|
68 |
+
{
|
69 |
+
"data": {
|
70 |
+
"text/plain": [
|
71 |
+
"(5000,)"
|
72 |
+
]
|
73 |
+
},
|
74 |
+
"execution_count": 43,
|
75 |
+
"metadata": {},
|
76 |
+
"output_type": "execute_result"
|
77 |
+
}
|
78 |
+
],
|
79 |
+
"source": [
|
80 |
+
"data.shape"
|
81 |
+
]
|
82 |
+
},
|
83 |
+
{
|
84 |
+
"cell_type": "code",
|
85 |
+
"execution_count": 49,
|
86 |
+
"metadata": {},
|
87 |
+
"outputs": [],
|
88 |
+
"source": [
|
89 |
+
"out = preprocess_ecg(data,250)"
|
90 |
+
]
|
91 |
+
},
|
92 |
+
{
|
93 |
+
"cell_type": "code",
|
94 |
+
"execution_count": 50,
|
95 |
+
"metadata": {},
|
96 |
+
"outputs": [
|
97 |
+
{
|
98 |
+
"data": {
|
99 |
+
"text/plain": [
|
100 |
+
"(5000,)"
|
101 |
+
]
|
102 |
+
},
|
103 |
+
"execution_count": 50,
|
104 |
+
"metadata": {},
|
105 |
+
"output_type": "execute_result"
|
106 |
+
}
|
107 |
+
],
|
108 |
+
"source": [
|
109 |
+
"out[:5000].shape"
|
110 |
+
]
|
111 |
+
},
|
112 |
+
{
|
113 |
+
"cell_type": "code",
|
114 |
+
"execution_count": 39,
|
115 |
+
"metadata": {},
|
116 |
+
"outputs": [
|
117 |
+
{
|
118 |
+
"data": {
|
119 |
+
"text/plain": [
|
120 |
+
"0.5"
|
121 |
+
]
|
122 |
+
},
|
123 |
+
"execution_count": 39,
|
124 |
+
"metadata": {},
|
125 |
+
"output_type": "execute_result"
|
126 |
+
}
|
127 |
+
],
|
128 |
+
"source": [
|
129 |
+
"500/1000"
|
130 |
+
]
|
131 |
+
},
|
132 |
+
{
|
133 |
+
"cell_type": "code",
|
134 |
+
"execution_count": 30,
|
135 |
+
"metadata": {},
|
136 |
+
"outputs": [],
|
137 |
+
"source": [
|
138 |
+
"upsamp = preprocess_ecg(data,1000)"
|
139 |
+
]
|
140 |
+
},
|
141 |
+
{
|
142 |
+
"cell_type": "code",
|
143 |
+
"execution_count": 31,
|
144 |
+
"metadata": {},
|
145 |
+
"outputs": [
|
146 |
+
{
|
147 |
+
"data": {
|
148 |
+
"text/plain": [
|
149 |
+
"array([0.])"
|
150 |
+
]
|
151 |
+
},
|
152 |
+
"execution_count": 31,
|
153 |
+
"metadata": {},
|
154 |
+
"output_type": "execute_result"
|
155 |
+
}
|
156 |
+
],
|
157 |
+
"source": [
|
158 |
+
"upsamp"
|
159 |
+
]
|
160 |
+
},
|
161 |
+
{
|
162 |
+
"cell_type": "code",
|
163 |
+
"execution_count": null,
|
164 |
+
"metadata": {},
|
165 |
+
"outputs": [],
|
166 |
+
"source": []
|
167 |
+
}
|
168 |
+
],
|
169 |
+
"metadata": {
|
170 |
+
"kernelspec": {
|
171 |
+
"display_name": "new_tf",
|
172 |
+
"language": "python",
|
173 |
+
"name": "python3"
|
174 |
+
},
|
175 |
+
"language_info": {
|
176 |
+
"codemirror_mode": {
|
177 |
+
"name": "ipython",
|
178 |
+
"version": 3
|
179 |
+
},
|
180 |
+
"file_extension": ".py",
|
181 |
+
"mimetype": "text/x-python",
|
182 |
+
"name": "python",
|
183 |
+
"nbconvert_exporter": "python",
|
184 |
+
"pygments_lexer": "ipython3",
|
185 |
+
"version": "3.9.12"
|
186 |
+
}
|
187 |
+
},
|
188 |
+
"nbformat": 4,
|
189 |
+
"nbformat_minor": 2
|
190 |
+
}
|