-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
152 lines (129 loc) · 5.79 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import streamlit as st
import numpy as np
import os
import pandas as pd
from tensorflow import keras
from tensorflow.keras.models import load_model
from PIL import Image, ImageOps
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, accuracy_score
import time
import sys
sys.path.append('../modules/')
import model as m
_ = """
All comments will be assigned to the underscore variable so they dont get rendered in streamlit
as mention in this discussion fourm:
https://discuss.streamlit.io/t/any-way-to-prevent-commented-out-code-via-triple-quotes-to-be-displayed-in-streamlit/8821/6
This code takes heavy influece from a previous project.
https://github.com/DerikVo/NN_hackathon/blob/main/Code/Helpers/streamlit/app.py
There were many changes to the code to get it to work with this data set as well as provide additional features,
but the general structure remains the same
"""
# function to load and cache pretrained model
@st.cache_resource
def load_model_stream():
path = "../Models/CNN_base.h5"
model = load_model(path)
return model
_ = """
function to preprocess an image and get a prediction from the model
code was copied into chatGPT3 with the prompt "how do I modify this code to covert a single image to make predictions on what class it belongs to.
The image and classes are in greyscale" was provided with this code.
According to stackoverflow this method is used for greyscaling an image.
My interptation is by greyscaling our image we ensure it matchs the training data which gets read in as a greyscale image:
https://stackoverflow.com/questions/52307290/what-is-the-difference-between-images-in-p-and-l-mode-in-pil
"""
def get_prediction(model, image):
open_image = Image.open(image)
resized_image = open_image.resize((256, 256))
# got help from chat gpt 3 by copy and pasting code and asking how get predictions from a single image
grayscale_image = resized_image.convert('L')
img = np.expand_dims(grayscale_image, axis=0)
predicted_prob = model.predict(img)[0]
classes = ['glioma', 'meningioma', 'notumor', 'pituitary']
probabilities = dict(zip(classes, predicted_prob))
#referenced https://www.freecodecamp.org/news/sort-dictionary-by-value-in-python/
sorted_probabilities = sorted(probabilities.items(), key=lambda x: x[1], reverse=True)
return sorted_probabilities
def upload_mode():
st.header("Classification Mode")
st.subheader("Upload an Image to Make a Prediction")
# upload an image
uploaded_image = st.file_uploader("Upload your own image to test the model:", type=['jpg', 'jpeg', 'png'])
# when an image is uploaded, display image and run inference
if uploaded_image is not None:
st.image(uploaded_image)
st.text(get_prediction(classifier, uploaded_image))
st.set_page_config(layout="wide")
# load model
classifier = load_model_stream()
st.title("Brain Tumor Classifier")
st.write('Use the sidebar to select a page to view.')
page = st.sidebar.selectbox('Select Mode',['Upload Image','Model Evaluation'])
_ ='''
This portion of the code was taken from the moduels function py file
this code also brows ideas from previous projects and intergrates it into a function.
Espically the model evaluation notebook.
'''
@st.cache_resource #cache so I can show this during presentation more easily
def model_Evaluation(path):
'''
Calculate accuracy, precision, recall, and F1 score.
'''
model = keras.models.load_model(path)
testing_folder_path = '../Images/Testing'
datagen = ImageDataGenerator()
test_ds = datagen.flow_from_directory(
testing_folder_path,
target_size=(256, 256),
color_mode='grayscale',
class_mode='categorical',
seed=42,
shuffle=False
)
true_classes = test_ds.classes
y_pred = model.predict(test_ds)
predicted_classes = np.argmax(y_pred, axis=1)
accuracy = accuracy_score(true_classes, predicted_classes)
precision = precision_score(true_classes, predicted_classes, average='weighted')
recall = recall_score(true_classes, predicted_classes, average='weighted')
f1 = f1_score(true_classes, predicted_classes, average='weighted')
data = {'Accuracy': round(accuracy,4), 'Precision': round(precision,4), 'Recall': round(recall,4), 'F1 Score': round(f1,4)}
return data
_ ='''
This code utilized the streamlit documentation to implement columns
and displaying images.
In the future I want users to be able to upload their model and have it
automatically be evaluated by the app. However, currently when I create a function to upload the model, I am unable to pass it into the model evaluation function.
The model being passed isnt being interpreted as a h5 file.
The links are as folows:
https://docs.streamlit.io/library/api-reference/layout/st.columns
https://docs.streamlit.io/library/api-reference/media/st.image
'''
if page == 'Model Evaluation':
path = ('../Models/CNN_base.h5')
data = model_Evaluation(path)
reg_path = ('../Models/CNN_regularization.h5')
reg_data = model_Evaluation(path)
st.write("CNN base Metrics:\n")
#create a column for metric scores and display the confusion matrix for the neural network without regularization
col1, col2 = st.columns(2)
with col1:
for metric_name, metric_value in data.items():
st.write(f"{metric_name}: {metric_value}")
with col2:
st.image("../Created_images/Neural Network confusion matrix.png", caption = "No regularization")
#add white space
st.write("")
st.write("")
st.write("\n CNN regularization Metrics:")
#create a column for metric scores and display the confusion matrix for the neural network with regularization
col3, col4 = st.columns(2)
with col3:
for metric_name, metric_value in reg_data.items():
st.write(f"{metric_name}: {metric_value}")
with col4:
st.image("../Created_images/Neural Network with regularization confusion matrix.png", caption = "With regularization")
else:
upload_mode()