<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Prerequisites
pip install clipper_admin==0.4.1 \
            keras==2.2.4 \
            tensorflow==1.13.1 \
            numpy==1.16.4 \
            pandas==0.24.2 \
            pillow==6.0.0
Load a pretrained Keras model(ResNet50)
Step1:  Initialize the Clipper cluster
Step2:  Define 'predict' function
Step3:  Deploy Keras model and 'predict' function to the Clipper cluster
Step4:  Download sample images
Step5:  Send some requests to the Clipper cluster
Step6:  First request, which is so slow due to downloading a file from https
Step7:  Second request, which is moderate!
Step8:  Clean-up
<ASSISTANT_TASK:>
Python Code:
from keras.applications.resnet50 import ResNet50
# https://keras.io/applications/#classify-imagenet-classes-with-resnet50
model = ResNet50(weights='imagenet')
Explanation: Prerequisites
pip install clipper_admin==0.4.1 \
            keras==2.2.4 \
            tensorflow==1.13.1 \
            numpy==1.16.4 \
            pandas==0.24.2 \
            pillow==6.0.0
Load a pretrained Keras model(ResNet50)
End of explanation
from clipper_admin import ClipperConnection, DockerContainerManager
clipper_conn = ClipperConnection(DockerContainerManager())
clipper_conn.start_clipper(cache_size=1)  # Disable PredictionCache
!docker ps -a
Explanation: Initialize the Clipper cluster
End of explanation
import io
import numpy as np
from PIL import Image
from keras.preprocessing.image import img_to_array
from keras.applications.resnet50 import preprocess_input, decode_predictions
    
def predict(model, inputs):
    def _predict_one(one_input_arr):
        try:
            image = Image.open(io.BytesIO(one_input_arr))
            if image.mode != "RGB":
                image = image.convert("RGB")
            image = image.resize((224, 224))
            image = img_to_array(image)
            image = np.expand_dims(image, axis=0)
            image = preprocess_input(image)
            return decode_predictions(preds=model.predict(image), top=3)[0]
        except Exception as e:
            print(e)
            return []
        
    return [_predict_one(i) for i in inputs]
Explanation: Define 'predict' function
End of explanation
import clipper_admin.deployers.keras as keras_deployer
app_name = 'keras-test-app'
model_name = 'keras-test-model'
keras_deployer.deploy_keras_model(clipper_conn=clipper_conn,
                                  name=model_name,
                                  version='1',
                                  input_type='bytes',
                                  func=predict,
                                  model_path_or_object=model,
                                  num_replicas=1,
                                  batch_size=1,  # Disable adaptive batching policy
                                  pkgs_to_install=['pillow'])
clipper_conn.register_application(name=app_name,
                                  input_type="bytes",
                                  default_output="-1.0",
                                  slo_micros=10000000)  # 10s
clipper_conn.link_model_to_app(app_name=app_name,
                               model_name=model_name)
import time
time.sleep(30)
Explanation: Deploy Keras model and 'predict' function to the Clipper cluster
End of explanation
!wget https://harishnarayanan.org/images/writing/artistic-style-transfer/output_13_0.png -O elephant.jpg
!wget http://kikei.github.io/images/plots/2018-08-05-rabbit2.jpg -O rabbit.jpg
from IPython.display import display
from PIL import Image
display(Image.open('elephant.jpg'))
display(Image.open('rabbit.jpg'))
Explanation: Download sample images
End of explanation
import json
import base64
import requests
from datetime import datetime
from keras.preprocessing import image
headers = {'Content-type': 'application/json'}
url = "http://{addr}/{app_name}/predict".format(
    addr=clipper_conn.get_query_addr(),
    app_name=app_name)
Explanation: Send some requests to the Clipper cluster
End of explanation
start = datetime.now()
req_json = json.dumps({ "input": base64.b64encode(open('elephant.jpg', "rb").read()).decode() })
r = requests.post(url, headers=headers, data=req_json)
end = datetime.now()
latency = (end - start).total_seconds() * 1000.0
print("'%s', %f ms" % (r.text, latency))
Explanation: First request, which is so slow due to downloading a file from https://storage.googleapis.com/download.tensorflow.org/data/imagenet_class_index.json.
End of explanation
start = datetime.now()
req_json = json.dumps({ "input": base64.b64encode(open('rabbit.jpg', "rb").read()).decode() })
r = requests.post(url, headers=headers, data=req_json)
end = datetime.now()
latency = (end - start).total_seconds() * 1000.0
print("'%s', %f ms" % (r.text, latency))
Explanation: Second request, which is moderate!
End of explanation
clipper_conn.stop_all()
!docker rm -f $(docker ps -a -q) && docker image prune -f
Explanation: Clean-up
End of explanation
<END_TASK>