This page was generated from examples/models/keras_mnist/keras_mnist.ipynb.

Keras MNIST Model DeploymentΒΆ

  • Wrap a Tensorflow MNIST python model for use as a prediction microservice in seldon-core
  • Run locally on Docker to test
  • Deploy on seldon-core running on minikube

DependenciesΒΆ

pip install seldon-core
pip install keras

Train locallyΒΆ

[1]:
import numpy as np
import math
import datetime
#from seldon.pipeline import PipelineSaver
import os
import tensorflow as tf
from keras import backend
from keras.models import Model,load_model
from keras.layers import Dense,Input
from keras.layers import Dropout
from keras.layers import Flatten, Reshape
from keras.constraints import maxnorm
from keras.layers.convolutional import Convolution2D
from keras.layers.convolutional import MaxPooling2D

from keras.callbacks import TensorBoard

class MnistFfnn(object):

    def __init__(self,
                 input_shape=(784,),
                 nb_labels=10,
                 optimizer='Adam',
                 run_dir='tensorboardlogs_test'):

        self.model_name='MnistFfnn'
        self.run_dir=run_dir
        self.input_shape=input_shape
        self.nb_labels=nb_labels
        self.optimizer=optimizer
        self.build_graph()

    def build_graph(self):

        inp = Input(shape=self.input_shape,name='input_part')

        #keras layers
        with tf.name_scope('dense_1') as scope:
            h1 = Dense(256,
                         activation='relu',
                         W_constraint=maxnorm(3))(inp)
            drop1 = Dropout(0.2)(h1)

        with tf.name_scope('dense_2') as scope:
            h2 = Dense(128,
                       activation='relu',
                       W_constraint=maxnorm(3))(drop1)
            drop2 = Dropout(0.5)(h2)

            out = Dense(self.nb_labels,
                        activation='softmax')(drop2)

        self.model = Model(inp,out)

        if self.optimizer ==  'rmsprop':
            self.model.compile(loss='categorical_crossentropy',
                               optimizer='rmsprop',
                               metrics=['accuracy'])
        elif self.optimizer == 'Adam':
            self.model.compile(loss='categorical_crossentropy',
                               optimizer='Adam',
                               metrics=['accuracy'])

        print('graph builded')

    def fit(self,X,y=None,
            X_test=None,y_test=None,
            batch_size=128,
            nb_epochs=2,
            shuffle=True):

        now = datetime.datetime.now()
        tensorboard_logname = self.run_dir+'/{}_{}'.format(self.model_name,
                                                           now.strftime('%Y.%m.%d_%H.%M'))
        tensorboard = TensorBoard(log_dir=tensorboard_logname)

        self.model.fit(X,y,
                       validation_data=(X_test,y_test),
                       callbacks=[tensorboard],
                       batch_size=batch_size,
                       nb_epoch=nb_epochs,
                       shuffle = shuffle)
        return self

    def predict_proba(self,X):

        return self.model.predict_proba(X)

    def predict(self, X):
        probas = self.model.predict_proba(X)
        return([[p>0.5 for p in p1] for p1 in probas])

    def score(self, X, y=None):
        pass

    def get_class_id_map(self):
        return ["proba"]

class MnistConv(object):

    def __init__(self,
                 input_shape=(784,),
                 nb_labels=10,
                 optimizer='Adam',
                 run_dir='tensorboardlogs_test',
                 saved_model_file='MnistClassifier.h5'):

        self.model_name='MnistConv'
        self.run_dir=run_dir
        self.input_shape=input_shape
        self.nb_labels=nb_labels
        self.optimizer=optimizer
        self.saved_model_file=saved_model_file
        self.build_graph()

    def build_graph(self):

        inp = Input(shape=self.input_shape,name='input_part')
        inp2 = Reshape((28,28,1))(inp)
        #keras layers
        with tf.name_scope('conv') as scope:
            conv = Convolution2D(32, 3, 3,
                                 input_shape=(32, 32, 3),
                                 border_mode='same',
                                 activation='relu',
                                 W_constraint=maxnorm(3))(inp2)
            drop_conv = Dropout(0.2)(conv)
            max_pool = MaxPooling2D(pool_size=(2, 2))(drop_conv)

        with tf.name_scope('dense') as scope:
            flat = Flatten()(max_pool)
            dense = Dense(128,
                          activation='relu',
                          W_constraint=maxnorm(3))(flat)
            drop_dense = Dropout(0.5)(dense)

            out = Dense(self.nb_labels,
                        activation='softmax')(drop_dense)

        self.model = Model(inp,out)

        if self.optimizer ==  'rmsprop':
            self.model.compile(loss='categorical_crossentropy',
                               optimizer='rmsprop',
                               metrics=['accuracy'])
        elif self.optimizer == 'Adam':
            self.model.compile(loss='categorical_crossentropy',
                               optimizer='Adam',
                               metrics=['accuracy'])

        print('graph builded')

    def fit(self,X,y=None,
            X_test=None,y_test=None,
            batch_size=128,
            nb_epochs=2,
            shuffle=True):

        now = datetime.datetime.now()
        tensorboard_logname = self.run_dir+'/{}_{}'.format(self.model_name,
                                                           now.strftime('%Y.%m.%d_%H.%M'))
        tensorboard = TensorBoard(log_dir=tensorboard_logname)

        self.model.fit(X,y,
                       validation_data=(X_test,y_test),
                       callbacks=[tensorboard],
                       batch_size=batch_size,
                       nb_epoch=nb_epochs,
                       shuffle = shuffle)
        #if not os.path.exists('saved_model'):
        #    os.makedirs('saved_model')
        self.model.save(self.saved_model_file)
        return self

    def predict_proba(self,X):
        return self.model.predict_proba(X)

    def predict(self, X):
        probas = self.model.predict_proba(X)
        return([[p>0.5 for p in p1] for p1 in probas])

    def score(self, X, y=None):
        pass

    def get_class_id_map(self):
        return ["proba"]


