<jupyter_start><jupyter_text>Deploy Models with TensorFlow Serving and Docker  Load and Preprocess Data<jupyter_code>#%%writefile -a train.py
import os
import time
import pandas as pd
import numpy as np

import tensorflow as tf
import tensorflow_hub as hub
#Souce: https://www.kaggle.com/snap/amazon-fine-food-reviews/data
!head -n 2 train.csv
#%%writefile -a train.py
def load_dataset(file_path,num_sample):
  df=pd.read_csv(file_path,usecols=[6,9],nrows=num_sample)
  df.columns=['rating','title']

  text=df['title'].tolist()
  text=[str(t).encode('ascii','replace') for t in text]
  text=np.array(text,dtype=object)

  labels=df['rating'].tolist()
  labels=[1 if i>=4 else 0 if i==3 else -1 for i in labels]
  labels=np.array(pd.get_dummies(labels),dtype=int)

  return labels,text
tmp_label,tmp_text= load_dataset('train.csv',100)
tmp_label.shape<jupyter_output><empty_output><jupyter_text>Build the Classification Model using TF Hub<jupyter_code>#%%writefile -a train.py

## https://tfhub.dev/google/tf2-preview/nnlm-en-dim50/1
## https://tfhub.dev/google/tf2-preview/nnlm-en-dim128/1


def get_model():
  pretrained_model = 'https://tfhub.dev/google/tf2-preview/nnlm-en-dim50/1'
  hub_layer = hub.KerasLayer(pretrained_model, output_shape=[50], input_shape = [], dtype=tf.string, trainable=False)
  model=tf.keras.Sequential()
  model.add(hub_layer)
  model.add(tf.keras.layers.Dense(16,activation="relu"))
  model.add(tf.keras.layers.Dense(3,activation="softmax"))
  model.compile(optimizer='Adam',loss='categorical_crossentropy',metrics=['accuracy'])
  model.summary()
  return model<jupyter_output><empty_output><jupyter_text>Define Training Procedure<jupyter_code>#%%writefile -a train.py
def train(EPOCHS=5, BATCH_SIZE=32, TRAIN_FILE='train.csv', VAL_FILE='test.csv'):
  WORKING_DIR= os.getcwd()
  print("Loading training/validation data ...")
  y_train,x_train=load_dataset(TRAIN_FILE,num_sample=100000)
  y_val,x_val=load_dataset(VAL_FILE,num_sample=10000)

  print("Training the model ...")
  model=get_model()
  model.fit(x_train,y_train,
          epochs=EPOCHS,
          batch_size=BATCH_SIZE,
          validation_data=(x_val,y_val),
          verbose=1,
          callbacks=[tf.keras.callbacks.ModelCheckpoint(os.path.join(WORKING_DIR),'model_checkpoint',
                                                        
                                                        verbose=1,
                                                        save_best_only=True,
                                                        save_weights_only=False,
                                                        mode='auto')])
  return model<jupyter_output><empty_output><jupyter_text>Train and Export Model as Protobuf<jupyter_code>#%%writefile -a train.py
def export_model(model,base_path='amazon_review/'):
  path=os.path.join(base_path,str(int(time.time())))
  tf.saved_model.save(model,path)

if __name__=='__main__':
  model=train()
  export_model(model)<jupyter_output>Loading training/validation data ...
Training the model ...
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
keras_layer (KerasLayer)     (None, 50)                48190600  
_________________________________________________________________
dense (Dense)                (None, 16)                816       
_________________________________________________________________
dense_1 (Dense)              (None, 3)                 51        
=================================================================
Total params: 48,191,467
Trainable params: 867
Non-trainable params: 48,190,600
_________________________________________________________________
Epoch 1/5
247/247 [==============================] - 5s 9ms/step - loss: 0.7533 - accuracy: 0.7490 - val_loss: 0.6561 - val_accuracy: 0.7838
WARNING:tensorflow:Can save best model [...]<jupyter_text>Test Model  Negative Review:<jupyter_code>test_sentence="Horrible movie"
model.predict([test_sentence])<jupyter_output><empty_output><jupyter_text>Positive Review:<jupyter_code>test_sentence="Great movie"
model.predict([test_sentence])<jupyter_output><empty_output><jupyter_text>TensorFlow Serving with Docker `docker pull tensorflow/serving` `docker run -p 8500:8500 \            -p 8501:8501 \            --mount type=bind,\            source=amazon_review/,\            target=/models/amazon_review \            -e MODEL_NAME=amazon_review \            -t tensorflow/serving`  Setup a REST Client to Perform Model Predictions<jupyter_code>%%writefile tf_serving_rest_client.py
import json
import requests
import sys

