<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Cifar10 Outlier Detection
In this example we will deploy an image classification model along with an outlier detector trained on the same dataset. For in depth details on creating an outlier detection model for your own dataset see the alibi-detect project and associated documentation. You can find details for this CIFAR10 example in their documentation as well.
Prequisites
Step1:  Setup Resources
Step2:  Create the Kfserving image classification model for Cifar10. We add in a logger for requests.
Step3:  Create the pretrained VAE Cifar10 Outlier Detector. We forward replies to the event-display we started.
Step4:  Create a Knative trigger to forward logging events to our Outlier Detector.
Step5:  Get the IP address of the Istio Ingress Gateway. This assumes you have installed istio with a LoadBalancer.
Step6:  If you are using Kind or Minikube you will need to port-forward to the istio ingressgateway and uncomment the following cell.
INGRESS_GATEWAY_SERVICE=$(kubectl get svc --namespace istio-system --selector="app=istio-ingressgateway" --output jsonpath='{.items[0].metadata.name}')
kubectl port-forward --namespace istio-system svc/${INGRESS_GATEWAY_SERVICE} 8080
Step7:  Normal Prediction
Step8:  After a few seconds you can check the event display for an outlier detection prediction. This should be false.
Step9:  Outlier Prediction
Step10:  Now lets check the event display for a new message. This should show we have found an outlier.
Step11:  We will now call our outlier detector directly and ask for the feature scores to gain more information about why it predicted this instance was an outlier.
Step12:  We now plot those feature scores returned by the outlier detector along with our original image.
Step13:  Tear Down
<ASSISTANT_TASK:>
Python Code:
!pip install -r requirements_notebook.txt
Explanation: Cifar10 Outlier Detection
In this example we will deploy an image classification model along with an outlier detector trained on the same dataset. For in depth details on creating an outlier detection model for your own dataset see the alibi-detect project and associated documentation. You can find details for this CIFAR10 example in their documentation as well.
Prequisites:
Running cluster with 
kfserving installed
Knative eventing installed >= 0.18
Tested on GKE and Kind with Knative 0.18 and Istio 1.7.3
End of explanation
!kubectl create namespace cifar10
%%writefile broker.yaml
apiVersion: eventing.knative.dev/v1
kind: broker
metadata:
 name: default
 namespace: cifar10
!kubectl create -f broker.yaml
%%writefile event-display.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-display
  namespace: cifar10
spec:
  replicas: 1
  selector:
    matchLabels: &labels
      app: hello-display
  template:
    metadata:
      labels: *labels
    spec:
      containers:
        - name: event-display
          image: gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display
---
kind: Service
apiVersion: v1
metadata:
  name: hello-display
  namespace: cifar10
spec:
  selector:
    app: hello-display
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
!kubectl apply -f event-display.yaml
Explanation: Setup Resources
End of explanation
%%writefile cifar10.yaml
apiVersion: "serving.kubeflow.org/v1alpha2"
kind: "InferenceService"
metadata:
  name: "tfserving-cifar10"
  namespace: cifar10
spec:
  default:
    predictor:
      tensorflow:
        storageUri: "gs://kfserving-samples/tfserving/cifar10/resnet32"
      logger:
        mode: all
        url: http://broker-ingress.knative-eventing.svc.cluster.local/cifar10/default
!kubectl apply -f cifar10.yaml
Explanation: Create the Kfserving image classification model for Cifar10. We add in a logger for requests.
End of explanation
%%writefile cifar10od.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: vae-outlier
  namespace: cifar10
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/minScale: "1"
    spec:
      containers:
      - image: seldonio/alibi-detect-server:0.0.2
        imagePullPolicy: IfNotPresent
        args:
        - --model_name
        - cifar10od
        - --http_port
        - '8080'
        - --protocol
        - tensorflow.http
        - --storage_uri
        - gs://seldon-models/alibi-detect/od/OutlierVAE/cifar10
        - --reply_url
        - http://hello-display.cifar10
        - --event_type
        - org.kubeflow.serving.inference.outlier
        - --event_source
        - org.kubeflow.serving.cifar10od
        - OutlierDetector
!kubectl apply -f cifar10od.yaml
Explanation: Create the pretrained VAE Cifar10 Outlier Detector. We forward replies to the event-display we started.
End of explanation
%%writefile trigger.yaml
apiVersion: eventing.knative.dev/v1
kind: Trigger
metadata:
  name: vaeoutlier-trigger
  namespace: cifar10
spec:
  broker: default
  filter:
    attributes:
      type: org.kubeflow.serving.inference.request
  subscriber:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: vae-outlier
      namespace: cifar10