Using TensorFlow backend.
[2]:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('data/MNIST_data', one_hot=True)
X_train = mnist.train.images
y_train = mnist.train.labels
X_test = mnist.test.images
y_test = mnist.test.labels
mc = MnistConv()
mc.fit(X_train,y=y_train,
    X_test=X_test,y_test=y_test)


WARNING:tensorflow:From <ipython-input-2-dac8c42b25f0>:2: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use alternatives such as official/mnist/dataset.py from tensorflow/models.
WARNING:tensorflow:From /home/clive/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.
Instructions for updating:
Please write your own downloading logic.
WARNING:tensorflow:From /home/clive/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use tf.data to implement this functionality.
Extracting data/MNIST_data/train-images-idx3-ubyte.gz
WARNING:tensorflow:From /home/clive/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use tf.data to implement this functionality.
Extracting data/MNIST_data/train-labels-idx1-ubyte.gz
WARNING:tensorflow:From /home/clive/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:110: dense_to_one_hot (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use tf.one_hot on tensors.
Extracting data/MNIST_data/t10k-images-idx3-ubyte.gz
Extracting data/MNIST_data/t10k-labels-idx1-ubyte.gz
WARNING:tensorflow:From /home/clive/anaconda3/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.
Instructions for updating:
Please use alternatives such as official/mnist/dataset.py from tensorflow/models.
/home/clive/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:126: UserWarning: Update your `Conv2D` call to the Keras 2 API: `Conv2D(32, (3, 3), input_shape=(32, 32, 3..., activation="relu", padding="same", kernel_constraint=<keras.con...)`
/home/clive/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:134: UserWarning: Update your `Dense` call to the Keras 2 API: `Dense(128, activation="relu", kernel_constraint=<keras.con...)`
/home/clive/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:169: UserWarning: The `nb_epoch` argument in `fit` has been renamed `epochs`.
graph builded
Train on 55000 samples, validate on 10000 samples
Epoch 1/2
55000/55000 [==============================] - 25s 463us/step - loss: 0.3302 - acc: 0.9025 - val_loss: 0.1015 - val_acc: 0.9727
Epoch 2/2
55000/55000 [==============================] - 27s 488us/step - loss: 0.1227 - acc: 0.9642 - val_loss: 0.0633 - val_acc: 0.9798
[2]:
<__main__.MnistConv at 0x7f048fbf9748>

Wrap model using s2i

[3]:
!s2i build . seldonio/seldon-core-s2i-python3:0.7 keras-mnist:0.1
---> Installing application source...
---> Installing dependencies ...
Looking in links: /whl
Requirement already satisfied: numpy>=1.8.2 in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 1)) (1.16.3)
Collecting scipy>=0.13.3 (from -r requirements.txt (line 2))
  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.
Downloading https://files.pythonhosted.org/packages/7f/5f/c48860704092933bf1c4c1574a8de1ffd16bf4fde8bab190d747598844b2/scipy-1.2.1-cp36-cp36m-manylinux1_x86_64.whl (24.8MB)
Collecting keras==2.1.3 (from -r requirements.txt (line 3))
  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.
