How to build an end-to-end machine learning application
It is easier than you might think!
Introduction:
Have you wondered how to show your skills and knowledge to the world and probably have a killer project on your resume?
You might have an idea or even an implementation of said idea, be it on Kaggle or your local workspace. Good!, but how will you show this to someone else – send them a link to your Kaggle notebook or your GitHub repository?
This sounds cumbersome, wouldn’t it be cool or convenient to just have an application to show them your exemplary work. So I will try to explain how you can build a complete workflow. The project that I took is Digit recognition for handwritten values. The idea is pretty simple, we draw a digit and then predict what it is between 0–9. (Ah! another digit recognition BS, trust me this will explain a lot and you can build something much cooler). We will deploy our project on Heroku. Let me know how this article can be improved.
How will we do that you ask?
The answer is pretty easy: all you need is some basic knowledge of HTML, CSS, and JavaScript. This will help to build our frontend. For our backend, we will use the flask. All this is okay, but how should we even start, what is the architecture we need to follow? — these are some questions that have to be answered before we even begin to code this.
How should we start?!
Well, the answer to this age-old question is first getting to know what exactly our goal is. I know there are too many questions that I have asked myself :P(most of them are rhetorical). But these are really necessary to our problem. The project structure will be:
So this answers both our questions. Firstly, we will keep all the static files(CSS, JS) in a folder aptly named static and our index.html in a folder named as templates. It is important that these names are not changed. With this, we are done with setting up our template.
Secondly, the architecture we will follow is one of many, there are many ways we can achieve this. We will use the following flow:
- The user draws a digit on the HTML5 canvas and clicks on submit button.
- This image is encoded to base64 at the client-side to reduce server computations.
- The encoded string will be received by our server (which is in python), we then decode this string to convert it to an image. We will use AJAX for client-server communications.
- We then will perform some basic operations on this image to fit our ML model which is already saved so we do not train it again and again. That can be done in the future for better results but we’ll limit ourselves to save time on this article.
In this post, I’ll just let you know how to build our frontend. If you do like this post then stay tuned for the server-side! (Here we go again, some guy trying to build a rapport with the users).
Client-side
So I have used basic HTML, CSS, and JS to build my web app but there is no limitation on you, if you are comfortable in building a better one I say go ahead and let me know too :P. I am a sucker for awesome looking webpages!
My landing page (index) will be put in the “templates” folder and the CSS and JS files will be put in the “static” folder. We will use only the JQuery script to fire requests and responses. The code for canvas looks like
var canvas = document.getElementById(‘myCanvas’);
var ctx = canvas.getContext(‘2d’);
var painting = document.getElementById(‘paint’);
var paint_style = getComputedStyle(painting);canvas.width = parseInt(paint_style.getPropertyValue(‘width’));
canvas.height = parseInt(paint_style.getPropertyValue(‘height’));var mouse = { x: 0, y: 0 };canvas.addEventListener(‘mousemove’, function (e) {mouse.x = e.pageX — this.offsetLeft;
mouse.y = e.pageY — this.offsetTop;}, false);ctx.lineWidth = 10;
ctx.lineJoin = ‘round’;
ctx.lineCap = ‘round’;
ctx.strokeStyle = ‘white’;
ctx.fillStyle = ‘black’;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);var onPaint = function () {
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();
};
The above code will create the canvas we need with a black background and the stroke color as white. We set background if we do not then the result would be an image with only the strokes which might make the prediction of the digit harder. Now basic code can be found on my GitHub.
For handling the Submit and Clear buttons we need to add JavaScript to handle them
The code for this can be like
For now, our canvas can only detect mouse movements but not touch. Touch movements can also be added but that is for another story.
What I am doing is adding an EventListener for the mouse movements — on mouseup the listener is closed so the strokes do not keep changing. The clearArea() function will clear the canvas and this will happen whenever we click on Clear or Submit button. The use of innerHTML will be explained later. The toDataURL() function will encode the canvas to base64: which will be used by FLask.
I hope you liked this article, stay tuned for more and I’ll soon publish another for training our model and backend.