!kubectl apply -f trigger.yaml
Explanation: Create a Knative trigger to forward logging events to our Outlier Detector.
End of explanation
CLUSTER_IPS=!(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
CLUSTER_IP=CLUSTER_IPS[0]
print(CLUSTER_IP)
Explanation: Get the IP address of the Istio Ingress Gateway. This assumes you have installed istio with a LoadBalancer.
End of explanation
#CLUSTER_IP="localhost:8080"
SERVICE_HOSTNAMES=!(kubectl get inferenceservice -n cifar10 tfserving-cifar10 -o jsonpath='{.status.url}' | cut -d "/" -f 3)
SERVICE_HOSTNAME_CIFAR10=SERVICE_HOSTNAMES[0]
print(SERVICE_HOSTNAME_CIFAR10)
SERVICE_HOSTNAMES=!(kubectl get ksvc -n cifar10 vae-outlier -o jsonpath='{.status.url}' | cut -d "/" -f 3)
SERVICE_HOSTNAME_VAEOD=SERVICE_HOSTNAMES[0]
print(SERVICE_HOSTNAME_VAEOD)
import matplotlib.pyplot as plt
import numpy as np
import json
import tensorflow as tf
tf.keras.backend.clear_session()
from alibi_detect.od.vae import OutlierVAE
from alibi_detect.utils.perturbation import apply_mask
from alibi_detect.utils.visualize import plot_feature_outlier_image
import requests
train, test = tf.keras.datasets.cifar10.load_data()
X_train, y_train = train
X_test, y_test = test
X_train = X_train.astype('float32') / 255
X_test = X_test.astype('float32') / 255
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)
classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
def show(X):
    plt.imshow(X.reshape(32, 32, 3))
    plt.axis('off')
    plt.show()
def predict(X):
    formData = {
    'instances': X.tolist()
    }
    headers = {}
    headers["Host"] = SERVICE_HOSTNAME_CIFAR10
    res = requests.post('http://'+CLUSTER_IP+'/v1/models/tfserving-cifar10:predict', json=formData, headers=headers)
    if res.status_code == 200:
        return classes[np.array(res.json()["predictions"])[0].argmax()]
    else:
        print("Failed with ",res.status_code)
        return []
    
def outlier(X):
    formData = {
    'instances': X.tolist()
    }
    headers = {"Alibi-Detect-Return-Feature-Score":"true","Alibi-Detect-Return-Instance-Score":"true", \
                "ce-namespace": "default","ce-modelid":"cifar10","ce-type":"io.seldon.serving.inference.request", \
                "ce-id":"1234","ce-source":"localhost","ce-specversion":"1.0"}
    headers["Host"] = SERVICE_HOSTNAME_VAEOD
    res = requests.post('http://'+CLUSTER_IP+'/', json=formData, headers=headers)
    if res.status_code == 200:
        od = res.json()
        od["data"]["feature_score"] = np.array(od["data"]["feature_score"])
        od["data"]["instance_score"] = np.array(od["data"]["instance_score"])
        return od
    else:
        print("Failed with ",res.status_code)
        return []
Explanation: If you are using Kind or Minikube you will need to port-forward to the istio ingressgateway and uncomment the following cell.
INGRESS_GATEWAY_SERVICE=$(kubectl get svc --namespace istio-system --selector="app=istio-ingressgateway" --output jsonpath='{.items[0].metadata.name}')
kubectl port-forward --namespace istio-system svc/${INGRESS_GATEWAY_SERVICE} 8080:80
End of explanation
idx = 1
X = X_train[idx:idx+1]
show(X)
predict(X)
Explanation: Normal Prediction
End of explanation
res=!kubectl logs -n cifar10 $(kubectl get pod -n cifar10 -l app=hello-display -o jsonpath='{.items[0].metadata.name}') 
data= []
for i in range(0,len(res)):
    if res[i] == 'Data,':
        data.append(res[i+1])
j = json.loads(json.loads(data[-1]))
print("Outlier",j["data"]["is_outlier"]==[1])
Explanation: After a few seconds you can check the event display for an outlier detection prediction. This should be false.
End of explanation
np.random.seed(0) 
X_mask, mask = apply_mask(X.reshape(1, 32, 32, 3),
                                  mask_size=(10,10),
                                  n_masks=1,
                                  channels=[0,1,2],
                                  mask_type='normal',
                                  noise_distr=(0,1),
                                  clip_rng=(0,1))
show(X_mask)
predict(X_mask)
Explanation: Outlier Prediction
End of explanation
res=!kubectl logs -n cifar10 $(kubectl get pod -n cifar10 -l app=hello-display -o jsonpath='{.items[0].metadata.name}') 
data= []
for i in range(0,len(res)):
    if res[i] == 'Data,':
        data.append(res[i+1])
j = json.loads(json.loads(data[-1]))
print("Outlier",j["data"]["is_outlier"]==[1])
Explanation: Now lets check the event display for a new message. This should show we have found an outlier.
End of explanation
od_preds = outlier(X_mask)
Explanation: We will now call our outlier detector directly and ask for the feature scores to gain more information about why it predicted this instance was an outlier.
End of explanation
plot_feature_outlier_image(od_preds, 
                           X_mask, 
                           X_recon=None)
Explanation: We now plot those feature scores returned by the outlier detector along with our original image.
End of explanation
!kubectl delete ns cifar10
Explanation: Tear Down
End of explanation
<END_TASK>