Downloading https://files.pythonhosted.org/packages/08/ae/7f94a03cb3f74cdc8a0f5f86d1df5c1dd686acb9a9c2a421c64f8497358e/Keras-2.1.3-py2.py3-none-any.whl (319kB)
Requirement already satisfied: tensorflow>=1.12.0 in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 4)) (1.13.1)
Requirement already satisfied: h5py in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 5)) (2.9.0)
Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.6/site-packages (from keras==2.1.3->-r requirements.txt (line 3)) (1.12.0)
Requirement already satisfied: pyyaml in /usr/local/lib/python3.6/site-packages (from keras==2.1.3->-r requirements.txt (line 3)) (5.1)
Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.7.1)
Requirement already satisfied: absl-py>=0.1.6 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.7.1)
Requirement already satisfied: tensorflow-estimator<1.14.0rc0,>=1.13.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.13.0)
Requirement already satisfied: keras-preprocessing>=1.0.5 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.0.9)
Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.20.1)
Requirement already satisfied: protobuf>=3.6.1 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (3.7.1)
Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.33.1)
Requirement already satisfied: keras-applications>=1.0.6 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.0.7)
Requirement already satisfied: gast>=0.2.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.2.2)
Requirement already satisfied: tensorboard<1.14.0,>=1.13.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.13.1)
Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.1.0)
Requirement already satisfied: mock>=2.0.0 in /usr/local/lib/python3.6/site-packages (from tensorflow-estimator<1.14.0rc0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 4)) (2.0.0)
Requirement already satisfied: setuptools in /usr/local/lib/python3.6/site-packages (from protobuf>=3.6.1->tensorflow>=1.12.0->-r requirements.txt (line 4)) (41.0.1)
Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.6/site-packages (from tensorboard<1.14.0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.15.2)
Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.6/site-packages (from tensorboard<1.14.0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 4)) (3.1)
Requirement already satisfied: pbr>=0.11 in /usr/local/lib/python3.6/site-packages (from mock>=2.0.0->tensorflow-estimator<1.14.0rc0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 4)) (5.2.0)
Installing collected packages: scipy, keras
Successfully installed keras-2.1.3 scipy-1.2.1
Build completed successfully
[4]:
!docker run --name "mnist_predictor" -d --rm -p 5000:5000 keras-mnist:0.1
6231efde4036974469fddd42585db66067e6a30bcfd40efe5cf474d385f0eeda

Send some random features that conform to the contract

[5]:
!seldon-core-tester contract.json 0.0.0.0 5000 -p
----------------------------------------
SENDING NEW REQUEST:

