This repository has been archived by the owner on Nov 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
predictor.py
163 lines (123 loc) · 5.16 KB
/
predictor.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
153
154
155
156
157
158
159
160
161
162
163
# This is the file that implements a flask server to do inferences. It's the
# file that you will modify to implement the scoring for your own algorithm.
########################################################################################################
############### Section 10: Define functions for local inference ##############################
########################################################################################################
from __future__ import print_function
import os
try:
from StringIO import StringIO ## for Python 2
except ImportError:
from io import StringIO ## for Python 3
import flask
from keras.layers import Dropout, Dense
from keras.wrappers.scikit_learn import KerasRegressor
from keras.models import Sequential
import tensorflow as tf
import numpy as np
import pandas as pd
from pickle import load
from tensorflow import Graph, Session
from keras import backend as K
graph = Graph()
from keras.models import load_model
from sklearn.preprocessing import StandardScaler
from keras.models import model_from_json
import h5py
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
prefix = '/opt/ml/'
model_path = os.path.join(prefix, 'model')
# A singleton for holding the model. This simply loads the model and holds it.
# It has a predict function that does a prediction based on the model and the
# input data.
def loadmodel(weightFile, jsonFile):
# load json and create model
json_file = open(jsonFile, 'r')
loaded_model_json = json_file.read()
json_file.close()
reg = model_from_json(loaded_model_json)
# load weights into new model
reg.load_weights(weightFile)
print("Loaded model from disk")
return reg
class ScoringService(object):
model = None # Where we keep the model when it's loaded
@classmethod
def get_model(cls):
"""
Get the model object for this instance,
loading it if it's not already loaded.
"""
if cls.model is None:
cls.model = loadmodel(os.path.join(model_path, 'model.h5'),os.path.join(model_path, 'model.json'))
return cls.model
@classmethod
def predict(cls,input):
"""For the input, do the predictions and return them.
Args:
input (a pandas dataframe): The data on which to do the
predictions.
There will be one prediction per row in the dataframe
"""
sess = K.get_session()
with sess.graph.as_default():
clf = cls.get_model()
return clf.predict(input)
def transform_data(dataset):
#######
dataset = dataset.dropna()
dataset = dataset.astype('float32')
#######
scaler = load(open(os.path.join(model_path, 'scaler.pkl'), 'rb'))
# Feature Scaling
dataset = scaler.fit_transform(dataset)
return pd.DataFrame(dataset)
########################################################################################################
############### Section 10b-D: Define functions for local inference ##############################
########################################################################################################
# The flask app for serving predictions
app = flask.Flask(__name__)
@app.route('/ping', methods=['GET'])
def ping():
"""
Determine if the container is working and healthy.
In this sample container, we declare it healthy if we can load the model
successfully.
"""
# Health check -- You can insert a health check here
health = ScoringService.get_model() is not None
status = 200 if health else 404
return flask.Response(
response='\n',
status=status,
mimetype='application/json')
@app.route('/invocations', methods=['POST'])
########################################################################################################
############### Section 11-D: Do inference ##############################
########################################################################################################
def transformation():
"""
Do an inference on a single batch of data. In this sample server, we take
data as CSV, convert it to a pandas data frame for internal use and then
convert the predictions back to CSV (which really just means one prediction
per line, since there's a single column.
"""
data = None
# Convert from CSV to pandas
if flask.request.content_type == 'text/csv':
data = flask.request.data.decode('utf-8')
s = StringIO(data)
data = pd.read_csv(s, header=None)
print('data.head()',data.head())
print('data.columns',data.columns)
data = transform_data(data)
else:
return flask.Response(response='This predictor only supports CSV data',status=415, mimetype='text/plain')
print('Invoked with {} records'.format(data.shape[0]))
# Do the prediction
predictions = ScoringService.predict(data)
# Convert from numpy back to CSV
out = StringIO()
pd.DataFrame(predictions).to_csv(out, header=False, index=False)
result = out.getvalue()
return flask.Response(response=result, status=200, mimetype='text/csv')