Files
CNN/Models/model_host.py
2024-10-26 12:20:02 -04:00

219 lines
8.5 KiB
Python

#import sys
#import os
#import glob
#import socket
#from keras.backend import GraphExecutionFunction
#sys.path.append('c:/git/keras')
#sys.path.append('c:/git/absl')
# This upgrades all modules
#py -mpip freeze | %{$_.split('==')[0]} | %{py -mpip install --upgrade $_}
# The following worked to install CUDA for using tensorflow with GPU
# 1) Install CUDA 11.8 Toolkit from here
# https://developer.nvidia.com/cuda-11-8-0-download-archive?target_os=Windows&target_arch=x86_64&target_version=11&target_type=exe_local
# 2) The binaries should wind up in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8\bin
# 3) Put the above path in the PATH environment variable
# 4) Also download cuDNN from here https://developer.nvidia.com/cudnn because tensorflow will look for cudnn64_8.dll which is in that package
# This download is just a bunch of DLLs with no install program. I left it in downloads folder.
# 5) put C:\download\cuDNN\cudnn-windows-x86_64-8.9.7.29_cuda11-archive\bin in the PATH
# 6) Run the check_gpu.py program and ensure no errors loading DLLs
# installed version
# py -m pip install keras==2.6.0
# py -mpip install flask==2.0.1
# py -mpip install numpy==1.19.5
# py -mpip show numpy
# py -mpip install tensorflow==2.6.0
# py -mpip show tensorflow
# py -mpip install matplotlib==3.4.3
# c:\users\skess\appdata\local\programs\python\python39\lib\site-packages
import keras
#from keras.preprocessing.image import ImageDataGenerator
from keras.src.legacy.preprocessing.image import ImageDataGenerator
from flask import Flask, render_template, send_file, request
import numpy as np
import tensorflow
import sys
import os
import io
import PIL.Image
import uuid
#init flaskapp
app = Flask(__name__)
# use this on image passed in to the API
def save_image(imgData):
filename=str(uuid.uuid4())+'.jpg'
print('saving {filename}'.format(filename=filename))
with open(filename,'wb') as output:
output.write(imgData)
# Use this after processing with PIL
def save_pil_image(image):
filename=str(uuid.uuid4())+'.jpg'
print('saving {filename}'.format(filename=filename))
imageByteArray = io.BytesIO()
image.save(imageByteArray, format='JPEG')
imageByteArray = imageByteArray.getvalue()
with open(filename,'wb') as output:
output.write(imageByteArray)
def render_index():
return """<!doctype html>
<html>
<head>
<title>Convolutional Neural Network Hosting Platform</title>
</head>
<body>
<p>You have reached the main page of the Convolutional Neural Network Hosting Platform. This platform hosts the following models:<strong>resnet50</strong>,<strong>vgg16</strong>, and <strong>inception</strong></p>
<p>The models can be invoked by submitting a POST request with 128,128 grayscale image in jpg format</p>
<p>The following are some examples</p>
<p>http://127.0.0.1/predict_vgg16</p>
<p>http://127.0.0.1/predict_resnet50</p>
</body>
</html>
"""
@app.route('/')
def index():
return render_index()
@app.route('/ping', methods=['GET','POST'])
def ping():
return "Alive"
@app.route('/predict_vgg16', methods=['GET','POST'])
def predict_vgg16():
test_image=request.get_data()
test_image = PIL.Image.open(io.BytesIO(test_image))
# save_pil_image(test_image)
# test_image = test_image.convert('L')
test_array=keras.preprocessing.image.img_to_array(test_image)
batch_test_array=np.array([test_array])
predictions=vgg16_model.predict(batch_test_array)
if type(predictions) == list:
average_prediction = sum(predictions)/len(predictions)
threshold_output = np.where(average_prediction > 0.5, 1, 0)
else :
threshold_output = np.where(predictions > 0.5, 1, 0)
response=str(predictions)+'-->'+str(threshold_output)
return response
@app.route('/predict_resnet50', methods=['GET','POST'])
def predict_resnet50():
print('/predict_resnet50')
test_image=request.get_data()
test_image = PIL.Image.open(io.BytesIO(test_image))
test_image = test_image.convert('L')
test_array=keras.preprocessing.image.img_to_array(test_image)
batch_test_array=np.array([test_array])
predictions=resnet50_model.predict(batch_test_array)
if type(predictions) == list:
average_prediction = sum(predictions)/len(predictions)
threshold_output = np.where(average_prediction > 0.5, 1, 0)
else :
threshold_output = np.where(predictions > 0.5, 1, 0)
response=str(predictions)+'-->'+str(threshold_output)
return response
# New model updated in October 2024
@app.route('/predict_resnet50_20241024_270', methods=['GET','POST'])
def predict_resnet50_20241024_270():
print('/predict_resnet50_20241024_270')
test_image=request.get_data()
test_image = PIL.Image.open(io.BytesIO(test_image))
test_image = test_image.convert('L')
test_array=keras.preprocessing.image.img_to_array(test_image)
batch_test_array=np.array([test_array])
predictions=resnet50_20241024_270_model.predict(batch_test_array)
if type(predictions) == list:
average_prediction = sum(predictions)/len(predictions)
threshold_output = np.where(average_prediction > 0.5, 1, 0)
else :
threshold_output = np.where(predictions > 0.5, 1, 0)
response=str(predictions)+'-->'+str(threshold_output)
return response
# This version expects the image to be of the form (x,x,3).
@app.route('/predict_resnet50B', methods=['GET','POST'])
def predict_resnet50B():
print('/predict_resnet50B')
test_image=request.get_data()
save_image(test_image)
test_image = PIL.Image.open(io.BytesIO(test_image))
test_array=keras.preprocessing.image.img_to_array(test_image)
batch_test_array=np.array([test_array])
predictions=resnet50b_model.predict(batch_test_array)
if type(predictions) == list:
average_prediction = sum(predictions)/len(predictions)
threshold_output = np.where(average_prediction > 0.5, 1, 0)
else :
threshold_output = np.where(predictions > 0.5, 1, 0)
response=str(predictions)+'-->'+str(threshold_output)
return response
@app.route('/predict_lenet5', methods=['GET','POST'])
def predict_lenet5():
print('/predict_lenet5')
test_image=request.get_data()
test_image = PIL.Image.open(io.BytesIO(test_image))
test_image = test_image.convert('L')
test_array=keras.preprocessing.image.img_to_array(test_image)
batch_test_array=np.array([test_array])
predictions=lenet_model.predict(batch_test_array)
if type(predictions) == list:
average_prediction = sum(predictions)/len(predictions)
threshold_output = np.where(average_prediction > 0.5, 1, 0)
else :
threshold_output = np.where(predictions > 0.5, 1, 0)
response=str(predictions)+'-->'+str(threshold_output)
return response
# This method is used to process an image through PIL and send it back to the client. The client can then used this processed image as part of the training data
# so that the model can adapt to images that are processed through PIL
@app.route('/process_image', methods=['GET','POST'])
def process_image():
print('/process_image')
image=request.get_data()
image = PIL.Image.open(io.BytesIO(image))
imageByteArray = io.BytesIO()
image.save(imageByteArray, format='JPEG')
imageByteArray = imageByteArray.getvalue()
print('processed {length} bytes.'.format(length=len(imageByteArray)))
return send_file(io.BytesIO(imageByteArray), mimetype='image/jpeg', as_attachment=True, download_name='%s.jpg' % str(uuid.uuid4()))
if __name__ == '__main__':
resnet50_model_name='../Weights/resnet50.h5'
print('Loading {model_name}'.format(model_name=resnet50_model_name))
resnet50_model = keras.models.load_model(resnet50_model_name)
resnet50_20241024_270_model_name='../Weights/resnet50_20241024_270.h5.keras'
print('Loading {model_name}'.format(model_name=resnet50_20241024_270_model_name))
resnet50_20241024_270_model = keras.models.load_model(resnet50_20241024_270_model_name)
resnet50b_model_name='../Weights/resnet50B.h5'
print('Loading {model_name}'.format(model_name=resnet50b_model_name))
resnet50b_model = keras.models.load_model(resnet50b_model_name)
vgg16_model_name='../Weights/vggnet16.h5'
print('Loading {model_name}'.format(model_name=vgg16_model_name))
vgg16_model=keras.models.load_model(vgg16_model_name)
lenet_model_name='../Weights/lenet5.h5'
print('Loading {model_name}'.format(model_name=lenet_model_name))
lenet_model=keras.models.load_model(lenet_model_name)
port = int(os.environ.get('PORT',5000))
app.run(host='0.0.0.0',port=port)