[[0.387 0.103 0.152 0.129 0.211 0.088 0.659 0.028 0.663 0.666 0.134 0.396
  0.704 0.089 0.407 0.896 0.734 0.375 0.109 0.796 0.917 0.186 0.736 0.013
  0.565 0.256 0.405 0.205 0.317 0.342 0.02  0.748 0.496 0.376 0.405 0.712
  0.775 0.904 0.277 0.973 0.004 0.996 0.692 0.802 0.967 0.361 0.222 0.358
  0.73  0.032 0.516 0.945 0.734 0.012 0.807 0.558 0.604 0.978 0.111 0.772
  0.276 0.484 0.645 0.73  0.953 0.306 0.049 0.299 0.872 0.197 0.389 0.191
  0.604 0.431 0.498 0.091 0.366 0.834 0.266 0.256 0.827 0.996 0.071 0.522
  0.108 0.063 0.607 0.126 0.97  0.758 0.99  0.961 0.285 0.547 0.633 0.788
  0.619 0.694 0.157 0.91  0.992 0.276 0.422 0.978 0.108 0.272 0.605 0.375
  0.964 0.257 0.215 0.583 0.594 0.162 0.118 0.518 0.026 0.687 0.98  0.666
  0.233 0.998 0.678 0.379 0.778 0.149 0.889 0.911 0.019 0.183 0.471 0.272
  0.513 0.628 0.769 0.062 0.706 0.029 0.31  0.322 0.341 0.492 0.124 0.154
  0.643 0.145 0.966 0.874 0.364 0.009 0.611 0.073 0.73  0.712 0.926 0.541
  0.96  0.055 0.105 0.869 0.958 0.892 0.437 0.477 0.477 0.09  0.929 0.708
  0.839 0.629 0.395 0.878 0.278 0.88  0.078 0.525 0.521 0.292 0.3   0.971
  0.002 0.89  0.968 0.19  0.946 0.784 0.926 0.017 0.748 0.287 0.76  0.786
  0.201 0.926 0.173 0.399 0.764 0.249 0.228 0.027 0.125 0.271 0.776 0.82
  0.007 0.685 0.87  0.997 0.115 0.972 0.439 0.761 0.666 0.793 0.72  0.399
  0.361 0.951 0.366 0.942 0.014 0.617 0.634 0.148 0.33  0.943 0.784 0.04
  0.514 0.823 0.346 0.428 0.376 0.908 0.584 0.238 0.929 0.149 0.392 0.898
  0.358 0.088 0.853 0.016 0.278 0.474 0.892 0.957 0.358 0.058 0.655 0.682
  0.32  0.322 0.367 0.069 0.274 0.587 0.662 0.281 0.377 0.281 0.989 0.989
  0.787 0.893 0.051 0.839 0.428 0.088 0.62  0.084 0.951 0.663 0.68  0.069
  0.208 0.186 0.976 0.657 0.955 0.452 0.429 0.71  0.819 0.091 0.228 0.427
  0.995 0.546 0.724 0.022 0.39  0.425 0.871 0.136 0.554 0.383 0.466 0.852
  0.673 0.021 0.957 0.573 0.587 0.579 0.149 0.787 0.303 0.484 0.876 0.766
  0.167 0.743 0.327 0.486 0.357 0.381 0.403 0.047 0.02  0.823 0.009 0.494
  0.919 0.474 0.369 0.364 0.208 0.762 0.942 0.68  0.463 0.369 0.146 0.591
  0.028 0.957 0.937 0.133 0.124 0.587 0.506 0.556 0.156 0.078 0.507 0.425
  0.634 0.147 0.151 0.278 0.467 0.119 0.682 0.486 0.627 0.599 0.837 0.117
  0.686 0.939 0.014 0.801 0.64  0.079 0.811 0.947 0.203 0.294 0.516 0.566
  0.237 0.514 0.696 0.121 0.57  0.334 0.206 0.002 0.735 0.951 0.673 0.524
  0.548 0.737 0.429 0.141 0.173 0.574 0.024 0.359 0.287 0.467 0.199 0.654
  0.682 0.237 0.874 0.909 0.417 0.311 0.764 0.833 0.566 0.207 0.572 0.798
  0.852 0.542 0.863 0.626 0.473 0.137 0.582 0.441 0.562 0.939 0.042 0.209
  0.763 0.315 0.833 0.923 0.565 0.056 0.002 0.833 0.157 0.905 0.221 0.993
  0.863 0.312 0.752 0.875 0.02  0.54  0.96  0.901 0.831 0.384 0.589 0.704
  0.161 0.591 0.068 0.656 0.713 0.347 0.775 0.903 0.137 0.846 0.497 0.394
  0.4   0.264 0.095 0.839 0.746 0.955 0.843 0.352 0.413 0.531 0.83  0.176
  0.89  0.114 0.06  0.012 0.56  0.443 0.78  0.946 0.922 0.178 0.76  0.547
  0.683 0.418 0.83  0.773 0.434 0.236 0.503 0.759 0.102 0.243 0.33  0.054
  0.629 0.014 0.612 0.257 0.281 0.519 0.619 0.385 0.759 0.513 0.753 0.862
  0.318 0.002 0.114 0.457 0.568 0.006 0.019 0.722 0.328 0.135 0.353 0.856
  0.434 0.839 0.123 0.864 0.173 0.307 0.711 0.767 0.528 0.2   0.195 0.854
  0.993 0.374 0.804 0.389 0.248 0.208 0.437 0.806 0.7   0.16  0.548 0.628
  0.768 0.278 0.62  0.17  0.603 0.716 0.294 0.426 0.655 0.373 0.229 0.666
  0.464 0.437 0.598 0.553 0.06  0.342 0.541 0.677 0.03  0.02  0.576 0.85
  0.829 0.696 0.069 0.321 0.945 0.218 0.768 0.84  0.735 0.93  0.107 0.962
  0.883 0.106 0.348 0.081 0.335 0.037 0.595 0.083 0.457 0.382 0.825 0.614
  0.925 0.959 0.689 0.988 0.604 0.937 0.8   0.191 0.633 0.744 0.999 0.812
  0.883 0.31  0.745 0.344 0.086 0.257 0.315 0.411 0.694 0.296 0.257 0.84
  0.381 0.237 0.28  0.842 0.535 0.439 0.191 0.814 0.224 0.813 0.901 0.797
  0.855 0.86  0.106 0.763 0.137 0.055 0.08  0.515 0.578 0.892 0.311 0.522
  0.31  0.145 0.171 0.684 0.682 0.577 0.294 0.278 0.485 0.867 0.205 0.483
  0.405 0.728 0.596 0.584 0.4   0.276 0.707 0.398 0.16  0.551 0.362 0.471
  0.031 0.125 0.254 0.224 0.091 0.948 0.941 0.383 0.506 0.324 0.125 0.049
  0.148 0.168 0.269 0.818 0.69  0.936 0.234 0.336 0.718 0.929 0.908 0.596
  0.208 0.042 0.657 0.26  0.577 0.691 0.953 0.193 0.772 0.245 0.296 0.527
  0.262 0.545 0.394 0.899 0.975 0.824 0.877 0.933 0.725 0.035 0.496 0.102
  0.313 0.287 0.894 0.046 0.574 0.766 0.761 0.493 0.25  0.454 0.475 0.272
  0.838 0.843 0.595 0.182 0.497 0.049 0.294 0.926 0.018 0.448 0.494 0.008
  0.667 0.392 0.659 0.703 0.113 0.435 0.411 0.011 0.851 0.214 0.364 0.074
  0.279 0.743 0.49  0.183 0.157 0.263 0.669 0.583 0.406 0.81  0.093 0.562
  0.525 0.631 0.786 0.74  0.156 0.797 0.251 0.599 0.959 0.553 0.343 0.167
  0.729 0.814 0.368 0.616 0.946 0.036 0.889 0.112 0.584 0.462 0.673 0.082
  0.538 0.901 0.973 0.161]]
