kidcoconut
commited on
Commit
β’
48f39fa
1
Parent(s):
09fd2b4
DEPLOY: updated all files for manual deploy to huggingface
Browse files- .dockerignore +10 -6
- .gitattributes +9 -2
- .gitignore +40 -4
- README.md +1 -1
- app.py +6 -9
- data/demo_tiles/raw/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10752_30720.tiff +0 -3
- data/demo_tiles/raw/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0144_svsvt_chunks_36864_4608.tiff +0 -3
- data/demo_tiles/raw/{Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10240_30720.tiff β sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsvt_chunks_10240_13312.tiff} +1 -1
- data/demo_tiles/raw/{Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10240_31232.tiff β sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svswt_chunks_38912_5632.tiff} +1 -1
- data/demo_tiles/raw/{Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10240_31744.tiff β sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0140_svsvt_chunks_45056_8192.tiff} +1 -1
- data/demo_tiles/raw/{Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10240_32256.tiff β sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0141_svsvt_chunks_39936_26624.tiff} +1 -1
- data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0141_svswt_chunks_46080_46080.tiff +3 -0
- data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0142_svswt_chunks_41472_21504.tiff +3 -0
- data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0145_svsvt_chunks_5632_28672.tiff +3 -0
- data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0161_svsvt_chunks_37888_35840.tiff +3 -0
- data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0161_svsvt_chunks_44032_38912.tiff +3 -0
- data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0161_svswt_chunks_46080_19456.tiff +3 -0
- lib/models/__init__.py +0 -0
- lib/models/mdl_autoenc.py +55 -0
- lib/models/mdl_kmeans.py +155 -0
- lib/models/mdl_logR.py +41 -0
- lib/models/mdl_svm.py +40 -0
- lib/models/mdl_utils.py +256 -0
- lib/models/mdl_xgb.py +66 -0
- lib/utils.py +1 -0
- util_dockerPreRun.sh β scripts/docker/util_docker_preRun.sh +17 -5
- scripts/docker/util_local_buildDockerDemo.sh +85 -0
- scripts/docker/util_local_runDockerDemo.sh +33 -0
- scripts/huggingface/util_local_readyDeploy_toHugSpace_streamlit.sh +88 -0
- {bin β scripts}/models/util_joinModel.sh +14 -1
- {bin β scripts}/models/util_splitModel.sh +14 -1
- util_startLocal_streamlitFastApi.sh β scripts/streamlitFastApi/util_local_runStreamlitFastApi.sh +10 -6
- scripts/util.sh +148 -0
- uix/lit_sidebar.py +8 -61
- uix/pages/lit_about.py +9 -5
- uix/pages/lit_diagnosis.py +91 -25
- uix/pages/lit_home.py +57 -13
.dockerignore
CHANGED
@@ -1,17 +1,21 @@
|
|
1 |
|
|
|
2 |
#--- ignore select binary files/folders
|
3 |
bin/images/sample*
|
4 |
bin/models/*.pth
|
5 |
bin/models/*.zip
|
|
|
6 |
bin/testing
|
7 |
-
|
|
|
|
|
8 |
|
9 |
#--- ignore all local data files; preserve/recreate folder structure
|
10 |
-
|
11 |
data/tiles
|
12 |
data/wsi
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
|
|
1 |
|
2 |
+
|
3 |
#--- ignore select binary files/folders
|
4 |
bin/images/sample*
|
5 |
bin/models/*.pth
|
6 |
bin/models/*.zip
|
7 |
+
bin/models/deeplabv3*vhflip30/*.pth
|
8 |
bin/testing
|
9 |
+
_ignore
|
10 |
+
.vscode
|
11 |
+
cicd_workflows
|
12 |
|
13 |
#--- ignore all local data files; preserve/recreate folder structure
|
14 |
+
data/demo_tiles/*.tiff
|
15 |
data/tiles
|
16 |
data/wsi
|
17 |
|
18 |
+
#--- ignore all doc files
|
19 |
+
docs
|
20 |
+
notebooks
|
21 |
+
preso
|
.gitattributes
CHANGED
@@ -1,3 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
@@ -23,7 +30,6 @@
|
|
23 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
24 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
25 |
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
27 |
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
28 |
*.tar filter=lfs diff=lfs merge=lfs -text
|
29 |
*.tflite filter=lfs diff=lfs merge=lfs -text
|
@@ -33,7 +39,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
-
*model_a* filter=lfs diff=lfs merge=lfs -text
|
37 |
*.tiff filter=lfs diff=lfs merge=lfs -text
|
38 |
data/demo_tiles/raw/*.tiff filter=lfs diff=lfs merge=lfs -text
|
39 |
bin/models/deeplabv3*vhflip30/model_a* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
1 |
+
#--- Note: omdena github does not allow git lfs. Disable.
|
2 |
+
#--- Note: huggingface does not allow _any_ binaries; git lfs has to be used
|
3 |
+
#bin/models/*.pth filter=lfs diff=lfs merge=lfs -text
|
4 |
+
#bin/models/deeplab*vhflip30/model_a* filter=lfs diff=lfs merge=lfs -text
|
5 |
+
#bin/images/* filter=lfs diff=lfs merge=lfs -text
|
6 |
+
#data/demo_tiles/raw/* filter=lfs diff=lfs merge=lfs -text
|
7 |
+
|
8 |
*.7z filter=lfs diff=lfs merge=lfs -text
|
9 |
*.arrow filter=lfs diff=lfs merge=lfs -text
|
10 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
|
|
30 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
31 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
32 |
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
|
|
33 |
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
34 |
*.tar filter=lfs diff=lfs merge=lfs -text
|
35 |
*.tflite filter=lfs diff=lfs merge=lfs -text
|
|
|
39 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
40 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
41 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
42 |
*.tiff filter=lfs diff=lfs merge=lfs -text
|
43 |
data/demo_tiles/raw/*.tiff filter=lfs diff=lfs merge=lfs -text
|
44 |
bin/models/deeplabv3*vhflip30/model_a* filter=lfs diff=lfs merge=lfs -text
|
45 |
+
*model_a* filter=lfs diff=lfs merge=lfs -text
|
46 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
.gitignore
CHANGED
@@ -1,13 +1,49 @@
|
|
|
|
|
|
|
|
|
|
1 |
#--- specific to task5-deploy
|
2 |
bin/images/sample*
|
3 |
-
bin/
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
bin/testing
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
data/tiles
|
8 |
data/wsi
|
9 |
data_host_mount
|
|
|
|
|
|
|
|
|
10 |
_ignore
|
|
|
|
|
|
|
11 |
|
12 |
|
13 |
# Byte-compiled / optimized / DLL files
|
@@ -26,7 +62,7 @@ dist/
|
|
26 |
downloads/
|
27 |
eggs/
|
28 |
.eggs/
|
29 |
-
lib/
|
30 |
lib64/
|
31 |
parts/
|
32 |
sdist/
|
|
|
1 |
+
#--- NOTE: this .gitignore is specific to the hugspace_docker cicd deploy
|
2 |
+
#--- WARN: omdena github does not support git lfs at all; allows small binary files
|
3 |
+
#--- WARN: huggingface github does not allow _any_ binary files outside of git lfs
|
4 |
+
|
5 |
#--- specific to task5-deploy
|
6 |
bin/images/sample*
|
7 |
+
bin/images/dbl.png
|
8 |
+
|
9 |
+
#--- specific to cicd_hugspace_streamlit deploy
|
10 |
+
#--- omdena github will not have access to git lfs or the complete model file
|
11 |
+
#--- cicd will rebuild the model file
|
12 |
+
#.vscode
|
13 |
+
#bin/models/deeplabv3*vhflip30/*.pth
|
14 |
+
#bin/testing
|
15 |
+
#data/demo_tiles/raw/*.tiff
|
16 |
+
#notebooks
|
17 |
+
#.dockerignore
|
18 |
+
#Dockerfile
|
19 |
+
#main.py
|
20 |
+
|
21 |
+
#--- specific to cicd_hugspace_docker deploy
|
22 |
+
#--- omdena github will not have access to git lfs or the complete model file
|
23 |
+
#--- cicd will rebuild the model file
|
24 |
+
.vscode
|
25 |
+
bin/models/deeplabv3*vhflip30/*.pth
|
26 |
bin/testing
|
27 |
+
data/demo_tiles/raw/*.tiff
|
28 |
+
notebooks
|
29 |
+
|
30 |
+
|
31 |
+
#--- omdena github does not allow large files or git lfs
|
32 |
+
bin/models/*.pth
|
33 |
+
bin/models/*.zip
|
34 |
+
#bin/models/deeplabv3*/model_a* #--- save partial model files in omdena github
|
35 |
+
#data/demo_tiles #--- allow demo tiles in the github for use and ref
|
36 |
data/tiles
|
37 |
data/wsi
|
38 |
data_host_mount
|
39 |
+
|
40 |
+
preso
|
41 |
+
|
42 |
+
*.pth
|
43 |
_ignore
|
44 |
+
*.bkp
|
45 |
+
*.dtmp
|
46 |
+
*.pptx
|
47 |
|
48 |
|
49 |
# Byte-compiled / optimized / DLL files
|
|
|
62 |
downloads/
|
63 |
eggs/
|
64 |
.eggs/
|
65 |
+
#lib/
|
66 |
lib64/
|
67 |
parts/
|
68 |
sdist/
|
README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
emoji: π’
|
4 |
colorFrom: purple
|
5 |
colorTo: green
|
|
|
1 |
---
|
2 |
+
title: spcDkr omdenaSaudi Liver HCC XAI
|
3 |
emoji: π’
|
4 |
colorFrom: purple
|
5 |
colorTo: green
|
app.py
CHANGED
@@ -2,7 +2,6 @@
|
|
2 |
toExecute: (from root app folder) ... streamlit run app.py
|
3 |
'''
|
4 |
import streamlit as st
|
5 |
-
#from uix import lit_sidebar as lit_sideBar
|
6 |
import uix.lit_sidebar as litSideBar
|
7 |
|
8 |
|
@@ -11,16 +10,14 @@ st.set_page_config(
|
|
11 |
page_title='Omdena Saudi Arabia - Liver HCC Diagnosis with XAI',
|
12 |
#page_icon='https://cdn.freebiesupply.com/logos/thumbs/1x/nvidia-logo.png',
|
13 |
layout="wide")
|
14 |
-
st.header(
|
|
|
|
|
|
|
|
|
|
|
15 |
st.markdown('---')
|
16 |
|
17 |
|
18 |
#--- streamlit: add a sidebar
|
19 |
litSideBar.init()
|
20 |
-
|
21 |
-
|
22 |
-
#if __name__ == '__main__':
|
23 |
-
# st.run("main:app", host="0.0.0.0", port=49300, reload=True)
|
24 |
-
# streamlit run app.py --server.port 49400 --server.maxUploadSize 2000
|
25 |
-
|
26 |
-
#aryPkg[moduleNames.index(page)].run()
|
|
|
2 |
toExecute: (from root app folder) ... streamlit run app.py
|
3 |
'''
|
4 |
import streamlit as st
|
|
|
5 |
import uix.lit_sidebar as litSideBar
|
6 |
|
7 |
|
|
|
10 |
page_title='Omdena Saudi Arabia - Liver HCC Diagnosis with XAI',
|
11 |
#page_icon='https://cdn.freebiesupply.com/logos/thumbs/1x/nvidia-logo.png',
|
12 |
layout="wide")
|
13 |
+
st.header('\
|
14 |
+
Detecting Liver Cancer from Histopathology WSI \
|
15 |
+
using Deep Learning and Explainability (XAI)\
|
16 |
+
')
|
17 |
+
st.markdown('#### Dr. Shaista Hussain (Saudi Arabia Chapter Lead)')
|
18 |
+
st.markdown("##### Iain McKone (Deployment Lead) [LinkedIn](%s)" % "https://linkedin.com/in/iainmckone")
|
19 |
st.markdown('---')
|
20 |
|
21 |
|
22 |
#--- streamlit: add a sidebar
|
23 |
litSideBar.init()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data/demo_tiles/raw/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10752_30720.tiff
DELETED
Git LFS Details
|
data/demo_tiles/raw/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0144_svsvt_chunks_36864_4608.tiff
DELETED
Git LFS Details
|
data/demo_tiles/raw/{Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10240_30720.tiff β sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsvt_chunks_10240_13312.tiff}
RENAMED
File without changes
|
data/demo_tiles/raw/{Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10240_31232.tiff β sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svswt_chunks_38912_5632.tiff}
RENAMED
File without changes
|
data/demo_tiles/raw/{Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10240_31744.tiff β sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0140_svsvt_chunks_45056_8192.tiff}
RENAMED
File without changes
|
data/demo_tiles/raw/{Dataset_PAIP2019_Omdena_Validation_Image_01_01_0105_svsbg_chunks_10240_32256.tiff β sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0141_svsvt_chunks_39936_26624.tiff}
RENAMED
File without changes
|
data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0141_svswt_chunks_46080_46080.tiff
ADDED
Git LFS Details
|
data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0142_svswt_chunks_41472_21504.tiff
ADDED
Git LFS Details
|
data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0145_svsvt_chunks_5632_28672.tiff
ADDED
Git LFS Details
|
data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0161_svsvt_chunks_37888_35840.tiff
ADDED
Git LFS Details
|
data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0161_svsvt_chunks_44032_38912.tiff
ADDED
Git LFS Details
|
data/demo_tiles/raw/sample/Dataset_PAIP2019_Omdena_Validation_Image_01_01_0161_svswt_chunks_46080_19456.tiff
ADDED
Git LFS Details
|
lib/models/__init__.py
ADDED
File without changes
|
lib/models/mdl_autoenc.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import numpy as np
|
3 |
+
from sklearn.decomposition import PCA
|
4 |
+
import lib.utils as libPaths
|
5 |
+
import pickle
|
6 |
+
|
7 |
+
|
8 |
+
m_kstrFile = __file__
|
9 |
+
m_kstrDataPath = libPaths.pth_data
|
10 |
+
m_kstrBinModelPath = libPaths.pth_binModels
|
11 |
+
m_kstrPcaModelPath = m_kstrBinModelPath + 'pca_unsuperv_colab.pkl'
|
12 |
+
m_kstrEncModelPath = m_kstrBinModelPath + 'enc_keras_seq/'
|
13 |
+
|
14 |
+
|
15 |
+
#--- Supervised: autoencoder - Principal Component Analysis
|
16 |
+
def load_encFromKeras():
|
17 |
+
from tensorflow import keras
|
18 |
+
mdlAnoms = keras.models.load_model(m_kstrEncModelPath)
|
19 |
+
return mdlAnoms
|
20 |
+
|
21 |
+
|
22 |
+
def load_pcaFromPkl():
|
23 |
+
with open(m_kstrPcaModelPath, 'rb') as filPkl:
|
24 |
+
# load using pickle de-serializer
|
25 |
+
mdlAnoms = pickle.load(filPkl)
|
26 |
+
return mdlAnoms
|
27 |
+
|
28 |
+
|
29 |
+
def save_encToKeras(mdlAnoms):
|
30 |
+
mdlAnoms.save(m_kstrEncModelPath)
|
31 |
+
|
32 |
+
|
33 |
+
|
34 |
+
def predict(pdfScaled):
|
35 |
+
|
36 |
+
#--- Pre: Transforming train and test dataframes based on PCA
|
37 |
+
mdlPCA = load_pcaFromPkl() #--- this is a pre-fit model based on training
|
38 |
+
npaPca = mdlPCA.transform(pdfScaled)
|
39 |
+
print("INFO (" + m_kstrFile + ".predict) npaPca.shape: ", npaPca.shape)
|
40 |
+
|
41 |
+
|
42 |
+
#--- predict on unseen data
|
43 |
+
mdlEnc = load_encFromKeras()
|
44 |
+
npaPredict = mdlEnc.predict(npaPca[:,:29])
|
45 |
+
print("INFO (" + m_kstrFile + ".predict) npaPredict.shape: ", npaPredict.shape)
|
46 |
+
#--- expected: 297, 29?
|
47 |
+
return npaPredict
|
48 |
+
|
49 |
+
|
50 |
+
"""
|
51 |
+
def train(pdfTrainData):
|
52 |
+
mdlAnoms = PCA() #---- TODO: this is Keras Sequential
|
53 |
+
mdlAnoms.fit(pdfTrainData.values)
|
54 |
+
save_encToKeras(mdlAnoms)
|
55 |
+
return mdlAnoms """
|
lib/models/mdl_kmeans.py
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sklearn.cluster import KMeans
|
2 |
+
import lib.utils as libPaths
|
3 |
+
import pickle
|
4 |
+
import pandas as pd
|
5 |
+
|
6 |
+
|
7 |
+
m_kstrFile = __file__
|
8 |
+
m_kstrDataPath = libPaths.pth_data
|
9 |
+
m_kstrBinModelPath = libPaths.pth_binModels
|
10 |
+
|
11 |
+
#m_kstrPcaModelPath = m_kstrBinModelPath + 'pca_kmeans_unsuperv_colab.pkl'
|
12 |
+
#m_kstrPcaModelPath = m_kstrBinModelPath + 'pca_kmeans_unsuperv_colab_v1.2.1.pkl'
|
13 |
+
m_kstrPcaModelPath_111 = m_kstrBinModelPath + 'claims_pca_v1.1.1_27cols.pkl' #--- ERROR: __randomstate_ctor() takes from 0 to 1 positional arguments but 2 were given
|
14 |
+
m_kstrPcaModelPath_121 = m_kstrBinModelPath + 'claims_pca_v1.2.1_27cols.pkl'
|
15 |
+
m_kstrPcaModelPath_claims_py3816_sk111hp = m_kstrBinModelPath + 'claims_pca_py3816_sk111hp_27cols.pkl'
|
16 |
+
m_kstrPcaModelPath = m_kstrPcaModelPath_claims_py3816_sk111hp
|
17 |
+
|
18 |
+
#m_kstrKmeansModelPath = m_kstrBinModelPath + 'kmeans_unsuperv_colab.pkl'
|
19 |
+
#m_kstrKmeansModelPath = m_kstrBinModelPath + 'kmn_unsuperv_colab_v1.2.1.pkl'
|
20 |
+
m_kstrModelPath_111 = m_kstrBinModelPath + 'claims_kmn_v1.1.1_22cols.pkl' #--- ERROR: __randomstate_ctor() takes from 0 to 1 positional arguments but 2 were given
|
21 |
+
m_kstrModelPath_121 = m_kstrBinModelPath + 'claims_kmn_v1.2.1_22cols.pkl'
|
22 |
+
m_kstrModelPath_claims_py3816_sk111hp = m_kstrBinModelPath + 'claims_kmn_py3816_sk111hp_22cols.pkl'
|
23 |
+
m_kstrKmeansModelPath = m_kstrModelPath_claims_py3816_sk111hp
|
24 |
+
|
25 |
+
m_blnTraceOn = True
|
26 |
+
|
27 |
+
|
28 |
+
#--- unsupervised: Logistic Regession
|
29 |
+
def load_pcaFromPkl():
|
30 |
+
with open(m_kstrPcaModelPath, 'rb') as filPkl:
|
31 |
+
mdlAnoms = pickle.load(filPkl)
|
32 |
+
return mdlAnoms
|
33 |
+
|
34 |
+
|
35 |
+
#--- unsupervised: KMeans
|
36 |
+
def load_kmeansFromPkl():
|
37 |
+
with open(m_kstrKmeansModelPath, 'rb') as filPkl:
|
38 |
+
mdlAnoms = pickle.load(filPkl)
|
39 |
+
return mdlAnoms
|
40 |
+
|
41 |
+
|
42 |
+
def save_pcaToPkl(mdlAnoms):
|
43 |
+
with open(m_kstrPcaModelPath, 'wb') as filPkl:
|
44 |
+
pickle.dump(mdlAnoms, filPkl)
|
45 |
+
return mdlAnoms
|
46 |
+
|
47 |
+
|
48 |
+
def save_kmeansToPkl(mdlAnoms):
|
49 |
+
with open(m_kstrKmeansModelPath, 'wb') as filPkl:
|
50 |
+
pickle.dump(mdlAnoms, filPkl)
|
51 |
+
return mdlAnoms
|
52 |
+
|
53 |
+
|
54 |
+
|
55 |
+
#--- determine which points can be labelled against which clusters
|
56 |
+
def predict(pdfScaled):
|
57 |
+
#--- load a persisted fit kmeans model
|
58 |
+
#--- predict will assign labels onto a similarly scaled data frame
|
59 |
+
|
60 |
+
|
61 |
+
#--- Note: reverse chron through the code ...
|
62 |
+
#--- 4. KMeans was fit on X-reduced (22 cols)
|
63 |
+
#--- 3. X_reduced was a reduced column set of X-scaled (27 -> 22; Dropped 5 cols: DeadOrNot; and hotEncoded Gender and Race)
|
64 |
+
#--- 2. x_scaled was transformed through stdScaler
|
65 |
+
#--- 1. StdScaler was fit on X to produce X-scaled (X has 27 cols)
|
66 |
+
pdfReduced = pdfScaled[['InscClaimAmtReimbursed', 'DeductibleAmtPaid',
|
67 |
+
'AdmittedDays', 'RenalDiseaseIndicator', 'NoOfMonths_PartACov',
|
68 |
+
'NoOfMonths_PartBCov', 'ChronicCond_Alzheimer',
|
69 |
+
'ChronicCond_Heartfailure', 'ChronicCond_KidneyDisease',
|
70 |
+
'ChronicCond_Cancer', 'ChronicCond_ObstrPulmonary',
|
71 |
+
'ChronicCond_Depression', 'ChronicCond_Diabetes',
|
72 |
+
'ChronicCond_IschemicHeart', 'ChronicCond_Osteoporasis',
|
73 |
+
'ChronicCond_rheumatoidarthritis', 'ChronicCond_stroke',
|
74 |
+
'IPAnnualReimbursementAmt', 'IPAnnualDeductibleAmt',
|
75 |
+
'OPAnnualReimbursementAmt', 'OPAnnualDeductibleAmt', 'Age']]
|
76 |
+
|
77 |
+
#--- prefit Kmeans clustering - was fit on trained pdfReduced
|
78 |
+
#--- Note: if we want to understand how kmeans performs on test/prod data, we need to predict
|
79 |
+
mdlKMeans = load_kmeansFromPkl()
|
80 |
+
#ndaPredict = mdlKMeans.predict(pdfScaled) #20230208: ValueError: X has 27 features, but KMeans is expecting 22 features as input.
|
81 |
+
ndaPredict = mdlKMeans.predict(pdfReduced) #ValueError: X has 22 features, but KMeans is expecting 27 features as input.
|
82 |
+
return ndaPredict
|
83 |
+
|
84 |
+
|
85 |
+
#--- feat eng
|
86 |
+
def do_featEng(pdfLoaded, blnIsTrain=False, hasGroupByProviderCols=True):
|
87 |
+
print("INFO (mdl_kmeans.doFeatEng): blnIsTrain, ", blnIsTrain)
|
88 |
+
|
89 |
+
#--- columns_to_remove
|
90 |
+
aryColsToDrop = ['BeneID', 'ClaimID', 'ClaimStartDt','ClaimEndDt','AttendingPhysician',
|
91 |
+
'OperatingPhysician', 'OtherPhysician', 'ClmDiagnosisCode_1',
|
92 |
+
'ClmDiagnosisCode_2', 'ClmDiagnosisCode_3', 'ClmDiagnosisCode_4',
|
93 |
+
'ClmDiagnosisCode_5', 'ClmDiagnosisCode_6', 'ClmDiagnosisCode_7',
|
94 |
+
'ClmDiagnosisCode_8', 'ClmDiagnosisCode_9', 'ClmDiagnosisCode_10',
|
95 |
+
'ClmProcedureCode_1', 'ClmProcedureCode_2', 'ClmProcedureCode_3',
|
96 |
+
'ClmProcedureCode_4', 'ClmProcedureCode_5', 'ClmProcedureCode_6',
|
97 |
+
'ClmAdmitDiagnosisCode', 'AdmissionDt',
|
98 |
+
'DischargeDt', 'DiagnosisGroupCode','DOB', 'DOD',
|
99 |
+
'State', 'County']
|
100 |
+
pdfFeatEng = pdfLoaded.drop(columns=aryColsToDrop, axis=1)
|
101 |
+
|
102 |
+
#--- flag categorical cols
|
103 |
+
pdfFeatEng.Gender = pdfFeatEng.Gender.astype('category')
|
104 |
+
pdfFeatEng.Race = pdfFeatEng.Race.astype('category')
|
105 |
+
|
106 |
+
#--- one-hot-encoding
|
107 |
+
pdfFeatEng = pd.get_dummies(pdfFeatEng, columns=['Gender', 'Race'], drop_first=True)
|
108 |
+
if (blnIsTrain):
|
109 |
+
#--- one-hot encode the potential fraud column (for training data only)
|
110 |
+
try:
|
111 |
+
#print("INFO (claims.doFeatEng): one-hot encoding potential fraud")
|
112 |
+
pdfFeatEng.loc[pdfFeatEng['PotentialFraud'] == 'Yes', 'PotentialFraud'] = 1
|
113 |
+
pdfFeatEng.loc[pdfFeatEng['PotentialFraud'] == 'No', 'PotentialFraud'] = 0
|
114 |
+
except KeyError:
|
115 |
+
#--- likely column not found; invalid fxn call
|
116 |
+
print("ERROR (claims.doFeatEng): Potential Fraud col not found")
|
117 |
+
|
118 |
+
pdfFeatEng.loc[pdfFeatEng['RenalDiseaseIndicator'] == 'Y', 'RenalDiseaseIndicator'] = 1
|
119 |
+
pdfFeatEng['DeductibleAmtPaid'].fillna(0, inplace=True)
|
120 |
+
pdfFeatEng['AdmittedDays'].fillna(0, inplace=True)
|
121 |
+
|
122 |
+
#--- check for correlated cols
|
123 |
+
|
124 |
+
#--- add new features to assist with predictions
|
125 |
+
if (hasGroupByProviderCols):
|
126 |
+
pdfFeatEng['InscClaimReimbursement_ProviderAvg'] = pdfFeatEng.groupby(['Provider'])['InscClaimAmtReimbursed'].transform('mean')
|
127 |
+
pdfFeatEng['DeductibleAmtPaid_ProviderAvg'] = pdfFeatEng.groupby(['Provider'])['DeductibleAmtPaid'].transform('mean')
|
128 |
+
|
129 |
+
pdfFeatEng['IPAnnualReimbursementAmt_ProviderAvg'] = pdfFeatEng.groupby(['Provider'])['IPAnnualReimbursementAmt'].transform('mean')
|
130 |
+
pdfFeatEng['IPAnnualDeductibleAmt_ProviderAvg'] = pdfFeatEng.groupby(['Provider'])['IPAnnualDeductibleAmt'].transform('mean')
|
131 |
+
|
132 |
+
pdfFeatEng['OPAnnualReimbursementAmt_ProviderAvg'] = pdfFeatEng.groupby(['Provider'])['OPAnnualReimbursementAmt'].transform('mean')
|
133 |
+
pdfFeatEng['OPAnnualDeductibleAmt_ProviderAvg'] = pdfFeatEng.groupby(['Provider'])['OPAnnualDeductibleAmt'].transform('mean')
|
134 |
+
return pdfFeatEng
|
135 |
+
|
136 |
+
|
137 |
+
def fit(pdfScaled):
|
138 |
+
#--- determine the centroids of the kmeans clusters
|
139 |
+
#--- refit kmeans clustering according to the pre-scaled data provided
|
140 |
+
#--- note: this all assumes that the nature of the data and the number of clusters remain unchanged
|
141 |
+
m_klngNumClusters = 3
|
142 |
+
if (m_blnTraceOn): print("TRACE (" + m_kstrFile + ".fit) instantiate KMeans ...")
|
143 |
+
mdlKMeans = KMeans(n_clusters=m_klngNumClusters, max_iter=50, random_state=2022) #--- #clusters was learned from training
|
144 |
+
|
145 |
+
if (m_blnTraceOn): print("TRACE (" + m_kstrFile + ".fit) fitting data (scaled) ...")
|
146 |
+
mdlKMeans.fit(pdfScaled) #--- fit on test/prod data
|
147 |
+
|
148 |
+
return mdlKMeans #--- this ibject will give us all results based on kmeans
|
149 |
+
|
150 |
+
|
151 |
+
def train(pdfTrainData):
|
152 |
+
mdlAnoms = KMeans(n_clusters=3, max_iter=50, random_state=2022)
|
153 |
+
mdlAnoms.fit(pdfTrainData.values)
|
154 |
+
save_kmeansToPkl(mdlAnoms)
|
155 |
+
return mdlAnoms
|
lib/models/mdl_logR.py
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sklearn.linear_model import LogisticRegressionCV
|
2 |
+
import lib.utils as libPaths
|
3 |
+
import pickle
|
4 |
+
|
5 |
+
|
6 |
+
m_kstrFile = __file__
|
7 |
+
m_kstrDataPath = libPaths.pth_data
|
8 |
+
m_kstrBinModelPath = libPaths.pth_binModels
|
9 |
+
m_kstrModelPath = m_kstrBinModelPath + 'lgr_model_colab.pkl'
|
10 |
+
|
11 |
+
|
12 |
+
#--- Supervised: Logistic Regession
|
13 |
+
def load_fromPkl():
|
14 |
+
with open(m_kstrModelPath, 'rb') as filPkl:
|
15 |
+
mdlAnoms = pickle.load(filPkl)
|
16 |
+
return mdlAnoms
|
17 |
+
|
18 |
+
|
19 |
+
|
20 |
+
def save_toPkl(mdlAnoms):
|
21 |
+
with open(m_kstrModelPath, 'wb') as filPkl:
|
22 |
+
pickle.dump(mdlAnoms, filPkl)
|
23 |
+
return mdlAnoms
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
def predict(npaData):
|
28 |
+
#--- input: numpy.ndarray of feature eng, and scaled data
|
29 |
+
mdlAnoms = load_fromPkl()
|
30 |
+
npaPredict = mdlAnoms.predict(npaData)
|
31 |
+
|
32 |
+
print("INFO (npaPredict.shape): ", npaPredict.shape)
|
33 |
+
return npaPredict
|
34 |
+
|
35 |
+
|
36 |
+
|
37 |
+
def train(pdfTrainData):
|
38 |
+
mdlAnoms = LogisticRegressionCV()
|
39 |
+
mdlAnoms.fit(pdfTrainData.values)
|
40 |
+
save_toPkl(mdlAnoms)
|
41 |
+
return mdlAnoms
|
lib/models/mdl_svm.py
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sklearn.svm import LinearSVC
|
2 |
+
import lib.utils as libPaths
|
3 |
+
import pickle
|
4 |
+
|
5 |
+
|
6 |
+
m_kstrFile = __file__
|
7 |
+
m_kstrDataPath = libPaths.pth_data
|
8 |
+
m_kstrBinModelPath = libPaths.pth_binModels
|
9 |
+
m_kstrModelPath = m_kstrBinModelPath + 'svm_model_colab.pkl'
|
10 |
+
|
11 |
+
|
12 |
+
#--- Supervised: Support Vector Machines
|
13 |
+
def load_fromPkl():
|
14 |
+
with open(m_kstrModelPath, 'rb') as filPkl:
|
15 |
+
mdlAnoms = pickle.load(filPkl)
|
16 |
+
return mdlAnoms
|
17 |
+
|
18 |
+
|
19 |
+
|
20 |
+
def save_toPkl(mdlAnoms):
|
21 |
+
with open(m_kstrModelPath, 'wb') as filPkl:
|
22 |
+
pickle.dump(mdlAnoms, filPkl)
|
23 |
+
return mdlAnoms
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
def predict(npaData):
|
28 |
+
#--- input: numpy.ndarray of feature eng, and scaled data
|
29 |
+
mdlAnoms = load_fromPkl()
|
30 |
+
npaPredict = mdlAnoms.predict(npaData)
|
31 |
+
print("INFO (" + m_kstrFile + ".predict) npaPredict.shape: ", npaPredict.shape)
|
32 |
+
return npaPredict
|
33 |
+
|
34 |
+
|
35 |
+
|
36 |
+
def train(pdfTrainData):
|
37 |
+
mdlAnoms = LinearSVC()
|
38 |
+
mdlAnoms.fit(pdfTrainData.values)
|
39 |
+
save_toPkl(mdlAnoms)
|
40 |
+
return mdlAnoms
|
lib/models/mdl_utils.py
ADDED
@@ -0,0 +1,256 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import pickle
|
3 |
+
import lib.utils as libPaths
|
4 |
+
|
5 |
+
m_blnTraceOn = False
|
6 |
+
|
7 |
+
#--- load, merge data from file
|
8 |
+
m_kstrDataPath = libPaths.pth_data
|
9 |
+
m_kstrModelPath = libPaths.pth_model
|
10 |
+
m_kstrBinModelPath = libPaths.pth_binModels
|
11 |
+
|
12 |
+
#m_kstrScalerPath_claims = m_kstrBinModelPath + 'stdClaims_scaler_colab.pkl' #--- does not work for scaling claims data; from v1.0.2; using 1.1.1
|
13 |
+
#m_kstrScalerPath_claims2 = m_kstrBinModelPath + 'std_scaler_unsuperv_colab.pkl' #--- does not work; expects 32 features
|
14 |
+
#m_kstrScalerPath_claims = m_kstrBinModelPath + 'stdClaims_scaler_colab_v1.2.1.pkl'
|
15 |
+
m_kstrScalerPath_claims111 = m_kstrBinModelPath + 'claims_stdScaler_v1.1.1_27cols.pkl'
|
16 |
+
m_kstrScalerPath_claims121 = m_kstrBinModelPath + 'claims_stdScaler_v1.2.1_27cols.pkl'
|
17 |
+
m_kstrScalerPath_claims_py3816_sk111hp = m_kstrBinModelPath + 'claims_stdScl_py3816_sk111hp_27cols.pkl'
|
18 |
+
m_kstrScalerPath_claims = m_kstrScalerPath_claims_py3816_sk111hp
|
19 |
+
|
20 |
+
m_kstrScalerPath_providers111 = m_kstrBinModelPath + 'prov_stdScaler_v1.1.1_32cols.pkl'
|
21 |
+
m_kstrScalerPath_providers121 = m_kstrBinModelPath + 'prov_stdScaler_v1.2.1_32cols.pkl'
|
22 |
+
m_kstrScalerPath_prov_py3816_sk111 = m_kstrBinModelPath + 'prov_stdScl_py3816_sk111_32cols.pkl'
|
23 |
+
m_kstrScalerPath_prov_py3816_sk111hp = m_kstrBinModelPath + 'prov_stdScl_py3816_sk111hp_32cols.pkl'
|
24 |
+
m_kstrScalerPath_prov = m_kstrScalerPath_prov_py3816_sk111hp
|
25 |
+
|
26 |
+
m_kstrScalerPath_providers_superv = m_kstrBinModelPath + 'gbc_scaler.pkl'
|
27 |
+
m_kstrScalerPath_providers_train = m_kstrBinModelPath + "stdProvider_scaler.pkl"
|
28 |
+
|
29 |
+
|
30 |
+
|
31 |
+
def doProviders_stdScaler(pdfFeatEng, blnIsTrain=False, hasGroupByProviderCols=True):
|
32 |
+
print("INFO (claims.do_stdScaler): blnIsTrain, ", blnIsTrain)
|
33 |
+
|
34 |
+
#--- Note: prediction runs on X_val
|
35 |
+
'''
|
36 |
+
#--- WARN: The default value of numeric_only in DataFrameGroupBy.sum is deprecated.
|
37 |
+
# In a future version, numeric_only will default to False. Either specify
|
38 |
+
# numeric_only or select only columns which should be valid for the function.
|
39 |
+
'''
|
40 |
+
|
41 |
+
#--- WARN: this code groups all data by provider; any predictions will also be by provider
|
42 |
+
pdfGroupBy = pdfFeatEng
|
43 |
+
if (hasGroupByProviderCols):
|
44 |
+
pdfGroupBy = pdfFeatEng.groupby(['Provider'], as_index=False).agg('sum')
|
45 |
+
|
46 |
+
X = pdfGroupBy
|
47 |
+
|
48 |
+
try:
|
49 |
+
X = X.drop(columns=['Provider'], axis=1) #--- cannot scale; text
|
50 |
+
except KeyError:
|
51 |
+
#--- likely column not found; invalid fxn call
|
52 |
+
print("ERROR (mdlUtils.doProviders_stdScaler): Provider col not found")
|
53 |
+
|
54 |
+
try:
|
55 |
+
X = X.drop(columns=['PotentialFraud'], axis=1)
|
56 |
+
except KeyError:
|
57 |
+
#--- likely column not found; invalid fxn call
|
58 |
+
if (blnIsTrain): print("ERROR (mdlUtils.doProviders_stdScaler): Potential Fraud col not found")
|
59 |
+
|
60 |
+
|
61 |
+
#--- apply std scaler
|
62 |
+
#--- WARN: scaling is also grouped by provider
|
63 |
+
if (m_blnTraceOn): print("INFO (mdlUtils.doProviders_stdScaler) cols: ", X.columns) #--- 32cols
|
64 |
+
X_std = fitProviders_txfStdScaler(X, blnIsTrain)
|
65 |
+
return X_std
|
66 |
+
|
67 |
+
|
68 |
+
|
69 |
+
def doClaims_stdScaler(pdfFeatEng, blnIsTrain=False):
|
70 |
+
print("INFO (mdlUtils.doClaims_stdScaler): blnIsTrain, ", blnIsTrain)
|
71 |
+
|
72 |
+
#--- Note: prediction runs on X_val
|
73 |
+
'''
|
74 |
+
#--- WARN: The default value of numeric_only in DataFrameGroupBy.sum is deprecated.
|
75 |
+
# In a future version, numeric_only will default to False. Either specify
|
76 |
+
# numeric_only or select only columns which should be valid for the function.
|
77 |
+
'''
|
78 |
+
|
79 |
+
#--- WARN: this code groups all data by provider; any predictions will also be by provider
|
80 |
+
X = pdfFeatEng
|
81 |
+
|
82 |
+
try:
|
83 |
+
X = X.drop(columns=['Provider'], axis=1) #--- cannot scale; text
|
84 |
+
except KeyError:
|
85 |
+
#--- likely column not found; invalid fxn call
|
86 |
+
print("ERROR (mdlUtils.do_stdScaler): Provider col not found")
|
87 |
+
|
88 |
+
try:
|
89 |
+
X = X.drop(columns=['PotentialFraud'], axis=1)
|
90 |
+
except KeyError:
|
91 |
+
#--- likely column not found; invalid fxn call
|
92 |
+
if (blnIsTrain): print("ERROR (mdlUtils.do_stdScaler): Potential Fraud col not found")
|
93 |
+
|
94 |
+
|
95 |
+
#--- apply std scaler
|
96 |
+
#--- WARN: scaling is also grouped by provider
|
97 |
+
#print("INFO (mdlUtils.doClaims_stdScaler) cols: ", X.columns)
|
98 |
+
X_std = fitClaims_txfStdScaler(X, blnIsTrain)
|
99 |
+
return X_std
|
100 |
+
|
101 |
+
|
102 |
+
|
103 |
+
def doProviders_stdScaler_toPdf(npaScaled):
|
104 |
+
#--- NOTE: the list of cols came from doProvider_stdScaler; print(X.columns)
|
105 |
+
aryCols = ['InscClaimAmtReimbursed', 'DeductibleAmtPaid', 'AdmittedDays',
|
106 |
+
'NoOfMonths_PartACov', 'NoOfMonths_PartBCov', 'ChronicCond_Alzheimer',
|
107 |
+
'ChronicCond_Heartfailure', 'ChronicCond_KidneyDisease',
|
108 |
+
'ChronicCond_Cancer', 'ChronicCond_ObstrPulmonary',
|
109 |
+
'ChronicCond_Depression', 'ChronicCond_Diabetes',
|
110 |
+
'ChronicCond_IschemicHeart', 'ChronicCond_Osteoporasis',
|
111 |
+
'ChronicCond_rheumatoidarthritis', 'ChronicCond_stroke',
|
112 |
+
'IPAnnualReimbursementAmt', 'IPAnnualDeductibleAmt',
|
113 |
+
'OPAnnualReimbursementAmt', 'OPAnnualDeductibleAmt', 'Age', 'DeadOrNot',
|
114 |
+
'Gender_2', 'Race_2', 'Race_3', 'Race_5',
|
115 |
+
'ClaimReimbursement_ProviderAvg',
|
116 |
+
'ClaimReimbursement_AttendingPhysician',
|
117 |
+
'ClaimReimbursement_OperatingPhysician',
|
118 |
+
'DeductibleAmtPaid_ProviderAvg', 'DeductibleAmtPaid_AttendingPhysician',
|
119 |
+
'DeductibleAmtPaid_OperatingPhysician']
|
120 |
+
|
121 |
+
#npaScaled = do_stdScaler(pdfFeatEng)
|
122 |
+
pdfScaled = pd.DataFrame(npaScaled, columns=aryCols)
|
123 |
+
return pdfScaled
|
124 |
+
|
125 |
+
|
126 |
+
|
127 |
+
def doClaims_stdScaler_toPdf(npaScaled):
|
128 |
+
#--- NOTE: the list of cols came from doClaims_stdScaler; print(X.columns)
|
129 |
+
aryCols = ['InscClaimAmtReimbursed', 'DeductibleAmtPaid', 'AdmittedDays',
|
130 |
+
'RenalDiseaseIndicator', 'NoOfMonths_PartACov', 'NoOfMonths_PartBCov', 'ChronicCond_Alzheimer',
|
131 |
+
'ChronicCond_Heartfailure', 'ChronicCond_KidneyDisease',
|
132 |
+
'ChronicCond_Cancer', 'ChronicCond_ObstrPulmonary',
|
133 |
+
'ChronicCond_Depression', 'ChronicCond_Diabetes',
|
134 |
+
'ChronicCond_IschemicHeart', 'ChronicCond_Osteoporasis',
|
135 |
+
'ChronicCond_rheumatoidarthritis', 'ChronicCond_stroke',
|
136 |
+
'IPAnnualReimbursementAmt', 'IPAnnualDeductibleAmt',
|
137 |
+
'OPAnnualReimbursementAmt', 'OPAnnualDeductibleAmt', 'Age', 'DeadOrNot',
|
138 |
+
'Gender_2', 'Race_2', 'Race_3', 'Race_5']
|
139 |
+
|
140 |
+
#npaScaled = do_stdScaler(pdfFeatEng)
|
141 |
+
pdfScaled = pd.DataFrame(npaScaled, columns=aryCols)
|
142 |
+
return pdfScaled
|
143 |
+
|
144 |
+
|
145 |
+
|
146 |
+
|
147 |
+
def fitClaims_stdScaler(pdfData, blnIsTrain=False):
|
148 |
+
#--- apply scaler
|
149 |
+
#--- WARN: scaling is not grouped by provider
|
150 |
+
from sklearn.preprocessing import StandardScaler
|
151 |
+
|
152 |
+
#--- note: this is a numpy.ndarray
|
153 |
+
#--- we need to fit the scaler, and then save as a pkl file
|
154 |
+
#strScalerPath = m_kstrScalerPath_claims
|
155 |
+
strScalerPath = m_kstrScalerPath_claims
|
156 |
+
# strScalerPath = m_kstrBinModelPath + "stdClaims_scaler_colab.pkl"
|
157 |
+
if (m_blnTraceOn): print("INFO (lib.model.fitClaims_stdScalar): ", strScalerPath)
|
158 |
+
if (blnIsTrain):
|
159 |
+
scaler = StandardScaler()
|
160 |
+
sclFit = scaler.fit(pdfData)
|
161 |
+
#--- if we train locally; write out to gbc_scalar.pkl
|
162 |
+
#--- we do not want to overwrite the colab version used for test
|
163 |
+
strScalerPath = m_kstrBinModelPath + "stdClaims_scaler.pkl"
|
164 |
+
if (m_blnTraceOn): print("INFO (lib.model.fit_stdScalar) Using local pkl for Train: ", strScalerPath)
|
165 |
+
with open(strScalerPath, 'wb') as filPkl:
|
166 |
+
pickle.dump(sclFit, filPkl)
|
167 |
+
else:
|
168 |
+
#--- we need to load the pkl file
|
169 |
+
import sklearn
|
170 |
+
if (m_blnTraceOn): print("INFO (lib.model.fit_stdScalar) Using colab pkl for Test: ", strScalerPath)
|
171 |
+
with open(strScalerPath, 'rb') as filPkl:
|
172 |
+
sclFit = pickle.load(filPkl)
|
173 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitClaims_stdScalar) sclFit.type: ", type(sclFit))
|
174 |
+
|
175 |
+
#--- testing
|
176 |
+
scaler = StandardScaler()
|
177 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitClaims_stdScalar) StdScaler.version: ", scaler.__getstate__()['_sklearn_version'])
|
178 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitClaims_stdScalar) sclFit.version: " , sclFit.__getstate__()['_sklearn_version'])
|
179 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitClaims_stdScalar) sklearn.version: " , sklearn.__version__)
|
180 |
+
return sclFit
|
181 |
+
|
182 |
+
|
183 |
+
|
184 |
+
def fitProviders_stdScaler(pdfData, blnIsTrain=False):
|
185 |
+
#--- apply scaler
|
186 |
+
#--- WARN: scaling is also grouped by provider
|
187 |
+
from sklearn.preprocessing import StandardScaler
|
188 |
+
|
189 |
+
#--- note: this is a numpy.ndarray
|
190 |
+
#--- we need to fit the scaler, and then save as a pkl file
|
191 |
+
#strScalerPath = m_kstrScalerPath_providers
|
192 |
+
#strScalerPath = m_kstrScalerPath_providers_train
|
193 |
+
strScalerPath = m_kstrScalerPath_prov
|
194 |
+
print("INFO (libModel.fitProviders_stdScalar): ", strScalerPath)
|
195 |
+
if (blnIsTrain):
|
196 |
+
scaler = StandardScaler()
|
197 |
+
sclFit = scaler.fit(pdfData)
|
198 |
+
#--- if we train locally; write out to gbc_scalar.pkl
|
199 |
+
#--- we do not want to overwrite the colab version used for test
|
200 |
+
strScalerPath = m_kstrScalerPath_providers_train #--- works for provider training
|
201 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitProviders_stdScalar) Using local pkl for Train: ", strScalerPath)
|
202 |
+
with open(strScalerPath, 'wb') as filPkl:
|
203 |
+
pickle.dump(sclFit, filPkl)
|
204 |
+
else:
|
205 |
+
#--- we need to load the pkl file
|
206 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitProviders_stdScalar) Using colab pkl for Test: ", strScalerPath)
|
207 |
+
with open(strScalerPath, 'rb') as filPkl:
|
208 |
+
sclFit = pickle.load(filPkl)
|
209 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitProviders_stdScalar) sclFit.type: ", type(sclFit))
|
210 |
+
return sclFit
|
211 |
+
|
212 |
+
|
213 |
+
|
214 |
+
def fitProviders_stdScalerSuperv(pdfData, blnIsTrain=False):
|
215 |
+
#--- apply scaler
|
216 |
+
#--- WARN: scaling is also grouped by provider
|
217 |
+
from sklearn.preprocessing import StandardScaler
|
218 |
+
|
219 |
+
#--- note: this is a numpy.ndarray
|
220 |
+
#--- we need to fit the scaler, and then save as a pkl file
|
221 |
+
strScalerPath = m_kstrScalerPath_prov
|
222 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitProviders_stdScalar): ", strScalerPath)
|
223 |
+
if (blnIsTrain):
|
224 |
+
scaler = StandardScaler()
|
225 |
+
sclFit = scaler.fit(pdfData)
|
226 |
+
#--- if we train locally; write out to gbc_scalar.pkl
|
227 |
+
#--- we do not want to overwrite the colab version used for test
|
228 |
+
strScalerPath = m_kstrBinModelPath + "stdProvider_scaler.pkl"
|
229 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitProviders_stdScalar) Using local pkl for Train: ", strScalerPath)
|
230 |
+
with open(strScalerPath, 'wb') as filPkl:
|
231 |
+
pickle.dump(sclFit, filPkl)
|
232 |
+
else:
|
233 |
+
#--- we need to load the pkl file
|
234 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitProviders_stdScalar) Using colab pkl for Test: ", strScalerPath)
|
235 |
+
with open(strScalerPath, 'rb') as filPkl:
|
236 |
+
sclFit = pickle.load(filPkl)
|
237 |
+
if (m_blnTraceOn): print("TRACE (libModel.fitProviders_stdScalar) sclFit.type: ", type(sclFit))
|
238 |
+
return sclFit
|
239 |
+
|
240 |
+
|
241 |
+
|
242 |
+
def fitProviders_txfStdScaler(pdfData, blnIsTrain=False):
|
243 |
+
from sklearn.preprocessing import StandardScaler
|
244 |
+
sclFit = fitProviders_stdScaler(pdfData, blnIsTrain)
|
245 |
+
X_std = sclFit.transform(pdfData)
|
246 |
+
return X_std
|
247 |
+
|
248 |
+
|
249 |
+
|
250 |
+
def fitClaims_txfStdScaler(pdfData, blnIsTrain=False):
|
251 |
+
from sklearn.preprocessing import StandardScaler
|
252 |
+
sclFit = fitClaims_stdScaler(pdfData, blnIsTrain)
|
253 |
+
|
254 |
+
|
255 |
+
X_std = sclFit.transform(pdfData)
|
256 |
+
return X_std
|
lib/models/mdl_xgb.py
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
from sklearn.ensemble import GradientBoostingClassifier
|
3 |
+
import lib.utils as libPaths
|
4 |
+
import pickle
|
5 |
+
import sys
|
6 |
+
|
7 |
+
|
8 |
+
m_kstrFile = __file__
|
9 |
+
m_kstrDataPath = libPaths.pth_data
|
10 |
+
m_kstrBinModelPath = libPaths.pth_binModels
|
11 |
+
m_kstrModelPath_gbc = m_kstrBinModelPath + 'gbc_model_colab.pkl'
|
12 |
+
m_kstrModelPath_prov111 = m_kstrBinModelPath + 'prov_gbc_v1.1.1_32cols.pkl' #--- ERROR: __randomstate_ctor() takes from 0 to 1 positional arguments but 2 were given
|
13 |
+
m_kstrModelPath_prov121 = m_kstrBinModelPath + 'prov_gbc_v1.2.1_32cols.pkl'
|
14 |
+
m_kstrModelPath_prov_py3816_sk111hp = m_kstrBinModelPath + 'prov_gbc_py3816_sk111hp_32cols.pkl'
|
15 |
+
m_kstrModelPath = m_kstrModelPath_prov_py3816_sk111hp
|
16 |
+
|
17 |
+
m_blnTraceOn = True
|
18 |
+
|
19 |
+
|
20 |
+
|
21 |
+
#--- Supervised: xg boost; gradient boosting classifier
|
22 |
+
def load_fromPkl():
|
23 |
+
try:
|
24 |
+
with open(m_kstrModelPath, 'rb') as filPkl:
|
25 |
+
mdlAnoms = pickle.load(filPkl)
|
26 |
+
return mdlAnoms
|
27 |
+
|
28 |
+
except:
|
29 |
+
e = sys.exc_info()
|
30 |
+
print("ERROR (mdl_xgb.load_fromPkl_genError): ", e)
|
31 |
+
|
32 |
+
|
33 |
+
|
34 |
+
def save_toPkl(mdlAnoms):
|
35 |
+
with open(m_kstrModelPath, 'wb') as filPkl:
|
36 |
+
pickle.dump(mdlAnoms, filPkl)
|
37 |
+
return mdlAnoms
|
38 |
+
|
39 |
+
|
40 |
+
|
41 |
+
def predict(npaData):
|
42 |
+
|
43 |
+
try:
|
44 |
+
#--- input: numpy.ndarray of feature eng, and scaled data
|
45 |
+
mdlAnoms = load_fromPkl()
|
46 |
+
if (m_blnTraceOn): print("TRACE (mdl_xgb.predict): data loaded ... ")
|
47 |
+
npaPredict = mdlAnoms.predict(npaData)
|
48 |
+
|
49 |
+
except:
|
50 |
+
e = sys.exc_info()
|
51 |
+
print("ERROR (mdl_xgb.predict_genError1): ", e)
|
52 |
+
|
53 |
+
|
54 |
+
#--- AttributeError: 'GradientBoostingClassifier' object has no attribute '_loss'
|
55 |
+
#--- version of scikit-learn? Monika: ?.?.? ; Iain: 1.2.0
|
56 |
+
|
57 |
+
#print("INFO (type.npaPredict): ", type(npaPredict))
|
58 |
+
#if (m_blnTraceOn): print("TRACE (mdl_xgb.predict) npaPredict.shape: ", npaPredict.shape)
|
59 |
+
return npaPredict
|
60 |
+
|
61 |
+
|
62 |
+
def train(pdfTrainData):
|
63 |
+
mdlAnoms = GradientBoostingClassifier()
|
64 |
+
mdlAnoms.fit(pdfTrainData.values)
|
65 |
+
save_toPkl(mdlAnoms)
|
66 |
+
return mdlAnoms
|
lib/utils.py
CHANGED
@@ -25,6 +25,7 @@ pth_dtaApp = pth_data #--- working folders for
|
|
25 |
pth_dtaDemoTiles = pth_data + "demo_tiles/" #--- dedicated area for demo data
|
26 |
pth_dtaTiles = pth_data + "tiles/"
|
27 |
pth_dtaWsi = pth_data + "wsi/"
|
|
|
28 |
|
29 |
#--- lib paths
|
30 |
pth_libModels = pth_lib + "models/"
|
|
|
25 |
pth_dtaDemoTiles = pth_data + "demo_tiles/" #--- dedicated area for demo data
|
26 |
pth_dtaTiles = pth_data + "tiles/"
|
27 |
pth_dtaWsi = pth_data + "wsi/"
|
28 |
+
pth_dtaTileSamples = pth_dtaDemoTiles + "raw/sample/"
|
29 |
|
30 |
#--- lib paths
|
31 |
pth_libModels = pth_lib + "models/"
|
util_dockerPreRun.sh β scripts/docker/util_docker_preRun.sh
RENAMED
@@ -1,10 +1,10 @@
|
|
1 |
#!/bin/bash
|
2 |
|
3 |
#--- Note: this file is designed to run locally as well as within docker to prep the environment
|
|
|
|
|
|
|
4 |
#--- for volume initialization; ensure folders are in place; assume: we are in the /app folder
|
5 |
-
mkdir -p data/demo_tiles/raw
|
6 |
-
mkdir -p data/tiles/raw data/tiles/pred data/tiles/grad_bg data/tiles/grad_wt data/tiles/grad_vt
|
7 |
-
mkdir -p data/wsi/raw
|
8 |
|
9 |
|
10 |
<<blockComment
|
@@ -12,9 +12,21 @@ mkdir -p data/wsi/raw
|
|
12 |
- this is done to ensure that the model can be stored within gitHub
|
13 |
- the split model is recreated on docker container startup using the cat command
|
14 |
blockComment
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
#--- recreate single model file from its parts, stored within a specific model version folder
|
17 |
-
|
|
|
|
|
|
|
18 |
|
19 |
#--- run streamlit/fastapi
|
20 |
-
|
|
|
1 |
#!/bin/bash
|
2 |
|
3 |
#--- Note: this file is designed to run locally as well as within docker to prep the environment
|
4 |
+
#--- Entry: this script is assumed to run from the /app root folder
|
5 |
+
#--- Usage: ./scripts/docker/util_docker_preRun.sh
|
6 |
+
|
7 |
#--- for volume initialization; ensure folders are in place; assume: we are in the /app folder
|
|
|
|
|
|
|
8 |
|
9 |
|
10 |
<<blockComment
|
|
|
12 |
- this is done to ensure that the model can be stored within gitHub
|
13 |
- the split model is recreated on docker container startup using the cat command
|
14 |
blockComment
|
15 |
+
echo -e "INFO(util_docker_preRun):\t Initializing ..."
|
16 |
+
|
17 |
+
strpth_pwd=$(pwd)
|
18 |
+
strpth_scriptLoc=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
19 |
+
strpth_scrHome="${strpth_scriptLoc}/../"
|
20 |
+
strpth_appHome="${strpth_scrHome}../"
|
21 |
+
strpth_scrModels="${strpth_scrHome}models/"
|
22 |
+
|
23 |
+
echo "strpth_appHome = ${strpth_appHome}"
|
24 |
|
25 |
#--- recreate single model file from its parts, stored within a specific model version folder
|
26 |
+
strpth_binModels="${strpth_appHome}bin/models/"
|
27 |
+
echo "strpth_binModels = ${strpth_binModels}"
|
28 |
+
#$("'${strpth_scrModels}util_joinModel.sh' '${strpth_binModels}deeplabv3*vhflip30/model_a*' '${strpth_binModels}model.pth'")
|
29 |
+
eval "'${strpth_scrModels}/util_joinModel.sh' '${strpth_binModels}/deeplabv3*vhflip30/model_a*' '${strpth_binModels}/model.pth'"
|
30 |
|
31 |
#--- run streamlit/fastapi
|
32 |
+
eval "'${strpth_scrHome}/streamlitFastApi/util_local_runStreamlitFastApi.sh'"
|
scripts/docker/util_local_buildDockerDemo.sh
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
#--- Note: this file is designed to run locally to build the docker image
|
4 |
+
#--- Entry: this script is assumed to run from the /app root folder
|
5 |
+
#--- Usage: ./scripts/docker/util_local_buildDockerDemo.sh
|
6 |
+
#--- Assume: any associated containers are not running
|
7 |
+
|
8 |
+
<<blockComment
|
9 |
+
util_local_buildDockerDemo -> img_stm_omdenasaudi_hcc:demo -> ctr_stm_omdenasaudi_hcc:demo
|
10 |
+
blockComment
|
11 |
+
|
12 |
+
|
13 |
+
#--- initialize/configuration
|
14 |
+
echo "TRACE: Initializing ..."
|
15 |
+
kstr_defDkrHubId="kidcoconut73"
|
16 |
+
kstr_defDkrImageName="img_stm_omdenasaudi_hcc"
|
17 |
+
kstr_defDkrTagVersion="0.1.2"
|
18 |
+
kstr_defDkrTagStage="demo"
|
19 |
+
|
20 |
+
strpth_pwd=$(pwd)
|
21 |
+
strpth_scriptLoc=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
22 |
+
strpth_scrHome="${strpth_scriptLoc}/../"
|
23 |
+
strpth_appHome="${strpth_scrHome}/../"
|
24 |
+
|
25 |
+
#--- declarations
|
26 |
+
echo "TRACE: Declarations ..."
|
27 |
+
|
28 |
+
#strUtl_scriptLoc="$(utl_getScriptLoc)"
|
29 |
+
source ${strpth_scrHome}/util.sh
|
30 |
+
|
31 |
+
#kstr_dkrImg="kidcoconut73/img_stm_omdenasaudi_hcc:demo"
|
32 |
+
#kstr_dkrCtr="kidcoconut73/ctr_stm_omdenasaudi_hcc:demo"
|
33 |
+
kstr_dkrHubImg="${kstr_defDkrHubId}/${kstr_defDkrImageName}:${kstr_defDkrTagStage}"
|
34 |
+
kstr_dkrImg="${kstr_defDkrImageName}:${kstr_defDkrTagVersion}"
|
35 |
+
kstr_dkrCtr="${kstr_dkrImg/img_/ctr_}" #--- bash replace one occurrence
|
36 |
+
|
37 |
+
|
38 |
+
|
39 |
+
function utl_trace_config {
|
40 |
+
#echo ""
|
41 |
+
local kbln_enableLog=true
|
42 |
+
utl_logInfo $kbln_enableLog 0 "(utl_trace_config) ... echo configuration"
|
43 |
+
|
44 |
+
utl_trace_var "strpth_pwd" $strpth_pwd
|
45 |
+
utl_trace_var "strpth_scriptLoc" $strpth_scriptLoc
|
46 |
+
echo ""
|
47 |
+
utl_trace_var "kstr_defDkrHubId" $kstr_defDkrHubId
|
48 |
+
utl_trace_var "kstr_defDkrImageName" $kstr_defDkrImageName
|
49 |
+
utl_trace_var "kstr_defDkrTagVersion" $kstr_defDkrTagVersion
|
50 |
+
utl_trace_var "kstr_defDkrTagStage" $kstr_defDkrTagStage
|
51 |
+
echo ""
|
52 |
+
utl_trace_var "kstr_dkrHubImg" $kstr_dkrHubImg
|
53 |
+
utl_trace_var "kstr_dkrImg" $kstr_dkrImg
|
54 |
+
utl_trace_var "kstr_dkrCtr" $kstr_dkrCtr
|
55 |
+
echo ""
|
56 |
+
}
|
57 |
+
|
58 |
+
#echo -e "\nTRACE: Echo config ..."
|
59 |
+
utl_trace_config
|
60 |
+
|
61 |
+
|
62 |
+
#--- to build/rebuild the image; make sure you stop and remove the container if you are replacing/upgrading; or change the version tag# from 0.1
|
63 |
+
#--- stop the container if it is running
|
64 |
+
#--- delete container if it exists
|
65 |
+
echo -e "\nTRACE: Stop and remove container if it exists ..."
|
66 |
+
docker stop $kstr_dkrCtr
|
67 |
+
docker rm $kstr_dkrCtr
|
68 |
+
|
69 |
+
#--- build the docker image
|
70 |
+
echo -e "\nTRACE: Build the docker image ..."
|
71 |
+
docker build -t $kstr_dkrImg .
|
72 |
+
|
73 |
+
|
74 |
+
#--- to tag the image prior to push to DockerHub; docker login and then register user/image:tag
|
75 |
+
#--- to push this image to DockerHub, example based on the repo: kidcoconut73/img_stm_omdenasaudi_hcc
|
76 |
+
# docker tag img_omdenasaudi_hcc:0.1 kidcoconut73/img_stm_omdenasaudi_hcc:demo
|
77 |
+
# docker tag img_omdenasaudi_hcc:0.1 kidcoconut73/img_stm_omdenasaudi_hcc:0.1
|
78 |
+
#--- tag the image
|
79 |
+
echo -e "\nTRACE: Tag the image ..."
|
80 |
+
docker tag ${kstr_dkrImg} $kstr_dkrHubImg
|
81 |
+
docker tag ${kstr_dkrImg} "${kstr_defDkrHubId}/${kstr_defDkrImageName}:${kstr_defDkrTagVersion}"
|
82 |
+
|
83 |
+
|
84 |
+
#--- push the image to dockerHub
|
85 |
+
docker push kidcoconut73/img_stm_omdenasaudi_hcc:demo
|
scripts/docker/util_local_runDockerDemo.sh
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
#--- Note: this file is designed to run locally to launch docker
|
4 |
+
#--- Entry: this script is assumed to run from the /app root folder
|
5 |
+
#--- Usage: ./scripts/util_local_runDockerDemo.sh
|
6 |
+
#--- Assume: docker image has been built; container is not running
|
7 |
+
|
8 |
+
<<blockComment
|
9 |
+
util_local_runDockerDemo -> Dockerfile -> util_dockerPreRun -> util_local_runStreamlitFastApi
|
10 |
+
blockComment
|
11 |
+
|
12 |
+
|
13 |
+
#--- initialize/config
|
14 |
+
kstr_defDkrHubId="kidcoconut73"
|
15 |
+
kstr_defDkrImageName="img_stm_omdenasaudi_hcc"
|
16 |
+
kstr_defDkrCtrName=${kstr_defDkrImageName/img_/ctr_}
|
17 |
+
kstr_defDkrTagVersion="0.1.2"
|
18 |
+
kstr_defDkrTagStage="demo"
|
19 |
+
|
20 |
+
kstr_dkrImg="${kstr_defDkrImageName}:${kstr_defDkrTagVersion}"
|
21 |
+
kstr_dkrCtr="${kstr_defDkrImageName/img_/ctr_}" #--- bash replace one occurrence
|
22 |
+
|
23 |
+
#--- stop the container if it is running
|
24 |
+
docker stop $kstr_dkrCtr
|
25 |
+
|
26 |
+
#--- delete container if it exists
|
27 |
+
docker rm $kstr_dkrCtr
|
28 |
+
|
29 |
+
#--- to run the container from the image; specific port mapping (-p) vs any available port mapping (-P)
|
30 |
+
# docker run -p 49400:39400 -p 49500:39500 --name ctr_stmOmdenaSaudiHcc -v ./data:/app/data img_stm_omdenasaudi_hcc:0.1
|
31 |
+
|
32 |
+
#--- run docker demo locally
|
33 |
+
docker run -p 49400:39400 -p 49500:39500 --name $kstr_dkrCtr -v ./data:/app/data $kstr_dkrImg
|
scripts/huggingface/util_local_readyDeploy_toHugSpace_streamlit.sh
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
#--- Note: this file is designed to run locally to ready the deploy branch for hugspace
|
4 |
+
#--- Entry: this script is assumed to run from the /app root folder
|
5 |
+
#--- Usage: ./scripts/util_local_readyDeploy_toHugSpace_streamlit.sh
|
6 |
+
|
7 |
+
<<blockComment
|
8 |
+
bash: util_local_readyDeploy_toHugSpace_streamlit -> git
|
9 |
+
git: local/task-5-deployment -> omdena/deploy_hugspace_streamlit -> hugspace/main
|
10 |
+
blockComment
|
11 |
+
|
12 |
+
|
13 |
+
#--- initialize/configuration
|
14 |
+
echo "TRACE: Initializing ..."
|
15 |
+
kstr_hugspaceId="kidcoconut"
|
16 |
+
|
17 |
+
|
18 |
+
#--- git checkout deploy_hugspace_streamlit
|
19 |
+
#--- git merge task-5-deployment
|
20 |
+
#--- delete all unnecessary files
|
21 |
+
<<deadCode
|
22 |
+
kstr_defDkrHubId="kidcoconut73"
|
23 |
+
kstr_defDkrImageName="img_stm_omdenasaudi_hcc"
|
24 |
+
kstr_defDkrTagVersion="0.1.2"
|
25 |
+
kstr_defDkrTagStage="demo"
|
26 |
+
strpth_pwd=$(pwd)
|
27 |
+
strpth_scriptLoc=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
28 |
+
|
29 |
+
|
30 |
+
#--- declarations
|
31 |
+
echo "TRACE: Declarations ..."
|
32 |
+
|
33 |
+
#strUtl_scriptLoc="$(utl_getScriptLoc)"
|
34 |
+
source ${strpth_scriptLoc}/util.sh
|
35 |
+
|
36 |
+
#kstr_dkrImg="kidcoconut73/img_stm_omdenasaudi_hcc:demo"
|
37 |
+
#kstr_dkrCtr="kidcoconut73/ctr_stm_omdenasaudi_hcc:demo"
|
38 |
+
kstr_dkrHubImg="${kstr_defDkrHubId}/${kstr_defDkrImageName}:${kstr_defDkrTagStage}"
|
39 |
+
kstr_dkrImg="${kstr_defDkrImageName}:${kstr_defDkrTagVersion}"
|
40 |
+
kstr_dkrCtr="${kstr_dkrImg/img_/ctr_}" #--- bash replace one occurrence
|
41 |
+
|
42 |
+
|
43 |
+
|
44 |
+
function utl_trace_config () {
|
45 |
+
echo ""
|
46 |
+
utl_trace_var "strpth_pwd" $strpth_pwd
|
47 |
+
utl_trace_var "strpth_scriptLoc" $strpth_scriptLoc
|
48 |
+
echo ""
|
49 |
+
utl_trace_var "kstr_defDkrHubId" $kstr_defDkrHubId
|
50 |
+
utl_trace_var "kstr_defDkrImageName" $kstr_defDkrImageName
|
51 |
+
utl_trace_var "kstr_defDkrTagVersion" $kstr_defDkrTagVersion
|
52 |
+
utl_trace_var "kstr_defDkrTagStage" $kstr_defDkrTagStage
|
53 |
+
echo ""
|
54 |
+
utl_trace_var "kstr_dkrHubImg" $kstr_dkrHubImg
|
55 |
+
utl_trace_var "kstr_dkrImg" $kstr_dkrImg
|
56 |
+
utl_trace_var "kstr_dkrCtr" $kstr_dkrCtr
|
57 |
+
echo ""
|
58 |
+
}
|
59 |
+
|
60 |
+
echo -e "\nTRACE: Echo config ...\n"
|
61 |
+
utl_trace_config
|
62 |
+
|
63 |
+
|
64 |
+
#--- to build/rebuild the image; make sure you stop and remove the container if you are replacing/upgrading; or change the version tag# from 0.1
|
65 |
+
#--- stop the container if it is running
|
66 |
+
#--- delete container if it exists
|
67 |
+
echo -e "\nTRACE: Stop and remove container if it exists ..."
|
68 |
+
docker stop $kstr_dkrCtr
|
69 |
+
docker rm $kstr_dkrCtr
|
70 |
+
|
71 |
+
#--- build the docker image
|
72 |
+
echo -e "\nTRACE: Build the docker image ..."
|
73 |
+
docker build -t $kstr_dkrImg .
|
74 |
+
|
75 |
+
|
76 |
+
#--- to tag the image prior to push to DockerHub; docker login and then register user/image:tag
|
77 |
+
#--- to push this image to DockerHub, example based on the repo: kidcoconut73/img_stm_omdenasaudi_hcc
|
78 |
+
# docker tag img_omdenasaudi_hcc:0.1 kidcoconut73/img_stm_omdenasaudi_hcc:demo
|
79 |
+
# docker tag img_omdenasaudi_hcc:0.1 kidcoconut73/img_stm_omdenasaudi_hcc:0.1
|
80 |
+
#--- tag the image
|
81 |
+
echo -e "\nTRACE: Tag the image ..."
|
82 |
+
docker tag ${kstr_dkrImg} $kstr_dkrHubImg
|
83 |
+
docker tag ${kstr_dkrImg} "${kstr_defDkrHubId}/${kstr_defDkrImageName}:${kstr_defDkrTagVersion}"
|
84 |
+
|
85 |
+
|
86 |
+
#--- push the image to dockerHub
|
87 |
+
# docker push kidcoconut73/img_stm_omdenasaudi_hcc:demo
|
88 |
+
deadCode
|
{bin β scripts}/models/util_joinModel.sh
RENAMED
@@ -13,14 +13,25 @@ blkHeader
|
|
13 |
#none
|
14 |
|
15 |
|
16 |
-
#---
|
17 |
#--- $1: first arg; source pattern match; eg './bin/models/deeplabv3*vhflip30/model_a*'; Note that this is wildcarded so must be in quotes
|
18 |
#--- $n: last arg; dest model file; eg. ./bin/models/model.pth
|
|
|
19 |
strPth_patternMatch=$1
|
|
|
|
|
|
|
|
|
|
|
20 |
strPth_filMatch=( $strPth_patternMatch ) #--- expand the pattern match; get the first value of the pattern match
|
21 |
strPth_parentFld=$(dirname $strPth_filMatch) #--- get the parent dir of the first file match
|
22 |
strPth_mdlFile=${@: -1} #--- Note: this gets the last arg; otherwise the 2nd arg would be an iteration of the 1st arg wildcard
|
23 |
|
|
|
|
|
|
|
|
|
|
|
24 |
#echo "TRACE: strPth_patternMatch= $strPth_patternMatch"
|
25 |
#echo "TRACE: strPth_filMatch= $strPth_filMatch"
|
26 |
#echo "TRACE: strPth_parentFld= $strPth_parentFld"
|
@@ -29,4 +40,6 @@ strPth_mdlFile=${@: -1} #--- Note: this gets the last a
|
|
29 |
#--- reconstitute model
|
30 |
#--- Note: cat command does not work with single-quote literals; do not reapply single quotes
|
31 |
#echo "cat ${strPth_patternMatch} > ${strPth_mdlFile}"
|
|
|
32 |
cat ${strPth_patternMatch} > ${strPth_mdlFile}
|
|
|
|
13 |
#none
|
14 |
|
15 |
|
16 |
+
#--- initialize/configuration
|
17 |
#--- $1: first arg; source pattern match; eg './bin/models/deeplabv3*vhflip30/model_a*'; Note that this is wildcarded so must be in quotes
|
18 |
#--- $n: last arg; dest model file; eg. ./bin/models/model.pth
|
19 |
+
echo -e "INFO(util_joinModel):\t Initializing ..."
|
20 |
strPth_patternMatch=$1
|
21 |
+
if [ -z "$strPth_patternMatch" ]; then
|
22 |
+
echo "WARN: no args provided. Exiting script."
|
23 |
+
exit
|
24 |
+
fi
|
25 |
+
|
26 |
strPth_filMatch=( $strPth_patternMatch ) #--- expand the pattern match; get the first value of the pattern match
|
27 |
strPth_parentFld=$(dirname $strPth_filMatch) #--- get the parent dir of the first file match
|
28 |
strPth_mdlFile=${@: -1} #--- Note: this gets the last arg; otherwise the 2nd arg would be an iteration of the 1st arg wildcard
|
29 |
|
30 |
+
strpth_pwd=$(pwd)
|
31 |
+
strpth_scriptLoc=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
32 |
+
strpth_scrHome="${strpth_scriptLoc}/../"
|
33 |
+
strpth_appHome="${strpth_scrHome}/../"
|
34 |
+
|
35 |
#echo "TRACE: strPth_patternMatch= $strPth_patternMatch"
|
36 |
#echo "TRACE: strPth_filMatch= $strPth_filMatch"
|
37 |
#echo "TRACE: strPth_parentFld= $strPth_parentFld"
|
|
|
40 |
#--- reconstitute model
|
41 |
#--- Note: cat command does not work with single-quote literals; do not reapply single quotes
|
42 |
#echo "cat ${strPth_patternMatch} > ${strPth_mdlFile}"
|
43 |
+
echo -e "INFO:\t Joining model binary ..."
|
44 |
cat ${strPth_patternMatch} > ${strPth_mdlFile}
|
45 |
+
echo -e "INFO:\t Done ...\n"
|
{bin β scripts}/models/util_splitModel.sh
RENAMED
@@ -13,13 +13,24 @@ blkHeader
|
|
13 |
#none
|
14 |
|
15 |
|
16 |
-
#--- initialization
|
17 |
#--- $1: first arg; the source model file; eg ./bin/models/model.pth
|
18 |
#--- $n: last arg; dest model path; eg. ./test_model_folder
|
19 |
strPth_mdlFile=$1
|
20 |
strPth_mdlFolder=$2
|
21 |
strPrefix='/model_'
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
#echo "TRACE: strPth_mdlFile= $strPth_mdlFile"
|
24 |
echo "TRACE: strPth_mdlFolder= $strPth_mdlFolder"
|
25 |
|
@@ -29,3 +40,5 @@ mkdir -p $strPth_mdlFolder
|
|
29 |
#--- split the model into smaller chunks
|
30 |
echo "split -b 10M $strPth_mdlFile $strPth_mdlFolder$strPrefix"
|
31 |
split -b 10M $strPth_mdlFile $strPth_mdlFolder$strPrefix
|
|
|
|
|
|
13 |
#none
|
14 |
|
15 |
|
16 |
+
#--- initialization/configuration
|
17 |
#--- $1: first arg; the source model file; eg ./bin/models/model.pth
|
18 |
#--- $n: last arg; dest model path; eg. ./test_model_folder
|
19 |
strPth_mdlFile=$1
|
20 |
strPth_mdlFolder=$2
|
21 |
strPrefix='/model_'
|
22 |
|
23 |
+
if [ -z "$strPth_mdlFile" ] || [ -z "$strPth_mdlFolder" ]; then
|
24 |
+
echo "WARN: no args provided. Exiting script."
|
25 |
+
exit
|
26 |
+
fi
|
27 |
+
|
28 |
+
strpth_pwd=$(pwd)
|
29 |
+
strpth_scriptLoc=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
30 |
+
strpth_scrHome="${strpth_scriptLoc}/../"
|
31 |
+
#strpth_ignHome="${strpth_scrHome}/../"
|
32 |
+
strpth_appHome="${strpth_scrHome}/../"
|
33 |
+
|
34 |
#echo "TRACE: strPth_mdlFile= $strPth_mdlFile"
|
35 |
echo "TRACE: strPth_mdlFolder= $strPth_mdlFolder"
|
36 |
|
|
|
40 |
#--- split the model into smaller chunks
|
41 |
echo "split -b 10M $strPth_mdlFile $strPth_mdlFolder$strPrefix"
|
42 |
split -b 10M $strPth_mdlFile $strPth_mdlFolder$strPrefix
|
43 |
+
|
44 |
+
echo -e "INFO:\t Done ...\n"
|
util_startLocal_streamlitFastApi.sh β scripts/streamlitFastApi/util_local_runStreamlitFastApi.sh
RENAMED
@@ -1,21 +1,25 @@
|
|
1 |
#!/bin/bash
|
2 |
|
3 |
#--- Note: this file is designed to run locally and within docker to prep the environment
|
|
|
|
|
|
|
|
|
4 |
#--- for volume initialization; ensure folders are in place; assume: we are in the /app folder
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
|
9 |
#--- for streamlit; external 49400; internal 39400
|
10 |
echo "INFO: starting streamlit ..."
|
11 |
-
streamlit run app.py --server.port=
|
12 |
|
13 |
#--- for fastapi; external 49500; internal 39500
|
14 |
echo "INFO: starting fastapi ..."
|
15 |
-
uvicorn main:app --reload --workers 1 --host 0.0.0.0 --port
|
16 |
|
17 |
#--- wait for any process to exit
|
18 |
wait -n
|
19 |
|
20 |
#--- Exit with status of process that exited first
|
21 |
-
exit $?
|
|
|
1 |
#!/bin/bash
|
2 |
|
3 |
#--- Note: this file is designed to run locally and within docker to prep the environment
|
4 |
+
#--- Entry: this script is assumed to run from the /app root folder
|
5 |
+
#--- Usage: ./scripts/util_local_runStreamlitFastApi.sh
|
6 |
+
echo -e "INFO(util_local_runStreamlitFastApi):\t Initializing ..."
|
7 |
+
|
8 |
#--- for volume initialization; ensure folders are in place; assume: we are in the /app folder
|
9 |
+
mkdir -p data/demo_tiles/raw
|
10 |
+
mkdir -p data/tiles/raw data/tiles/pred data/tiles/grad_bg data/tiles/grad_wt data/tiles/grad_vt
|
11 |
+
mkdir -p data/wsi/raw
|
12 |
|
13 |
#--- for streamlit; external 49400; internal 39400
|
14 |
echo "INFO: starting streamlit ..."
|
15 |
+
streamlit run app.py --server.port=39400 --server.maxUploadSize=2000 &
|
16 |
|
17 |
#--- for fastapi; external 49500; internal 39500
|
18 |
echo "INFO: starting fastapi ..."
|
19 |
+
uvicorn main:app --reload --workers 1 --host 0.0.0.0 --port 39500 &
|
20 |
|
21 |
#--- wait for any process to exit
|
22 |
wait -n
|
23 |
|
24 |
#--- Exit with status of process that exited first
|
25 |
+
exit $?
|
scripts/util.sh
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
|
3 |
+
#--- Note: this file acts as a bash function library
|
4 |
+
|
5 |
+
|
6 |
+
<<blockComment
|
7 |
+
Name:
|
8 |
+
Usage:
|
9 |
+
PreReqs:
|
10 |
+
blockComment
|
11 |
+
|
12 |
+
|
13 |
+
|
14 |
+
#--- declarations
|
15 |
+
<<blockComment
|
16 |
+
function utl_trace_config (aryConfigVars) {
|
17 |
+
for each strConfig in aryConfigVars
|
18 |
+
trace_var("kstr_defDkrHubId")
|
19 |
+
#echo "TRACE: kstr_defDkrHubId = ${kstr_defDkrHubId}"
|
20 |
+
echo "TRACE: kstr_defDkrImageName = ${kstr_defDkrImageName}"
|
21 |
+
echo "TRACE: kstr_defDkrTagVersion = ${kstr_defDkrTagVersion}"
|
22 |
+
echo "TRACE: kstr_defDkrTagStage = ${kstr_defDkrTagStage}"
|
23 |
+
echo "TRACE: kstr_dkrImg = ${kstr_dkrImg}"
|
24 |
+
echo "TRACE: kstr_dkrCtr = ${kstr_dkrCtr}"
|
25 |
+
}
|
26 |
+
blockComment
|
27 |
+
|
28 |
+
|
29 |
+
function utl_strRepeat {
|
30 |
+
#--- Usage1: utl_strRepeat <repeatVal> <repeatCount> <returnVar>
|
31 |
+
local strRptVal="${1:-null}" #--- value to repeat
|
32 |
+
local intRptCount="${2:-1}" #--- repeat count; num times to repeat text
|
33 |
+
local varReturn="${3:-output}" #--- output var
|
34 |
+
local strTemp #--- temp variable
|
35 |
+
printf -v strTemp '%*s' "$intRptCount"
|
36 |
+
printf -v "$varReturn" '%s' "${strTemp// /$strRptVal}"
|
37 |
+
}
|
38 |
+
|
39 |
+
|
40 |
+
function utl_valIsEmpty {
|
41 |
+
#--- Usage1: utl_valIsEmpty <val> | "<val>"
|
42 |
+
#--- Usage2: returnVal=$(utl_valIsEmpty <val> | "<val>")
|
43 |
+
local strTestVal="${1:-null}" #--- test value
|
44 |
+
local __blnReturn=NULL #--- output var
|
45 |
+
|
46 |
+
#echo -e "TRACE: \t $1\n"
|
47 |
+
# if [ ! -z "$strTestVal" -a "$strTestVal" != " " -a "$strTestVal" != "" ]; then #--- check for empty string
|
48 |
+
if [ ! -z "$strTestVal" ]; then
|
49 |
+
__blnReturn=false
|
50 |
+
if [ "$strTestVal" == " " ] || [ "$strTestVal" == "" ]; then
|
51 |
+
__blnReturn=true
|
52 |
+
else
|
53 |
+
if [ "$strTestVal" == null ] || [ "$strTestVal" == NULL ] || [ "$strTestVal" == Null ]; then
|
54 |
+
__blnReturn=true
|
55 |
+
fi
|
56 |
+
fi
|
57 |
+
else
|
58 |
+
__blnReturn=true
|
59 |
+
fi
|
60 |
+
echo "$__blnReturn"
|
61 |
+
}
|
62 |
+
|
63 |
+
|
64 |
+
function utl_varIsEmpty {
|
65 |
+
local strTestVar="${1:-null}" #--- test variable
|
66 |
+
local __blnReturn=false #--- output var
|
67 |
+
|
68 |
+
if [ -z "$strTestVar" ]; then #--- check for empty string
|
69 |
+
__blnReturn=true
|
70 |
+
fi
|
71 |
+
echo "$__blnReturn"
|
72 |
+
}
|
73 |
+
|
74 |
+
|
75 |
+
function utl_getScriptLoc {
|
76 |
+
local __blnReturn=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
77 |
+
echo "$__blnReturn"
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
function utl_logMsg {
|
82 |
+
#--- format: <date/time> \ t <logType> <logLevel> \t <preMsg> \t <Msg> \t <postMsg> \t <varName> \t <varValue>
|
83 |
+
local blnLogOn="${1:-true}" #--- true: log, false: do not log
|
84 |
+
local strLogType="${2:-LOG}" #--- INFO, ERR, WARN, TRACE, TRMOD, TRFXN, EXCPT, DEBUG
|
85 |
+
local strLogLevel="${3:-0}" #--- Depth of log (tab indent)
|
86 |
+
local strMsgPrefix="${4:-null}" #---
|
87 |
+
local strMsg="${5:-null}" #---
|
88 |
+
local strMsgPostfix="${6:-null}" #---
|
89 |
+
local strVarName="${7:-null}" #---
|
90 |
+
local strVarVal="${8:-null}" #---
|
91 |
+
|
92 |
+
#local blnIsEmpty=$(utl_valIsEmpty $strMsg)
|
93 |
+
#echo -e "TRACE: blnIsEmpty=$blnIsEmpty \t $strMsg \t $(blnEmpty==false) \t $(blnEmpty=='false')"
|
94 |
+
if $(utl_valIsEmpty $strMsgPrefix); then strMsgPrefix=""; else strMsgPrefix="$strMsgPrefix \t"; fi
|
95 |
+
if $(utl_valIsEmpty $strMsg); then strMsg=""; else strMsg="$strMsg \t"; fi
|
96 |
+
if $(utl_valIsEmpty $strMsgPostfix); then strMsgPostfix=""; else strMsgPostfix="$strMsgPostfix \t"; fi
|
97 |
+
if $(utl_valIsEmpty $strVarName); then strVarName=""; else strVarName="$strVarName = "; fi
|
98 |
+
if $(utl_valIsEmpty $strVarVal); then strVarVal=""; else strVarVal="$strVarVal"; fi
|
99 |
+
|
100 |
+
local intTabLevel="$strLogLevel"
|
101 |
+
#echo "TRACE (utl_logMsg): $strLogLevel"
|
102 |
+
utl_strRepeat "\t" $intTabLevel strTabLevel
|
103 |
+
#echo "TRACE (utl_logMsg): $strTabLevel"
|
104 |
+
|
105 |
+
if $(utl_valIsEmpty $strLogLevel); then strLogLevel="\b"; strTabLevel=""; fi
|
106 |
+
if [ "$strLogLevel" -eq "0" ]; then strLogLevel="\b"; strTabLevel=""; fi
|
107 |
+
|
108 |
+
#if $($strLogLevel==0); then strLogLevel=""; strTabLevel=""; fi
|
109 |
+
|
110 |
+
if [ "$blnLogOn" ]; then
|
111 |
+
echo -e "$strTabLevel $strLogType $strLogLevel: \t $strMsgPrefix $strMsg $strMsgPostfix $strVarName $strVarVal"
|
112 |
+
fi
|
113 |
+
}
|
114 |
+
|
115 |
+
|
116 |
+
function utl_logTrace {
|
117 |
+
#--- format: <date/time> \ t <logType> <logLevel> \t <preMsg> \t <Msg> \t <postMsg> \t <varName> \t <varValue>
|
118 |
+
local blnLogOn="${1:-true}" #--- true: log, false: do not log
|
119 |
+
local strLogType="TRACE" #--- INFO, ERR, WARN, TRACE, TRMOD, TRFXN, EXCPT, DEBUG
|
120 |
+
local strLogLevel="${2:-0}" #--- Depth of log (tab indent)
|
121 |
+
local strMsg="${3:-null}" #---
|
122 |
+
|
123 |
+
utl_logMsg $blnLogOn "$strLogType" "$strLogLevel" null "$strMsg" null null null
|
124 |
+
}
|
125 |
+
|
126 |
+
function utl_logInfo {
|
127 |
+
#--- format: <date/time> \ t <logType> <logLevel> \t <preMsg> \t <Msg> \t <postMsg> \t <varName> \t <varValue>
|
128 |
+
local blnLogOn="${1:-true}" #--- true: log, false: do not log
|
129 |
+
local strLogType="INFO" #--- INFO, ERR, WARN, TRACE, TRMOD, TRFXN, EXCPT, DEBUG
|
130 |
+
local strLogLevel="${2:-0}" #--- Depth of log (tab indent)
|
131 |
+
local strMsg="${3:-null}" #---
|
132 |
+
|
133 |
+
utl_logMsg $blnLogOn "$strLogType" "$strLogLevel" null "$strMsg" null null null
|
134 |
+
}
|
135 |
+
|
136 |
+
|
137 |
+
function utl_trace_var {
|
138 |
+
local strVarName="${1:-null}" #---
|
139 |
+
local strVarVal="${2:-null}" #---
|
140 |
+
#echo "\t(util.utl_trace_var) TRACE: \t strVarName = ${strVarName}"
|
141 |
+
|
142 |
+
#kstr_tracePtn="TRACE: <var> = \${<var>}"
|
143 |
+
#str_tracePtn="${kstr_tracePtn//<var>/"$strVarName"}" #--- bash replace all occurrences
|
144 |
+
#echo ${str_tracePtn}
|
145 |
+
#echo "TRACE (utl_trace_var): $strVarName = $strVarVal"
|
146 |
+
#utl_logMsg true "TRACE" 0 "msgPrefix" "msg" "msgPostfix" $strVarName $strVarVal
|
147 |
+
utl_logMsg true "TRACE" 0 null null null $strVarName $strVarVal
|
148 |
+
}
|
uix/lit_sidebar.py
CHANGED
@@ -5,12 +5,14 @@ from uix import lit_packages
|
|
5 |
from uix.pages import lit_home, lit_about, lit_diagnosis
|
6 |
from uix.pages import lit_qaConfigCheck
|
7 |
|
|
|
|
|
8 |
|
9 |
#--- alt define sidebar pages
|
10 |
m_aryPages = {
|
11 |
"Home": lit_home, #--- TODO: update
|
12 |
-
"Diagnosis:
|
13 |
-
#"QA: File Check":
|
14 |
"About": lit_about
|
15 |
}
|
16 |
|
@@ -26,71 +28,16 @@ def init():
|
|
26 |
with st.sidebar:
|
27 |
kstrUrl_image = "bin/images/logo_omdena_saudi.png"
|
28 |
st.sidebar.image(kstrUrl_image, width=200)
|
29 |
-
#st.sidebar.markdown('Omdena Saudi - Liver HCC Diagnosis with XAI')
|
30 |
-
|
31 |
|
32 |
-
#---
|
33 |
-
strKey = st.sidebar.radio("", list(m_aryPages.keys()))
|
34 |
pagSel = m_aryPages[strKey]
|
35 |
writePage(pagSel)
|
36 |
|
37 |
|
38 |
-
|
39 |
-
def init_selectBox():
|
40 |
-
#--- init module array of page names, and descr
|
41 |
-
init_modDescrAry()
|
42 |
-
|
43 |
-
# Display the sidebar with a menu of apps
|
44 |
-
kstrMsg = """
|
45 |
-
__Claims Anomaly Views__
|
46 |
-
"""
|
47 |
-
with st.sidebar:
|
48 |
-
st.markdown('---')
|
49 |
-
st.markdown(kstrMsg)
|
50 |
-
page = st.selectbox('Select:', m_aryModNames, format_func=fmt_modName)
|
51 |
-
|
52 |
-
#--- display sidebar footer
|
53 |
-
with st.sidebar:
|
54 |
-
st.markdown('---')
|
55 |
-
st.write('Developed by Chavarria, McKone, Sharma')
|
56 |
-
st.write('Contact at iain.mckone@gmail.com')
|
57 |
-
|
58 |
-
# Run the chosen app
|
59 |
-
m_aryMods[m_aryModNames.index(page)].run()
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
def init_modDescrAry():
|
64 |
-
#--- init global array of page names, and descr
|
65 |
-
#--- note: you need to specify global scope for fxns to access module-level variables
|
66 |
-
global m_aryMods
|
67 |
-
global m_aryDescr
|
68 |
-
|
69 |
-
m_aryMods = []
|
70 |
-
m_aryDescr = []
|
71 |
-
for modName in m_aryModNames:
|
72 |
-
modTemp = importlib.import_module('.'+modName,'uix')
|
73 |
-
m_aryMods.append(modTemp)
|
74 |
-
|
75 |
-
#--- If the module has a description attribute use that in the
|
76 |
-
#--- select box otherwise use the module name
|
77 |
-
try:
|
78 |
-
m_aryDescr.append(modTemp.description)
|
79 |
-
except:
|
80 |
-
m_aryDescr.append(modName)
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
#--- display the app descriptions instead of the module names in the selctbox
|
85 |
-
def fmt_modName(strName):
|
86 |
-
global m_aryModNames
|
87 |
-
global m_aryDescr
|
88 |
-
return m_aryDescr[m_aryModNames.index(strName)]
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
def writePage(uixFile):
|
93 |
#--- writes out the page for the selected combo
|
94 |
-
|
95 |
# _reload_module(page)
|
96 |
uixFile.run()
|
|
|
|
5 |
from uix.pages import lit_home, lit_about, lit_diagnosis
|
6 |
from uix.pages import lit_qaConfigCheck
|
7 |
|
8 |
+
m_kblnTraceOn=False
|
9 |
+
|
10 |
|
11 |
#--- alt define sidebar pages
|
12 |
m_aryPages = {
|
13 |
"Home": lit_home, #--- TODO: update
|
14 |
+
"Diagnosis: Single Tile": lit_diagnosis,
|
15 |
+
#"QA: File Check": lit_qaConfigCheck,
|
16 |
"About": lit_about
|
17 |
}
|
18 |
|
|
|
28 |
with st.sidebar:
|
29 |
kstrUrl_image = "bin/images/logo_omdena_saudi.png"
|
30 |
st.sidebar.image(kstrUrl_image, width=200)
|
|
|
|
|
31 |
|
32 |
+
#--- get radio selection
|
33 |
+
strKey = st.sidebar.radio("rdoPageSel", list(m_aryPages.keys()), label_visibility="hidden")
|
34 |
pagSel = m_aryPages[strKey]
|
35 |
writePage(pagSel)
|
36 |
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
def writePage(uixFile):
|
39 |
#--- writes out the page for the selected combo
|
40 |
+
|
41 |
# _reload_module(page)
|
42 |
uixFile.run()
|
43 |
+
|
uix/pages/lit_about.py
CHANGED
@@ -10,13 +10,17 @@ def run():
|
|
10 |
#st.experimental_memo.clear() #--- try to clear cache each time this page is hit
|
11 |
#st.cache_data.clear()
|
12 |
|
13 |
-
st.markdown('### About')
|
14 |
-
st.markdown('### Omdena Saudi
|
15 |
-
st.markdown('
|
16 |
-
|
|
|
|
|
|
|
17 |
st.markdown(
|
18 |
"""
|
19 |
About page
|
20 |
""",
|
21 |
unsafe_allow_html=True,
|
22 |
-
)
|
|
|
|
10 |
#st.experimental_memo.clear() #--- try to clear cache each time this page is hit
|
11 |
#st.cache_data.clear()
|
12 |
|
13 |
+
#st.markdown('### About')
|
14 |
+
#st.markdown('### Omdena Saudi Arabia')
|
15 |
+
#st.markdown('### Detecting Liver Cancer from Histopathology WSI Using Deep Learning and Explainability')
|
16 |
+
#st.markdown('#### Dr. Shaista Hussain (Saudi Arabia Chapter Lead)')
|
17 |
+
#st.markdown('##### Deployment Lead: Iain McKone')
|
18 |
+
st.markdown('##### Project Url: https://github.com/OmdenaAI/saudi-arabia-histopathology-detection')
|
19 |
+
'''
|
20 |
st.markdown(
|
21 |
"""
|
22 |
About page
|
23 |
""",
|
24 |
unsafe_allow_html=True,
|
25 |
+
)
|
26 |
+
'''
|
uix/pages/lit_diagnosis.py
CHANGED
@@ -18,7 +18,7 @@ from pytorch_grad_cam.utils.image import show_cam_on_image
|
|
18 |
import lib.utils as libUtils
|
19 |
|
20 |
import sys
|
21 |
-
import os
|
22 |
|
23 |
description = "Diagnosis"
|
24 |
m_kblnTraceOn = True #--- enable/disable module level tracing
|
@@ -42,6 +42,25 @@ backbone_model_name = DEFAULT_BACKBONE_MODEL
|
|
42 |
|
43 |
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
def run():
|
46 |
#--- note: in python, you need to specify global scope for fxns to access module-level variables
|
47 |
global m_kbln_TraceOn
|
@@ -50,36 +69,59 @@ def run():
|
|
50 |
|
51 |
#--- page settings
|
52 |
if (m_kblnTraceOn): print("TRACE1 (litDiagnosis.run): Initialize Page Settings ...")
|
53 |
-
st.header("Single Tile Diagnosis")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
|
56 |
#--- provide file drag/drop capability
|
57 |
m_blnDisableDragDrop = False
|
58 |
-
if(not m_blnDisableDragDrop):
|
59 |
#btnSave = st.button("Save")
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
|
64 |
-
|
|
|
|
|
65 |
try:
|
66 |
-
|
|
|
|
|
|
|
|
|
67 |
#--- show:
|
68 |
#if (m_kblnTraceOn): print("TRACE (litDiagnosis.run): load WSI ...")
|
69 |
-
if (m_blnDisableDragDrop):
|
70 |
#--- load wsi
|
71 |
-
|
72 |
-
else:
|
73 |
-
#--- display uploaded file details
|
74 |
-
if (m_kblnTraceOn): print("TRACE1 (litDiagnosis.run): Print upload file details ...")
|
75 |
-
st.write(
|
76 |
-
"FileName:", "   ", imgDropped.name, "\n",
|
77 |
-
"FileType:", "   ", imgDropped.type, "\n"
|
78 |
-
)
|
79 |
|
80 |
#--- display diagnosis results ... format (vertical)
|
81 |
-
#showDiagnosis_vert(
|
82 |
-
|
83 |
|
84 |
except TypeError as e:
|
85 |
print("ERROR (litDiagnosis.run_typeError1): ", e)
|
@@ -110,23 +152,24 @@ def showImg_wsi(img):
|
|
110 |
|
111 |
|
112 |
def readyModel_getPreds(imgDropped):
|
113 |
-
print("TRACE:
|
|
|
114 |
strPth_tilRaw = save_tilRaw(imgDropped)
|
115 |
|
116 |
#--- ready the model
|
117 |
-
print("
|
118 |
mdlBase = readyBaseModel()
|
119 |
-
print("
|
120 |
mdlWeights = readyModelWithWeights(mdlBase)
|
121 |
-
print("
|
122 |
mdlXai = readyModelWithXAI(mdlWeights)
|
123 |
|
124 |
#--- get the XAI weighted prediction
|
125 |
-
print("
|
126 |
output_pred, tns_batch = predXai_tile(mdlXai, strPth_tilRaw)
|
127 |
|
128 |
#--- get the GRADCAM predictions
|
129 |
-
print("
|
130 |
cam_img_bg, cam_img_wt, cam_img_vt = predGradCam_tile(output_pred, mdlXai, tns_batch)
|
131 |
|
132 |
print("TRACE: return readyModel_getPreds ...")
|
@@ -164,11 +207,16 @@ def showCol_rawTil(colRaw, strPth_tilRaw):
|
|
164 |
print("TRACE3: showCol_rawTil ...")
|
165 |
colRaw.image(strPth_tilRaw, width=400, use_column_width=True)
|
166 |
|
167 |
-
|
|
|
|
|
168 |
def showCol_predTil(colPred, xai_pred, strPth_tilRaw):
|
169 |
kstrPth_tilePred = "data/tiles/pred/"
|
170 |
strFilName = os.path.basename(strPth_tilRaw)
|
171 |
strFil_tilePred = kstrPth_tilePred + strFilName
|
|
|
|
|
|
|
172 |
|
173 |
print("TRACE3: showCol_predTil2 ... ", strFil_tilePred)
|
174 |
argmax_mask = torch.argmax(xai_pred, dim=0)
|
@@ -217,10 +265,28 @@ def showDiagnosis_vert(imgDropped):
|
|
217 |
colImage.image(lstImages[imgIdx], width=400, use_column_width=True)
|
218 |
|
219 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
def save_tilRaw(imgDropped):
|
|
|
221 |
#--- copy the uploaded raw Tile to data/tiles/raw
|
222 |
kstrPth_tileRaw = "data/tiles/raw/"
|
223 |
strFil_tileRaw = kstrPth_tileRaw + imgDropped.name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
with open(strFil_tileRaw,"wb") as filUpload:
|
225 |
filUpload.write(imgDropped.getbuffer())
|
226 |
print("TRACE: uploaded file saved to ", strFil_tileRaw)
|
|
|
18 |
import lib.utils as libUtils
|
19 |
|
20 |
import sys
|
21 |
+
import os, random, io
|
22 |
|
23 |
description = "Diagnosis"
|
24 |
m_kblnTraceOn = True #--- enable/disable module level tracing
|
|
|
42 |
|
43 |
|
44 |
|
45 |
+
def image_toBytesIO(image: Image) -> bytes:
|
46 |
+
#--- BytesIO is a file-like buffer stored in memory
|
47 |
+
imgByteArr = io.BytesIO()
|
48 |
+
|
49 |
+
#--- image.save expects a file-like as a argument
|
50 |
+
image.save(imgByteArr, format=image.format)
|
51 |
+
|
52 |
+
return imgByteArr
|
53 |
+
|
54 |
+
|
55 |
+
def image_toByteArray(image: Image) -> bytes:
|
56 |
+
#--- convert image to bytesIO
|
57 |
+
imgByteArr = image_toBytesIO(image)
|
58 |
+
|
59 |
+
#--- Turn the BytesIO object back into a bytes object
|
60 |
+
imgByteArr = imgByteArr.getvalue()
|
61 |
+
return imgByteArr
|
62 |
+
|
63 |
+
|
64 |
def run():
|
65 |
#--- note: in python, you need to specify global scope for fxns to access module-level variables
|
66 |
global m_kbln_TraceOn
|
|
|
69 |
|
70 |
#--- page settings
|
71 |
if (m_kblnTraceOn): print("TRACE1 (litDiagnosis.run): Initialize Page Settings ...")
|
72 |
+
#st.header("Single Tile Diagnosis")
|
73 |
+
st.markdown("#### Single Tile Diagnosis")
|
74 |
+
|
75 |
+
#--- allow the user to select a random sample
|
76 |
+
imgUploaded = None
|
77 |
+
if st.button("Random Sample"):
|
78 |
+
#--- get a random sample file
|
79 |
+
strPth_sample = libUtils.pth_dtaTileSamples
|
80 |
+
strFil_sample = random.choice(os.listdir(strPth_sample))
|
81 |
+
strFullPth_sample = os.path.join(strPth_sample, strFil_sample)
|
82 |
+
|
83 |
+
print("INFO (litDiagnosis.run): sample file selected ... ", strFullPth_sample)
|
84 |
+
|
85 |
+
#--- display; convert file image to bytesIO
|
86 |
+
imgSample = Image.open(strFullPth_sample)
|
87 |
+
imgSample = image_toBytesIO(imgSample)
|
88 |
+
imgUploaded = imgSample
|
89 |
+
imgUploaded.name = strFil_sample
|
90 |
+
imgUploaded.type = os.path.splitext(strFil_sample)[1]
|
91 |
|
92 |
|
93 |
#--- provide file drag/drop capability
|
94 |
m_blnDisableDragDrop = False
|
95 |
+
#if(not m_blnDisableDragDrop):
|
96 |
#btnSave = st.button("Save")
|
97 |
+
imgDropped = st.file_uploader("Upload a single Tile",
|
98 |
+
type=["png", "jpg", "tif", "tiff", "img"],
|
99 |
+
accept_multiple_files=False )
|
100 |
+
#m_blnDisableDragDrop = (imgDropped is None)
|
101 |
+
#--- <class 'streamlit.runtime.uploaded_file_manager.UploadedFile'>
|
102 |
+
if (imgDropped is not None):
|
103 |
+
imgUploaded = imgDropped
|
104 |
|
105 |
|
106 |
+
if (imgUploaded is None):
|
107 |
+
if (m_kblnTraceOn): print("ERROR (litDiagnosis.run): imgUploaded is None ...")
|
108 |
+
else:
|
109 |
try:
|
110 |
+
#--- display uploaded file details
|
111 |
+
if (m_kblnTraceOn): print("TRACE1 (litDiagnosis.run): Print uploaded file details ...")
|
112 |
+
st.write("FileName:", "   ", imgUploaded.name)
|
113 |
+
st.write("FileType:", "   ", imgUploaded.type)
|
114 |
+
|
115 |
#--- show:
|
116 |
#if (m_kblnTraceOn): print("TRACE (litDiagnosis.run): load WSI ...")
|
117 |
+
#if (m_blnDisableDragDrop):
|
118 |
#--- load wsi
|
119 |
+
# print("")
|
120 |
+
#else:
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
#--- display diagnosis results ... format (vertical)
|
123 |
+
#showDiagnosis_vert(imgUploaded)
|
124 |
+
showDiagnosis_horiz(imgUploaded)
|
125 |
|
126 |
except TypeError as e:
|
127 |
print("ERROR (litDiagnosis.run_typeError1): ", e)
|
|
|
152 |
|
153 |
|
154 |
def readyModel_getPreds(imgDropped):
|
155 |
+
print("TRACE: readyModel_getPreds ...")
|
156 |
+
print("INFO: save raw tile ...")
|
157 |
strPth_tilRaw = save_tilRaw(imgDropped)
|
158 |
|
159 |
#--- ready the model
|
160 |
+
print("INFO: ready base model ...")
|
161 |
mdlBase = readyBaseModel()
|
162 |
+
print("INFO: ready model with weights ...")
|
163 |
mdlWeights = readyModelWithWeights(mdlBase)
|
164 |
+
print("INFO: ready model with xai ...")
|
165 |
mdlXai = readyModelWithXAI(mdlWeights)
|
166 |
|
167 |
#--- get the XAI weighted prediction
|
168 |
+
print("INFO: get xai weighted pred ...")
|
169 |
output_pred, tns_batch = predXai_tile(mdlXai, strPth_tilRaw)
|
170 |
|
171 |
#--- get the GRADCAM predictions
|
172 |
+
print("INFO: get GRADCAM preds ...")
|
173 |
cam_img_bg, cam_img_wt, cam_img_vt = predGradCam_tile(output_pred, mdlXai, tns_batch)
|
174 |
|
175 |
print("TRACE: return readyModel_getPreds ...")
|
|
|
207 |
print("TRACE3: showCol_rawTil ...")
|
208 |
colRaw.image(strPth_tilRaw, width=400, use_column_width=True)
|
209 |
|
210 |
+
#--- Dark blue -> Background
|
211 |
+
# Brown -> Whole tumor
|
212 |
+
# Green/Aqua -> Viable tumor
|
213 |
def showCol_predTil(colPred, xai_pred, strPth_tilRaw):
|
214 |
kstrPth_tilePred = "data/tiles/pred/"
|
215 |
strFilName = os.path.basename(strPth_tilRaw)
|
216 |
strFil_tilePred = kstrPth_tilePred + strFilName
|
217 |
+
|
218 |
+
#--- make sure the dir exists
|
219 |
+
ensureDirExists(kstrPth_tilePred)
|
220 |
|
221 |
print("TRACE3: showCol_predTil2 ... ", strFil_tilePred)
|
222 |
argmax_mask = torch.argmax(xai_pred, dim=0)
|
|
|
265 |
colImage.image(lstImages[imgIdx], width=400, use_column_width=True)
|
266 |
|
267 |
|
268 |
+
def ensureDirExists(strPth):
|
269 |
+
blnExists = os.path.exists(strPth)
|
270 |
+
if not blnExists:
|
271 |
+
os.makedirs(strPth)
|
272 |
+
print("TRACE: creating dir ... ", strPth)
|
273 |
+
|
274 |
+
|
275 |
def save_tilRaw(imgDropped):
|
276 |
+
print("TRACE: save_tilRaw ...")
|
277 |
#--- copy the uploaded raw Tile to data/tiles/raw
|
278 |
kstrPth_tileRaw = "data/tiles/raw/"
|
279 |
strFil_tileRaw = kstrPth_tileRaw + imgDropped.name
|
280 |
+
print("TRACE: save_tilRaw.file ... ", strFil_tileRaw)
|
281 |
+
|
282 |
+
#--- make sure the dir exists
|
283 |
+
ensureDirExists(kstrPth_tileRaw)
|
284 |
+
|
285 |
+
#--- check if the file already exists; delete
|
286 |
+
if (os.path.isfile(strFil_tileRaw)):
|
287 |
+
print("WARN: save_tilRaw.file exists; delete ... ", strFil_tileRaw)
|
288 |
+
os.remove(strFil_tileRaw)
|
289 |
+
|
290 |
with open(strFil_tileRaw,"wb") as filUpload:
|
291 |
filUpload.write(imgDropped.getbuffer())
|
292 |
print("TRACE: uploaded file saved to ", strFil_tileRaw)
|
uix/pages/lit_home.py
CHANGED
@@ -7,21 +7,60 @@ def run():
|
|
7 |
print("\nINFO (lit_home.run) loading ", description, " page ...")
|
8 |
|
9 |
|
10 |
-
st.markdown('### Home')
|
11 |
-
st.markdown('### Omdena Saudi
|
12 |
-
st.markdown('
|
|
|
13 |
st.markdown('\
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
st.markdown('\
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
st.markdown(
|
26 |
"""
|
27 |
|
@@ -29,4 +68,9 @@ def run():
|
|
29 |
|
30 |
""",
|
31 |
unsafe_allow_html=True,
|
32 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
7 |
print("\nINFO (lit_home.run) loading ", description, " page ...")
|
8 |
|
9 |
|
10 |
+
#st.markdown('### Home')
|
11 |
+
#st.markdown('### Omdena Saudi Arabia')
|
12 |
+
#st.markdown('### Detecting Liver Cancer from Histopathology WSI Using Deep Learning and Explainability')
|
13 |
+
st.markdown('#### Background ')
|
14 |
st.markdown('\
|
15 |
+
Hepatocellular Carcinoma (HCC) is a primary liver malignancy, with \
|
16 |
+
alarming global impact. It is the 4th most common cause of cancer \
|
17 |
+
mortality worldwide, and the 6th most common malignancy overall. \
|
18 |
+
\
|
19 |
+
A patient\'s prognosis increases markedly with the speed of diagnosis \
|
20 |
+
and treatment, however the rates of occurrence are increasing at an \
|
21 |
+
alarming rate which will commensurately challenge the medical \
|
22 |
+
community. \
|
23 |
+
\
|
24 |
+
There are already several tools and technologies available to assist \
|
25 |
+
pathologists, however the current approach is ultimately constrained by \
|
26 |
+
a number of factors including: the rising demand, a limited supply \
|
27 |
+
of skilled specialists, the time required to grow/replenish this talent \
|
28 |
+
pool, and human factors which influence quality, accuracy, consistency, \
|
29 |
+
and speed (timeliness). \
|
30 |
+
')
|
31 |
+
|
32 |
+
st.markdown('#### Claim ')
|
33 |
st.markdown('\
|
34 |
+
It is the desire of this project team to increase the prognosis of \
|
35 |
+
hepatocellular cancer patients.\
|
36 |
+
\
|
37 |
+
Machine Learning techniques, specifically Deep Learning and \
|
38 |
+
Explainability (XAI) show promise in mimic\'ing the role of the \
|
39 |
+
pathologist. \
|
40 |
+
\
|
41 |
+
MLOps promises to establish a baseline for performance\
|
42 |
+
and a basis for continuous process improvement. This could greatly \
|
43 |
+
reduce human factor elements while accelerating the times and \
|
44 |
+
increasing the volumes of response.\
|
45 |
+
\
|
46 |
+
As a minimum, an ML application can serve as a supplement to the\
|
47 |
+
pathologist, a teaching aide, a verification tool, or as a framework\
|
48 |
+
for community collaboration and the advancement of quality diagnosis.\
|
49 |
+
')
|
50 |
|
51 |
+
st.markdown('#### Objectives ')
|
52 |
+
st.markdown('\
|
53 |
+
A key objective of this project is to produce a deployed app that will\
|
54 |
+
enable pathologists to upload a digital liver histopathology slide\
|
55 |
+
image and then receive an output that classifies the segment as\
|
56 |
+
malignant (or not). \
|
57 |
+
\
|
58 |
+
The utilization of Machine Learning and Explainability Techniques \
|
59 |
+
to the traditional process of Liver Histopathology and HCC Diagnosis \
|
60 |
+
could serve to greatly reduce the time to diagnosis and treatment. \
|
61 |
+
\
|
62 |
+
')
|
63 |
+
'''
|
64 |
st.markdown(
|
65 |
"""
|
66 |
|
|
|
68 |
|
69 |
""",
|
70 |
unsafe_allow_html=True,
|
71 |
+
)
|
72 |
+
<style>
|
73 |
+
# MainMenu {visibility: hidden;}
|
74 |
+
footer {visibility: hidden;}
|
75 |
+
</style>
|
76 |
+
'''
|