how do i reduce the loading time of a pre-trained model? - python

While loading the weights of "Imagenet" using ResNet50 it nearly takes 10-11sec each time while loading the weights.
Is there any way to reduces the loading time ?
Code:
from flask import Flask, render_template, request
from werkzeug import secure_filename
from flask import request,Flask
import json
import os
import time
from keras.preprocessing import image as image_util
from keras.applications.imagenet_utils import preprocess_input
from keras.applications.imagenet_utils import decode_predictions
# from keras.applications import ResNet50
from keras.applications.inception_v3 import InceptionV3
import numpy as np
app = Flask(__name__)
#app.route('/object_rec', methods=['POST'])
def object_rec():
f = request.files['file']
file_path = ("./upload/"+secure_filename(f.filename))
f.save(file_path)
image = image_util.load_img(file_path,target_size=(299,299))
image = image_util.img_to_array(image)
image = np.expand_dims(image,axis=0) #(224,224,3) --> (1,224,224,3)
image = preprocess_input(image)
start_time = time.time()
model = InceptionV3(weights="imagenet")
pred = model.predict(image)
p = decode_predictions(pred)
ans = p[0][0]
acc = ans[2]
acc = str(acc)
if ans[1] == "Granny_Smith":
ans = ans[1]
ans = 'Apple'
else:
ans = ans[1]
print("THE PREDICTED IMAGE IS: "+ans)
print("THE ACCURACY IS: "+acc)
print("--- %s seconds ---" % (time.time() - start_time))
result = {
"status": True,
"object": ans,
"score":acc
}
result = json.dumps(result)
return result
if __name__ == '__main__':
app.run(host='0.0.0.0',port=6000,debug=True)
time taken would differ between 8-11 sec.
I would be good if it loads the model in 3-4sec and does classification.
Thanks in advance

The way you can do it, is to load the model in a specific session and then every time you want to use the model just set that specific session, then just call predict where you need it:
app = Flask(__name__)
sess = tf.Session(config=tf_config)
graph = tf.get_default_graph()
# IMPORTANT: models have to be loaded AFTER SETTING THE SESSION for keras!
# Otherwise, their weights will be unavailable in the threads after the
session there has been set
set_session(sess)
model = InceptionV3(weights="imagenet")
#app.route('/object_rec', methods=['POST'])
def object_rec():
global sess
global graph
with graph.as_default():
set_session(sess)
model.predict(...)
if __name__ == '__main__':
app.run(host='0.0.0.0',port=6000,debug=True)

Related

Udacity Self Driving Car Simulator