RECEIVED RESPONSE:
meta {
}
data {
  names: "t:0"
  names: "t:1"
  names: "t:2"
  names: "t:3"
  names: "t:4"
  names: "t:5"
  names: "t:6"
  names: "t:7"
  names: "t:8"
  names: "t:9"
  ndarray {
    values {
      list_value {
        values {
          number_value: 0.00022297287068795413
        }
        values {
          number_value: 0.003534407587721944
        }
        values {
          number_value: 0.1571815013885498
        }
        values {
          number_value: 0.22603441774845123
        }
        values {
          number_value: 5.994380626361817e-05
        }
        values {
          number_value: 0.0454179011285305
        }
        values {
          number_value: 0.34811070561408997
        }
        values {
          number_value: 0.21694059669971466
        }
        values {
          number_value: 0.0018390808254480362
        }
        values {
          number_value: 0.0006583957583643496
        }
      }
    }
  }
}


[6]:
!docker rm mnist_predictor --force
mnist_predictor

Test using MinikubeΒΆ

Due to a `minikube/s2i issue <https://github.com/SeldonIO/seldon-core/issues/253>`__ you will need `s2i >= 1.1.13 <https://github.com/openshift/source-to-image/releases/tag/v1.1.13>`__

[7]:
!minikube start --memory 4096
πŸ˜„  minikube v1.0.0 on linux (amd64)
🀹  Downloading Kubernetes v1.14.0 images in the background ...
πŸ”₯  Creating virtualbox VM (CPUs=2, Memory=4096MB, Disk=20000MB) ...
πŸ“Ά  "minikube" IP address is 192.168.99.100
🐳  Configuring Docker as the container runtime ...
🐳  Version of container runtime is 18.06.2-ce
βŒ›  Waiting for image downloads to complete ...
✨  Preparing Kubernetes environment ...
🚜  Pulling images required by Kubernetes v1.14.0 ...
πŸš€  Launching Kubernetes v1.14.0 using kubeadm ...
βŒ›  Waiting for pods: apiserver proxy etcd scheduler controller dns
πŸ”‘  Configuring cluster permissions ...
πŸ€”  Verifying component health .....
πŸ’—  kubectl is now configured to use "minikube"
πŸ„  Done! Thank you for using minikube!
[8]:
!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default
clusterrolebinding.rbac.authorization.k8s.io/kube-system-cluster-admin created
[9]:
!helm init
$HELM_HOME has been configured at /home/clive/.helm.

Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.

Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!
[10]:
!kubectl rollout status deploy/tiller-deploy -n kube-system
Waiting for deployment "tiller-deploy" rollout to finish: 0 of 1 updated replicas are available...
deployment "tiller-deploy" successfully rolled out
[13]:
!helm install ../../../helm-charts/seldon-core-operator --name seldon-core --set usageMetrics.enabled=true --namespace seldon-system
NAME:   seldon-core
LAST DEPLOYED: Fri May  3 19:38:47 2019
NAMESPACE: seldon-system
STATUS: DEPLOYED

RESOURCES:
==> v1/ClusterRoleBinding
NAME                                 AGE
seldon-operator-manager-rolebinding  0s

==> v1/Service
NAME                                        TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)  AGE
seldon-operator-controller-manager-service  ClusterIP  10.101.135.115  <none>       443/TCP  0s

==> v1/StatefulSet
NAME                                DESIRED  CURRENT  AGE
seldon-operator-controller-manager  1        1        0s

==> v1/Pod(related)
NAME                                  READY  STATUS             RESTARTS  AGE
seldon-operator-controller-manager-0  0/1    ContainerCreating  0         0s

==> v1/Secret
NAME                                   TYPE    DATA  AGE
seldon-operator-webhook-server-secret  Opaque  0     0s

==> v1beta1/CustomResourceDefinition
NAME                                         AGE
seldondeployments.machinelearning.seldon.io  0s

==> v1/ClusterRole
seldon-operator-manager-role  0s


NOTES:
NOTES: TODO


[14]:
!kubectl rollout status statefulset.apps/seldon-operator-controller-manager -n seldon-system
Waiting for 1 pods to be ready...
partitioned roll out complete: 1 new pods have been updated...

Setup IngressΒΆ

There are gRPC issues with the latest Ambassador, so we rewcommend 0.40.2 until these are fixed.

[15]:
!helm install stable/ambassador --name ambassador --set crds.keep=false
NAME:   ambassador
LAST DEPLOYED: Fri May  3 19:40:12 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME        DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
ambassador  3        3        3           0          0s

==> v1/Pod(related)
NAME                         READY  STATUS             RESTARTS  AGE
ambassador-5b89d44544-f7prg  0/1    ContainerCreating  0         0s
ambassador-5b89d44544-jkbtz  0/1    ContainerCreating  0         0s
ambassador-5b89d44544-mjgj8  0/1    ContainerCreating  0         0s

