Spaces:
Running
Running
Upload 4 files
Browse files- pages/1_💾_Data.py +8 -23
- pages/2_📝_Model.py +9 -7
- pages/3_🎯_Evaluation_Panel.py +12 -6
- pages/4_🔬_Decision_Exploration_Panel.py +31 -450
pages/1_💾_Data.py
CHANGED
@@ -29,38 +29,23 @@ st.session_state['user_group'] = backend
|
|
29 |
# # with st.sidebar:
|
30 |
# st.sidebar.title("🎈Explore Data Panel")
|
31 |
|
32 |
-
st.title("
|
33 |
|
34 |
st.write(
|
35 |
"""
|
36 |
##
|
37 |
-
Examining data is the key factor
|
38 |
""")
|
39 |
|
|
|
40 |
list_test = """<ul>
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
45 |
st.markdown(list_test, unsafe_allow_html=True)
|
46 |
|
47 |
|
48 |
-
# with st.sidebar.expander("🧩 COMPONENTS", True):
|
49 |
-
|
50 |
-
# # genre = st.radio("",('Data Info', 'Data EDA', 'Data ONboard'))
|
51 |
-
# status_a = st.checkbox("Test editor", key="a")
|
52 |
-
# status_b = st.checkbox("Ace editor", key="b")
|
53 |
-
# if status_a:
|
54 |
-
# st.write("A checked")
|
55 |
-
# if status_a and status_b:
|
56 |
-
# st.write("They arechecked")
|
57 |
-
|
58 |
if backend == "Developer":
|
59 |
get_product_dev_page_layout()
|
60 |
-
# st.checkbox("Ace editor", key="b", disabled=selected)
|
61 |
-
# page.item("Ace editor", components.ace_editor)
|
62 |
-
# page.item("Disqus", components.disqus)
|
63 |
-
# page.item("Elements⭐", components.elements)
|
64 |
-
# page.item("Pandas profiling", components.pandas_profiling)
|
65 |
-
# page.item("Quill editor", components.quill_editor)
|
66 |
-
# page.item("React player", components.react_player)
|
|
|
29 |
# # with st.sidebar:
|
30 |
# st.sidebar.title("🎈Explore Data Panel")
|
31 |
|
32 |
+
st.title("Explore Data Panel for OCT Image Analysis")
|
33 |
|
34 |
st.write(
|
35 |
"""
|
36 |
##
|
37 |
+
Examining the data is the key factor for better understanding of the AI system.Therefore,this panel introduces deta-centric approach by providing details regarding forllowing aspect of the data .
|
38 |
""")
|
39 |
|
40 |
+
|
41 |
list_test = """<ul>
|
42 |
+
<li>Data Source Information: This tab contains information regarding following aspect of the data:
|
43 |
+
modality,format, domain, ethical considerations including license and data version. </li>
|
44 |
+
<li>Exploratory Data Stats: This tab includes exploratory data analysis info covering following aspects: train/validation/test data division,summary statistics, sample visualization from each category.</li>
|
45 |
+
<li>Data Onboarding: This tab provides details of data pre-processing and post-processing steps applied over the dataset before traning, and data augmentations.</li>
|
46 |
+
</ul>"""
|
47 |
st.markdown(list_test, unsafe_allow_html=True)
|
48 |
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
if backend == "Developer":
|
51 |
get_product_dev_page_layout()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/2_📝_Model.py
CHANGED
@@ -28,16 +28,18 @@ st.session_state['user_group'] = backend
|
|
28 |
st.title("Explore Model Panel for OCT Image Analysis")
|
29 |
st.write(
|
30 |
"""
|
31 |
-
|
32 |
-
|
33 |
-
Developer, model owners and managers can use this section by hemselves.
|
34 |
""")
|
35 |
|
36 |
list_test = """<ul>
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
41 |
st.markdown(list_test, unsafe_allow_html=True)
|
42 |
|
43 |
if backend == "Developer":
|
|
|
28 |
st.title("Explore Model Panel for OCT Image Analysis")
|
29 |
st.write(
|
30 |
"""
|
31 |
+
The users can find following information regarding the AI model developed for the task: what the mode does, how it was developed and how it is used. Thus, we provide answers
|
32 |
+
to those questions via below described tabs.
|
|
|
33 |
""")
|
34 |
|
35 |
list_test = """<ul>
|
36 |
+
<li>Model generic information: This tab contains summary of the model’s details, including its main features, capabilities, and intended use.
|
37 |
+
It also hihglights the model’s behaviour, such as the type of data inputs(image, feature etc) it can handle and the types of outputs it produces.</li>
|
38 |
+
<li>Model development information: The tab includes information on the hyperparameters, model development framework such as Tensorflow or PyTorch, and other technical details. It also includes a complete analysis of the model’s inference performance, such as the model size,
|
39 |
+
hardware-specific (GPU and CPU) inference time,and speed, as well as reproducibility check list.</li>
|
40 |
+
<li>Model deployment information: This tab provides information on how the model is used in production, including details on the inference speed and latency,
|
41 |
+
and how users can access and interact with the model in production.</li>
|
42 |
+
</ul>"""
|
43 |
st.markdown(list_test, unsafe_allow_html=True)
|
44 |
|
45 |
if backend == "Developer":
|
pages/3_🎯_Evaluation_Panel.py
CHANGED
@@ -23,13 +23,19 @@ backend = st.sidebar.selectbox(
|
|
23 |
|
24 |
st.session_state['user_group'] = backend
|
25 |
|
26 |
-
st.title("
|
27 |
-
|
28 |
st.write(
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
if backend == "Developer":
|
35 |
get_product_dev_page_layout()
|
|
|
23 |
|
24 |
st.session_state['user_group'] = backend
|
25 |
|
26 |
+
st.title("Explore Performance Panel for OCT Image Analysis")
|
|
|
27 |
st.write(
|
28 |
+
"""
|
29 |
+
This panel provides information on the evaluation of the AI model’s performance, including details on the metrics used and the results of the evaluation. USerrs can also find
|
30 |
+
our notes regarding the issues. The performance metric visualizations and samples of failure and success cases are given in in this panel as well.""")
|
31 |
+
|
32 |
+
list_test = """<ul>
|
33 |
+
<li>Evaluation Metrics: This tab explains the details of the performance metrics and how each metric is calculated.
|
34 |
+
Users can also find the characteristics of the evaluation data set. </li>
|
35 |
+
<li>Performance Summary: This tab includes visualizations of the performance metrics over test set.</li>
|
36 |
+
<li>Limitations: This tab provides examples of observed failure and success cases, along with visualizations and any possible observations behind the failure cases.</li>
|
37 |
+
</ul>"""
|
38 |
+
st.markdown(list_test, unsafe_allow_html=True)
|
39 |
|
40 |
if backend == "Developer":
|
41 |
get_product_dev_page_layout()
|
pages/4_🔬_Decision_Exploration_Panel.py
CHANGED
@@ -1,458 +1,39 @@
|
|
1 |
-
import os
|
2 |
-
import sys
|
3 |
-
import json
|
4 |
-
import shutil
|
5 |
-
import urllib.request
|
6 |
-
from pathlib import Path
|
7 |
-
import pathlib
|
8 |
-
import time
|
9 |
-
import urllib
|
10 |
-
from ast import literal_eval
|
11 |
-
import albumentations as A
|
12 |
-
import tensorflow as tf
|
13 |
-
|
14 |
-
import cv2
|
15 |
-
import numpy as np
|
16 |
-
import pandas as pd
|
17 |
-
import plotly.express as px
|
18 |
-
import matplotlib.pyplot as plt
|
19 |
-
from PIL import Image
|
20 |
-
|
21 |
import streamlit as st
|
22 |
-
|
23 |
-
import seaborn as sns
|
24 |
|
25 |
sys.path.append(f'{os.getcwd()}/utils')
|
26 |
-
from utils.eval_users import get_product_dev_page_layout
|
27 |
-
|
28 |
-
# print(os.getcwd())
|
29 |
-
|
30 |
-
# Hide GPU from visible devices
|
31 |
-
tf.config.set_visible_devices([], 'GPU')
|
32 |
-
# Enable GPU memory growth - avoid allocating all memory at start
|
33 |
-
# gpus = tf.config.experimental.list_physical_devices(device_type='GPU')
|
34 |
-
# for gpu in gpus:
|
35 |
-
# tf.config.experimental.set_memory_growth(device=gpu, enable=True)
|
36 |
-
|
37 |
-
from utils.control import show_tsne_vis,show_random_samples
|
38 |
|
39 |
-
from utils.
|
40 |
-
# from utils import (
|
41 |
-
# load_augmentations_config,
|
42 |
-
# get_arguments,
|
43 |
-
# get_placeholder_params,
|
44 |
-
# select_transformations,
|
45 |
-
# show_random_params,
|
46 |
-
# )
|
47 |
-
# from visuals import (
|
48 |
-
# select_image,
|
49 |
-
# show_credentials,
|
50 |
-
# show_docstring,
|
51 |
-
# get_transormations_params,
|
52 |
-
# )
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
sns.set_style('darkgrid')
|
58 |
-
plt.rcParams['axes.grid'] = False
|
59 |
|
60 |
st.set_page_config(layout="wide")
|
61 |
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
train_ids = np.load(train_emb_id_path)
|
90 |
-
train_id_list = list(train_ids)
|
91 |
-
train_labels = [_id.split("\\")[1] for _id in train_id_list]
|
92 |
-
print(" NUmber of training samples: ",len(train_labels))
|
93 |
-
|
94 |
-
annoy_tree = load_annoy_tree(test_features.shape[1],annoy_tree_save_path)
|
95 |
-
def annoy_matching(annoy_f,query_item, query_index, n=10):
|
96 |
-
return annoy_f.get_nns_by_vector(query_item, n)
|
97 |
-
|
98 |
-
def get_img(fn ,thumbnail=False):
|
99 |
-
img = Image.open(fn)
|
100 |
-
if thumbnail:
|
101 |
-
img.thumbnail((100,100))
|
102 |
-
return img
|
103 |
-
|
104 |
-
|
105 |
-
### Within the streamlit.cache() decorator you’ll get better performance
|
106 |
-
# if you use allow_output_mutation=True because this means Streamlit just uses the same copy of the model in memory,
|
107 |
-
# rather than reloading when it’s re-run.
|
108 |
-
|
109 |
-
# MODEL_WEIGHTS = f'{DEFAULT_MODEL_BASE_DIR}/hpe_epoch107_.hdf5'
|
110 |
-
# MODEL_JSON = f'{DEFAULT_MODEL_BASE_DIR}/hpe_hourglass_stacks_04_.json'
|
111 |
-
|
112 |
-
# MODEL_WEIGHTS_DEPLOYMENT_URL = 'https://github.com/robertklee/COCO-Human-Pose/releases/download/v0.1-alpha/hpe_epoch107_.hdf5'
|
113 |
-
# MODEL_JSON_DEPLOYMENT_URL = 'https://github.com/robertklee/COCO-Human-Pose/releases/download/v0.1-alpha/hpe_hourglass_stacks_04_.json'
|
114 |
-
|
115 |
-
# Constants for sidebar dropdown
|
116 |
-
SIDEBAR_OPTION_PROJECT_INFO = "Show Panel Info"
|
117 |
-
SIDEBAR_OPTION_GLOBAL_EXP = "Show Global Explanations"
|
118 |
-
SIDEBAR_OPTION_INSTANCE_EXP = "Select a Demo Image"
|
119 |
-
SIDEBAR_OPTION_INSTANCE_AUG= "Apply Augmentations"
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
SIDEBAR_OPTIONS = [SIDEBAR_OPTION_PROJECT_INFO, SIDEBAR_OPTION_GLOBAL_EXP,SIDEBAR_OPTION_INSTANCE_EXP, SIDEBAR_OPTION_INSTANCE_AUG]
|
124 |
-
|
125 |
-
def plot_n_similar(seed_id,similar_ids, test_path,n=10, scale=5):
|
126 |
-
f,ax = plt.subplots(1,n+1,figsize=((n+1)*scale,scale))
|
127 |
-
# print(os.path.basename(test_labels[seed_id])[:-4])
|
128 |
-
title = "SEED ID:{0}\nLabel:{1}".format(seed_id,os.path.basename(test_labels[seed_id]))
|
129 |
-
# print("path:", test_labels[seed_id].replace("F:/","E:/"))
|
130 |
-
ax[0].imshow(get_img(test_path.replace("F:/","E:/")),cmap='gray')
|
131 |
-
ax[0].set_title(title,fontsize=12)
|
132 |
-
for i in range(len(similar_ids)):
|
133 |
-
ax[i+1].imshow(get_img(similar_ids[i].replace("F:/","E:/")),cmap='gray')
|
134 |
-
title = "ID:{0}\nDistance: {1:.3f}\nLabel:{2}".format(i,0.1223,os.path.basename(similar_ids[i])[:-4])
|
135 |
-
ax[i+1].set_title(title,fontsize=10)
|
136 |
-
f.suptitle("Images similar to seed_id {0}".format(seed_id),fontsize=18)
|
137 |
-
plt.subplots_adjust(top=0.5)
|
138 |
-
return f
|
139 |
-
|
140 |
-
def load_image(filename,change_url=True):
|
141 |
-
# if change_url:
|
142 |
-
print(filename)
|
143 |
-
print(os.path.exists(filename))
|
144 |
-
img = cv2.imread(filename)
|
145 |
-
return img
|
146 |
-
|
147 |
-
@st.cache(allow_output_mutation=True)
|
148 |
-
def get_model(model_path):
|
149 |
-
new_model = tf.keras.models.load_model(model_path)
|
150 |
-
# keras_model = load_model(model_path)
|
151 |
-
return new_model
|
152 |
-
|
153 |
-
@st.cache(allow_output_mutation=True)
|
154 |
-
def get_feature_vector_model(model_path):
|
155 |
-
keras_model = tf.keras.models.load_model(model_path)
|
156 |
-
feature_extractor = tf.keras.Model(keras_model.inputs,keras_model.layers[-3].output)
|
157 |
-
return feature_extractor
|
158 |
-
# feature_mod = get_feature_extractor_model(keras_model)
|
159 |
-
# return feature_mod
|
160 |
-
|
161 |
-
def load_pd_data_frame(df_csv_path):
|
162 |
-
return pd.read_csv(df_csv_path)
|
163 |
-
|
164 |
-
def get_path_list_from_df(df_data):
|
165 |
-
return list(df_data['path'])
|
166 |
-
|
167 |
-
def get_class_probs_from_df(df_data):
|
168 |
-
return list(df_data['class_probs'])
|
169 |
-
|
170 |
-
|
171 |
-
def visualize_bar_plot(df_data):
|
172 |
-
fig = px.bar(df_data, x="probability", y="class", orientation='h')
|
173 |
-
return fig
|
174 |
-
|
175 |
-
# def get_file_content_as_string(path):
|
176 |
-
# """[summary]
|
177 |
-
|
178 |
-
# Args:
|
179 |
-
# path (string): path to instructions.md
|
180 |
-
|
181 |
-
# Returns:
|
182 |
-
# url (url): url format
|
183 |
-
# """
|
184 |
-
|
185 |
-
# #url = 'https://raw.githubusercontent.com/streamlit/demo-self-driving/master/' + path
|
186 |
-
# path = os.path.abspath(path)
|
187 |
-
# url=pathlib.Path(path).as_uri()
|
188 |
-
# #url = path
|
189 |
-
# response = urllib.request.urlopen(url)
|
190 |
-
# return response.read().decode("utf-8")
|
191 |
-
|
192 |
-
def run_instance_exp(img_path, img_path_list,prob_list,grad_vis_path_list):
|
193 |
-
|
194 |
-
st.subheader('Instance Exploration')
|
195 |
-
# st.columns((1,1,1)) with row4_2:
|
196 |
-
LABELS = ['CNV', 'DRUSEN', 'DME', 'NORMAL']
|
197 |
-
|
198 |
-
left_column, middle_column, right_column = st.columns((1,1,1))
|
199 |
-
display_image = load_image(img_path)
|
200 |
-
# fig = px.imshow(display_image)
|
201 |
-
# left_column.plotly_chart(fig, use_container_width=True)
|
202 |
-
left_column.image(cv2.resize(display_image, (180,180)),caption = "Selected Input")
|
203 |
-
|
204 |
-
# get class probabilities
|
205 |
-
indx = img_path_list.index(img_path)
|
206 |
-
print(img_path)
|
207 |
-
prb_tmp = prob_list[indx]
|
208 |
-
print(f"{prb_tmp[1:-1]}")
|
209 |
-
clss_probs = literal_eval('"'+prb_tmp[1:-1]+'"')
|
210 |
-
print(clss_probs[1:-1].split(' '))
|
211 |
-
prob_cls = [float(p) for p in clss_probs[1:-1].split(' ')]
|
212 |
-
tmp_df = pd.DataFrame.from_dict({'class':LABELS,'probability':prob_cls})
|
213 |
-
print(tmp_df.head())
|
214 |
-
fig = plt.figure(figsize=(15, 13))
|
215 |
-
sns.barplot(x='probability', y='class', data=tmp_df)
|
216 |
-
middle_column.pyplot(fig)
|
217 |
-
# st.caption('Predictions')
|
218 |
-
|
219 |
-
tmp_grad_img = GRAD_CAM_IMAGE_DIR + img_path.split("\\")[-2] +'/'+img_path.split("\\") [-1]
|
220 |
-
|
221 |
-
display_image = load_image(tmp_grad_img,replace=False)
|
222 |
-
# left_column.plotly_chart(fig, use_container_width=True)
|
223 |
-
right_column.image(display_image,caption = "ROI")
|
224 |
-
|
225 |
-
# seed_id = 900
|
226 |
-
seed_id = test_id_list.index(img_path)
|
227 |
-
query_item = test_features[seed_id]
|
228 |
-
print(query_item.shape)
|
229 |
-
closest_idxs = annoy_matching(annoy_tree,query_item, seed_id, 10)
|
230 |
-
closest_fns = [train_ids[close_i] for close_i in closest_idxs]
|
231 |
-
st.subheader('Top-10 Similar Samples from Gallery Set')
|
232 |
-
st.pyplot(plot_n_similar(seed_id,closest_fns, img_path,n=10, scale=4))
|
233 |
-
|
234 |
-
# ax = sns.barplot(x='totalCount', y='name', data=df)
|
235 |
-
# plt_fig = visualize_bar_plot(tmp_df)
|
236 |
-
# middle_column.plotly_chart(plt_fig, use_container_width=True)
|
237 |
-
|
238 |
-
def run_instance_exp_keras_model(img_path, new_model, feature_extractor_model):
|
239 |
-
|
240 |
-
st.subheader('Instance Exploration')
|
241 |
-
# st.columns((1,1,1)) with row4_2:
|
242 |
-
LABELS = ['CNV', 'DRUSEN', 'DME', 'NORMAL']
|
243 |
-
|
244 |
-
left_column, middle_column, right_column = st.columns((1,1,1))
|
245 |
-
print(img_path)
|
246 |
-
org_img_path = img_path
|
247 |
-
|
248 |
-
img_path = f'{os.getcwd()}/data/oct2017/test/' + img_path.split("\\")[-2] +'/'+img_path.split("\\") [-1]
|
249 |
-
# img_path.replace("F:/XAI/data/OCT2017/","/home/hodor/dev/Learning/XAI/streamlit_demo/multipage-app/data/xai_framework_data/")
|
250 |
-
display_image = load_image(img_path)
|
251 |
-
# fig = px.imshow(display_image)
|
252 |
-
# left_column.plotly_chart(fig, use_container_width=True)
|
253 |
-
left_column.image(cv2.resize(display_image, (180,180)),caption = "Selected Input")
|
254 |
-
|
255 |
-
|
256 |
-
roi_img, probs = get_predictions_and_roi(img_path, new_model)
|
257 |
-
|
258 |
-
## probs
|
259 |
-
print(np.asarray(probs))
|
260 |
-
print(probs.shape)
|
261 |
-
prob_cls =np.asarray(probs)[0]
|
262 |
-
print(prob_cls)
|
263 |
-
tmp_df = pd.DataFrame.from_dict({'class':LABELS,'probability':prob_cls})
|
264 |
-
fig = plt.figure(figsize=(5, 4))
|
265 |
-
sns.barplot(x='probability', y='class', data=tmp_df)
|
266 |
-
middle_column.pyplot(fig)
|
267 |
-
# middle_column.write("Probabilities")
|
268 |
-
|
269 |
-
# grad img
|
270 |
-
right_column.image(roi_img, caption = "Decision ROI")
|
271 |
-
|
272 |
-
# seed_id = 900
|
273 |
-
seed_id = test_id_list.index(org_img_path)
|
274 |
-
query_item = get_feature_vector(img_path,feature_extractor_model)
|
275 |
-
query_item = query_item.reshape(-1,1792)
|
276 |
-
print(query_item.shape)
|
277 |
-
closest_idxs = annoy_matching(annoy_tree,query_item[0,:], seed_id, 10)
|
278 |
-
closest_fns = [train_ids[close_i] for close_i in closest_idxs]
|
279 |
-
|
280 |
-
closest_fns_tmp = [f'{os.getcwd()}/data/oct2017/train/' + each_fn.split("\\")[-2] +'/'+each_fn.split("\\") [-1]
|
281 |
-
for each_fn in closest_fns]
|
282 |
-
print(closest_fns)
|
283 |
-
st.subheader('Top-10 Similar Samples from Gallery Set')
|
284 |
-
st.pyplot(plot_n_similar(seed_id,closest_fns_tmp, img_path,n=10,scale=3))
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
def run_augmentations(transforms,image):
|
289 |
-
data = None
|
290 |
-
try:
|
291 |
-
# apply the transformation to the image
|
292 |
-
data = A.Compose(transforms)(image=image)
|
293 |
-
error = 0
|
294 |
-
except ValueError:
|
295 |
-
error = 1
|
296 |
-
|
297 |
-
return data, error
|
298 |
-
|
299 |
-
@st.cache
|
300 |
-
def get_sample():
|
301 |
-
print("running!")
|
302 |
-
|
303 |
-
def main():
|
304 |
-
|
305 |
-
st.sidebar.warning('\
|
306 |
-
Please upload SINGLE single...')
|
307 |
-
st.sidebar.write(" ------ ")
|
308 |
-
st.sidebar.title("Explore the Instance Predictions and Explanations")
|
309 |
-
new_model = get_model(MODEL_PATH)
|
310 |
-
feature_extractor_model = get_feature_vector_model(MODEL_PATH)
|
311 |
-
|
312 |
-
app_mode = st.sidebar.selectbox("Please select from the following", SIDEBAR_OPTIONS)
|
313 |
-
|
314 |
-
if app_mode == SIDEBAR_OPTION_PROJECT_INFO:
|
315 |
-
st.sidebar.write(" ------ ")
|
316 |
-
st.sidebar.success("Project information showing on the right!")
|
317 |
-
# st.write(get_file_content_as_string("README.md"))
|
318 |
-
|
319 |
-
elif app_mode == SIDEBAR_OPTION_INSTANCE_EXP:
|
320 |
-
st.sidebar.write(" ------ ")
|
321 |
-
|
322 |
-
DF_TEST_PROP = load_pd_data_frame(TEST_CSV_FILE)
|
323 |
-
IMG_PATH_LISTS = get_path_list_from_df(DF_TEST_PROP)
|
324 |
-
IMG_CLSS_PROBS_LIST = get_class_probs_from_df(DF_TEST_PROP)
|
325 |
-
grad_vis_path_list = None
|
326 |
-
|
327 |
-
# new_model = load_model(MODEL_PATH)
|
328 |
-
option = st.sidebar.selectbox('Please select a sample image, then click Explain Me button', IMG_PATH_LISTS)
|
329 |
-
pressed = st.sidebar.button('Explain ME')
|
330 |
-
if pressed:
|
331 |
-
st.empty()
|
332 |
-
st.sidebar.write('Please wait for the magic to happen! This may take up to a minute.')
|
333 |
-
run_instance_exp_keras_model(option, new_model,feature_extractor_model)
|
334 |
-
# run_instance_exp(option, IMG_PATH_LISTS,IMG_CLSS_PROBS_LIST,grad_vis_path_list)
|
335 |
-
|
336 |
-
elif app_mode == SIDEBAR_OPTION_GLOBAL_EXP:
|
337 |
-
borderline_cases = np.load(borderline_id_path)
|
338 |
-
representative_cases = np.load(repr_id_path)
|
339 |
-
borderline_id_list = list(borderline_cases)
|
340 |
-
# print(borderline_id_list)
|
341 |
-
|
342 |
-
borderline_id_list = [f'{os.getcwd()}/data/oct2017/train/' + each_fn.split("\\")[-2] +'/'+each_fn.split("\\") [-1]
|
343 |
-
for each_fn in borderline_id_list]
|
344 |
-
representative_id_list = list(representative_cases)
|
345 |
-
representative_id_list = [f'{os.getcwd()}/data/oct2017/train/' + each_fn.split("\\")[-2] +'/'+each_fn.split("\\") [-1]
|
346 |
-
for each_fn in representative_id_list]
|
347 |
-
print(representative_id_list)
|
348 |
-
print(borderline_id_list)
|
349 |
-
#with upload:
|
350 |
-
st.sidebar.info('GLOABAL EXPLANATION!! ')
|
351 |
-
option = st.sidebar.selectbox('Please select Global Samples, then click Explain Me button', ["Representative Samples","Borderline Cases"])
|
352 |
-
if option:
|
353 |
-
clss = st.sidebar.selectbox('Select A Class', ["CNV","DME", "NORMAL", "DRUSEN"])
|
354 |
-
side_1, side_2 = st.sidebar.columns(2)
|
355 |
-
# cls1, cls2, cls3, cls4 = st.sidebar.columns(4)
|
356 |
-
# st.sidebar.title("Choose A Class:")
|
357 |
-
# with cls1:
|
358 |
-
# st.radio('', ["CNV"])
|
359 |
-
# with cls2:
|
360 |
-
# st.radio('', ["DRUSEN"])
|
361 |
-
# with cls3:
|
362 |
-
# st.radio('', ["DME"])
|
363 |
-
# with cls4:
|
364 |
-
# st.radio('', ["NORMAL"])
|
365 |
-
with side_1:
|
366 |
-
check_emb = st.checkbox('Embdedding Space Visuzalization')
|
367 |
-
|
368 |
-
with side_2:
|
369 |
-
check_samp = st.checkbox('Random Sample Visuzalization')
|
370 |
-
|
371 |
-
if check_emb and check_samp:
|
372 |
-
st.write("Emb and vis")
|
373 |
-
if option.startswith("Rep"):
|
374 |
-
filter_lst = list(filter(lambda k: clss in k, representative_id_list))
|
375 |
-
show_random_samples(filter_lst,clss)
|
376 |
-
show_tsne_vis("./figures/tsne_representative.png", title="Representative")
|
377 |
-
else:
|
378 |
-
filter_lst = list(filter(lambda k: clss in k, borderline_id_list))
|
379 |
-
show_random_samples(filter_lst,clss)
|
380 |
-
show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_borderline.png", title="Borderline")
|
381 |
-
elif check_emb:
|
382 |
-
st.write("embedding vis")
|
383 |
-
if option.startswith("Rep"):
|
384 |
-
show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_representative.png", title="Representative")
|
385 |
-
else:
|
386 |
-
show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_borderline.png", title="Borderline")
|
387 |
-
elif check_samp:
|
388 |
-
st.write("rand vis")
|
389 |
-
if option.startswith("Rep"):
|
390 |
-
filter_lst = list(filter(lambda k: clss in k, representative_id_list))
|
391 |
-
show_random_samples(filter_lst,clss)
|
392 |
-
else:
|
393 |
-
filter_lst = list(filter(lambda k: clss in k, borderline_id_list))
|
394 |
-
show_random_samples(filter_lst,clss)
|
395 |
-
|
396 |
-
|
397 |
-
# f = st.sidebar.file_uploader("Please Select to Upload an Image", type=['png', 'jpg', 'jpeg', 'tiff', 'gif'])
|
398 |
-
# if f is not None:
|
399 |
-
# tfile = tempfile.NamedTemporaryFile(delete=True)
|
400 |
-
# tfile.write(f.read())
|
401 |
-
# st.sidebar.write('Please wait for the magic to happen! This may take up to a minute.')
|
402 |
-
# run_app(tfile)
|
403 |
-
# elif app_mode == SIDEBAR_OPTION_INSTANCE_AUG:
|
404 |
-
# DF_TEST_PROP = load_pd_data_frame(TEST_CSV_FILE)
|
405 |
-
# IMG_PATH_LISTS = get_path_list_from_df(DF_TEST_PROP)
|
406 |
-
# get_sample()
|
407 |
-
# option = st.sidebar.selectbox('Please select a sample image, then choose augmentations', IMG_PATH_LISTS)
|
408 |
-
|
409 |
-
# side_1, side_2 = st.columns(2)
|
410 |
-
# with side_2:
|
411 |
-
# st.title("Testing!!")
|
412 |
-
# with side_1:
|
413 |
-
# st.title("Demo of Albumentations")
|
414 |
-
# image_box = st.empty()
|
415 |
-
# image =load_image(option.replace("F:/","E:/"))
|
416 |
-
|
417 |
-
# # proceed only if everything is ok
|
418 |
-
|
419 |
-
# image_box.image(image, caption="Original image")
|
420 |
-
# # image was loaded successfully
|
421 |
-
# placeholder_params = get_placeholder_params(image)
|
422 |
-
|
423 |
-
# # load the config
|
424 |
-
# augmentations = load_augmentations_config(
|
425 |
-
# placeholder_params, "configs/augs.json"
|
426 |
-
# )
|
427 |
-
|
428 |
-
# # get the list of transformations names
|
429 |
-
# transform_names = select_transformations(augmentations, interface_type="Simple")
|
430 |
-
|
431 |
-
# # get parameters for each transform
|
432 |
-
# transforms = get_transormations_params(transform_names, augmentations)
|
433 |
-
|
434 |
-
# data, error = run_augmentations(transforms, image)
|
435 |
-
|
436 |
-
# if error == 0:
|
437 |
-
# augmented_image = data["image"]
|
438 |
-
# # show title
|
439 |
-
# # st.title("Demo of Albumentations")
|
440 |
-
# # show the images
|
441 |
-
# width_transformed = int(
|
442 |
-
# image.shape[1] / image.shape[1] * augmented_image.shape[1]
|
443 |
-
# )
|
444 |
-
# image_box.image(
|
445 |
-
# augmented_image,
|
446 |
-
# caption="Transformed image",
|
447 |
-
# )
|
448 |
-
# # side_1.image(augmented_image, caption="Original image")
|
449 |
-
|
450 |
-
else:
|
451 |
-
raise ValueError('Selected sidebar option is not implemented. Please open an issue on Github: https://github.com/kaplansinan/MLOps')
|
452 |
-
|
453 |
-
# st.plotly_chart(fig)
|
454 |
-
|
455 |
-
# new_model = load_model(MODEL_PATH)
|
456 |
-
main()
|
457 |
-
expander_faq = st.expander("More About Our Project")
|
458 |
-
expander_faq.write("Hi there! If you have any questions about our project, or simply want to check out the source code, please visit our github repo: https://github.com/kaplansinan/MLOPS")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
+
import sys,os
|
|
|
3 |
|
4 |
sys.path.append(f'{os.getcwd()}/utils')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
+
from utils.decisions_users import get_product_dev_page_layout
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
+
# st.write(st.session_state.user_group)
|
9 |
+
USER_GROUPS = ["Developer", "Manager", "Practitioner"]
|
|
|
|
|
|
|
10 |
|
11 |
st.set_page_config(layout="wide")
|
12 |
|
13 |
+
if 'user_group' not in st.session_state:
|
14 |
+
index_tmp = 0
|
15 |
+
else:
|
16 |
+
index_tmp = USER_GROUPS.index(st.session_state['user_group'])
|
17 |
+
|
18 |
+
#Sidebar for USER GROUPS
|
19 |
+
st.sidebar.title("USER GROUPS")
|
20 |
+
backend = st.sidebar.selectbox(
|
21 |
+
"Select User-Group ", USER_GROUPS, index=index_tmp
|
22 |
+
)
|
23 |
+
|
24 |
+
st.session_state['user_group'] = backend
|
25 |
+
|
26 |
+
st.title("DecisionExploration Panel for OCT Image Analysis")
|
27 |
+
st.write(
|
28 |
+
"""
|
29 |
+
This panel provides information on the evaluation of the AI model’s performance, including details on the metrics used and the results of the evaluation. USerrs can also find
|
30 |
+
our notes regarding the issues. The performance metric visualizations and samples of failure and success cases are given in in this panel as well.""")
|
31 |
+
|
32 |
+
list_test = """<ul>
|
33 |
+
<li>Evaluation Metrics: This tab explains the details of the performance metrics and how each metric is calculated.
|
34 |
+
Users can also find the characteristics of the evaluation data set. </li>
|
35 |
+
</ul>"""
|
36 |
+
st.markdown(list_test, unsafe_allow_html=True)
|
37 |
+
|
38 |
+
if backend == "Developer":
|
39 |
+
get_product_dev_page_layout()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|