aimodelshare 0.3.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aimodelshare/README.md +26 -0
- aimodelshare/__init__.py +100 -0
- aimodelshare/aimsonnx.py +2381 -0
- aimodelshare/api.py +836 -0
- aimodelshare/auth.py +163 -0
- aimodelshare/aws.py +511 -0
- aimodelshare/aws_client.py +173 -0
- aimodelshare/base_image.py +154 -0
- aimodelshare/bucketpolicy.py +106 -0
- aimodelshare/color_mappings/color_mapping_keras.csv +121 -0
- aimodelshare/color_mappings/color_mapping_pytorch.csv +117 -0
- aimodelshare/containerisation.py +244 -0
- aimodelshare/containerization.py +712 -0
- aimodelshare/containerization_templates/Dockerfile.txt +8 -0
- aimodelshare/containerization_templates/Dockerfile_PySpark.txt +23 -0
- aimodelshare/containerization_templates/buildspec.txt +14 -0
- aimodelshare/containerization_templates/lambda_function.txt +40 -0
- aimodelshare/custom_approach/__init__.py +1 -0
- aimodelshare/custom_approach/lambda_function.py +17 -0
- aimodelshare/custom_eval_metrics.py +103 -0
- aimodelshare/data_sharing/__init__.py +0 -0
- aimodelshare/data_sharing/data_sharing_templates/Dockerfile.txt +3 -0
- aimodelshare/data_sharing/data_sharing_templates/__init__.py +1 -0
- aimodelshare/data_sharing/data_sharing_templates/buildspec.txt +15 -0
- aimodelshare/data_sharing/data_sharing_templates/codebuild_policies.txt +129 -0
- aimodelshare/data_sharing/data_sharing_templates/codebuild_trust_relationship.txt +12 -0
- aimodelshare/data_sharing/download_data.py +620 -0
- aimodelshare/data_sharing/share_data.py +373 -0
- aimodelshare/data_sharing/utils.py +8 -0
- aimodelshare/deploy_custom_lambda.py +246 -0
- aimodelshare/documentation/Makefile +20 -0
- aimodelshare/documentation/karma_sphinx_theme/__init__.py +28 -0
- aimodelshare/documentation/karma_sphinx_theme/_version.py +2 -0
- aimodelshare/documentation/karma_sphinx_theme/breadcrumbs.html +70 -0
- aimodelshare/documentation/karma_sphinx_theme/layout.html +172 -0
- aimodelshare/documentation/karma_sphinx_theme/search.html +50 -0
- aimodelshare/documentation/karma_sphinx_theme/searchbox.html +14 -0
- aimodelshare/documentation/karma_sphinx_theme/static/css/custom.css +2 -0
- aimodelshare/documentation/karma_sphinx_theme/static/css/custom.css.map +1 -0
- aimodelshare/documentation/karma_sphinx_theme/static/css/theme.css +2751 -0
- aimodelshare/documentation/karma_sphinx_theme/static/css/theme.css.map +1 -0
- aimodelshare/documentation/karma_sphinx_theme/static/css/theme.min.css +2 -0
- aimodelshare/documentation/karma_sphinx_theme/static/css/theme.min.css.map +1 -0
- aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.eot +0 -0
- aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.svg +32 -0
- aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.ttf +0 -0
- aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.woff +0 -0
- aimodelshare/documentation/karma_sphinx_theme/static/font/fontello.woff2 +0 -0
- aimodelshare/documentation/karma_sphinx_theme/static/js/theme.js +68 -0
- aimodelshare/documentation/karma_sphinx_theme/theme.conf +9 -0
- aimodelshare/documentation/make.bat +35 -0
- aimodelshare/documentation/requirements.txt +2 -0
- aimodelshare/documentation/source/about.rst +18 -0
- aimodelshare/documentation/source/advanced_features.rst +137 -0
- aimodelshare/documentation/source/competition.rst +218 -0
- aimodelshare/documentation/source/conf.py +58 -0
- aimodelshare/documentation/source/create_credentials.rst +86 -0
- aimodelshare/documentation/source/example_notebooks.rst +132 -0
- aimodelshare/documentation/source/functions.rst +151 -0
- aimodelshare/documentation/source/gettingstarted.rst +390 -0
- aimodelshare/documentation/source/images/creds1.png +0 -0
- aimodelshare/documentation/source/images/creds2.png +0 -0
- aimodelshare/documentation/source/images/creds3.png +0 -0
- aimodelshare/documentation/source/images/creds4.png +0 -0
- aimodelshare/documentation/source/images/creds5.png +0 -0
- aimodelshare/documentation/source/images/creds_file_example.png +0 -0
- aimodelshare/documentation/source/images/predict_tab.png +0 -0
- aimodelshare/documentation/source/index.rst +110 -0
- aimodelshare/documentation/source/modelplayground.rst +132 -0
- aimodelshare/exceptions.py +11 -0
- aimodelshare/generatemodelapi.py +1270 -0
- aimodelshare/iam/codebuild_policy.txt +129 -0
- aimodelshare/iam/codebuild_trust_relationship.txt +12 -0
- aimodelshare/iam/lambda_policy.txt +15 -0
- aimodelshare/iam/lambda_trust_relationship.txt +12 -0
- aimodelshare/json_templates/__init__.py +1 -0
- aimodelshare/json_templates/api_json.txt +155 -0
- aimodelshare/json_templates/auth/policy.txt +1 -0
- aimodelshare/json_templates/auth/role.txt +1 -0
- aimodelshare/json_templates/eval/policy.txt +1 -0
- aimodelshare/json_templates/eval/role.txt +1 -0
- aimodelshare/json_templates/function/policy.txt +1 -0
- aimodelshare/json_templates/function/role.txt +1 -0
- aimodelshare/json_templates/integration_response.txt +5 -0
- aimodelshare/json_templates/lambda_policy_1.txt +15 -0
- aimodelshare/json_templates/lambda_policy_2.txt +8 -0
- aimodelshare/json_templates/lambda_role_1.txt +12 -0
- aimodelshare/json_templates/lambda_role_2.txt +16 -0
- aimodelshare/leaderboard.py +174 -0
- aimodelshare/main/1.txt +132 -0
- aimodelshare/main/1B.txt +112 -0
- aimodelshare/main/2.txt +153 -0
- aimodelshare/main/3.txt +134 -0
- aimodelshare/main/4.txt +128 -0
- aimodelshare/main/5.txt +109 -0
- aimodelshare/main/6.txt +105 -0
- aimodelshare/main/7.txt +144 -0
- aimodelshare/main/8.txt +142 -0
- aimodelshare/main/__init__.py +1 -0
- aimodelshare/main/authorization.txt +275 -0
- aimodelshare/main/eval_classification.txt +79 -0
- aimodelshare/main/eval_lambda.txt +1709 -0
- aimodelshare/main/eval_regression.txt +80 -0
- aimodelshare/main/lambda_function.txt +8 -0
- aimodelshare/main/nst.txt +149 -0
- aimodelshare/model.py +1543 -0
- aimodelshare/modeluser.py +215 -0
- aimodelshare/moral_compass/README.md +408 -0
- aimodelshare/moral_compass/__init__.py +65 -0
- aimodelshare/moral_compass/_version.py +3 -0
- aimodelshare/moral_compass/api_client.py +601 -0
- aimodelshare/moral_compass/apps/__init__.py +69 -0
- aimodelshare/moral_compass/apps/ai_consequences.py +540 -0
- aimodelshare/moral_compass/apps/bias_detective.py +714 -0
- aimodelshare/moral_compass/apps/ethical_revelation.py +898 -0
- aimodelshare/moral_compass/apps/fairness_fixer.py +889 -0
- aimodelshare/moral_compass/apps/judge.py +888 -0
- aimodelshare/moral_compass/apps/justice_equity_upgrade.py +853 -0
- aimodelshare/moral_compass/apps/mc_integration_helpers.py +820 -0
- aimodelshare/moral_compass/apps/model_building_game.py +1104 -0
- aimodelshare/moral_compass/apps/model_building_game_beginner.py +687 -0
- aimodelshare/moral_compass/apps/moral_compass_challenge.py +858 -0
- aimodelshare/moral_compass/apps/session_auth.py +254 -0
- aimodelshare/moral_compass/apps/shared_activity_styles.css +349 -0
- aimodelshare/moral_compass/apps/tutorial.py +481 -0
- aimodelshare/moral_compass/apps/what_is_ai.py +853 -0
- aimodelshare/moral_compass/challenge.py +365 -0
- aimodelshare/moral_compass/config.py +187 -0
- aimodelshare/placeholders/model.onnx +0 -0
- aimodelshare/placeholders/preprocessor.zip +0 -0
- aimodelshare/playground.py +1968 -0
- aimodelshare/postprocessormodules.py +157 -0
- aimodelshare/preprocessormodules.py +373 -0
- aimodelshare/pyspark/1.txt +195 -0
- aimodelshare/pyspark/1B.txt +181 -0
- aimodelshare/pyspark/2.txt +220 -0
- aimodelshare/pyspark/3.txt +204 -0
- aimodelshare/pyspark/4.txt +187 -0
- aimodelshare/pyspark/5.txt +178 -0
- aimodelshare/pyspark/6.txt +174 -0
- aimodelshare/pyspark/7.txt +211 -0
- aimodelshare/pyspark/8.txt +206 -0
- aimodelshare/pyspark/__init__.py +1 -0
- aimodelshare/pyspark/authorization.txt +258 -0
- aimodelshare/pyspark/eval_classification.txt +79 -0
- aimodelshare/pyspark/eval_lambda.txt +1441 -0
- aimodelshare/pyspark/eval_regression.txt +80 -0
- aimodelshare/pyspark/lambda_function.txt +8 -0
- aimodelshare/pyspark/nst.txt +213 -0
- aimodelshare/python/my_preprocessor.py +58 -0
- aimodelshare/readme.md +26 -0
- aimodelshare/reproducibility.py +181 -0
- aimodelshare/sam/Dockerfile.txt +8 -0
- aimodelshare/sam/Dockerfile_PySpark.txt +24 -0
- aimodelshare/sam/__init__.py +1 -0
- aimodelshare/sam/buildspec.txt +11 -0
- aimodelshare/sam/codebuild_policies.txt +129 -0
- aimodelshare/sam/codebuild_trust_relationship.txt +12 -0
- aimodelshare/sam/codepipeline_policies.txt +173 -0
- aimodelshare/sam/codepipeline_trust_relationship.txt +12 -0
- aimodelshare/sam/spark-class.txt +2 -0
- aimodelshare/sam/template.txt +54 -0
- aimodelshare/tools.py +103 -0
- aimodelshare/utils/__init__.py +78 -0
- aimodelshare/utils/optional_deps.py +38 -0
- aimodelshare/utils.py +57 -0
- aimodelshare-0.3.7.dist-info/METADATA +298 -0
- aimodelshare-0.3.7.dist-info/RECORD +171 -0
- aimodelshare-0.3.7.dist-info/WHEEL +5 -0
- aimodelshare-0.3.7.dist-info/licenses/LICENSE +5 -0
- aimodelshare-0.3.7.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#Text Classification Prediction Runtime Code
|
|
2
|
+
|
|
3
|
+
import boto3
|
|
4
|
+
import pandas as pd
|
|
5
|
+
import os
|
|
6
|
+
from io import BytesIO
|
|
7
|
+
import pickle
|
|
8
|
+
import numpy as np
|
|
9
|
+
import json
|
|
10
|
+
import onnxruntime as rt
|
|
11
|
+
import warnings
|
|
12
|
+
import six
|
|
13
|
+
|
|
14
|
+
def get_model_onnx(runtimemodel_s3_filename="runtime_model.onnx"):
|
|
15
|
+
s3 = boto3.resource('s3')
|
|
16
|
+
obj = s3.Object("$bucket_name", "$unique_model_id" +
|
|
17
|
+
"/runtime_model.onnx")
|
|
18
|
+
model = rt.InferenceSession(obj.get()['Body'].read())
|
|
19
|
+
return model
|
|
20
|
+
|
|
21
|
+
def _get_pyspark_modules():
|
|
22
|
+
import pyspark
|
|
23
|
+
import pyspark.ml
|
|
24
|
+
import re
|
|
25
|
+
|
|
26
|
+
pyspark_modules = ['ml', 'ml.feature', 'ml.classification', 'ml.clustering', 'ml.regression']
|
|
27
|
+
|
|
28
|
+
models_modules_dict = {}
|
|
29
|
+
|
|
30
|
+
for i in pyspark_modules:
|
|
31
|
+
models_list = [j for j in dir(eval('pyspark.'+i, {'pyspark': pyspark})) if callable(getattr(eval('pyspark.'+i, {'pyspark': pyspark}), j))]
|
|
32
|
+
models_list = [j for j in models_list if re.match('^[A-Z]', j)]
|
|
33
|
+
|
|
34
|
+
for k in models_list:
|
|
35
|
+
models_modules_dict[k] = 'pyspark.'+i
|
|
36
|
+
|
|
37
|
+
return models_modules_dict
|
|
38
|
+
|
|
39
|
+
def pyspark_model_from_string(model_type):
|
|
40
|
+
import importlib
|
|
41
|
+
|
|
42
|
+
models_modules_dict = _get_pyspark_modules()
|
|
43
|
+
module = models_modules_dict[model_type]
|
|
44
|
+
model_class = getattr(importlib.import_module(module), model_type)
|
|
45
|
+
return model_class
|
|
46
|
+
|
|
47
|
+
def get_preprocessor(preprocessor_s3_filename="runtime_preprocessor.zip"):
|
|
48
|
+
import os
|
|
49
|
+
import pickle
|
|
50
|
+
import tempfile
|
|
51
|
+
from io import BytesIO
|
|
52
|
+
from pathlib import Path
|
|
53
|
+
from zipfile import ZipFile
|
|
54
|
+
|
|
55
|
+
#create temporary folder
|
|
56
|
+
temp_dir = tempfile.gettempdir()
|
|
57
|
+
|
|
58
|
+
# there are some other zip files on temp_dir that might affect import process
|
|
59
|
+
temp_dir = os.path.join(temp_dir, "$unique_model_id")
|
|
60
|
+
os.makedirs(temp_dir, exist_ok=True)
|
|
61
|
+
|
|
62
|
+
s3 = boto3.resource("s3")
|
|
63
|
+
bucket = s3.Bucket("$bucket_name")
|
|
64
|
+
|
|
65
|
+
zip_obj = s3.Object(bucket_name="$bucket_name",
|
|
66
|
+
key="$unique_model_id/runtime_preprocessor.zip")
|
|
67
|
+
buffer = BytesIO(zip_obj.get()["Body"].read())
|
|
68
|
+
z = ZipFile(buffer)
|
|
69
|
+
# Extract all the contents of zip file in temp directory
|
|
70
|
+
z.extractall(temp_dir)
|
|
71
|
+
|
|
72
|
+
# Then import all pkl files you want from bucket (need to generate this list from
|
|
73
|
+
# function globals
|
|
74
|
+
pickle_file_list = []
|
|
75
|
+
zip_file_list = []
|
|
76
|
+
for file in os.listdir(temp_dir):
|
|
77
|
+
if file.endswith(".pkl"):
|
|
78
|
+
pickle_file_list.append(os.path.join(temp_dir, file))
|
|
79
|
+
if file.endswith(".zip"):
|
|
80
|
+
zip_file_list.append(os.path.join(temp_dir, file))
|
|
81
|
+
|
|
82
|
+
for i in pickle_file_list:
|
|
83
|
+
objectname = str(os.path.basename(i)).replace(".pkl", "")
|
|
84
|
+
objects = { objectname: "" }
|
|
85
|
+
globals()[objectname] = pickle.load(open(str(i), "rb"))
|
|
86
|
+
|
|
87
|
+
# Need spark session and context to instantiate model object
|
|
88
|
+
# zip_file_list is only used by pyspark
|
|
89
|
+
if len(zip_file_list):
|
|
90
|
+
from pyspark.sql import SparkSession
|
|
91
|
+
|
|
92
|
+
spark = SparkSession \
|
|
93
|
+
.builder \
|
|
94
|
+
.appName('Pyspark Model') \
|
|
95
|
+
.getOrCreate()
|
|
96
|
+
|
|
97
|
+
for i in zip_file_list:
|
|
98
|
+
objectnames = str(os.path.basename(i)).replace(".zip", "").split("__")
|
|
99
|
+
dir_path = i.replace(".zip", "")
|
|
100
|
+
Path(dir_path).mkdir(parents=True, exist_ok=True)
|
|
101
|
+
|
|
102
|
+
# Create a ZipFile Object and load module.zip in it
|
|
103
|
+
with ZipFile(i, 'r') as zipObj:
|
|
104
|
+
# Extract all the contents of zip file in current directory
|
|
105
|
+
zipObj.extractall(dir_path)
|
|
106
|
+
|
|
107
|
+
preprocessor_type = objectnames[0].split("_")[0]
|
|
108
|
+
objectname = objectnames[1]
|
|
109
|
+
preprocessor_class = pyspark_model_from_string(preprocessor_type)
|
|
110
|
+
if preprocessor_type == "PipelineModel":
|
|
111
|
+
print(preprocessor_class)
|
|
112
|
+
preprocessor_model = preprocessor_class(stages=None)
|
|
113
|
+
else:
|
|
114
|
+
preprocessor_model = preprocessor_class()
|
|
115
|
+
|
|
116
|
+
preprocessor_model = preprocessor_model.load(dir_path)
|
|
117
|
+
globals()[objectname] = preprocessor_model
|
|
118
|
+
|
|
119
|
+
# First import preprocessor function to session from preprocessor.py
|
|
120
|
+
exec(open(os.path.join(temp_dir, 'preprocessor.py')).read(),globals())
|
|
121
|
+
return preprocessor
|
|
122
|
+
|
|
123
|
+
def get_runtimedata(runtimedata_s3_filename="runtime_data.json"):
|
|
124
|
+
|
|
125
|
+
s3 = boto3.resource('s3')
|
|
126
|
+
obj = s3.Object("$bucket_name", "$unique_model_id"+"/"+runtimedata_s3_filename)
|
|
127
|
+
runtime_data = json.load(obj.get()['Body'])
|
|
128
|
+
|
|
129
|
+
return runtime_data
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
runtime_data=get_runtimedata(runtimedata_s3_filename="runtime_data.json")
|
|
133
|
+
|
|
134
|
+
preprocessor_type=runtime_data["runtime_preprocessor"]
|
|
135
|
+
|
|
136
|
+
runtime_model=runtime_data["runtime_model"]["name"]
|
|
137
|
+
|
|
138
|
+
# Load model
|
|
139
|
+
model=get_model_onnx(runtimemodel_s3_filename='runtime_model.onnx')
|
|
140
|
+
|
|
141
|
+
# Load preprocessor
|
|
142
|
+
preprocessor=get_preprocessor(preprocessor_s3_filename="runtime_preprocessor.zip")
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def predict(event,model,preprocessor):
|
|
146
|
+
body = event["body"]
|
|
147
|
+
if isinstance(event["body"], six.string_types):
|
|
148
|
+
body = json.loads(event["body"])
|
|
149
|
+
print(body["data"])
|
|
150
|
+
bodynew = pd.Series(body["data"])
|
|
151
|
+
else:
|
|
152
|
+
print(body["data"])
|
|
153
|
+
bodynew = pd.Series(body["data"])
|
|
154
|
+
print(bodynew)
|
|
155
|
+
|
|
156
|
+
sess=model
|
|
157
|
+
def predict_classes(x): # adjusted from keras github code
|
|
158
|
+
proba=x
|
|
159
|
+
if proba.shape[-1] > 1:
|
|
160
|
+
return proba.argmax(axis=-1)
|
|
161
|
+
else:
|
|
162
|
+
return (proba > 0.5).astype("int32")
|
|
163
|
+
input_name = sess.get_inputs()[0].name
|
|
164
|
+
|
|
165
|
+
input_data = preprocessor(bodynew).astype(np.float32) #needs to be float32
|
|
166
|
+
|
|
167
|
+
res = sess.run(None, {input_name: input_data})
|
|
168
|
+
prob = res[0]
|
|
169
|
+
print(prob)
|
|
170
|
+
try:
|
|
171
|
+
prediction_index=predict_classes(prob)
|
|
172
|
+
def index_to_label(labels,index_n):
|
|
173
|
+
return labels[index_n]
|
|
174
|
+
labels=$labels
|
|
175
|
+
result=list(map(lambda x: labels[x], prediction_index))
|
|
176
|
+
except:
|
|
177
|
+
result=prob.tolist()
|
|
178
|
+
|
|
179
|
+
# pyspark returns np.longlong which is not json serializable.
|
|
180
|
+
if len(result) and type(result[0]) == np.longlong:
|
|
181
|
+
result = [int(x) for x in result]
|
|
182
|
+
|
|
183
|
+
return result
|
|
184
|
+
|
|
185
|
+
def handler(event, context):
|
|
186
|
+
result = predict(event,model,preprocessor)
|
|
187
|
+
return {"statusCode": 200,
|
|
188
|
+
"headers": {
|
|
189
|
+
"Access-Control-Allow-Origin" : "*",
|
|
190
|
+
"Access-Control-Allow-Credentials": True,
|
|
191
|
+
"Allow" : "GET, OPTIONS, POST",
|
|
192
|
+
"Access-Control-Allow-Methods" : "GET, OPTIONS, POST",
|
|
193
|
+
"Access-Control-Allow-Headers" : "*"
|
|
194
|
+
},
|
|
195
|
+
"body": json.dumps(result)}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#Text Regression Prediction Runtime Code
|
|
2
|
+
|
|
3
|
+
import boto3
|
|
4
|
+
import pandas as pd
|
|
5
|
+
import os
|
|
6
|
+
from io import BytesIO
|
|
7
|
+
import pickle
|
|
8
|
+
import numpy as np
|
|
9
|
+
import json
|
|
10
|
+
import onnxruntime as rt
|
|
11
|
+
import warnings
|
|
12
|
+
import six
|
|
13
|
+
|
|
14
|
+
def get_model_onnx(runtimemodel_s3_filename="runtime_model.onnx"):
|
|
15
|
+
s3 = boto3.resource('s3')
|
|
16
|
+
obj = s3.Object("$bucket_name", "$unique_model_id" +
|
|
17
|
+
"/runtime_model.onnx")
|
|
18
|
+
model = rt.InferenceSession(obj.get()['Body'].read())
|
|
19
|
+
return model
|
|
20
|
+
|
|
21
|
+
def _get_pyspark_modules():
|
|
22
|
+
import pyspark
|
|
23
|
+
import pyspark.ml
|
|
24
|
+
import re
|
|
25
|
+
|
|
26
|
+
pyspark_modules = ['ml', 'ml.feature', 'ml.classification', 'ml.clustering', 'ml.regression']
|
|
27
|
+
|
|
28
|
+
models_modules_dict = {}
|
|
29
|
+
|
|
30
|
+
for i in pyspark_modules:
|
|
31
|
+
models_list = [j for j in dir(eval('pyspark.'+i, {'pyspark': pyspark})) if callable(getattr(eval('pyspark.'+i, {'pyspark': pyspark}), j))]
|
|
32
|
+
models_list = [j for j in models_list if re.match('^[A-Z]', j)]
|
|
33
|
+
|
|
34
|
+
for k in models_list:
|
|
35
|
+
models_modules_dict[k] = 'pyspark.'+i
|
|
36
|
+
|
|
37
|
+
return models_modules_dict
|
|
38
|
+
|
|
39
|
+
def pyspark_model_from_string(model_type):
|
|
40
|
+
import importlib
|
|
41
|
+
|
|
42
|
+
models_modules_dict = _get_pyspark_modules()
|
|
43
|
+
module = models_modules_dict[model_type]
|
|
44
|
+
model_class = getattr(importlib.import_module(module), model_type)
|
|
45
|
+
return model_class
|
|
46
|
+
|
|
47
|
+
def get_preprocessor(preprocessor_s3_filename="runtime_preprocessor.zip"):
|
|
48
|
+
import os
|
|
49
|
+
import pickle
|
|
50
|
+
import tempfile
|
|
51
|
+
from io import BytesIO
|
|
52
|
+
from pathlib import Path
|
|
53
|
+
from zipfile import ZipFile
|
|
54
|
+
|
|
55
|
+
#create temporary folder
|
|
56
|
+
temp_dir = tempfile.gettempdir()
|
|
57
|
+
|
|
58
|
+
# there are some other zip files on temp_dir that might affect import process
|
|
59
|
+
temp_dir = os.path.join(temp_dir, "$unique_model_id")
|
|
60
|
+
os.makedirs(temp_dir, exist_ok=True)
|
|
61
|
+
|
|
62
|
+
s3 = boto3.resource("s3")
|
|
63
|
+
bucket = s3.Bucket("$bucket_name")
|
|
64
|
+
|
|
65
|
+
zip_obj = s3.Object(bucket_name="$bucket_name",
|
|
66
|
+
key="$unique_model_id/runtime_preprocessor.zip")
|
|
67
|
+
buffer = BytesIO(zip_obj.get()["Body"].read())
|
|
68
|
+
z = ZipFile(buffer)
|
|
69
|
+
# Extract all the contents of zip file in temp directory
|
|
70
|
+
z.extractall(temp_dir)
|
|
71
|
+
|
|
72
|
+
# Then import all pkl files you want from bucket (need to generate this list from
|
|
73
|
+
# function globals
|
|
74
|
+
pickle_file_list = []
|
|
75
|
+
zip_file_list = []
|
|
76
|
+
for file in os.listdir(temp_dir):
|
|
77
|
+
if file.endswith(".pkl"):
|
|
78
|
+
pickle_file_list.append(os.path.join(temp_dir, file))
|
|
79
|
+
if file.endswith(".zip"):
|
|
80
|
+
zip_file_list.append(os.path.join(temp_dir, file))
|
|
81
|
+
|
|
82
|
+
for i in pickle_file_list:
|
|
83
|
+
objectname = str(os.path.basename(i)).replace(".pkl", "")
|
|
84
|
+
objects = { objectname: "" }
|
|
85
|
+
globals()[objectname] = pickle.load(open(str(i), "rb"))
|
|
86
|
+
|
|
87
|
+
# Need spark session and context to instantiate model object
|
|
88
|
+
# zip_file_list is only used by pyspark
|
|
89
|
+
if len(zip_file_list):
|
|
90
|
+
from pyspark.sql import SparkSession
|
|
91
|
+
|
|
92
|
+
spark = SparkSession \
|
|
93
|
+
.builder \
|
|
94
|
+
.appName('Pyspark Model') \
|
|
95
|
+
.getOrCreate()
|
|
96
|
+
|
|
97
|
+
for i in zip_file_list:
|
|
98
|
+
objectnames = str(os.path.basename(i)).replace(".zip", "").split("__")
|
|
99
|
+
dir_path = i.replace(".zip", "")
|
|
100
|
+
Path(dir_path).mkdir(parents=True, exist_ok=True)
|
|
101
|
+
|
|
102
|
+
# Create a ZipFile Object and load module.zip in it
|
|
103
|
+
with ZipFile(i, 'r') as zipObj:
|
|
104
|
+
# Extract all the contents of zip file in current directory
|
|
105
|
+
zipObj.extractall(dir_path)
|
|
106
|
+
|
|
107
|
+
preprocessor_type = objectnames[0].split("_")[0]
|
|
108
|
+
objectname = objectnames[1]
|
|
109
|
+
preprocessor_class = pyspark_model_from_string(preprocessor_type)
|
|
110
|
+
if preprocessor_type == "PipelineModel":
|
|
111
|
+
print(preprocessor_class)
|
|
112
|
+
preprocessor_model = preprocessor_class(stages=None)
|
|
113
|
+
else:
|
|
114
|
+
preprocessor_model = preprocessor_class()
|
|
115
|
+
|
|
116
|
+
preprocessor_model = preprocessor_model.load(dir_path)
|
|
117
|
+
globals()[objectname] = preprocessor_model
|
|
118
|
+
|
|
119
|
+
# First import preprocessor function to session from preprocessor.py
|
|
120
|
+
exec(open(os.path.join(temp_dir, 'preprocessor.py')).read(),globals())
|
|
121
|
+
return preprocessor
|
|
122
|
+
|
|
123
|
+
def get_runtimedata(runtimedata_s3_filename="runtime_data.json"):
|
|
124
|
+
|
|
125
|
+
s3 = boto3.resource('s3')
|
|
126
|
+
obj = s3.Object("$bucket_name", "$unique_model_id"+"/"+runtimedata_s3_filename)
|
|
127
|
+
runtime_data = json.load(obj.get()['Body'])
|
|
128
|
+
|
|
129
|
+
return runtime_data
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
runtime_data=get_runtimedata(runtimedata_s3_filename="runtime_data.json")
|
|
133
|
+
|
|
134
|
+
preprocessor_type=runtime_data["runtime_preprocessor"]
|
|
135
|
+
|
|
136
|
+
runtime_model=runtime_data["runtime_model"]["name"]
|
|
137
|
+
|
|
138
|
+
# Load model
|
|
139
|
+
model=get_model_onnx(runtimemodel_s3_filename='runtime_model.onnx')
|
|
140
|
+
|
|
141
|
+
# Load preprocessor
|
|
142
|
+
preprocessor=get_preprocessor(preprocessor_s3_filename="runtime_preprocessor.zip")
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def predict(event,model,preprocessor):
|
|
146
|
+
body = event["body"]
|
|
147
|
+
if isinstance(event["body"], six.string_types):
|
|
148
|
+
body = json.loads(event["body"])
|
|
149
|
+
print(body["data"])
|
|
150
|
+
bodynew = pd.Series(body["data"])
|
|
151
|
+
else:
|
|
152
|
+
print(body["data"])
|
|
153
|
+
bodynew = pd.Series(body["data"])
|
|
154
|
+
print(bodynew)
|
|
155
|
+
|
|
156
|
+
sess=model
|
|
157
|
+
def predict_classes(x): # adjusted from keras github code
|
|
158
|
+
proba=x
|
|
159
|
+
if proba.shape[-1] > 1:
|
|
160
|
+
return proba.argmax(axis=-1)
|
|
161
|
+
else:
|
|
162
|
+
return (proba > 0.5).astype("int32")
|
|
163
|
+
input_name = sess.get_inputs()[0].name
|
|
164
|
+
|
|
165
|
+
input_data = preprocessor(bodynew).astype(np.float32) #needs to be float32
|
|
166
|
+
|
|
167
|
+
res = sess.run(None, {input_name: input_data})
|
|
168
|
+
prob = res[0]
|
|
169
|
+
return prob.tolist()[0]
|
|
170
|
+
|
|
171
|
+
def handler(event, context):
|
|
172
|
+
result = predict(event,model,preprocessor)
|
|
173
|
+
return {"statusCode": 200,
|
|
174
|
+
"headers": {
|
|
175
|
+
"Access-Control-Allow-Origin" : "*",
|
|
176
|
+
"Access-Control-Allow-Credentials": True,
|
|
177
|
+
"Allow" : "GET, OPTIONS, POST",
|
|
178
|
+
"Access-Control-Allow-Methods" : "GET, OPTIONS, POST",
|
|
179
|
+
"Access-Control-Allow-Headers" : "*"
|
|
180
|
+
},
|
|
181
|
+
"body": json.dumps(result)}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#Image Classification Prediction Runtime Code
|
|
2
|
+
|
|
3
|
+
import boto3
|
|
4
|
+
import cv2
|
|
5
|
+
import os
|
|
6
|
+
import numpy as np
|
|
7
|
+
import json
|
|
8
|
+
import onnxruntime as rt
|
|
9
|
+
import base64
|
|
10
|
+
import imghdr
|
|
11
|
+
import six
|
|
12
|
+
from functools import partial
|
|
13
|
+
import os.path
|
|
14
|
+
from os import path
|
|
15
|
+
import pandas as pd
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_model_onnx(runtimemodel_s3_filename="runtime_model.onnx"):
|
|
19
|
+
s3 = boto3.resource('s3')
|
|
20
|
+
obj = s3.Object("$bucket_name", "$unique_model_id" +
|
|
21
|
+
"/runtime_model.onnx")
|
|
22
|
+
model = rt.InferenceSession(obj.get()['Body'].read())
|
|
23
|
+
return model
|
|
24
|
+
|
|
25
|
+
def _get_pyspark_modules():
|
|
26
|
+
import pyspark
|
|
27
|
+
import pyspark.ml
|
|
28
|
+
import re
|
|
29
|
+
|
|
30
|
+
pyspark_modules = ['ml', 'ml.feature', 'ml.classification', 'ml.clustering', 'ml.regression']
|
|
31
|
+
|
|
32
|
+
models_modules_dict = {}
|
|
33
|
+
|
|
34
|
+
for i in pyspark_modules:
|
|
35
|
+
models_list = [j for j in dir(eval('pyspark.'+i, {'pyspark': pyspark})) if callable(getattr(eval('pyspark.'+i, {'pyspark': pyspark}), j))]
|
|
36
|
+
models_list = [j for j in models_list if re.match('^[A-Z]', j)]
|
|
37
|
+
|
|
38
|
+
for k in models_list:
|
|
39
|
+
models_modules_dict[k] = 'pyspark.'+i
|
|
40
|
+
|
|
41
|
+
return models_modules_dict
|
|
42
|
+
|
|
43
|
+
def pyspark_model_from_string(model_type):
|
|
44
|
+
import importlib
|
|
45
|
+
|
|
46
|
+
models_modules_dict = _get_pyspark_modules()
|
|
47
|
+
module = models_modules_dict[model_type]
|
|
48
|
+
model_class = getattr(importlib.import_module(module), model_type)
|
|
49
|
+
return model_class
|
|
50
|
+
|
|
51
|
+
def get_preprocessor(preprocessor_s3_filename="runtime_preprocessor.zip"):
|
|
52
|
+
import os
|
|
53
|
+
import pickle
|
|
54
|
+
import tempfile
|
|
55
|
+
from io import BytesIO
|
|
56
|
+
from pathlib import Path
|
|
57
|
+
from zipfile import ZipFile
|
|
58
|
+
|
|
59
|
+
#create temporary folder
|
|
60
|
+
temp_dir = tempfile.gettempdir()
|
|
61
|
+
|
|
62
|
+
# there are some other zip files on temp_dir that might affect import process
|
|
63
|
+
temp_dir = os.path.join(temp_dir, "$unique_model_id")
|
|
64
|
+
os.makedirs(temp_dir, exist_ok=True)
|
|
65
|
+
|
|
66
|
+
s3 = boto3.resource("s3")
|
|
67
|
+
bucket = s3.Bucket("$bucket_name")
|
|
68
|
+
|
|
69
|
+
zip_obj = s3.Object(bucket_name="$bucket_name",
|
|
70
|
+
key="$unique_model_id/runtime_preprocessor.zip")
|
|
71
|
+
buffer = BytesIO(zip_obj.get()["Body"].read())
|
|
72
|
+
z = ZipFile(buffer)
|
|
73
|
+
# Extract all the contents of zip file in temp directory
|
|
74
|
+
z.extractall(temp_dir)
|
|
75
|
+
|
|
76
|
+
# Then import all pkl files you want from bucket (need to generate this list from
|
|
77
|
+
# function globals
|
|
78
|
+
pickle_file_list = []
|
|
79
|
+
zip_file_list = []
|
|
80
|
+
for file in os.listdir(temp_dir):
|
|
81
|
+
if file.endswith(".pkl"):
|
|
82
|
+
pickle_file_list.append(os.path.join(temp_dir, file))
|
|
83
|
+
if file.endswith(".zip"):
|
|
84
|
+
zip_file_list.append(os.path.join(temp_dir, file))
|
|
85
|
+
|
|
86
|
+
for i in pickle_file_list:
|
|
87
|
+
objectname = str(os.path.basename(i)).replace(".pkl", "")
|
|
88
|
+
objects = { objectname: "" }
|
|
89
|
+
globals()[objectname] = pickle.load(open(str(i), "rb"))
|
|
90
|
+
|
|
91
|
+
# Need spark session and context to instantiate model object
|
|
92
|
+
# zip_file_list is only used by pyspark
|
|
93
|
+
if len(zip_file_list):
|
|
94
|
+
from pyspark.sql import SparkSession
|
|
95
|
+
|
|
96
|
+
spark = SparkSession \
|
|
97
|
+
.builder \
|
|
98
|
+
.appName('Pyspark Model') \
|
|
99
|
+
.getOrCreate()
|
|
100
|
+
|
|
101
|
+
for i in zip_file_list:
|
|
102
|
+
objectnames = str(os.path.basename(i)).replace(".zip", "").split("__")
|
|
103
|
+
dir_path = i.replace(".zip", "")
|
|
104
|
+
Path(dir_path).mkdir(parents=True, exist_ok=True)
|
|
105
|
+
|
|
106
|
+
# Create a ZipFile Object and load module.zip in it
|
|
107
|
+
with ZipFile(i, 'r') as zipObj:
|
|
108
|
+
# Extract all the contents of zip file in current directory
|
|
109
|
+
zipObj.extractall(dir_path)
|
|
110
|
+
|
|
111
|
+
preprocessor_type = objectnames[0].split("_")[0]
|
|
112
|
+
objectname = objectnames[1]
|
|
113
|
+
preprocessor_class = pyspark_model_from_string(preprocessor_type)
|
|
114
|
+
if preprocessor_type == "PipelineModel":
|
|
115
|
+
print(preprocessor_class)
|
|
116
|
+
preprocessor_model = preprocessor_class(stages=None)
|
|
117
|
+
else:
|
|
118
|
+
preprocessor_model = preprocessor_class()
|
|
119
|
+
|
|
120
|
+
preprocessor_model = preprocessor_model.load(dir_path)
|
|
121
|
+
globals()[objectname] = preprocessor_model
|
|
122
|
+
|
|
123
|
+
# First import preprocessor function to session from preprocessor.py
|
|
124
|
+
exec(open(os.path.join(temp_dir, 'preprocessor.py')).read(),globals())
|
|
125
|
+
return preprocessor
|
|
126
|
+
|
|
127
|
+
def get_runtimedata(runtimedata_s3_filename="runtime_data.json"):
|
|
128
|
+
|
|
129
|
+
s3 = boto3.resource('s3')
|
|
130
|
+
obj = s3.Object("$bucket_name", "$unique_model_id"+"/"+runtimedata_s3_filename)
|
|
131
|
+
runtime_data = json.load(obj.get()['Body'])
|
|
132
|
+
|
|
133
|
+
return runtime_data
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
runtime_data=get_runtimedata(runtimedata_s3_filename="runtime_data.json")
|
|
137
|
+
|
|
138
|
+
preprocessor_type=runtime_data["runtime_preprocessor"]
|
|
139
|
+
|
|
140
|
+
runtime_model=runtime_data["runtime_model"]["name"]
|
|
141
|
+
|
|
142
|
+
model=get_model_onnx(runtimemodel_s3_filename='runtime_model.onnx')
|
|
143
|
+
|
|
144
|
+
# Load preprocessor
|
|
145
|
+
|
|
146
|
+
preprocessor=get_preprocessor(preprocessor_s3_filename="runtime_preprocessor.zip")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def predict(event,model,preprocessor):
|
|
150
|
+
|
|
151
|
+
labels=$labels
|
|
152
|
+
|
|
153
|
+
# Load base64 encoded image stored within "data" key of event dictionary
|
|
154
|
+
print(event["body"])
|
|
155
|
+
body = event["body"]
|
|
156
|
+
if isinstance(event["body"], six.string_types):
|
|
157
|
+
body = json.loads(event["body"])
|
|
158
|
+
|
|
159
|
+
bodydata=body["data"]
|
|
160
|
+
|
|
161
|
+
# Extract image file extension (e.g.-jpg, png, etc.)
|
|
162
|
+
sample = base64.decodebytes(bytearray(bodydata, "utf-8"))
|
|
163
|
+
|
|
164
|
+
for tf in imghdr.tests:
|
|
165
|
+
image_file_type = tf(sample, None)
|
|
166
|
+
if image_file_type:
|
|
167
|
+
break;
|
|
168
|
+
image_file_type=image_file_type
|
|
169
|
+
|
|
170
|
+
if(image_file_type==None):
|
|
171
|
+
print("This file is not an image, please submit an image base64 encoded image file.")
|
|
172
|
+
|
|
173
|
+
# Save image to local file, read into session, and preprocess image with preprocessor function
|
|
174
|
+
|
|
175
|
+
with open("/tmp/imagetopredict."+image_file_type, "wb") as fh:
|
|
176
|
+
fh.write(base64.b64decode(bodydata))
|
|
177
|
+
|
|
178
|
+
input_data = preprocessor("/tmp/imagetopredict."+image_file_type)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
# Generate prediction using preprocessed input data
|
|
182
|
+
print("The model expects input shape:", model.get_inputs()[0].shape)
|
|
183
|
+
|
|
184
|
+
input_name = model.get_inputs()[0].name
|
|
185
|
+
|
|
186
|
+
res = model.run(None, {input_name: input_data})
|
|
187
|
+
|
|
188
|
+
#extract predicted probability for all classes, extract predicted label
|
|
189
|
+
|
|
190
|
+
prob = res[0]
|
|
191
|
+
|
|
192
|
+
def predict_classes(x): # adjusted from keras github code
|
|
193
|
+
if len(x.shape)==2:
|
|
194
|
+
index = x.argmax(axis=-1)
|
|
195
|
+
return list(map(lambda x: labels[x], index))
|
|
196
|
+
else:
|
|
197
|
+
return list(x)
|
|
198
|
+
|
|
199
|
+
result=predict_classes(prob)
|
|
200
|
+
|
|
201
|
+
os.remove("/tmp/imagetopredict."+image_file_type)
|
|
202
|
+
|
|
203
|
+
# pyspark returns np.longlong which is not json serializable.
|
|
204
|
+
if len(result) and type(result[0]) == np.longlong:
|
|
205
|
+
result = [int(x) for x in result]
|
|
206
|
+
|
|
207
|
+
return result
|
|
208
|
+
|
|
209
|
+
def handler(event, context):
|
|
210
|
+
|
|
211
|
+
result = predict(event,model,preprocessor)
|
|
212
|
+
return {"statusCode": 200,
|
|
213
|
+
"headers": {
|
|
214
|
+
"Access-Control-Allow-Origin" : "*",
|
|
215
|
+
"Access-Control-Allow-Credentials": True,
|
|
216
|
+
"Allow" : "GET, OPTIONS, POST",
|
|
217
|
+
"Access-Control-Allow-Methods" : "GET, OPTIONS, POST",
|
|
218
|
+
"Access-Control-Allow-Headers" : "*"
|
|
219
|
+
},
|
|
220
|
+
"body" : json.dumps(result)}
|