==> v1/ServiceAccount
NAME        SECRETS  AGE
ambassador  1        0s

==> v1beta1/ClusterRole
NAME        AGE
ambassador  0s

==> v1beta1/ClusterRoleBinding
NAME        AGE
ambassador  0s

==> v1/Service
NAME               TYPE          CLUSTER-IP      EXTERNAL-IP  PORT(S)                     AGE
ambassador-admins  ClusterIP     10.100.85.59    <none>       8877/TCP                    0s
ambassador         LoadBalancer  10.109.230.160  <pending>    80:31635/TCP,443:30969/TCP  0s


NOTES:
Congratuations! You've successfully installed Ambassador.

For help, visit our Slack at https://d6e.co/slack or view the documentation online at https://www.getambassador.io.

To get the IP address of Ambassador, run the following commands:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
     You can watch the status of by running 'kubectl get svc -w  --namespace default ambassador'

  On GKE/Azure:
  export SERVICE_IP=$(kubectl get svc --namespace default ambassador -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

  On AWS:
  export SERVICE_IP=$(kubectl get svc --namespace default ambassador -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')

  echo http://$SERVICE_IP:

[16]:
!kubectl rollout status deployment.apps/ambassador
Waiting for deployment "ambassador" rollout to finish: 0 of 3 updated replicas are available...
Waiting for deployment "ambassador" rollout to finish: 1 of 3 updated replicas are available...
Waiting for deployment "ambassador" rollout to finish: 2 of 3 updated replicas are available...
deployment "ambassador" successfully rolled out
[17]:
!eval $(minikube docker-env) && s2i build . seldonio/seldon-core-s2i-python3:0.7 keras-mnist:0.1
---> Installing application source...
---> Installing dependencies ...
Looking in links: /whl
Requirement already satisfied: numpy>=1.8.2 in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 1)) (1.16.3)
Collecting scipy>=0.13.3 (from -r requirements.txt (line 2))
  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.
Downloading https://files.pythonhosted.org/packages/7f/5f/c48860704092933bf1c4c1574a8de1ffd16bf4fde8bab190d747598844b2/scipy-1.2.1-cp36-cp36m-manylinux1_x86_64.whl (24.8MB)
Collecting keras==2.1.3 (from -r requirements.txt (line 3))
  WARNING: Url '/whl' is ignored. It is either a non-existing path or lacks a specific scheme.
Downloading https://files.pythonhosted.org/packages/08/ae/7f94a03cb3f74cdc8a0f5f86d1df5c1dd686acb9a9c2a421c64f8497358e/Keras-2.1.3-py2.py3-none-any.whl (319kB)
Requirement already satisfied: tensorflow>=1.12.0 in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 4)) (1.13.1)
Requirement already satisfied: h5py in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 5)) (2.9.0)
Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.6/site-packages (from keras==2.1.3->-r requirements.txt (line 3)) (1.12.0)
Requirement already satisfied: pyyaml in /usr/local/lib/python3.6/site-packages (from keras==2.1.3->-r requirements.txt (line 3)) (5.1)
Requirement already satisfied: gast>=0.2.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.2.2)
Requirement already satisfied: keras-applications>=1.0.6 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.0.7)
Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.1.0)
Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.33.1)
Requirement already satisfied: absl-py>=0.1.6 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.7.1)
Requirement already satisfied: tensorboard<1.14.0,>=1.13.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.13.1)
Requirement already satisfied: keras-preprocessing>=1.0.5 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.0.9)
Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.20.1)
Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.7.1)
Requirement already satisfied: protobuf>=3.6.1 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (3.7.1)
Requirement already satisfied: tensorflow-estimator<1.14.0rc0,>=1.13.0 in /usr/local/lib/python3.6/site-packages (from tensorflow>=1.12.0->-r requirements.txt (line 4)) (1.13.0)
Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.6/site-packages (from tensorboard<1.14.0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 4)) (3.1)
Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.6/site-packages (from tensorboard<1.14.0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 4)) (0.15.2)
Requirement already satisfied: setuptools in /usr/local/lib/python3.6/site-packages (from protobuf>=3.6.1->tensorflow>=1.12.0->-r requirements.txt (line 4)) (41.0.1)
Requirement already satisfied: mock>=2.0.0 in /usr/local/lib/python3.6/site-packages (from tensorflow-estimator<1.14.0rc0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 4)) (2.0.0)
Requirement already satisfied: pbr>=0.11 in /usr/local/lib/python3.6/site-packages (from mock>=2.0.0->tensorflow-estimator<1.14.0rc0,>=1.13.0->tensorflow>=1.12.0->-r requirements.txt (line 4)) (5.2.0)
Installing collected packages: scipy, keras
Successfully installed keras-2.1.3 scipy-1.2.1
Build completed successfully
[18]:
!kubectl create -f keras_mnist_deployment.json
seldondeployment.machinelearning.seldon.io/seldon-deployment-example created
[19]:
!kubectl rollout status deploy/keras-mnist-deployment-keras-mnist-predictor-8baf5cc
Waiting for deployment "keras-mnist-deployment-keras-mnist-predictor-8baf5cc" rollout to finish: 0 of 1 updated replicas are available...
deployment "keras-mnist-deployment-keras-mnist-predictor-8baf5cc" successfully rolled out
[20]:
!seldon-core-api-tester contract.json `minikube ip` `kubectl get svc ambassador -o jsonpath='{.spec.ports[0].nodePort}'` \
    seldon-deployment-example --namespace default -p
