-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLambda.py
130 lines (86 loc) · 4.29 KB
/
Lambda.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
"""
Lambda Function 1: serializeImageData
A lambda function that copies an object from S3, base64 encodes it, and
then return it (serialized data) to the step function as `image_data` in an event.
"""
import json
import boto3
import base64
# A low-level client representing Amazon Simple Storage Service (S3)
s3 = boto3.client('s3')
def lambda_handler(event, context):
"""A function to serialize target data from S3"""
# Get the s3 address from the Step Function event input (You may also check lambda test)
key = event['s3_key'] ## TODO: fill in
bucket = event['s3_bucket'] ## TODO: fill in
# Download the data from s3 to /tmp/image.png
## TODO: fill in
s3.download_file(bucket, key, "/tmp/image.png")
# We read the data from a file
with open("/tmp/image.png", "rb") as f: # Read binary file
image_data = base64.b64encode(f.read()) # Base64 encode binary data ('image_data' -> class:bytes)
# Pass the data back to the Step Function
print("Event:", event.keys())
return {
'statusCode': 200,
'body': {
"image_data": image_data, # Bytes data
"s3_bucket": bucket,
"s3_key": key,
"inferences": []
}
}
"""
Lambda Function 2: Image-Classification
A lambda function that is responsible for the classification part. It takes the image output from the
lambda 1 function, decodes it, and then pass inferences back to the the Step Function
"""
import json
import base64
import boto3
# Using low-level client representing Amazon SageMaker Runtime ( To invoke endpoint)
runtime_client = boto3.client('sagemaker-runtime')
# Fill this in with the name of your deployed model
ENDPOINT = "image-classification-2023-01-19-23-58-02-999" ## TODO: fill in (Trained IC Model Name)
def lambda_handler(event, context):
# Decode the image data
image = base64.b64decode(event['image_data']) ## TODO: fill in (Decoding the encoded 'Base64' image-data and class remains'bytes')
# Instantiate a Predictor (Here we have renamed 'Predictor' to 'response')
# Response after invoking a deployed endpoint via SageMaker Runtime
response = runtime_client.invoke_endpoint(
EndpointName=ENDPOINT, # Endpoint Name
Body=image, # Decoded Image Data as Input (class:'Bytes') Image Data
ContentType='image/png' # Type of inference input data - Content type (Eliminates the need of serializer)
)
# Make a prediction: Unpack reponse
# (NOTE: 'response' returns a dictionary with inferences in the "Body" : (StreamingBody needs to be read) having Content_type='string')
## TODO: fill in (Read and decode predictions/inferences to 'utf-8' & convert JSON string obj -> Python object)
inferences = json.loads(response['Body'].read().decode('utf-8')) # list
# We return the data back to the Step Function
event['inferences'] = inferences ## List of predictions
return {
'statusCode': 200,
'body': event ## Passing the event python dictionary in the body
}
"""
Lambda Function 3: Filter-Low-Confidence-Inferences
A lambda function that takes the inferences from the Lambda 2 function output and filters low-confidence inferences
(above a certain threshold indicating success)
"""
import json
THRESHOLD = 0.70
def lambda_handler(event, context):
# Grab the inferences from the event
inferences = event['inferences'] ## TODO: fill in
# Check if any values in our inferences are above THRESHOLD
meets_threshold = max(list(inferences))>THRESHOLD ## TODO: fill in (True, if a value exists above 'THRESHOLD')
# If our threshold is met, pass our data back out of the
# Step Function, else, end the Step Function with an error
if meets_threshold:
pass
else:
raise Exception("THRESHOLD_CONFIDENCE_NOT_MET")
return {
'statusCode': 200,
'body': event ## Passing the final event as a python dictionary
}