I am working on Udacity's self-driving car simulator. I am facing a problem in this when I run the drive.py file with my model as argument model.h5 nothing happens in the simulator.
The model has been trained completely without any errors but still, there is no response from the simulator.
Here is the drive.py python code and a link to the video to show what is actually happening
drive.py
import argparse
import base64
from datetime import datetime
import os
import shutil
import numpy as np
import socketio
import eventlet
import eventlet.wsgi
from PIL import Image
from flask import Flask
from io import BytesIO
from keras.models import load_model
import h5py
from keras import __version__ as keras_version
sio = socketio.Server()
app = Flask(__name__)
model = None
prev_image_array = None
class SimplePIController:
def __init__(self, Kp, Ki):
self.Kp = Kp
self.Ki = Ki
self.set_point = 0.
self.error = 0.
self.integral = 0.
def set_desired(self, desired):
self.set_point = desired
def update(self, measurement):
# proportional error
self.error = self.set_point - measurement
# integral error
self.integral += self.error
return self.Kp * self.error + self.Ki * self.integral
controller = SimplePIController(0.1, 0.002)
set_speed = 30
controller.set_desired(set_speed)
def crop_image(img, img_height=75, img_width=200):
height = img.shape[0]
width = img.shape[1]
y_start = 60
#x_start = int(width/2)-int(img_width/2)
return img[y_start:y_start+img_height, 0:width ]#x_start:x_start+img_width]
#sio.on('telemetry')
def telemetry(sid, data):
if data:
# The current steering angle of the car
steering_angle = data["steering_angle"]
# The current throttle of the car
throttle = data["throttle"]
# The current speed of the car
speed = data["speed"]
# The current image from the center camera of the car
imgString = data["image"]
image = Image.open(BytesIO(base64.b64decode(imgString)))
image_array = np.asarray(image)
image_array = crop_image(image_array)
steering_angle = float(model.predict(image_array[None, :, :, :], batch_size=1))
throttle = controller.update(float(speed))
print(steering_angle, throttle)
send_control(steering_angle, throttle)
# save frame
if args.image_folder != '':
timestamp = datetime.utcnow().strftime('%Y_%m_%d_%H_%M_%S_%f')[:-3]
image_filename = os.path.join(args.image_folder, timestamp)
image.save('{}.jpg'.format(image_filename))
else:
# NOTE: DON'T EDIT THIS.
sio.emit('manual', data={}, skip_sid=True)
#sio.on('connect')
def connect(sid, environ):
print("connect ", sid)
send_control(0, 0)
def send_control(steering_angle, throttle):
sio.emit(
"steer",
data={
'steering_angle': steering_angle.__str__(),
'throttle': throttle.__str__()
},
skip_sid=True)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Remote Driving')
parser.add_argument(
'model',
type=str,
help='Path to model h5 file. Model should be on the same path.'
)
parser.add_argument(
'image_folder',
type=str,
nargs='?',
default='',
help='Path to image folder. This is where the images from the run will be saved.'
)
args = parser.parse_args()
# check that model Keras version is same as local Keras version
f = h5py.File(args.model, mode='r')
model_version = f.attrs.get('keras_version')
keras_version = str(keras_version).encode('utf8')
if model_version != keras_version:
print('You are using Keras version ', keras_version,
', but the model was built using ', model_version)
model = load_model(args.model)
if args.image_folder != '':
print("Creating image folder at {}".format(args.image_folder))
if not os.path.exists(args.image_folder):
os.makedirs(args.image_folder)
else:
shutil.rmtree(args.image_folder)
os.makedirs(args.image_folder)
print("RECORDING THIS RUN ...")
else:
print("NOT RECORDING THIS RUN ...")
# wrap Flask application with engineio's middleware
app = socketio.Middleware(sio, app)
# deploy as an eventlet WSGI server
eventlet.wsgi.server(eventlet.listen(('', 4567)), app)
problem video link
https://youtu.be/nP8WH8pM29Q
This is due to the socketio version. Use 4.2.1, that should fix your problem

keras and tensorflow(backend error) Tensor conv2d_1_input:0, specified in either feed_devices or fetch_devices was not found in the Graph

