├── README.md ├── app.py ├── static ├── css │ └── main.css └── js │ └── main.js └── templates ├── base.html └── index.html /README.md: -------------------------------------------------------------------------------- 1 | # Deployment-Deep-Learning-Model -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from __future__ import division, print_function 2 | # coding=utf-8 3 | import sys 4 | import os 5 | import glob 6 | import re 7 | import numpy as np 8 | 9 | # Keras 10 | from keras.applications.imagenet_utils import preprocess_input, decode_predictions 11 | from keras.models import load_model 12 | from keras.preprocessing import image 13 | 14 | # Flask utils 15 | from flask import Flask, redirect, url_for, request, render_template 16 | from werkzeug.utils import secure_filename 17 | from gevent.pywsgi import WSGIServer 18 | 19 | # Define a flask app 20 | app = Flask(__name__) 21 | 22 | # Model saved with Keras model.save() 23 | MODEL_PATH = 'models/model_resnet.h5' 24 | 25 | # Load your trained model 26 | model = load_model(MODEL_PATH) 27 | model._make_predict_function() # Necessary 28 | # print('Model loaded. Start serving...') 29 | 30 | # You can also use pretrained model from Keras 31 | # Check https://keras.io/applications/ 32 | #from keras.applications.resnet50 import ResNet50 33 | #model = ResNet50(weights='imagenet') 34 | #model.save('') 35 | print('Model loaded. Check http://127.0.0.1:5000/') 36 | 37 | 38 | def model_predict(img_path, model): 39 | img = image.load_img(img_path, target_size=(224, 224)) 40 | 41 | # Preprocessing the image 42 | x = image.img_to_array(img) 43 | # x = np.true_divide(x, 255) 44 | x = np.expand_dims(x, axis=0) 45 | 46 | # Be careful how your trained model deals with the input 47 | # otherwise, it won't make correct prediction! 48 | x = preprocess_input(x, mode='caffe') 49 | 50 | preds = model.predict(x) 51 | return preds 52 | 53 | 54 | @app.route('/', methods=['GET']) 55 | def index(): 56 | # Main page 57 | return render_template('index.html') 58 | 59 | 60 | @app.route('/predict', methods=['GET', 'POST']) 61 | def upload(): 62 | if request.method == 'POST': 63 | # Get the file from post request 64 | f = request.files['file'] 65 | 66 | # Save the file to ./uploads 67 | basepath = os.path.dirname(__file__) 68 | file_path = os.path.join( 69 | basepath, 'uploads', secure_filename(f.filename)) 70 | f.save(file_path) 71 | 72 | # Make prediction 73 | preds = model_predict(file_path, model) 74 | 75 | # Process your result for human 76 | # pred_class = preds.argmax(axis=-1) # Simple argmax 77 | pred_class = decode_predictions(preds, top=1) # ImageNet Decode 78 | result = str(pred_class[0][0][1]) # Convert to string 79 | return result 80 | return None 81 | 82 | 83 | if __name__ == '__main__': 84 | app.run(debug=True) 85 | 86 | -------------------------------------------------------------------------------- /static/css/main.css: -------------------------------------------------------------------------------- 1 | .img-preview { 2 | width: 256px; 3 | height: 256px; 4 | position: relative; 5 | border: 5px solid #F8F8F8; 6 | box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1); 7 | margin-top: 1em; 8 | margin-bottom: 1em; 9 | } 10 | 11 | .img-preview>div { 12 | width: 100%; 13 | height: 100%; 14 | background-size: 256px 256px; 15 | background-repeat: no-repeat; 16 | background-position: center; 17 | } 18 | 19 | input[type="file"] { 20 | display: none; 21 | } 22 | 23 | .upload-label{ 24 | display: inline-block; 25 | padding: 12px 30px; 26 | background: #39D2B4; 27 | color: #fff; 28 | font-size: 1em; 29 | transition: all .4s; 30 | cursor: pointer; 31 | } 32 | 33 | .upload-label:hover{ 34 | background: #34495E; 35 | color: #39D2B4; 36 | } 37 | 38 | .loader { 39 | border: 8px solid #f3f3f3; /* Light grey */ 40 | border-top: 8px solid #3498db; /* Blue */ 41 | border-radius: 50%; 42 | width: 50px; 43 | height: 50px; 44 | animation: spin 1s linear infinite; 45 | } 46 | 47 | @keyframes spin { 48 | 0% { transform: rotate(0deg); } 49 | 100% { transform: rotate(360deg); } 50 | } -------------------------------------------------------------------------------- /static/js/main.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | // Init 3 | $('.image-section').hide(); 4 | $('.loader').hide(); 5 | $('#result').hide(); 6 | 7 | // Upload Preview 8 | function readURL(input) { 9 | if (input.files && input.files[0]) { 10 | var reader = new FileReader(); 11 | reader.onload = function (e) { 12 | $('#imagePreview').css('background-image', 'url(' + e.target.result + ')'); 13 | $('#imagePreview').hide(); 14 | $('#imagePreview').fadeIn(650); 15 | } 16 | reader.readAsDataURL(input.files[0]); 17 | } 18 | } 19 | $("#imageUpload").change(function () { 20 | $('.image-section').show(); 21 | $('#btn-predict').show(); 22 | $('#result').text(''); 23 | $('#result').hide(); 24 | readURL(this); 25 | }); 26 | 27 | // Predict 28 | $('#btn-predict').click(function () { 29 | var form_data = new FormData($('#upload-file')[0]); 30 | 31 | // Show loading animation 32 | $(this).hide(); 33 | $('.loader').show(); 34 | 35 | // Make prediction by calling api /predict 36 | $.ajax({ 37 | type: 'POST', 38 | url: '/predict', 39 | data: form_data, 40 | contentType: false, 41 | cache: false, 42 | processData: false, 43 | async: true, 44 | success: function (data) { 45 | // Get and display the result 46 | $('.loader').hide(); 47 | $('#result').fadeIn(600); 48 | $('#result').text(' Result: ' + data); 49 | console.log('Success!'); 50 | }, 51 | }); 52 | }); 53 | 54 | }); 55 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |