-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
executable file
·150 lines (120 loc) · 4.41 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
# Jinja2 templating http://bit.ly/flask_walkthrough
from flask import Flask, request, jsonify, render_template, current_app, Response
# needed to ensure weights are loaded
from tensorflow.python.keras.backend import set_session
# specified instead of vague next line
from tensorflow.python.keras.models import load_model
# from keras.models import load_model
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
# import tensorflow
from numpy import asarray
from PIL import Image as Image_PIL # PYTHON IMAGING LIBRARY
import base64
import numpy as np
import os
import re # regular expresions
global graph
global model
global session
def get_model():
model = load_model(model_path)
print(f'Model from {model_path} is Loaded')
return model
def convert_canvas(canvas_data):
'''
USER INPUT (CANVAS) IMAGE CONVERSION;
Canvas will sytem_outputput user entry as Base64 Encoded String;
This function will Decode the string to binary data to work with;
'''
# pinpoint 64 encoded string
encoded_string = re.search(r'base64,(.*)', canvas_data).group(1)
decoded_binary_data = base64.b64decode(encoded_string) # decode
# print(encoded_string)
# save canvas output as png file to process prediction;
sytem_output = open(filepath, 'wb')
sytem_output.write(decoded_binary_data)
sytem_output.close()
return filepath
def preprocess_image(filepath):
'''
Argument: Filepath
- Converts image to grayscale
- Resizes image to 28 x 28
- Creates Array from Pixel Data
- Inverts Array Values;
Returns Array from pixels & prints to console Image
'''
image = Image_PIL.open(filepath) # create instance of downloaded image;
# convert to grayscale; remove rgb channel;
image = image.convert(mode='L')
image = image.resize((28, 28)) # resize from 280x280 to 28x28;
image_array = asarray(image)
image_array = np.invert(image_array)
# NEXT TWO LINES WERE USED FOR DEBUGGING
# plt.imshow(image_array)
# plt.show()
return image_array
def preprocess_array(array):
'''
Arguments: Numpy Array
––––––––––––––––––––––
- Convert Array Elements to Floats (from Ints)
- Reshape Array to be 4-D Tensor; (Model Was Trained on (1, 28, 28, 1))
- Standardize Elements by Dividing Each by 255 (0-256)
- Return Preprocessed Array
'''
array = array.astype('float32')
array = array.reshape(1, 28, 28, 1)
array /= 255
return array
def make_prediction(image_array):
'''
Makes a Prediction Using Our Model & Returns it
'''
# Issue w/ model.predict in Flask; using tensorflow.graph instead
# prediction = model.predict(image_array).argmax()
# print(f'The predicted number is {prediction}')
accross_columns = 1
with graph.as_default():
# set_session(session)
# 10 unique probabilities of integer likelihoods;
probability_array = model.predict(image_array)
highest_probability_index = np.argmax(
probability_array, axis=accross_columns) # Prediction = highest probability
# Prediction = highest probability
prediction = str(highest_probability_index)
# probability = '{:.5%}'.format(
# float(probability_array[0][highest_probability_index]))
# return prediction, probability
return prediction
filepath = 'assets/temp/image_canvas.png' # location of file output from canvas
model_path = 'MNIST_CNN.h5'
session = tf.Session()
# session = tensorflow.compat.v1.Session
graph = tf.get_default_graph()
# graph = tensorflow.compat.v1.get_default_graph()
# SESSION MUST BE SET PRIOR TO LOADING MODEL & BEFORE EACH PREDICTION
set_session(session)
model = get_model()
#––––––––––––––––––––––––––––––––––––– * FLASK APPLICATION * –––––––––––––––––––––––––––––––––––––– #
app = Flask(__name__)
app.config["DEBUG"] = True
@app.route('/')
def home():
return render_template("index.html")
@app.route('/predict/', methods=['GET', 'POST'])
def predict():
set_session(session)
canvas_data = request.get_data().decode('utf-8')
filepath = convert_canvas(canvas_data)
image_array = preprocess_image(filepath)
image_array = preprocess_array(image_array)
prediction = make_prediction(image_array)
print(prediction)
# prediction, probability = make_prediction(image_array)
# return prediction, probability
return prediction
if __name__ == "__main__":
# app.run(debug=True)
app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))