I was using keras and tensorfoow and i'm completely new to it.
I had trained my models and when i make to predict it the error is showing.
This is the code i have used for the image prediction
import numpy as np
from flask import Flask, request, jsonify, render_template
import numpy
from PIL import Image
import os
import tensorflow.keras
from werkzeug.utils import secure_filename
from keras.models import load_model
app = Flask(__name__)
model = load_model('traffic_classifier.h5')
model._make_predict_function()
#app.route('/')
def index():
# Main page
return render_template('index.html')
#app.route('/traffic')
def traffic():
# Main page
return render_template('traffic.html')
#app.route('/sleep')
def sleep():
# Main page
return render_template('sleep.html')
#app.route('/predict',methods=['POST'])
def predict():
'''
For rendering results on HTML GUI
'''
classes = { 1:'Speed limit (20km/h)',
2:'Speed limit (30km/h)',
3:'Speed limit (50km/h)',
4:'Speed limit (60km/h)',
5:'Speed limit (70km/h)',
6:'Speed limit (80km/h)',
7:'End of speed limit (80km/h)',
8:'Speed limit (100km/h)',
9:'Speed limit (120km/h)',
10:'No passing',
11:'No passing veh over 3.5 tons',
12:'Right-of-way at intersection',
13:'Priority road',
14:'Yield',
15:'Stop',
16:'No vehicles',
17:'Veh > 3.5 tons prohibited',
18:'No entry',
19:'General caution',
20:'Dangerous curve left',
21:'Dangerous curve right',
22:'Double curve',
23:'Bumpy road',
24:'Slippery road',
25:'Road narrows on the right',
26:'Road work',
27:'Traffic signals',
28:'Pedestrians',
29:'Children crossing',
30:'Bicycles crossing',
31:'Beware of ice/snow',
32:'Wild animals crossing',
33:'End speed + passing limits',
34:'Turn right ahead',
35:'Turn left ahead',
36:'Ahead only',
37:'Go straight or right',
38:'Go straight or left',
39:'Keep right',
40:'Keep left',
41:'Roundabout mandatory',
42:'End of no passing',
43:'End no passing veh > 3.5 tons' }
if request. method == "POST":
#image=request. form["fileupload"]
f = request.files['file']
# Save the file to ./uploads
basepath = os.path.dirname(__file__)
file_path = os.path.join(
basepath, 'uploads', secure_filename(f.filename))
f.save(file_path)
image = Image.open(file_path)
image = image.resize((30,30))
image = numpy.expand_dims(image, axis=0)
image = numpy.array(image)
pred = model.predict_classes([image])[0]
sign = classes[pred+1]
return render_template('traffic.html', prediction_text='This sign represents {}'.format(sign))
if __name__ == "__main__":
app.run(debug=True)
I'm getting error
tensorflow.python.framework.errors_impl.InvalidArgumentError
tensorflow.python.framework.errors_impl.InvalidArgumentError: Tensor conv2d_1_input:0, specified in either feed_devices or fetch_devices was not found in the Graph
what to do with it??
Solved it by adding these codes
config = tensorflow.ConfigProto(
device_count={'GPU': 1},
intra_op_parallelism_threads=1,
allow_soft_placement=True
)
config.gpu_options.allow_growth = True
config.gpu_options.per_process_gpu_memory_fraction = 0.6
session = tensorflow.Session(config=config)
keras.backend.set_session(session)
model = load_model('traffic_classifier.h5')
model._make_predict_function()
The problem is that Flask is using threads. This means that for each request, Flask creates a new thread. As such, your model is not visible from the request.
To solve this problem, you need to make the model part of a global session that is used throughout.
The solution can be found here as this bug.
from tensorflow.python.keras.backend import set_session
from tensorflow.python.keras.models import load_model
tf_config = some_custom_config
sess = tf.Session(config=tf_config)
graph = tf.get_default_graph()
# IMPORTANT: models have to be loaded AFTER SETTING THE SESSION for keras!
# Otherwise, their weights will be unavailable in the threads after the session there has been set
set_session(sess)
model = load_model(...)
then, inside your method:
def predict():
....
global sess
global graph
with graph.as_default():
set_session(sess)
pred = model.predict_classes(...)
...

Prediction on model exported model using tf.estimator on a base64 input in JSON

