Spaces:
Sleeping
Sleeping
Upload 13 files
Browse files- utils/control.py +1 -1
- utils/data_users.py +232 -51
- utils/decisions_users.py +150 -69
- utils/eval_users.py +12 -18
- utils/model_users.py +263 -10
utils/control.py
CHANGED
@@ -21,7 +21,7 @@ def visualize_samples(sample_list,class_name,columns=5):
|
|
21 |
plt.suptitle("Class {0}".format(class_name))
|
22 |
for i, image in enumerate(sample_list):
|
23 |
plt.subplot(len(sample_list) / columns + 1, columns, i + 1)
|
24 |
-
plt.imshow(cv2.imread(image))
|
25 |
return f
|
26 |
|
27 |
def select_num_interval(
|
|
|
21 |
plt.suptitle("Class {0}".format(class_name))
|
22 |
for i, image in enumerate(sample_list):
|
23 |
plt.subplot(len(sample_list) / columns + 1, columns, i + 1)
|
24 |
+
plt.imshow(cv2.imread(image.replace("F:/","E:/")))
|
25 |
return f
|
26 |
|
27 |
def select_num_interval(
|
utils/data_users.py
CHANGED
@@ -5,55 +5,239 @@ import os
|
|
5 |
|
6 |
ROOT_FIG_DIR = f'{os.getcwd()}/figures/'
|
7 |
def get_product_dev_page_layout():
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
-
# list_test = """<ul>
|
17 |
-
# <li><strong>Target Group: </strong>Developer, Model Owners, Product Managers</li>
|
18 |
-
# </ul>"""
|
19 |
-
# st.markdown(list_test, unsafe_allow_html=True)
|
20 |
-
# LAYING OUT THE MIDDLE SECTION OF THE APP WITH THE MAPS
|
21 |
-
# row4_1, row4_2, row4_3 = st.columns((1,1,1))
|
22 |
|
23 |
row4_1, row4_2, row4_3 = st.tabs(["Data Source Information", "Exploratory Data Stats", "Data Onboarding"])
|
24 |
|
25 |
with row4_1:
|
26 |
# st.write("**Data Source Info**")
|
27 |
-
st.subheader('Data Source Information')
|
28 |
# new_title = '<h4 style="color:Green;">Data set infor:</h4>'
|
29 |
# st.markdown(new_title, unsafe_allow_html=True)
|
30 |
# where the data comes and how it is collected, what the data includes, what are the details of the data, how the data is used.
|
31 |
# answers four different questions
|
32 |
-
st.write("
|
33 |
|
34 |
-
st.
|
35 |
st.write("[Labeled Optical Coherence Tomography (OCT) and Chest X-Ray Images for Classification](https://data.mendeley.com/datasets/rscbjbr9sj/3)")
|
|
|
36 |
|
37 |
with st.expander('Data Collection Details(Click for more info)'):
|
38 |
-
st.write("""
|
39 |
the California Retinal Research Foundation,
|
40 |
Medical Center Ophthalmology Associates, the Shanghai First People’s Hospital, and Beijing Tongren Eye Center between
|
41 |
July 1, 2013 and March 1, 2017.""")
|
42 |
-
|
|
|
|
|
43 |
# https://www.aao.org/eye-health/ask-ophthalmologist-q/choroidal-neovascularization-definition-treatment
|
44 |
st.image('./figures/oct_details.png')
|
45 |
|
46 |
list_test = """<ul>Case explanations:
|
47 |
-
<li><strong>CNV
|
48 |
-
|
49 |
-
<li
|
50 |
-
|
51 |
-
<li>
|
|
|
|
|
52 |
</ul>"""
|
53 |
st.markdown(list_test, unsafe_allow_html=True)
|
54 |
|
55 |
|
56 |
-
st.
|
57 |
with st.expander('License: CC BY 4.0 license'):
|
58 |
st.write("""
|
59 |
The files associated with this dataset are licensed under a Creative Commons Attribution 4.0 International license. What does this mean?
|
@@ -69,17 +253,22 @@ def get_product_dev_page_layout():
|
|
69 |
|
70 |
with row4_2:
|
71 |
st.subheader('Exploratory Data Stats')
|
72 |
-
|
|
|
|
|
|
|
|
|
73 |
HtmlFile = open(f'{ROOT_FIG_DIR}/train_set_report.html', 'r', encoding='utf-8')
|
74 |
source_code = HtmlFile.read()
|
75 |
components.html(source_code,scrolling=True, height=500)
|
76 |
|
77 |
-
with st.expander('Test Data
|
|
|
78 |
HtmlFile = open(f'{ROOT_FIG_DIR}/test_set_report.html', 'r', encoding='utf-8')
|
79 |
source_code = HtmlFile.read()
|
80 |
components.html(source_code,scrolling=True, height=500)
|
81 |
|
82 |
-
with st.expander('
|
83 |
clss = st.selectbox('Select a category(class)', ["CNV","DME", "NORMAL", "DRUSEN"])
|
84 |
img_path = f'{ROOT_FIG_DIR}/{clss}_samples.png'
|
85 |
st.image(img_path)
|
@@ -88,27 +277,29 @@ def get_product_dev_page_layout():
|
|
88 |
# components.html(source_code,scrolling=True, height=500)
|
89 |
|
90 |
with row4_3:
|
91 |
-
|
92 |
-
st.subheader('
|
93 |
st.write(
|
94 |
"""
|
95 |
-
|
96 |
-
Since the training set has a problem of class imbalanced, we need to solve this issue. To do so, representative sampling strategy is used with hierarchical clustering.
|
97 |
-
""")
|
98 |
# st.caption('')
|
99 |
-
new_title = '<h5 style="color:Black;">Post Processing Steps:</h5>'
|
100 |
-
st.markdown(new_title, unsafe_allow_html=True)
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
|
|
|
|
109 |
HtmlFile = open(f'{ROOT_FIG_DIR}/filtered_set_report.html', 'r', encoding='utf-8')
|
110 |
source_code = HtmlFile.read()
|
111 |
components.html(source_code,scrolling=True, height=500)
|
|
|
|
|
112 |
st.write("Model Input Size Resizing: 180x180x3")
|
113 |
# st.caption('Post Processing Steps:')
|
114 |
# code = '''def representative_sampling():
|
@@ -118,14 +309,4 @@ def get_product_dev_page_layout():
|
|
118 |
# st.code('for class_i in category_list: hiearhical_cluster(class_i)')
|
119 |
|
120 |
|
121 |
-
def get_developer_page_layout():
|
122 |
-
st.header("Developer")
|
123 |
-
|
124 |
-
markdown = """
|
125 |
-
1. For the [GitHub repository](https://github.com/giswqs/streamlit-multipage-template) or [use it as a template](https://github.com/giswqs/streamlit-multipage-template/generate) for your own project.
|
126 |
-
2. Customize the sidebar by changing the sidebar text and logo in each Python files.
|
127 |
-
3. Find your favorite emoji from https://emojipedia.org.
|
128 |
-
"""
|
129 |
-
|
130 |
-
st.markdown(markdown)
|
131 |
|
|
|
5 |
|
6 |
ROOT_FIG_DIR = f'{os.getcwd()}/figures/'
|
7 |
def get_product_dev_page_layout():
|
8 |
+
row4_1, row4_2, row4_3 = st.tabs(["Data Source Information", "Exploratory Data Stats", "Data Onboarding"])
|
9 |
+
|
10 |
+
with row4_1:
|
11 |
+
# st.write("**Data Source Info**")
|
12 |
+
st.subheader('Data Source and Version Information')
|
13 |
+
# new_title = '<h4 style="color:Green;">Data set infor:</h4>'
|
14 |
+
# st.markdown(new_title, unsafe_allow_html=True)
|
15 |
+
# where the data comes and how it is collected, what the data includes, what are the details of the data, how the data is used.
|
16 |
+
# answers four different questions
|
17 |
+
st.write("The data set consists of OCT images from CNV, DME, DRUSEN and NORMAL cases(from 4686 adult patients in total).")
|
18 |
+
|
19 |
+
st.warning('Source')
|
20 |
+
st.write("[Labeled Optical Coherence Tomography (OCT) and Chest X-Ray Images for Classification](https://data.mendeley.com/datasets/rscbjbr9sj/3)")
|
21 |
+
st.caption("Version: 3")
|
22 |
+
|
23 |
+
with st.expander('Data Collection Details(Click for more info)'):
|
24 |
+
st.write("""OCT images are collected from the Shiley Eye Institute of the University of California San Diego,
|
25 |
+
the California Retinal Research Foundation,
|
26 |
+
Medical Center Ophthalmology Associates, the Shanghai First People’s Hospital, and Beijing Tongren Eye Center between
|
27 |
+
July 1, 2013 and March 1, 2017.""")
|
28 |
+
|
29 |
+
st.subheader('Case Samples')
|
30 |
+
# st.caption('VisuCase Samples')
|
31 |
+
# https://www.aao.org/eye-health/ask-ophthalmologist-q/choroidal-neovascularization-definition-treatment
|
32 |
+
st.image('./figures/oct_details.png')
|
33 |
+
|
34 |
+
list_test = """<ul>Case explanations:
|
35 |
+
<li><strong>Choroidal Neovascularization (CNV)</strong> is a type of retinal disease that involves the growth of abnormal blood vessels in the choroid layer of the eye. These new blood vessels can lead to fluid accumulation beneath and within the layers of tissue, causing vision loss.
|
36 |
+
</li>
|
37 |
+
<li> <strong>Diabetic Macular Edema (DME)</strong> is a common complication of diabetes that affects the retina responsible for central vision. This condition occurs when fluid accumulates in and around the macula, leading to retinal thickening and swelling, which can result in impaired vision or blindness.
|
38 |
+
</li>
|
39 |
+
<li><strong>DRUSEN</strong> is a condition associated with early Age-Related Macular Degeneration (AMD) in the retina. It involves the accumulation of small deposits of waste material in the retina, which can lead to vision problems.
|
40 |
+
</li>
|
41 |
+
<li><strong>NORMAL </strong> represents healthy retinalconditions and is a baseline for comparison with the aforementioned anomalies</li>
|
42 |
+
</ul>"""
|
43 |
+
st.markdown(list_test, unsafe_allow_html=True)
|
44 |
+
|
45 |
+
|
46 |
+
st.subheader('License Infomation')
|
47 |
+
with st.expander('License: CC BY 4.0 license'):
|
48 |
+
st.write("""
|
49 |
+
The files associated with this dataset are licensed under a Creative Commons Attribution 4.0 International license. What does this mean?
|
50 |
+
You can share, copy and modify this dataset so long as you give appropriate credit,
|
51 |
+
provide a link to the CC BY license, and indicate if changes were made, but you may not do
|
52 |
+
so in a way that suggests the rights holder has endorsed you or your use of the dataset.
|
53 |
+
Note that further permission may be required for any content within the dataset
|
54 |
+
that is identified as belonging to a third party. More details about the licences can be found
|
55 |
+
[here](https://creativecommons.org/about/cclicenses/).
|
56 |
+
""")
|
57 |
+
|
58 |
+
# st.write("Open to be used for researh.")
|
59 |
+
|
60 |
+
with row4_2:
|
61 |
+
st.subheader('Exploratory Data Stats')
|
62 |
+
st.write("""
|
63 |
+
The details regarding the train and test data are presented here. The details cover the following variables: number of samples per each category(label), image width and height, image aspect ratio.
|
64 |
+
""")
|
65 |
+
with st.expander('Click to Explore Training Data'):
|
66 |
+
st.info("While exploring, select a column name under Variable to see further details.")
|
67 |
+
HtmlFile = open(f'{ROOT_FIG_DIR}/train_set_report.html', 'r', encoding='utf-8')
|
68 |
+
source_code = HtmlFile.read()
|
69 |
+
components.html(source_code,scrolling=True, height=500)
|
70 |
+
|
71 |
+
with st.expander('Click to Explore Test Data'):
|
72 |
+
st.info("While exploring, select a column name under Variable to see further details.")
|
73 |
+
HtmlFile = open(f'{ROOT_FIG_DIR}/test_set_report.html', 'r', encoding='utf-8')
|
74 |
+
source_code = HtmlFile.read()
|
75 |
+
components.html(source_code,scrolling=True, height=500)
|
76 |
+
|
77 |
+
with st.expander('Click to Explore Sample Visualization'):
|
78 |
+
clss = st.selectbox('Select a category(class)', ["CNV","DME", "NORMAL", "DRUSEN"])
|
79 |
+
img_path = f'{ROOT_FIG_DIR}/{clss}_samples.png'
|
80 |
+
st.image(img_path)
|
81 |
+
# HtmlFile = open(f'{ROOT_FIG_DIR}/test_set_report.html', 'r', encoding='utf-8')
|
82 |
+
# source_code = HtmlFile.read()
|
83 |
+
# components.html(source_code,scrolling=True, height=500)
|
84 |
+
|
85 |
+
with row4_3:
|
86 |
+
st.write("Data post-processing and augmentations are given in this section")
|
87 |
+
st.subheader('Post-Processing Details')
|
88 |
+
st.write(
|
89 |
+
"""
|
90 |
+
Due to the presence of class imbalance in the data, a representative sampling strategy has been employed for the training set, utilizing hierarchical clustering to address this issue.The following algorthm describes the steps carried out to solve the issue.""")
|
91 |
+
# st.caption('')
|
92 |
+
# new_title = '<h5 style="color:Black;">Post Processing Steps:</h5>'
|
93 |
+
# st.markdown(new_title, unsafe_allow_html=True)
|
94 |
+
algo_path = f'{ROOT_FIG_DIR}/classimbalance.png'
|
95 |
+
st.image(algo_path)
|
96 |
+
# code = '''def representative_sampling():
|
97 |
+
# for each_class in category_list:
|
98 |
+
# embeddings = get_resnet50_embeddings(each_class)
|
99 |
+
# n_cluster = run_hierarchical_clustering(embeddings)
|
100 |
+
# samples = get_representative_n_samples_within_each_cluster(n_cluster)'''
|
101 |
+
# st.code(code, language='python')
|
102 |
+
|
103 |
+
with st.expander('Click to Explore Post-processed Training Data by Representative Sampling'):
|
104 |
+
HtmlFile = open(f'{ROOT_FIG_DIR}/filtered_set_report.html', 'r', encoding='utf-8')
|
105 |
+
source_code = HtmlFile.read()
|
106 |
+
components.html(source_code,scrolling=True, height=500)
|
107 |
+
|
108 |
+
st.subheader('Applied Data Augmentations')
|
109 |
+
st.write("Model Input Size Resizing: 180x180x3")
|
110 |
+
# st.caption('Post Processing Steps:')
|
111 |
+
# code = '''def representative_sampling():
|
112 |
+
# ... for class_i in category_list:
|
113 |
+
# ... print("Hello, Streamlit!")'''
|
114 |
+
# st.code(code, language='python')
|
115 |
+
# st.code('for class_i in category_list: hiearhical_cluster(class_i)')
|
116 |
+
|
117 |
|
118 |
+
def get_product_manager_page_layout():
|
119 |
+
|
120 |
+
row4_1, row4_2 = st.tabs(["Data Source Information", "Exploratory Data Stats"])
|
121 |
+
|
122 |
+
with row4_1:
|
123 |
+
# st.write("**Data Source Info**")
|
124 |
+
st.subheader('Data Source and Version Information')
|
125 |
+
# new_title = '<h4 style="color:Green;">Data set infor:</h4>'
|
126 |
+
# st.markdown(new_title, unsafe_allow_html=True)
|
127 |
+
# where the data comes and how it is collected, what the data includes, what are the details of the data, how the data is used.
|
128 |
+
# answers four different questions
|
129 |
+
st.write(" The data set consists of OCT images from CNV, DME, DRUSEN and NORMAL cases(from 4686 adult patients in total).")
|
130 |
+
|
131 |
+
st.warning('Source')
|
132 |
+
st.write("[Labeled Optical Coherence Tomography (OCT) and Chest X-Ray Images for Classification](https://data.mendeley.com/datasets/rscbjbr9sj/3)")
|
133 |
+
st.caption("Version: 3")
|
134 |
+
|
135 |
+
with st.expander('Data Collection Details(Click for more info)'):
|
136 |
+
st.write("""OCT images are collected from the Shiley Eye Institute of the University of California San Diego,
|
137 |
+
the California Retinal Research Foundation,
|
138 |
+
Medical Center Ophthalmology Associates, the Shanghai First People’s Hospital, and Beijing Tongren Eye Center between
|
139 |
+
July 1, 2013 and March 1, 2017.""")
|
140 |
+
|
141 |
+
st.subheader('Case Samples')
|
142 |
+
# st.caption('VisuCase Samples')
|
143 |
+
# https://www.aao.org/eye-health/ask-ophthalmologist-q/choroidal-neovascularization-definition-treatment
|
144 |
+
st.image('./figures/oct_details.png')
|
145 |
+
|
146 |
+
list_test = """<ul>Case explanations:
|
147 |
+
<li><strong>Choroidal Neovascularization (CNV)</strong> is a type of retinal disease that involves the growth of abnormal blood vessels in the choroid layer of the eye. These new blood vessels can lead to fluid accumulation beneath and within the layers of tissue, causing vision loss.
|
148 |
+
</li>
|
149 |
+
<li> <strong>Diabetic Macular Edema (DME)</strong> is a common complication of diabetes that affects the retina responsible for central vision. This condition occurs when fluid accumulates in and around the macula, leading to retinal thickening and swelling, which can result in impaired vision or blindness.
|
150 |
+
</li>
|
151 |
+
<li><strong>DRUSEN</strong> is a condition associated with early Age-Related Macular Degeneration (AMD) in the retina. It involves the accumulation of small deposits of waste material in the retina, which can lead to vision problems.
|
152 |
+
</li>
|
153 |
+
<li><strong>NORMAL </strong> represents healthy retinalconditions and is a baseline for comparison with the aforementioned anomalies</li>
|
154 |
+
</ul>"""
|
155 |
+
st.markdown(list_test, unsafe_allow_html=True)
|
156 |
+
|
157 |
+
|
158 |
+
st.subheader('License Infomation')
|
159 |
+
with st.expander('License: CC BY 4.0 license'):
|
160 |
+
st.write("""
|
161 |
+
The files associated with this dataset are licensed under a Creative Commons Attribution 4.0 International license. What does this mean?
|
162 |
+
You can share, copy and modify this dataset so long as you give appropriate credit,
|
163 |
+
provide a link to the CC BY license, and indicate if changes were made, but you may not do
|
164 |
+
so in a way that suggests the rights holder has endorsed you or your use of the dataset.
|
165 |
+
Note that further permission may be required for any content within the dataset
|
166 |
+
that is identified as belonging to a third party. More details about the licences can be found
|
167 |
+
[here](https://creativecommons.org/about/cclicenses/).
|
168 |
+
""")
|
169 |
+
|
170 |
+
# st.write("Open to be used for researh.")
|
171 |
+
|
172 |
+
with row4_2:
|
173 |
+
st.subheader('Exploratory Data Stats')
|
174 |
+
st.write("""
|
175 |
+
The details regarding the train and test data are presented here. The details cover the following variables: number of samples per each category(label), image width and height, image aspect ratio.
|
176 |
+
""")
|
177 |
+
with st.expander('Click to Explore Training Data'):
|
178 |
+
st.info("While exploring, select a column name under Variable to see further details.")
|
179 |
+
HtmlFile = open(f'{ROOT_FIG_DIR}/train_set_report.html', 'r', encoding='utf-8')
|
180 |
+
source_code = HtmlFile.read()
|
181 |
+
components.html(source_code,scrolling=True, height=500)
|
182 |
+
|
183 |
+
with st.expander('Click to Explore Test Data'):
|
184 |
+
st.info("While exploring, select a column name under Variable to see further details.")
|
185 |
+
HtmlFile = open(f'{ROOT_FIG_DIR}/test_set_report.html', 'r', encoding='utf-8')
|
186 |
+
source_code = HtmlFile.read()
|
187 |
+
components.html(source_code,scrolling=True, height=500)
|
188 |
+
|
189 |
+
with st.expander('Click to Explore Sample Visualization'):
|
190 |
+
clss = st.selectbox('Select a category(class)', ["CNV","DME", "NORMAL", "DRUSEN"])
|
191 |
+
img_path = f'{ROOT_FIG_DIR}/{clss}_samples.png'
|
192 |
+
st.image(img_path)
|
193 |
+
# HtmlFile = open(f'{ROOT_FIG_DIR}/test_set_report.html', 'r', encoding='utf-8')
|
194 |
+
# source_code = HtmlFile.read()
|
195 |
+
# components.html(source_code,scrolling=True, height=500)
|
196 |
+
|
197 |
+
|
198 |
+
|
199 |
+
def get_product_practitioner_page_layout():
|
200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
|
202 |
row4_1, row4_2, row4_3 = st.tabs(["Data Source Information", "Exploratory Data Stats", "Data Onboarding"])
|
203 |
|
204 |
with row4_1:
|
205 |
# st.write("**Data Source Info**")
|
206 |
+
st.subheader('Data Source and Version Information')
|
207 |
# new_title = '<h4 style="color:Green;">Data set infor:</h4>'
|
208 |
# st.markdown(new_title, unsafe_allow_html=True)
|
209 |
# where the data comes and how it is collected, what the data includes, what are the details of the data, how the data is used.
|
210 |
# answers four different questions
|
211 |
+
st.write(" The data set consists of OCT images from CNV, DME, DRUSEN and NORMAL cases(from 4686 adult patients in total).")
|
212 |
|
213 |
+
st.warning('Source')
|
214 |
st.write("[Labeled Optical Coherence Tomography (OCT) and Chest X-Ray Images for Classification](https://data.mendeley.com/datasets/rscbjbr9sj/3)")
|
215 |
+
st.caption("Version: 3")
|
216 |
|
217 |
with st.expander('Data Collection Details(Click for more info)'):
|
218 |
+
st.write("""OCT images are collected from the Shiley Eye Institute of the University of California San Diego,
|
219 |
the California Retinal Research Foundation,
|
220 |
Medical Center Ophthalmology Associates, the Shanghai First People’s Hospital, and Beijing Tongren Eye Center between
|
221 |
July 1, 2013 and March 1, 2017.""")
|
222 |
+
|
223 |
+
st.subheader('Case Samples')
|
224 |
+
# st.caption('VisuCase Samples')
|
225 |
# https://www.aao.org/eye-health/ask-ophthalmologist-q/choroidal-neovascularization-definition-treatment
|
226 |
st.image('./figures/oct_details.png')
|
227 |
|
228 |
list_test = """<ul>Case explanations:
|
229 |
+
<li><strong>Choroidal Neovascularization (CNV)</strong> is a type of retinal disease that involves the growth of abnormal blood vessels in the choroid layer of the eye. These new blood vessels can lead to fluid accumulation beneath and within the layers of tissue, causing vision loss.
|
230 |
+
</li>
|
231 |
+
<li> <strong>Diabetic Macular Edema (DME)</strong> is a common complication of diabetes that affects the retina responsible for central vision. This condition occurs when fluid accumulates in and around the macula, leading to retinal thickening and swelling, which can result in impaired vision or blindness.
|
232 |
+
</li>
|
233 |
+
<li><strong>DRUSEN</strong> is a condition associated with early Age-Related Macular Degeneration (AMD) in the retina. It involves the accumulation of small deposits of waste material in the retina, which can lead to vision problems.
|
234 |
+
</li>
|
235 |
+
<li><strong>NORMAL </strong> represents healthy retinalconditions and is a baseline for comparison with the aforementioned anomalies</li>
|
236 |
</ul>"""
|
237 |
st.markdown(list_test, unsafe_allow_html=True)
|
238 |
|
239 |
|
240 |
+
st.subheader('License Infomation')
|
241 |
with st.expander('License: CC BY 4.0 license'):
|
242 |
st.write("""
|
243 |
The files associated with this dataset are licensed under a Creative Commons Attribution 4.0 International license. What does this mean?
|
|
|
253 |
|
254 |
with row4_2:
|
255 |
st.subheader('Exploratory Data Stats')
|
256 |
+
st.write("""
|
257 |
+
The details regarding the train and test data are presented here. The details cover the following variables: number of samples per each category(label), image width and height, image aspect ratio.
|
258 |
+
""")
|
259 |
+
with st.expander('Click to Explore Training Data'):
|
260 |
+
st.info("While exploring, select a column name under Variable to see further details.")
|
261 |
HtmlFile = open(f'{ROOT_FIG_DIR}/train_set_report.html', 'r', encoding='utf-8')
|
262 |
source_code = HtmlFile.read()
|
263 |
components.html(source_code,scrolling=True, height=500)
|
264 |
|
265 |
+
with st.expander('Click to Explore Test Data'):
|
266 |
+
st.info("While exploring, select a column name under Variable to see further details.")
|
267 |
HtmlFile = open(f'{ROOT_FIG_DIR}/test_set_report.html', 'r', encoding='utf-8')
|
268 |
source_code = HtmlFile.read()
|
269 |
components.html(source_code,scrolling=True, height=500)
|
270 |
|
271 |
+
with st.expander('Click to Explore Sample Visualization'):
|
272 |
clss = st.selectbox('Select a category(class)', ["CNV","DME", "NORMAL", "DRUSEN"])
|
273 |
img_path = f'{ROOT_FIG_DIR}/{clss}_samples.png'
|
274 |
st.image(img_path)
|
|
|
277 |
# components.html(source_code,scrolling=True, height=500)
|
278 |
|
279 |
with row4_3:
|
280 |
+
st.write("Data post-processing and augmentations are given in this section")
|
281 |
+
st.subheader('Post-Processing Details')
|
282 |
st.write(
|
283 |
"""
|
284 |
+
Due to the presence of class imbalance in the data, a representative sampling strategy has been employed for the training set, utilizing hierarchical clustering to address this issue.The following algorthm describes the steps carried out to solve the issue.""")
|
|
|
|
|
285 |
# st.caption('')
|
286 |
+
# new_title = '<h5 style="color:Black;">Post Processing Steps:</h5>'
|
287 |
+
# st.markdown(new_title, unsafe_allow_html=True)
|
288 |
+
algo_path = f'{ROOT_FIG_DIR}/classimbalance.png'
|
289 |
+
st.image(algo_path)
|
290 |
+
# code = '''def representative_sampling():
|
291 |
+
# for each_class in category_list:
|
292 |
+
# embeddings = get_resnet50_embeddings(each_class)
|
293 |
+
# n_cluster = run_hierarchical_clustering(embeddings)
|
294 |
+
# samples = get_representative_n_samples_within_each_cluster(n_cluster)'''
|
295 |
+
# st.code(code, language='python')
|
296 |
+
|
297 |
+
with st.expander('Click to Explore Post-processed Training Data by Representative Sampling'):
|
298 |
HtmlFile = open(f'{ROOT_FIG_DIR}/filtered_set_report.html', 'r', encoding='utf-8')
|
299 |
source_code = HtmlFile.read()
|
300 |
components.html(source_code,scrolling=True, height=500)
|
301 |
+
|
302 |
+
st.subheader('Applied Data Augmentations')
|
303 |
st.write("Model Input Size Resizing: 180x180x3")
|
304 |
# st.caption('Post Processing Steps:')
|
305 |
# code = '''def representative_sampling():
|
|
|
309 |
# st.code('for class_i in category_list: hiearhical_cluster(class_i)')
|
310 |
|
311 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
312 |
|
utils/decisions_users.py
CHANGED
@@ -45,6 +45,10 @@ from utils.model_utils import get_feature_vector, get_feature_extractor_model, g
|
|
45 |
sns.set_style('darkgrid')
|
46 |
plt.rcParams['axes.grid'] = False
|
47 |
|
|
|
|
|
|
|
|
|
48 |
# st.set_page_config(layout="wide")
|
49 |
|
50 |
#https://github.com/IliaLarchenko/albumentations-demo/blob/3cb6528a513fe3b35dbb2c2a63cdcfbb9bb2a932/src/utils.py#L149
|
@@ -95,6 +99,27 @@ def open_gray(fn):
|
|
95 |
img = cv2.resize(img,(224,224))
|
96 |
return img
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
def plot_n_similar(seed_id,similar_ids, test_path,n=10, scale=5):
|
99 |
# img_list = []
|
100 |
# title_list = ["SEED ID:{0} <br> Label:{1}".format(seed_id,os.path.basename(test_labels[seed_id]))]
|
@@ -223,7 +248,7 @@ def visualize_bar_plot(df_data):
|
|
223 |
|
224 |
def run_instance_exp_keras_model(img_path, new_model, feature_extractor_model):
|
225 |
|
226 |
-
st.subheader('Instance
|
227 |
# st.columns((1,1,1)) with row4_2:
|
228 |
LABELS = ['CNV', 'DRUSEN', 'DME', 'NORMAL']
|
229 |
|
@@ -236,7 +261,9 @@ def run_instance_exp_keras_model(img_path, new_model, feature_extractor_model):
|
|
236 |
display_image = load_image(img_path)
|
237 |
# fig = px.imshow(display_image)
|
238 |
# left_column.plotly_chart(fig, use_container_width=True)
|
239 |
-
left_column.image(display_image
|
|
|
|
|
240 |
# left_column.image(cv2.resize(display_image, (180,180)),caption = "Selected Input")
|
241 |
|
242 |
|
@@ -248,14 +275,24 @@ def run_instance_exp_keras_model(img_path, new_model, feature_extractor_model):
|
|
248 |
prob_cls =np.asarray(probs)[0]
|
249 |
# print(prob_cls)
|
250 |
tmp_df = pd.DataFrame.from_dict({'class':LABELS,'probability':prob_cls})
|
251 |
-
fig = plt.figure(figsize=(8,
|
252 |
-
sns.barplot(x='probability', y='class', data=tmp_df)
|
|
|
253 |
middle_column.pyplot(fig)
|
254 |
-
|
|
|
|
|
|
|
|
|
|
|
255 |
|
256 |
# grad img
|
257 |
-
|
258 |
-
# right_column.image(
|
|
|
|
|
|
|
|
|
259 |
|
260 |
# seed_id = 900
|
261 |
seed_id = test_id_list.index(org_img_path)
|
@@ -268,26 +305,29 @@ def run_instance_exp_keras_model(img_path, new_model, feature_extractor_model):
|
|
268 |
closest_fns_tmp = [f'{os.getcwd()}/data/oct2017/train/' + each_fn.split("\\")[-2] +'/'+each_fn.split("\\") [-1]
|
269 |
for each_fn in closest_fns]
|
270 |
# print(closest_fns)
|
271 |
-
st.subheader('Top-10 Similar Samples from Gallery Set')
|
272 |
# st.plotly_chart(plot_n_similar(seed_id,closest_fns, img_path,n=10, scale=4), use_container_width=True)
|
273 |
st.pyplot(plot_n_similar(seed_id,closest_fns_tmp, img_path,n=10,scale=4))
|
274 |
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
|
|
|
|
|
|
291 |
|
292 |
new_model = get_model(MODEL_PATH)
|
293 |
feature_extractor_model = get_feature_vector_model(MODEL_PATH)
|
@@ -306,41 +346,62 @@ def main():
|
|
306 |
representative_id_list = [f'{os.getcwd()}/data/oct2017/train/' + each_fn.split("\\")[-2] +'/'+each_fn.split("\\") [-1]
|
307 |
for each_fn in representative_id_list]
|
308 |
# st.info('GLOABAL EXPLANATION!! ')
|
309 |
-
option = st.selectbox('Please select to explore Representative
|
310 |
-
if option:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
311 |
clss = st.selectbox('Select a category(class)', ["CNV","DME", "NORMAL", "DRUSEN"])
|
312 |
-
side_1, side_2 = st.columns(2)
|
313 |
-
|
314 |
-
with side_1:
|
315 |
-
check_emb = st.checkbox('Embdedding Space Visuzalization')
|
316 |
|
317 |
-
with side_2:
|
318 |
-
check_samp = st.checkbox('Random Sample Visuzalization')
|
319 |
|
320 |
-
if check_emb and check_samp:
|
321 |
-
st.write("Emb and vis")
|
322 |
-
if option.startswith("Rep"):
|
323 |
-
filter_lst = list(filter(lambda k: clss in k, representative_id_list))
|
324 |
-
show_random_samples(filter_lst,clss)
|
325 |
-
show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_representative.png", title="Representative")
|
326 |
-
else:
|
327 |
-
filter_lst = list(filter(lambda k: clss in k, borderline_id_list))
|
328 |
-
show_random_samples(filter_lst,clss)
|
329 |
-
show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_borderline.png", title="Borderline")
|
330 |
-
elif check_emb:
|
331 |
-
st.write("embedding vis")
|
332 |
-
if option.startswith("Rep"):
|
333 |
-
show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_representative.png", title="Representative")
|
334 |
-
else:
|
335 |
-
show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_borderline.png", title="Borderline")
|
336 |
-
elif check_samp:
|
337 |
-
st.write("rand vis")
|
338 |
if option.startswith("Rep"):
|
339 |
filter_lst = list(filter(lambda k: clss in k, representative_id_list))
|
340 |
show_random_samples(filter_lst,clss)
|
341 |
else:
|
342 |
filter_lst = list(filter(lambda k: clss in k, borderline_id_list))
|
343 |
show_random_samples(filter_lst,clss)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
with row4_2:
|
345 |
DF_TEST_PROP = load_pd_data_frame(TEST_CSV_FILE)
|
346 |
IMG_PATH_LISTS = get_path_list_from_df(DF_TEST_PROP)
|
@@ -348,29 +409,43 @@ def main():
|
|
348 |
grad_vis_path_list = None
|
349 |
row2_col1, row2_col2 = st.columns(2)
|
350 |
with row2_col1:
|
351 |
-
option = st.selectbox('Please select a sample image
|
352 |
with row2_col2:
|
353 |
-
st.
|
354 |
pressed = st.button('Explain ME')
|
355 |
|
356 |
if pressed:
|
357 |
st.empty()
|
358 |
-
st.write('Please wait for
|
359 |
run_instance_exp_keras_model(option, new_model,feature_extractor_model)
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
374 |
|
375 |
|
376 |
|
@@ -383,5 +458,11 @@ def main():
|
|
383 |
# 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")
|
384 |
|
385 |
|
386 |
-
def get_product_dev_page_layout():
|
387 |
-
return main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
sns.set_style('darkgrid')
|
46 |
plt.rcParams['axes.grid'] = False
|
47 |
|
48 |
+
|
49 |
+
# import tensorflow as tf
|
50 |
+
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # Suppress TensorFlow logging (1)
|
51 |
+
tf.get_logger().setLevel('ERROR') # Suppress TensorFlow logging (2)
|
52 |
# st.set_page_config(layout="wide")
|
53 |
|
54 |
#https://github.com/IliaLarchenko/albumentations-demo/blob/3cb6528a513fe3b35dbb2c2a63cdcfbb9bb2a932/src/utils.py#L149
|
|
|
99 |
img = cv2.resize(img,(224,224))
|
100 |
return img
|
101 |
|
102 |
+
def show_values(axs, orient="v", space=.01):
|
103 |
+
def _single(ax):
|
104 |
+
if orient == "v":
|
105 |
+
for p in ax.patches:
|
106 |
+
_x = p.get_x() + p.get_width() / 2
|
107 |
+
_y = p.get_y() + p.get_height() + (p.get_height()*0.01)
|
108 |
+
value = '{:.1f}'.format(p.get_height())
|
109 |
+
ax.text(_x, _y, value, ha="center")
|
110 |
+
elif orient == "h":
|
111 |
+
for p in ax.patches:
|
112 |
+
_x = p.get_x() + p.get_width() + float(space)
|
113 |
+
_y = p.get_y() + p.get_height() - (p.get_height()*0.5)
|
114 |
+
value = '{:.2f}'.format(p.get_width())
|
115 |
+
ax.text(_x, _y, value, ha="left")
|
116 |
+
|
117 |
+
if isinstance(axs, np.ndarray):
|
118 |
+
for idx, ax in np.ndenumerate(axs):
|
119 |
+
_single(ax)
|
120 |
+
else:
|
121 |
+
_single(axs)
|
122 |
+
|
123 |
def plot_n_similar(seed_id,similar_ids, test_path,n=10, scale=5):
|
124 |
# img_list = []
|
125 |
# title_list = ["SEED ID:{0} <br> Label:{1}".format(seed_id,os.path.basename(test_labels[seed_id]))]
|
|
|
248 |
|
249 |
def run_instance_exp_keras_model(img_path, new_model, feature_extractor_model):
|
250 |
|
251 |
+
# st.subheader('Instance Predictions')
|
252 |
# st.columns((1,1,1)) with row4_2:
|
253 |
LABELS = ['CNV', 'DRUSEN', 'DME', 'NORMAL']
|
254 |
|
|
|
261 |
display_image = load_image(img_path)
|
262 |
# fig = px.imshow(display_image)
|
263 |
# left_column.plotly_chart(fig, use_container_width=True)
|
264 |
+
left_column.image(display_image)
|
265 |
+
left_column.write("Input Image")
|
266 |
+
|
267 |
# left_column.image(cv2.resize(display_image, (180,180)),caption = "Selected Input")
|
268 |
|
269 |
|
|
|
275 |
prob_cls =np.asarray(probs)[0]
|
276 |
# print(prob_cls)
|
277 |
tmp_df = pd.DataFrame.from_dict({'class':LABELS,'probability':prob_cls})
|
278 |
+
fig = plt.figure(figsize=(8, 8.8))
|
279 |
+
p =sns.barplot(x='probability', y='class', data=tmp_df)
|
280 |
+
show_values(p, "h", space=0.05)
|
281 |
middle_column.pyplot(fig)
|
282 |
+
middle_column.write("Predicted Class Probabilities")
|
283 |
+
|
284 |
+
# fig = px.bar(LABELS, prob_cls)
|
285 |
+
# fig = px.bar(tmp_df, x="class", y="probability", orientation='h')
|
286 |
+
|
287 |
+
# middle_column.plotly_chart(fig, use_container_width=False)
|
288 |
|
289 |
# grad img
|
290 |
+
print("roi image stats", roi_img.shape)
|
291 |
+
# right_column.image(roi_img, caption = "Decision ROI")
|
292 |
+
print(display_image.shape)
|
293 |
+
tmp_shape = display_image.shape[:2]
|
294 |
+
right_column.image(cv2.resize(roi_img, (tmp_shape[1],tmp_shape[0])))
|
295 |
+
right_column.write("GradCAM RoI")
|
296 |
|
297 |
# seed_id = 900
|
298 |
seed_id = test_id_list.index(org_img_path)
|
|
|
305 |
closest_fns_tmp = [f'{os.getcwd()}/data/oct2017/train/' + each_fn.split("\\")[-2] +'/'+each_fn.split("\\") [-1]
|
306 |
for each_fn in closest_fns]
|
307 |
# print(closest_fns)
|
308 |
+
st.subheader('Top-10 Similar Samples from Gallery(representative) Set')
|
309 |
# st.plotly_chart(plot_n_similar(seed_id,closest_fns, img_path,n=10, scale=4), use_container_width=True)
|
310 |
st.pyplot(plot_n_similar(seed_id,closest_fns_tmp, img_path,n=10,scale=4))
|
311 |
|
312 |
+
if "load_state" not in st.session_state:
|
313 |
+
st.session_state.load_state = True
|
314 |
+
# if st.session_state.load_state:
|
315 |
+
# st.session_state.load_state = False
|
316 |
+
# with st.expander('Correct Decision'):
|
317 |
+
# st.info("Correct th decision if it is not valid. This sample will be added to next training bucket.")
|
318 |
+
# tmp_col1, tmp_col2 = st.columns(2)
|
319 |
+
# with tmp_col1:
|
320 |
+
# label_correect = st.radio(
|
321 |
+
# "Choose label visibility 👇",
|
322 |
+
# ["CNV", "DME", "NORMAL","DRUSEN"],
|
323 |
+
# disabled=False,
|
324 |
+
# horizontal=True)
|
325 |
+
# with tmp_col2:
|
326 |
+
# tmp_btn = st.button('ADD TO TRAINING BUCKET')
|
327 |
+
# if tmp_btn:
|
328 |
+
# st.warning("Sample added to training set..")
|
329 |
+
|
330 |
+
def main(user_type='Developer'):
|
331 |
|
332 |
new_model = get_model(MODEL_PATH)
|
333 |
feature_extractor_model = get_feature_vector_model(MODEL_PATH)
|
|
|
346 |
representative_id_list = [f'{os.getcwd()}/data/oct2017/train/' + each_fn.split("\\")[-2] +'/'+each_fn.split("\\") [-1]
|
347 |
for each_fn in representative_id_list]
|
348 |
# st.info('GLOABAL EXPLANATION!! ')
|
349 |
+
option = st.selectbox('Please select to explore Representative/Borderline Samples', ["Choose here","Representative Samples","Borderline Cases"],index=0)
|
350 |
+
if not option.startswith("Choose"):
|
351 |
+
if user_type!='Manager':
|
352 |
+
if option.startswith('Rep'):
|
353 |
+
with st.expander('Click to see Representative Sampling Algorithm'):
|
354 |
+
algo_path = f'{ROOT_FIG_DIR}/representativesampling.png'
|
355 |
+
st.image(algo_path)
|
356 |
+
with st.expander('Click to see Manifold(t-SNE) Visualization of Representative Samples'):
|
357 |
+
show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_representative.png", title="Representative")
|
358 |
+
else:
|
359 |
+
with st.expander('Click to see Borderline Sampling Algorithm'):
|
360 |
+
algo_path = f'{ROOT_FIG_DIR}/borderlinesampling.png'
|
361 |
+
st.image(algo_path)
|
362 |
+
with st.expander('Click to see Manifold(t-SNE) Visualization of Broderline Samples'):
|
363 |
+
show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_borderline.png", title="Borderline")
|
364 |
clss = st.selectbox('Select a category(class)', ["CNV","DME", "NORMAL", "DRUSEN"])
|
365 |
+
# side_1, side_2 = st.columns(2)
|
|
|
|
|
|
|
366 |
|
|
|
|
|
367 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
if option.startswith("Rep"):
|
369 |
filter_lst = list(filter(lambda k: clss in k, representative_id_list))
|
370 |
show_random_samples(filter_lst,clss)
|
371 |
else:
|
372 |
filter_lst = list(filter(lambda k: clss in k, borderline_id_list))
|
373 |
show_random_samples(filter_lst,clss)
|
374 |
+
|
375 |
+
# with side_1:
|
376 |
+
# check_emb = st.checkbox('Embdedding Space Visuzalization')
|
377 |
+
|
378 |
+
# with side_2:
|
379 |
+
# check_samp = st.checkbox('Random Sample Visuzalization')
|
380 |
+
|
381 |
+
# if check_emb and check_samp:
|
382 |
+
# st.write("Emb and vis")
|
383 |
+
# if option.startswith("Rep"):
|
384 |
+
# filter_lst = list(filter(lambda k: clss in k, representative_id_list))
|
385 |
+
# show_random_samples(filter_lst,clss)
|
386 |
+
# show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_representative.png", title="Representative")
|
387 |
+
# else:
|
388 |
+
# filter_lst = list(filter(lambda k: clss in k, borderline_id_list))
|
389 |
+
# show_random_samples(filter_lst,clss)
|
390 |
+
# # show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_borderline.png", title="Borderline")
|
391 |
+
# elif check_emb:
|
392 |
+
# st.write("embedding vis")
|
393 |
+
# if option.startswith("Rep"):
|
394 |
+
# show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_representative.png", title="Representative")
|
395 |
+
# else:
|
396 |
+
# show_tsne_vis(f"{ROOT_FIG_DIR}/tsne_borderline.png", title="Borderline")
|
397 |
+
# elif check_samp:
|
398 |
+
# st.write("rand vis")
|
399 |
+
# if option.startswith("Rep"):
|
400 |
+
# filter_lst = list(filter(lambda k: clss in k, representative_id_list))
|
401 |
+
# show_random_samples(filter_lst,clss)
|
402 |
+
# else:
|
403 |
+
# filter_lst = list(filter(lambda k: clss in k, borderline_id_list))
|
404 |
+
# show_random_samples(filter_lst,clss)
|
405 |
with row4_2:
|
406 |
DF_TEST_PROP = load_pd_data_frame(TEST_CSV_FILE)
|
407 |
IMG_PATH_LISTS = get_path_list_from_df(DF_TEST_PROP)
|
|
|
409 |
grad_vis_path_list = None
|
410 |
row2_col1, row2_col2 = st.columns(2)
|
411 |
with row2_col1:
|
412 |
+
option = st.selectbox('Please select a sample image👇', IMG_PATH_LISTS)
|
413 |
with row2_col2:
|
414 |
+
st.write("Click button")
|
415 |
pressed = st.button('Explain ME')
|
416 |
|
417 |
if pressed:
|
418 |
st.empty()
|
419 |
+
st.write('Please wait for a while! This may take up to a minute.')
|
420 |
run_instance_exp_keras_model(option, new_model,feature_extractor_model)
|
421 |
+
def form_callback():
|
422 |
+
st.write("Training set updated")
|
423 |
+
# st.write("test2")
|
424 |
+
if user_type!='Manager':
|
425 |
+
with st.expander('Correct the Decision'):
|
426 |
+
with st.form("my_form"):
|
427 |
+
st.info("Correct the decision if it is not valid. The sample will be added to next training bucket.")
|
428 |
+
tmp_col1, tmp_col2 = st.columns(2)
|
429 |
+
with tmp_col1:
|
430 |
+
label_correect = st.radio(
|
431 |
+
"Choose label 👇",
|
432 |
+
["NONE","CNV", "DME", "NORMAL","DRUSEN"],
|
433 |
+
key="visibility",
|
434 |
+
horizontal=True)
|
435 |
+
# st.stop()
|
436 |
+
# Every form must have a submit button.
|
437 |
+
submit_button = st.form_submit_button(label='ADD TO TRAINING BUCKET', on_click=form_callback)
|
438 |
+
|
439 |
+
# st.session_state.load_state = False
|
440 |
+
# if submitted and not st.session_state.load_state:
|
441 |
+
# st.warning("Sample added to training set..")
|
442 |
+
# st.write("Outside the form")
|
443 |
+
# st.write("slider", slider_val, "checkbox", checkbox_val)
|
444 |
+
|
445 |
+
# with tmp_col2:
|
446 |
+
# tmp_btn = st.button('ADD TO TRAINING BUCKET')
|
447 |
+
# if tmp_btn:
|
448 |
+
# st.warning("Sample added to training set..")
|
449 |
|
450 |
|
451 |
|
|
|
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")
|
459 |
|
460 |
|
461 |
+
def get_product_dev_page_layout(user_type ="Developer"):
|
462 |
+
return main(user_type=user_type)
|
463 |
+
|
464 |
+
# def get_product_dev_page_layout():
|
465 |
+
# return main()
|
466 |
+
|
467 |
+
|
468 |
+
|
utils/eval_users.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import streamlit as st
|
|
|
2 |
import os
|
3 |
ROOT_FIG_DIR = f'{os.getcwd()}/figures/'
|
4 |
|
@@ -10,19 +11,19 @@ def get_product_dev_page_layout():
|
|
10 |
# st.write("**Performance Metrics**")
|
11 |
st.subheader('Performance Metrics')
|
12 |
st.write('Following metrics are used for evaluation:')
|
13 |
-
st.image(f'{ROOT_FIG_DIR}/
|
14 |
list_test = """<ul>
|
15 |
-
<li><strong>Accuracy: </strong>
|
16 |
</ul>"""
|
17 |
st.markdown(list_test, unsafe_allow_html=True)
|
18 |
# st.latex(r''' Accuracy=\frac{TP + TN}{TP+TN+FP+FN}''')
|
19 |
list_test = """<ul>
|
20 |
-
<li><strong>Precision: </strong>
|
21 |
</ul>"""
|
22 |
st.markdown(list_test, unsafe_allow_html=True)
|
23 |
# st.latex(r''' Precision=\frac{TP}{TP+FP}''')
|
24 |
list_test = """<ul>
|
25 |
-
<li><strong>Recall: </strong>
|
26 |
</ul>"""
|
27 |
st.markdown(list_test, unsafe_allow_html=True)
|
28 |
# st.latex(r''' Recall=\frac{TP}{TP+FN}''')
|
@@ -31,27 +32,20 @@ def get_product_dev_page_layout():
|
|
31 |
# st.image('./figures/test_confmat_20210404.png')
|
32 |
|
33 |
with row6_2:
|
34 |
-
# st.write("**Prediction Samples**")
|
35 |
-
# with st.expander('Test Set Confusion Matrix'):
|
36 |
-
# # st.caption('Test Set Results:')
|
37 |
st.subheader('Test Set Confusion Matrix')
|
38 |
st.image(f'{ROOT_FIG_DIR}/test_confmat_20210404.png')
|
39 |
-
# st.subheader('Prediction Samples')
|
40 |
-
# st.caption('Correctly Classified sample predictions:')
|
41 |
-
# st.image(f'{ROOT_FIG_DIR}/pred_stats.png')
|
42 |
-
|
43 |
-
# st.caption('Miss Classified sample predictions:')
|
44 |
-
# st.image(f'{ROOT_FIG_DIR}/pred_stats.png')
|
45 |
|
46 |
-
|
47 |
-
|
|
|
|
|
48 |
|
49 |
with row6_3:
|
50 |
-
st.write("
|
51 |
|
52 |
-
st.
|
53 |
st.image(f'{ROOT_FIG_DIR}/cnv_missclass.png')
|
54 |
|
55 |
-
st.
|
56 |
st.image(f'{ROOT_FIG_DIR}/normal_missclass.png')
|
57 |
|
|
|
1 |
import streamlit as st
|
2 |
+
import streamlit.components.v1 as components
|
3 |
import os
|
4 |
ROOT_FIG_DIR = f'{os.getcwd()}/figures/'
|
5 |
|
|
|
11 |
# st.write("**Performance Metrics**")
|
12 |
st.subheader('Performance Metrics')
|
13 |
st.write('Following metrics are used for evaluation:')
|
14 |
+
st.image(f'{ROOT_FIG_DIR}/eval_metrics.png')
|
15 |
list_test = """<ul>
|
16 |
+
<li><strong>Accuracy: </strong>is the ratio of correctly predicted observation to the total observations..</li>
|
17 |
</ul>"""
|
18 |
st.markdown(list_test, unsafe_allow_html=True)
|
19 |
# st.latex(r''' Accuracy=\frac{TP + TN}{TP+TN+FP+FN}''')
|
20 |
list_test = """<ul>
|
21 |
+
<li><strong>Precision: </strong> is the ratio of correctly predicted positive observations to the total predicted positive observations</li>
|
22 |
</ul>"""
|
23 |
st.markdown(list_test, unsafe_allow_html=True)
|
24 |
# st.latex(r''' Precision=\frac{TP}{TP+FP}''')
|
25 |
list_test = """<ul>
|
26 |
+
<li><strong>Recall: </strong> is the ratio of correctly predicted positive observations to all observations in the actual class.</li>
|
27 |
</ul>"""
|
28 |
st.markdown(list_test, unsafe_allow_html=True)
|
29 |
# st.latex(r''' Recall=\frac{TP}{TP+FN}''')
|
|
|
32 |
# st.image('./figures/test_confmat_20210404.png')
|
33 |
|
34 |
with row6_2:
|
|
|
|
|
|
|
35 |
st.subheader('Test Set Confusion Matrix')
|
36 |
st.image(f'{ROOT_FIG_DIR}/test_confmat_20210404.png')
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
+
with st.expander('Click to Explore Test Data Details'):
|
39 |
+
HtmlFile = open(f'{ROOT_FIG_DIR}/test_set_report.html', 'r', encoding='utf-8')
|
40 |
+
source_code = HtmlFile.read()
|
41 |
+
components.html(source_code,scrolling=True, height=500)
|
42 |
|
43 |
with row6_3:
|
44 |
+
st.write("After examining the performance of the AI model, it was found that the main misclassifications occur in the CNV and NORMAL classes. One can also see this in the given confusion matrix under the Performance Evaluation tab. In particular, CNV cases are often confused with DME and DRUSEN. This can be attributed to the specific characteristics of CNV images present within the dataset. Therefore, it is recommend to thoroughly review the decisions made for CNV cases.")
|
45 |
|
46 |
+
st.warning('Mis classified CNV Samples')
|
47 |
st.image(f'{ROOT_FIG_DIR}/cnv_missclass.png')
|
48 |
|
49 |
+
st.warning('Mis classified NORMAL Samples')
|
50 |
st.image(f'{ROOT_FIG_DIR}/normal_missclass.png')
|
51 |
|
utils/model_users.py
CHANGED
@@ -5,7 +5,7 @@ ROOT_FIG_DIR = f'{os.getcwd()}/figures/'
|
|
5 |
|
6 |
def get_product_dev_page_layout():
|
7 |
model_details ={
|
8 |
-
"Model Description": "EfficientNet is used for transfer learning.",
|
9 |
"Model Type": "Convolutional Neural Nets",
|
10 |
}
|
11 |
|
@@ -19,7 +19,7 @@ def get_product_dev_page_layout():
|
|
19 |
"learning_rate":0.001,
|
20 |
"early_stopping_epochs":10,
|
21 |
"reduce_learning_rate_patience":3,
|
22 |
-
"source_code":"https://github.com/kaplansinan/
|
23 |
|
24 |
}
|
25 |
|
@@ -44,13 +44,13 @@ def get_product_dev_page_layout():
|
|
44 |
|
45 |
list_test = """<ul>
|
46 |
<li><strong>Model Type: </strong>Convolutional Neural Nets</li>
|
47 |
-
<li> <strong>Model Description: </strong>An architecture from EfficientNet family is used for
|
48 |
</ul>"""
|
49 |
st.markdown(list_test, unsafe_allow_html=True)
|
50 |
# st.json(model_details)
|
51 |
|
52 |
st.caption('Architeture Visualization')
|
53 |
-
st.image(f'{ROOT_FIG_DIR}/
|
54 |
|
55 |
with st.expander('License: CC BY 4.0 license(Click for details)'):
|
56 |
st.write("""
|
@@ -99,11 +99,264 @@ def get_product_dev_page_layout():
|
|
99 |
|
100 |
with row2_3:
|
101 |
# st.write("**Production Details**")
|
102 |
-
st.subheader('
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
list_test = """<ul>
|
104 |
-
<li><strong>Model
|
105 |
-
<li> <strong>Model
|
106 |
-
<li> <strong>Model Output: </strong>(1x4)</li>
|
107 |
-
<li> <strong>Model Framework: </strong> ONNXRuntime</li>
|
108 |
</ul>"""
|
109 |
-
st.markdown(list_test, unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
def get_product_dev_page_layout():
|
7 |
model_details ={
|
8 |
+
"Model Description": "[EfficientNet](https://arxiv.org/abs/1905.11946) is used for transfer learning.",
|
9 |
"Model Type": "Convolutional Neural Nets",
|
10 |
}
|
11 |
|
|
|
19 |
"learning_rate":0.001,
|
20 |
"early_stopping_epochs":10,
|
21 |
"reduce_learning_rate_patience":3,
|
22 |
+
"source_code":"https://github.com/kaplansinan/OCTRetImageGen_CLcVAE",
|
23 |
|
24 |
}
|
25 |
|
|
|
44 |
|
45 |
list_test = """<ul>
|
46 |
<li><strong>Model Type: </strong>Convolutional Neural Nets</li>
|
47 |
+
<li> <strong>Model Description: </strong>An architecture from [EfficientNet](https://arxiv.org/abs/1905.11946) family is used for designing the model.</li>
|
48 |
</ul>"""
|
49 |
st.markdown(list_test, unsafe_allow_html=True)
|
50 |
# st.json(model_details)
|
51 |
|
52 |
st.caption('Architeture Visualization')
|
53 |
+
st.image(f'{ROOT_FIG_DIR}/model_architecture_vis.png')
|
54 |
|
55 |
with st.expander('License: CC BY 4.0 license(Click for details)'):
|
56 |
st.write("""
|
|
|
99 |
|
100 |
with row2_3:
|
101 |
# st.write("**Production Details**")
|
102 |
+
st.subheader('How to use the model')
|
103 |
+
st.write("The model is served through gRpc client and one can call the model in the production environment by following a sample code snippet written in python:")
|
104 |
+
with st.expander("Inference Call"):
|
105 |
+
code_txt = '''
|
106 |
+
import json,base64
|
107 |
+
import requests
|
108 |
+
|
109 |
+
# convert image file to base64str
|
110 |
+
def img_to_base64(filename):
|
111 |
+
with open(filename, "rb") as image_file:
|
112 |
+
base64str = base64.b64encode(image_file.read()).decode("utf-8")
|
113 |
+
return base64str
|
114 |
+
|
115 |
+
# run prediction
|
116 |
+
def predict(image_file:str,url:str):
|
117 |
+
base64_img = img_to_base64(image_file)
|
118 |
+
payload = json.dumps({"base64str": base64_img})
|
119 |
+
result = requests.post(url,data = payload)
|
120 |
+
return result.json()
|
121 |
+
|
122 |
+
# Image file
|
123 |
+
image_path = "your_image_file_with_path.png"
|
124 |
+
|
125 |
+
# Server url (an example -> "http://127.0.0.1:8080/predict")
|
126 |
+
serving_server_url = '<model_server_url>/predict'
|
127 |
+
|
128 |
+
# Inference call to serving server
|
129 |
+
preds = predict(image_path,url=serving_server_url) '''
|
130 |
+
st.code(code_txt, language='python')
|
131 |
+
|
132 |
+
st.subheader('Served Model details')
|
133 |
+
col1, col2, col3, col4,col5,col6 = st.columns(6)
|
134 |
+
col1.metric("Model Size", "26MB")
|
135 |
+
col2.metric("Model Input Size", "180x180x3")
|
136 |
+
col3.metric("Model Output", "1x4")
|
137 |
+
col6.metric("Model Framework", "ONNX")
|
138 |
+
col5.metric("GPU Inference(fps)", "45 fps")
|
139 |
+
col4.metric("CPU Inference(fps)", "20 fps")
|
140 |
+
|
141 |
+
# list_test = """<ul>
|
142 |
+
# <li><strong>Model Size: </strong>26MB</li>
|
143 |
+
# <li> <strong>Model Input: </strong>(180x180x3)</li>
|
144 |
+
# <li> <strong>Model Output: </strong>(1x4)</li>
|
145 |
+
# <li> <strong>Model Framework: </strong> ONNXRuntime</li>
|
146 |
+
# </ul>"""
|
147 |
+
# st.markdown(list_test, unsafe_allow_html=True)
|
148 |
+
|
149 |
+
|
150 |
+
|
151 |
+
def get_product_manager_page_layout():
|
152 |
+
model_details ={
|
153 |
+
"Model Description": "[EfficientNet](https://arxiv.org/abs/1905.11946) is used for transfer learning.",
|
154 |
+
"Model Type": "Convolutional Neural Nets",
|
155 |
+
}
|
156 |
+
|
157 |
+
dev_details = {
|
158 |
+
"Training Framework": "Tensorflow Keras",
|
159 |
+
"Backbone Architeture":"EfficientNetB4",
|
160 |
+
"Number of classes":4,
|
161 |
+
"Number of training epochs": 10,
|
162 |
+
"Dropout rate": 0.2,
|
163 |
+
"batch_size": 8,
|
164 |
+
"learning_rate":0.001,
|
165 |
+
"early_stopping_epochs":10,
|
166 |
+
"reduce_learning_rate_patience":3,
|
167 |
+
"source_code":"https://github.com/kaplansinan/MLOps",
|
168 |
+
|
169 |
+
}
|
170 |
+
|
171 |
+
production_details ={
|
172 |
+
"Model size": "26MB",
|
173 |
+
"Model Input": "(N,180,180,3)",
|
174 |
+
"Modeul Output":"(N,4)",
|
175 |
+
"Framework":"ONNXRuntime",
|
176 |
+
|
177 |
+
}
|
178 |
+
|
179 |
+
|
180 |
+
hardware_details ={
|
181 |
+
"Os System": "Ubuntu 20.14",
|
182 |
+
"GPU Card": "NVIDIA GeForce 3060 6GB",
|
183 |
+
}
|
184 |
+
row2_1, row2_3= st.tabs(["General Info", "Production Info"])
|
185 |
+
|
186 |
+
with row2_1:
|
187 |
+
# st.write("**Architectural Details**")
|
188 |
+
st.subheader('Architectural Details')
|
189 |
+
|
190 |
+
list_test = """<ul>
|
191 |
+
<li><strong>Model Type: </strong>Convolutional Neural Nets</li>
|
192 |
+
<li> <strong>Model Description: </strong>An architecture from [EfficientNet](https://arxiv.org/abs/1905.11946) family is used for designing the model.</li>
|
193 |
+
</ul>"""
|
194 |
+
st.markdown(list_test, unsafe_allow_html=True)
|
195 |
+
# st.json(model_details)
|
196 |
+
|
197 |
+
st.caption('Architeture Visualization')
|
198 |
+
st.image(f'{ROOT_FIG_DIR}/model_architecture_vis.png')
|
199 |
+
|
200 |
+
with st.expander('License: CC BY 4.0 license(Click for details)'):
|
201 |
+
st.write("""
|
202 |
+
The files associated with this dataset are licensed under a Creative Commons Attribution 4.0 International license. What does this mean?
|
203 |
+
You can share, copy and modify this dataset so long as you give appropriate credit,
|
204 |
+
provide a link to the CC BY license, and indicate if changes were made, but you may not do
|
205 |
+
so in a way that suggests the rights holder has endorsed you or your use of the dataset.
|
206 |
+
Note that further permission may be required for any content within the dataset
|
207 |
+
that is identified as belonging to a third party. More details about the licences can be found
|
208 |
+
[here](https://creativecommons.org/about/cclicenses/).
|
209 |
+
""")
|
210 |
+
|
211 |
+
# with st.expander('Click for More Info'):
|
212 |
+
with row2_3:
|
213 |
+
# st.write("**Production Details**")
|
214 |
+
st.subheader('How to use the model')
|
215 |
+
st.write("The model is served through gRpc client and one can call the model in the production environment by following a sample code snippet written in python:")
|
216 |
+
with st.expander("Inference Call"):
|
217 |
+
code_txt = '''
|
218 |
+
import json,base64
|
219 |
+
import requests
|
220 |
+
|
221 |
+
# convert image file to base64str
|
222 |
+
def img_to_base64(filename):
|
223 |
+
with open(filename, "rb") as image_file:
|
224 |
+
base64str = base64.b64encode(image_file.read()).decode("utf-8")
|
225 |
+
return base64str
|
226 |
+
|
227 |
+
# run prediction
|
228 |
+
def predict(image_file:str,url:str):
|
229 |
+
base64_img = img_to_base64(image_file)
|
230 |
+
payload = json.dumps({"base64str": base64_img})
|
231 |
+
result = requests.post(url,data = payload)
|
232 |
+
return result.json()
|
233 |
+
|
234 |
+
# Image file
|
235 |
+
image_path = "your_image_file_with_path.png"
|
236 |
+
|
237 |
+
# Server url (an example -> "http://127.0.0.1:8080/predict")
|
238 |
+
serving_server_url = '<model_server_url>/predict'
|
239 |
+
|
240 |
+
# Inference call to serving server
|
241 |
+
preds = predict(image_path,url=serving_server_url) '''
|
242 |
+
st.code(code_txt, language='python')
|
243 |
+
|
244 |
+
st.subheader('Served Model details')
|
245 |
+
col1, col2, col3, col4,col5,col6 = st.columns(6)
|
246 |
+
col1.metric("Model Size", "26MB")
|
247 |
+
col2.metric("Model Input Size", "180x180x3")
|
248 |
+
col3.metric("Model Output", "1x4")
|
249 |
+
col6.metric("Model Framework", "ONNX")
|
250 |
+
col5.metric("GPU Inference(fps)", "45 fps")
|
251 |
+
col4.metric("CPU Inference(fps)", "20 fps")
|
252 |
+
|
253 |
+
|
254 |
+
def get_product_practitioner_page_layout():
|
255 |
+
model_details ={
|
256 |
+
"Model Description": "[EfficientNet](https://arxiv.org/abs/1905.11946) is used for transfer learning.",
|
257 |
+
"Model Type": "Convolutional Neural Nets",
|
258 |
+
}
|
259 |
+
|
260 |
+
dev_details = {
|
261 |
+
"Training Framework": "Tensorflow Keras",
|
262 |
+
"Backbone Architeture":"EfficientNetB4",
|
263 |
+
"Number of classes":4,
|
264 |
+
"Number of training epochs": 10,
|
265 |
+
"Dropout rate": 0.2,
|
266 |
+
"batch_size": 8,
|
267 |
+
"learning_rate":0.001,
|
268 |
+
"early_stopping_epochs":10,
|
269 |
+
"reduce_learning_rate_patience":3,
|
270 |
+
"source_code":"https://github.com/kaplansinan/MLOps",
|
271 |
+
|
272 |
+
}
|
273 |
+
|
274 |
+
production_details ={
|
275 |
+
"Model size": "26MB",
|
276 |
+
"Model Input": "(N,180,180,3)",
|
277 |
+
"Modeul Output":"(N,4)",
|
278 |
+
"Framework":"ONNXRuntime",
|
279 |
+
|
280 |
+
}
|
281 |
+
|
282 |
+
|
283 |
+
hardware_details ={
|
284 |
+
"Os System": "Ubuntu 20.14",
|
285 |
+
"GPU Card": "NVIDIA GeForce 3060 6GB",
|
286 |
+
}
|
287 |
+
row2_1, row2_3= st.tabs(["General Info", "Production Info"])
|
288 |
+
|
289 |
+
with row2_1:
|
290 |
+
# st.write("**Architectural Details**")
|
291 |
+
st.subheader('Architectural Details')
|
292 |
+
|
293 |
list_test = """<ul>
|
294 |
+
<li><strong>Model Type: </strong>Convolutional Neural Nets</li>
|
295 |
+
<li> <strong>Model Description: </strong>An architecture from [EfficientNet](https://arxiv.org/abs/1905.11946) family is used for designing the model.</li>
|
|
|
|
|
296 |
</ul>"""
|
297 |
+
st.markdown(list_test, unsafe_allow_html=True)
|
298 |
+
# st.json(model_details)
|
299 |
+
|
300 |
+
st.caption('Architeture Visualization')
|
301 |
+
st.image(f'{ROOT_FIG_DIR}/model_architecture_vis.png')
|
302 |
+
|
303 |
+
with st.expander('License: CC BY 4.0 license(Click for details)'):
|
304 |
+
st.write("""
|
305 |
+
The files associated with this dataset are licensed under a Creative Commons Attribution 4.0 International license. What does this mean?
|
306 |
+
You can share, copy and modify this dataset so long as you give appropriate credit,
|
307 |
+
provide a link to the CC BY license, and indicate if changes were made, but you may not do
|
308 |
+
so in a way that suggests the rights holder has endorsed you or your use of the dataset.
|
309 |
+
Note that further permission may be required for any content within the dataset
|
310 |
+
that is identified as belonging to a third party. More details about the licences can be found
|
311 |
+
[here](https://creativecommons.org/about/cclicenses/).
|
312 |
+
""")
|
313 |
+
|
314 |
+
# with st.expander('Click for More Info'):
|
315 |
+
with row2_3:
|
316 |
+
# st.write("**Production Details**")
|
317 |
+
st.subheader('How to use the model')
|
318 |
+
st.write("The model is served through gRpc client and one can call the model in the production environment by following a sample code snippet written in python:")
|
319 |
+
with st.expander("Inference Call"):
|
320 |
+
code_txt = '''
|
321 |
+
import json,base64
|
322 |
+
import requests
|
323 |
+
|
324 |
+
# convert image file to base64str
|
325 |
+
def img_to_base64(filename):
|
326 |
+
with open(filename, "rb") as image_file:
|
327 |
+
base64str = base64.b64encode(image_file.read()).decode("utf-8")
|
328 |
+
return base64str
|
329 |
+
|
330 |
+
# run prediction
|
331 |
+
def predict(image_file:str,url:str):
|
332 |
+
base64_img = img_to_base64(image_file)
|
333 |
+
payload = json.dumps({"base64str": base64_img})
|
334 |
+
result = requests.post(url,data = payload)
|
335 |
+
return result.json()
|
336 |
+
|
337 |
+
# Image file
|
338 |
+
image_path = "your_image_file_with_path.png"
|
339 |
+
|
340 |
+
# Server url (an example -> "http://127.0.0.1:8080/predict")
|
341 |
+
serving_server_url = '<model_server_url>/predict'
|
342 |
+
|
343 |
+
# Inference call to serving server
|
344 |
+
preds = predict(image_path,url=serving_server_url) '''
|
345 |
+
st.code(code_txt, language='python')
|
346 |
+
|
347 |
+
st.subheader('Served Model details')
|
348 |
+
col1, col2, col3, col4,col5,col6 = st.columns(6)
|
349 |
+
col1.metric("Model Size", "26MB")
|
350 |
+
col2.metric("Model Input Size", "180x180x3")
|
351 |
+
col3.metric("Model Output", "1x4")
|
352 |
+
col6.metric("Model Framework", "ONNX")
|
353 |
+
col5.metric("GPU Inference(fps)", "45 fps")
|
354 |
+
col4.metric("CPU Inference(fps)", "20 fps")
|
355 |
+
|
356 |
+
# list_test = """<ul>
|
357 |
+
# <li><strong>Model Size: </strong>26MB</li>
|
358 |
+
# <li> <strong>Model Input: </strong>(180x180x3)</li>
|
359 |
+
# <li> <strong>Model Output: </strong>(1x4)</li>
|
360 |
+
# <li> <strong>Model Framework: </strong> ONNXRuntime</li>
|
361 |
+
# </ul>"""
|
362 |
+
# st.markdown(list_test, unsafe_allow_html=True)
|