shehan16 commited on
Commit
130cbf2
1 Parent(s): 3977440

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -0
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()