i want to built a rest api for model prediction my model accepts base64 string of image in json file as i have tested over google cloud ML. and it is not accepting predict request from android app so i am trying to use rest api. from python script my prediction is giving me so many errors by just testing locally without api yet
here is my export model code
import os
import shutil
import tensorflow as tf
from tensorflow import keras
HEIGHT = 48
WIDTH = 48
CHANNELS = 1
version = 'v1'
h5_model_path = os.path.join('model_4layer_2_2_pool yes.h5')
tf_model_path = os.path.join('D:/university/working/trying/Facial-
Expression-Recognition-master/tryMore')
estimator = keras.estimator.model_to_estimator(
keras_model_path=h5_model_path,
model_dir=tf_model_path)
def image_preprocessing(image):
image = tf.expand_dims(image, 0)
image = tf.image.resize_bilinear(image, [HEIGHT, WIDTH],
align_corners=False)
image = tf.squeeze(image, axis=[0])
image = tf.cast(image, dtype=tf.uint8)
return image
#
IMAGE AS BASE64 BYTES
def serving_input_receiver_fn():
def prepare_image(image_str_tensor):
image = tf.image.decode_jpeg(image_str_tensor, channels=CHANNELS)
return image_preprocessing(image)
input_ph = tf.placeholder(tf.string, shape=[None])
images_tensor = tf.map_fn(
prepare_image, input_ph, back_prop=False, dtype=tf.uint8)
images_tensor = tf.image.convert_image_dtype(images_tensor,
dtype=tf.float32)
return tf.estimator.export.ServingInputReceiver(
{'conv2d_1_input': images_tensor},
{'image_bytes': input_ph})
export_path = os.path.join('models\json_b64', version)
if os.path.exists(export_path): # clean up old exports with this
version
shutil.rmtree(export_path)
estimator.export_savedmodel(
export_path,
serving_input_receiver_fn=serving_input_receiver_fn)
and my code for prediction is as follows
import tensorflow as tf
import pickle
import os
import imgJSON
dir_path = os.path.dirname(__file__)
exported_path= os.path.join(dir_path, "models/json_b64/v1/1539157474")
model_input=imgJSON.img_bytes
global data
def main():
with tf.Session() as sess:
Model=tf.saved_model.loader.load(sess,
[tf.saved_model.tag_constants.SERVING], exported_path)
predictor= tf.contrib.predictor.from_saved_model(exported_path)
import json
with open("D:/university/working/trying/Facial-Expression-Recognition-
master/tryMore/test_json_b64.json") as f:
data = json.loads(f.read())
print(data["image_bytes"])
output_dict= predictor({"image_bytes":[model_input]})
print(" prediction is " , output_dict['scores'])
if __name__ == "__main__":
main()
my error message is as follows:
InvalidArgumentError (see above for traceback): Expected image (JPEG, PNG, or GIF), got unknown format starting with '/9j/4AAQSkZJRgAB'
[[Node: map/while/DecodeJpeg = DecodeJpeg[acceptable_fraction=1, channels=1, dct_method="", fancy_upscaling=true, ratio=1, try_recover_truncated=false, _device="/job:localhost/replica:0/task:0/device:CPU:0"](map/while/TensorArrayReadV3)]]
how to predict passing base64 string to my respective exported model?

how to load keras models which are being called within a function outside the URL's endpoint?

i have the following script which currently is working fine (although quite slow 33s/qry). My main problem right now is that i am calling the loadweights() function under the \predict endpoint and so everytime i start a query it starts initializing the the keras models and the weights which makes it really slow. i somehow want to call the function outside the endpoints scope or store the models and weights somewhere. How can i do that? i tried to call the function outside the endpoint just beneath the loadweights() definition but it gives me 504 gateway error related to nginx. i am working with flask,nginx,uwsgi on google cloud server.
import dlib
import requests
import numpy as np
from skimage import io
from skimage.transform import resize
from keras import backend as K
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications
from flask import Flask, jsonify, request, abort, make_response
import tensorflow as tf
app = Flask(__name__)
auth_token = 'WyIxYSDFg467YT'
top_model_weights_ethnicity = '/ethnicity.071217.23-0.28.hdf5'
img_width, img_height = 139, 139
confidence_ethnicity = '0.59'
detector = dlib.get_frontal_face_detector()
g1 = tf.Graph()
class_to_label_ethnicity = {"0": "arabs", "1": "asia", "2": "black", "3": "hispanics-latinos",
"4": "southasia", "5": "white"}
with g1.as_default():
model_ethnicity = Sequential()
model_ethnicity.add(Flatten(input_shape=(3, 3, 1536)))
model_ethnicity.add(Dense(256, activation='relu'))
model_ethnicity.add(Dropout(0.5))
model_ethnicity.add(Dense(6, activation='softmax'))
def get_face(path):
with g1.as_default():
img = io.imread(path)
dets = detector(img, 1)
output = None
for i, d in enumerate(dets):
img = img[d.top():d.bottom(), d.left():d.right()]
img = resize(img, (img_width, img_height))
output = np.expand_dims(img, axis=0)
break
return output
def get_pretrained_model():
with g1.as_default():
global pretrained_model
pretrained_model = applications.InceptionResNetV2(include_top=False, weights='imagenet',
input_shape=(img_width, img_height, 3))
return pretrained_model
def get_features(image, pretrained_model):
with g1.as_default():
features = pretrained_model.predict(image)
return features
def loadweights():
with g1.as_default():
model_ethnicity.load_weights(top_model_weights_ethnicity)
pretrained_model = get_pretrained_model()
return model_ethnicity
#app.route("/predict", methods=['GET', 'POST'])
def predict_ethnicity():
with g1.as_default():
loadweights()
confidence = request.args.get('confidence', confidence_ethnicity)
path_to_img = request.args.get('url')
if get_face(path_to_img) is None:
abort(make_response(jsonify(message="No face found."), 454))
else:
features = get_features(get_face(path_to_img), pretrained_model)
prediction = model_ethnicity.predict_proba(features)
ethnicity = {class_to_label_ethnicity[str(y)]: str(value) for (x, y), value in np.ndenumerate(prediction)}
suggestion = class_to_label_ethnicity[str(np.argmax(prediction[0]))] \
if np.max(prediction[0]) > float(confidence) else ""
return jsonify({'probabilities': ethnicity, 'suggestion': suggestion}), 200
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=False)

Swift Client with DecisionTreeRegressor

I am working with bluemix object storage container, What i want to do that i want to store my "RandomForestRegressor" into a pkl file with joblib. But when i run the code with the Swift client i receives the error.
TypeError: object of type 'DecisionTreeRegressor' has no len()
Here is my code please help.
import os
from flask import Flask,render_template, request,json
from flask.ext.cors import CORS
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
import random
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error
import os
from sklearn.externals import joblib
import pickle
import sys
import json
import csv
import swiftclient
app = Flask(__name__)
CORS(app)
cloudant_service = json.loads(os.environ['VCAP_SERVICES'])['Object-Storage'][0]
objectstorage_creds = cloudant_service['credentials']
if objectstorage_creds:
auth_url = objectstorage_creds['auth_url'] + '/v3' #authorization URL
password = objectstorage_creds['password'] #password
project_id = objectstorage_creds['projectId'] #project id
user_id = objectstorage_creds['userId'] #user id
region_name = objectstorage_creds['region'] #region name
def predict_joblib():
conn = swiftclient.Connection(key=password,
authurl=auth_url,
auth_version='3',
os_options={"project_id": project_id,
"user_id": user_id,
"region_name": region_name})
container_name = 'my-container'
# File name for testing
file_name = 'example_file.txt'
# Create a new container
conn.put_container(container_name)
print ("nContainer %s created successfully." % container_name)
# List your containers
print ("nContainer List:")
for container in conn.get_account()[1]:
print (container['name'])
# List objects in a container, and prints out each object name, the file size, and last modified date
print ("nObject List:")
for container in conn.get_account()[1]:
for data in conn.get_container(container['name'])[1]:
print ('object: {0}t size: {1}t date: {2}'.format(data['name'], data['bytes'], data['last_modified']))
print ("-----------LEARN-----------\n")
with open('training_set.json') as json_data:
df_train= pd.read_json(json_data)
train_X = df_train.drop('Price', 1)
train_y = df_train['Price']
print ("Training...")
rfreg = RandomForestRegressor(n_estimators=100, n_jobs=-1)
rfreg.fit(train_X, train_y)
print("\nPerformance on training set:")
print('R^2: %f' % rfreg.score(train_X, train_y))
# print('MSE: %f' % mean_squared_error(rfreg.predict(train_X), train_y))
# print('ABS: %f' % mean_absolute_error(rfreg.predict(train_X), train_y))
importances = rfreg.feature_importances_
std = np.std([tree.feature_importances_ for tree in rfreg.estimators_], axis=0)
indices = np.argsort(importances)[::-1]
# Print the feature ranking
print("\nFeature ranking:")
for f in range(len(importances)):
print("%d. feature %d %s (%f)" % (f + 1, indices[f], df_train.columns[indices[f]], importances[indices[f]]))
# SERIALIZE MODEL USING joblib
print ("Serializing models using joblib...")
conn.put_object(container_name,'v3.pkl', contents= rfreg)
print ("Serializing vectorizers using joblib...")
for feature in ['Fluorescence', 'Culet']:
conn.put_object(container_name,feature+'_v3.pkl', contents= vectorizers[feature])
return rfreg, vectorizers
#app.route('/')
def hello():
predict_joblib()
return 'Welcome to Python Flask!'
#app.route('/signUp')
def signUp():
return 'signUp'
port = os.getenv('PORT', '5000')
if __name__ == "__main__":
app.debug = True
app.run(host='0.0.0.0', port=int(port))

Categories