----------------------------------------
SENDING NEW REQUEST:

[[0.615 0.937 0.603 0.929 0.9   0.267 0.498 0.514 0.13  0.579 0.213 0.063
  0.671 0.524 0.455 0.049 0.159 0.379 0.886 0.302 0.024 0.57  0.86  0.979
  0.908 0.502 0.427 0.818 0.711 0.83  0.496 0.908 0.567 0.065 0.639 0.464
  0.699 0.415 0.356 0.181 0.152 0.409 0.901 0.981 0.648 0.761 0.721 0.867
  0.76  0.834 0.092 0.236 0.881 0.292 0.229 0.37  0.069 0.413 0.007 0.15
  0.132 0.851 0.75  0.026 0.614 0.533 0.082 0.805 0.176 0.662 0.379 0.002
  0.001 0.132 0.345 0.016 0.317 0.418 0.197 0.846 0.956 0.193 0.447 0.835
  0.2   0.313 0.094 0.94  0.068 0.724 0.732 0.561 0.763 0.589 0.056 0.893
  0.867 0.548 0.365 0.865 0.459 0.217 0.686 0.831 0.952 0.526 0.567 0.544
  0.84  0.642 0.659 0.266 0.666 0.401 0.77  0.646 0.477 0.646 0.186 0.39
  0.197 0.216 0.552 0.465 0.294 0.596 0.955 0.117 0.644 0.31  0.925 0.559
  0.113 0.897 0.379 0.307 0.581 0.044 0.644 0.31  0.871 0.001 0.266 0.356
  0.17  0.16  0.761 0.035 0.217 0.417 0.877 0.862 0.199 0.39  0.135 0.795
  0.181 0.587 0.597 0.498 0.711 0.957 0.033 0.238 0.964 0.112 0.292 0.703
  0.797 0.931 0.582 0.438 0.56  0.599 0.015 0.438 0.807 0.013 0.812 0.841
  0.604 0.763 0.084 0.325 0.854 0.523 0.562 0.112 0.296 0.674 0.173 0.323
  0.077 0.743 0.396 0.848 0.666 0.505 0.319 0.366 0.345 0.394 0.656 0.124
  0.86  0.301 0.481 0.547 0.552 0.769 0.812 0.241 0.476 0.513 0.946 0.877
  0.415 0.396 0.553 0.261 0.987 0.157 0.417 0.311 0.    0.49  0.315 0.051
  0.847 0.848 0.595 0.707 0.536 0.604 0.844 0.149 0.499 0.763 0.474 0.795
  0.95  0.829 0.193 0.032 0.753 0.15  0.759 0.269 0.186 0.084 0.373 0.728
  0.316 0.919 0.052 0.722 0.434 0.314 0.215 0.394 0.814 0.973 0.08  0.378
  0.47  0.29  0.626 0.737 0.714 0.04  0.243 0.474 0.649 0.812 0.565 0.544
  0.716 0.521 0.831 0.638 0.294 0.441 0.55  0.975 0.409 0.126 0.767 0.761
  0.121 0.998 0.389 0.057 0.009 0.933 0.947 0.727 0.376 0.297 0.108 0.104
  0.516 0.014 0.844 0.044 0.804 0.292 0.985 0.933 0.091 0.643 0.238 0.249
  0.023 0.065 0.65  0.453 0.658 0.053 0.725 0.939 0.732 0.65  0.59  0.835
  0.537 0.829 0.649 0.414 0.396 0.805 0.46  0.098 0.707 0.39  0.441 0.567
  0.961 0.361 0.203 0.04  0.528 0.553 0.591 0.682 0.137 0.661 0.401 0.132
  0.16  0.421 0.13  0.567 0.054 0.802 0.784 0.301 0.708 0.409 0.171 0.745
  0.5   0.475 0.813 0.397 0.486 0.406 0.841 0.792 0.77  0.216 0.122 0.126
  0.774 0.458 0.363 0.233 0.765 0.616 0.473 0.029 0.16  0.09  0.699 0.19
  0.891 0.857 0.626 0.132 0.994 0.415 0.53  0.918 0.095 0.589 0.685 0.184
  0.355 0.829 0.519 0.164 0.636 0.042 0.869 0.507 0.756 0.535 0.72  0.881
  0.526 0.632 0.583 0.838 0.838 0.917 0.369 0.466 0.884 0.015 0.591 0.214
  0.053 0.944 0.946 0.652 0.341 0.697 0.229 0.35  0.275 0.729 0.856 0.066
  0.196 0.095 0.421 0.462 0.769 0.424 0.704 0.963 0.446 0.574 0.379 0.151
  0.247 0.04  0.325 0.853 0.046 0.286 0.85  0.909 0.236 0.867 0.022 0.936
  0.039 0.096 0.062 0.516 0.317 0.551 0.058 0.504 0.503 0.795 0.576 0.093
  0.529 0.409 0.37  0.444 0.113 0.113 0.037 0.967 0.278 0.339 0.343 0.979
  0.341 0.843 0.836 0.678 0.775 0.935 0.104 0.505 0.839 0.421 0.838 0.644
  0.078 0.365 0.521 0.754 0.511 0.195 0.606 0.088 0.932 0.74  0.703 0.132
  0.172 0.962 0.261 0.786 0.642 0.207 0.899 0.405 0.493 0.58  0.541 0.684
  0.616 0.878 0.39  0.834 0.505 0.765 0.292 0.658 0.373 0.961 0.69  0.094
  0.318 0.657 0.466 0.58  0.975 0.559 0.114 0.667 0.46  0.719 0.447 0.383
  0.106 0.55  0.331 0.614 0.47  0.107 0.939 0.526 0.32  0.667 0.064 0.738
  0.755 0.598 0.96  0.268 0.646 0.774 0.951 0.519 0.645 0.767 0.188 0.003
  0.202 0.962 0.272 0.798 0.278 0.072 0.128 0.629 0.025 0.78  0.911 0.335
  0.178 0.854 0.568 0.276 0.76  0.52  0.55  0.934 0.735 0.421 0.805 0.979
  0.039 0.711 0.144 0.685 0.655 0.913 0.621 0.848 0.397 0.249 0.825 0.336
  0.601 0.631 0.868 0.54  0.788 0.542 0.588 0.036 0.01  0.412 0.114 0.244
  0.026 0.362 0.551 0.982 0.508 0.718 0.889 0.701 0.385 0.701 0.183 0.694
  0.238 0.745 0.749 0.595 0.835 0.495 0.018 0.698 0.36  0.64  0.723 0.724
  0.417 0.962 0.857 0.908 0.308 0.011 0.397 0.599 0.443 0.399 0.224 0.973
  0.69  0.254 0.777 0.756 0.91  0.973 0.999 0.17  0.824 0.087 0.238 0.821
  0.96  0.336 0.922 0.822 0.595 0.439 0.311 0.304 0.389 0.835 0.904 0.408
  0.992 0.593 0.906 0.84  0.749 0.706 0.401 0.86  0.137 0.559 0.205 0.948
  0.446 0.58  0.762 0.738 0.566 0.149 0.725 0.238 0.484 0.027 0.758 0.409
  0.98  0.028 0.433 0.911 0.893 0.346 0.502 0.311 0.154 0.606 0.979 0.89
  0.276 0.388 0.404 0.666 0.273 0.088 0.193 0.557 0.009 0.293 0.479 0.3
  0.919 0.212 0.119 0.669 0.893 0.926 0.853 0.671 0.739 0.007 0.241 0.633
  0.185 0.709 0.99  0.175 0.623 0.523 0.864 0.948 0.779 0.161 0.645 0.778
  0.377 0.593 0.531 0.668 0.551 0.363 0.798 0.444 0.808 0.691 0.15  0.915
  0.502 0.858 0.373 0.568 0.301 0.339 0.035 0.333 0.763 0.789 0.541 0.964
  0.578 0.575 0.875 0.267 0.128 0.64  0.068 0.633 0.723 0.19  0.768 0.446
  0.387 0.946 0.366 0.947]]
RECEIVED RESPONSE:
meta {
  puid: "8t8gotatm360hcu7ldv5s9goeo"
  requestPath {
    key: "keras-mnist-classifier"
    value: "keras-mnist:0.1"
  }
}
data {
  names: "t:0"
  names: "t:1"
  names: "t:2"
  names: "t:3"
  names: "t:4"
  names: "t:5"
  names: "t:6"
  names: "t:7"
  names: "t:8"
  names: "t:9"
  ndarray {
    values {
      list_value {
        values {
          number_value: 1.9628670997917652e-05
        }
        values {
          number_value: 0.000876674719620496
        }
        values {
          number_value: 0.011045475490391254
        }
        values {
          number_value: 0.39959368109703064
        }
        values {
          number_value: 1.71219180629123e-05
        }
        values {
          number_value: 0.24513600766658783
        }
        values {
          number_value: 0.024894580245018005
        }
        values {
          number_value: 0.31388890743255615
        }
        values {
          number_value: 0.00057043950073421
        }
        values {
          number_value: 0.0039573488757014275
        }
      }
    }
  }
}


[ ]:
!minikube delete
[ ]: