Spaces:
Build error
Build error
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import keras
|
2 |
+
from keras.models import Model
|
3 |
+
from tensorflow.keras.applications import densenet
|
4 |
+
from keras import backend as K
|
5 |
+
import tensorflow as tf
|
6 |
+
from keras.layers import Dense, GlobalAveragePooling2D
|
7 |
+
from keras.models import Model
|
8 |
+
import numpy as np
|
9 |
+
|
10 |
+
chexnet_weights_path = "brucechou1983_CheXNet_Keras_0.3.0_weights.h5"
|
11 |
+
IMG_SIZE = 320
|
12 |
+
|
13 |
+
base = densenet.DenseNet121(weights=None,
|
14 |
+
include_top=False,
|
15 |
+
input_shape=(IMG_SIZE,IMG_SIZE,3)
|
16 |
+
)
|
17 |
+
## workaround - add dummy layer then load weights then pop dummy layer, in order to match expected shape for pretrained weights
|
18 |
+
predictions = tf.keras.layers.Dense(14, activation='sigmoid', name='predictions')(base.output)
|
19 |
+
## ,by_name=True - could save on workaround, but don't know if names will necessarily match + how to validate? - https://github.com/keras-team/keras/issues/5397
|
20 |
+
base = tf.keras.Model(inputs=base.input, outputs=predictions)
|
21 |
+
base.load_weights(chexnet_weights_path)
|
22 |
+
print("CheXNet loaded")
|
23 |
+
base.trainable=False # freeze most layers
|
24 |
+
base.training=False
|
25 |
+
|
26 |
+
base.layers.pop()
|
27 |
+
|
28 |
+
base.layers.pop()
|
29 |
+
|
30 |
+
### https://stackoverflow.com/questions/41668813/how-to-add-and-remove-new-layers-in-keras-after-loading-weights
|
31 |
+
new_model = GlobalAveragePooling2D()(base.layers[-4].output)
|
32 |
+
new_model = Dense(4, activation='softmax')(new_model)
|
33 |
+
chexnet_model = keras.Model(base.input, new_model)
|
34 |
+
|
35 |
+
### Loading Weights from the saved Weights
|
36 |
+
|
37 |
+
from keras.models import load_model
|
38 |
+
chexnet_model.load_weights('./chexnet_with_data_aug_and standardized.05.hdf5')
|
39 |
+
|
40 |
+
### User-Defined Functions for Pre-Processing
|
41 |
+
|
42 |
+
labels = ['Negative for Pneumonia',
|
43 |
+
'Typical Appearance',
|
44 |
+
'Indeterminate Appearance',
|
45 |
+
'Atypical Appearance']
|
46 |
+
|
47 |
+
def get_mean_std(inp):
|
48 |
+
sample_data = []
|
49 |
+
sample_data.append(np.array(inp))
|
50 |
+
mean = np.mean(sample_data)
|
51 |
+
std = np.std(sample_data)
|
52 |
+
return mean, std
|
53 |
+
|
54 |
+
def standardize_image(inp, preprocess=True):
|
55 |
+
"""Load and preprocess image."""
|
56 |
+
mean, std = get_mean_std(inp)
|
57 |
+
if preprocess:
|
58 |
+
inp = np.array(inp, dtype=np.float32)
|
59 |
+
inp -= mean
|
60 |
+
inp /= std
|
61 |
+
inp = np.expand_dims(inp, axis=0)
|
62 |
+
return inp
|
63 |
+
|
64 |
+
def preprocess_input(inp):
|
65 |
+
inp = standardize_image(inp, preprocess=True)
|
66 |
+
return inp
|
67 |
+
|
68 |
+
def get_prediction(inp):
|
69 |
+
prediction = chexnet_model.predict(inp)
|
70 |
+
confidences = {labels[i]: float(prediction[i]) for i in range(4)}
|
71 |
+
return confidences
|
72 |
+
|
73 |
+
def classify_image(inp):
|
74 |
+
inp = standardize_image(inp, preprocess=True)
|
75 |
+
prediction = chexnet_model.predict(inp)
|
76 |
+
confidences = {labels[i]: float(prediction[0][i]) for i in range(4)}
|
77 |
+
return confidences
|
78 |
+
|
79 |
+
### Application Code
|
80 |
+
|
81 |
+
import gradio as gr
|
82 |
+
|
83 |
+
title = "Decision Support System to Diagnose COVID-19 using Chest X-Ray"
|
84 |
+
description = """
|
85 |
+
A prototype app for classifying the four COVID-19 Pneumonia Classes, created as a Demo for Gradio and HuggingFace Spaces
|
86 |
+
. It is currently able to classify a given image as one of the following four classes: Typical Appearance, Atypical Appearance,
|
87 |
+
Indeterminate Appearance and Negative for Pneumonia. The System has an interpretability component as well.
|
88 |
+
"""
|
89 |
+
|
90 |
+
examples = ['0a3afeef9c01.png']
|
91 |
+
interpretation='default'
|
92 |
+
enable_queue=True
|
93 |
+
|
94 |
+
gr.Interface(fn=classify_image,inputs=gr.inputs.Image(shape=(320, 320)),outputs=gr.outputs.Label(num_top_classes=4),
|
95 |
+
title=title,description=description, examples=examples,
|
96 |
+
interpretation=interpretation,enable_queue=enable_queue).launch()
|