def get_rest_url(model_name, host='127.0.0.1', port='8501', verb='predict', version=None):
    """ generate the URL path"""
    url = "http://{host}:{port}/v1/models/{model_name}".format(host=host, port=port, model_name=model_name)
    if version:
        url += 'versions/{version}'.format(version=version)
    url += ':{verb}'.format(verb=verb)
    return url


def get_model_prediction(model_input, model_name='amazon_review', signature_name='serving_default'):
    """ no error handling at all, just poc"""

    url = get_rest_url(model_name)
    #In the row format, inputs are keyed to instances key in the JSON request.
    #When there is only one named input, specify the value of instances key to be the value of the input:
    data = {"instances": [model_input]}
    
    rv = requests.post(url, data=json.dumps(data))
    if rv.status_code != requests.codes.ok:
        rv.raise_for_status()
    
    return rv.json()['predictions']

if __name__ == '__main__':

    print("\nGenerate REST url ...")
    url = get_rest_url(model_name='amazon_review')
    print(url)
    
    while True:
        print("\nEnter an Amazon review [:q for Quit]")
        if sys.version_info[0] <= 3:
            sentence = input()
        if sentence == ':q':
            break
        model_input = sentence
        model_prediction = get_model_prediction(model_input)
        print("The model predicted ...")
        print(model_prediction)<jupyter_output><empty_output><jupyter_text>Setup a gRPC Client to Perform Model Predictions<jupyter_code>%%writefile tf_serving_grpc_client.py
import sys
import grpc
from grpc.beta import implementations
import tensorflow as tf
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2, get_model_metadata_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc


def get_stub(host='127.0.0.1', port='8500'):
    channel = grpc.insecure_channel('127.0.0.1:8500') 
    stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
    return stub


def get_model_prediction(model_input, stub, model_name='amazon_review', signature_name='serving_default'):
    """ no error handling at all, just poc"""
    request = predict_pb2.PredictRequest()
    request.model_spec.name = model_name
    request.model_spec.signature_name = signature_name
    request.inputs['input_input'].CopyFrom(tf.make_tensor_proto(model_input))
    response = stub.Predict.future(request, 5.0)  # 5 seconds
    return response.result().outputs["output"].float_val


def get_model_version(model_name, stub):
    request = get_model_metadata_pb2.GetModelMetadataRequest()
    request.model_spec.name = 'amazon_review'
    request.metadata_field.append("signature_def")
    response = stub.GetModelMetadata(request, 10)
    # signature of loaded model is available here: response.metadata['signature_def']
    return response.model_spec.version.value

if __name__ == '__main__':
    print("\nCreate RPC connection ...")
    stub = get_stub()
    while True:
        print("\nEnter an Amazon review [:q for Quit]")
        if sys.version_info[0] <= 3:
            sentence = raw_input() if sys.version_info[0] < 3 else input()
        if sentence == ':q':
            break
        model_input = [sentence]
        model_prediction = get_model_prediction(model_input, stub)
        print("The model predicted ...")
        print(model_prediction)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13223039215686275, 'fraction_numerical': 0.021813725490196077, 'mean_word_length': 3.7392566782810683, 'pattern_counts': {'":': 1, '<': 35, '<?xml version=': 0, '>': 33, 'https://': 4, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 3, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '631331', 'license': 'Apache-2.0', 'n_tokens_mistral': 2638, 'n_tokens_neox': 2473, 'n_words': 490, 'path': 'Python_virtual_environment.ipynb', 'repo_name': 'deepak916/Setup-virtual-application-environment-', 'size': '8160'}