DEV Community

Cover image for From SageMaker to Static Site: Hosting a Deep Learning Model on the Frontend
Alex Retana
Alex Retana

Posted on

From SageMaker to Static Site: Hosting a Deep Learning Model on the Frontend

A couple of weeks ago, I revisited an old project: a face mask classifier I originally built in Keras.
In my last article, I retrained it three different ways:

✅ Classic deep learning (TensorFlow inside SageMaker Studio)

⚙️ Low-code SageMaker Canvas

🧠 Fully managed Rekognition Custom Labels

This time, I wanted to see if I could make the model run entirely in the browser. Not just for fun, but because it felt like a win on multiple fronts: it would remove backend inference costs since there’d be no server running 24/7; keep the webcam feed local to the user’s machine, improving privacy; and create a live demo anyone could try instantly, without waiting on an API call or spinning up infrastructure.

Here’s how that turned out, and why it was trickier than I first thought.

⚙️ Step 1: Converting my Keras model for TensorFlow.js

My original classifier was trained in SageMaker Studio, saved in the latest Keras v3 format.
Problem: TensorFlow.js only supports converting the old Keras v2 .h5 format.

So the first thing I had to do:

Retrain the model (same code, but explicitly save it to .h5)

Use the CLI:

tensorflowjs_converter \
  --input_format keras \
  my_model.h5 \
  ./model_web/
That produced a browser-ready model.json + weight files.
Loading it in JS was simple:
Enter fullscreen mode Exit fullscreen mode
const model = await tf.loadLayersModel('/model_web/model.json');
Enter fullscreen mode Exit fullscreen mode

This felt like a small win — but the model only takes cropped face images.
Next problem: how do I detect faces?

📦 Step 2: Adding face detection

In the original pipeline, I used a YOLOv3 model to detect faces, then classified them.
But YOLOv3 is heavy for browser use.

I needed something smaller, that worked in TensorFlow.js.

Luckily, TensorFlow.js has some pretrained lightweight face detectors.
I picked one, tested it on the webcam stream, and it worked surprisingly well:

Detect faces → crop → run classifier → draw predictions

All in real time.

Suddenly, I had a browser app that could see your face and tell if you were wearing a mask — without sending anything to a server.

🚫 Honorable Mention: Why Canvas & Rekognition models didn’t make it

At this point, I was hoping I could also bring over the models I built in SageMaker Canvas and Rekognition to run directly in the browser. But pretty quickly, I ran into hard limits: SageMaker Canvas only lets you export a model meant for Python or TensorFlow Serving, with no option to get a .h5 or SavedModel that I could convert for TensorFlow.js; and Rekognition Custom Labels doesn’t let you download the trained model at all — it’s locked behind AWS’s API. Since the whole goal was to keep everything frontend-only and client-side, these two paths just didn’t fit. It was a good reminder that the more managed and abstracted a tool is, the less portable your model ends up being.

🧰 Step 3: Building the demo & making it repeatable

With the model running locally in the browser, I wanted to take the next step: actually host it online so anyone could try it, and make deployments effortless. To do that, I built a small React frontend that grabs the webcam feed, detects faces, runs the mask classifier, and draws the predictions on screen in real time. Then I wrote some Terraform to handle the infrastructure: provisioning a public S3 bucket for static hosting, a CloudFront distribution for global CDN, and IAM roles to support CI/CD. Finally, I set up GitHub Actions so that every time I push to the repository, it automatically builds the site and deploys it to S3.

Now it’s fully repeatable:

terraform apply
Enter fullscreen mode Exit fullscreen mode

And it’s live.

✅ Wrapping it up

In the end, what started as an old Keras side project turned into a modern, privacy‑friendly browser demo — running real‑time face detection and mask classification entirely on the client. To clean up the frontend, I rebuilt it using Solid.js for fast reactivity, styled it with Tailwind CSS and daisyUI, and added subtle animations with auto‑animate and solid‑transition‑group to make the UI feel more alive.

I even tried to get it working on mobile devices, but ran into a familiar wall: the model was just too big to run smoothly in the browser on most phones. At that point, training a new, smaller model felt like it deserved to be its own project — and I decided to leave it for another day.

Still, I’m happy with how it turned out: a repeatable, low‑cost, fully frontend ML demo that anyone can try without sending a single frame to a backend. And while it’s not production‑ready, it’s proof that with the right tools and some cloud glue, you can bring even an old deep learning project back to life — and make it feel brand new.

If you’ve tried something similar, run into the same Keras/TensorFlow.js headaches, or have ideas on building lighter models for mobile, I’d love to hear about it in the comments!

You can try the live demo here → Face Mask Classifier Demo, and if you’re curious about my other projects, check out my portfolio at retanatech.com.

Top comments (0)