← Projects

Deep-Fake-Detector

Classroom CNN experiment on real and face-swap images; about 94% on an internal evaluation.

Summer 2024 · Machine learning · Archived experiment

Deepfake Detection web app upload page — large white card over teal and blue background panels with warning text, best-results note, dashed drag-and-drop upload zone, TensorFlow.js and BlazeFace footer, and copyright line
The browser version — a TensorFlow.js model behind a drag-and-drop face upload.

Stack

Stack: Python · TensorFlow · Keras · InsightFace · TensorFlow.js · BlazeFace · React

A still-image class experiment: FFHQ photographs for the real class and InsightFace-generated face-swaps for the fake class.

Log

  1. Summer 2024 — UTD research class

    Two weeks of fundamentals — model architectures, use cases, a detour through reinforcement learning — and a final brief: pick a thing and train a CNN on it. The brief picked itself.

  2. The pipeline

    Six steps on the whiteboard: collect a dataset, clean it, augment it, define the layers, train and test, ship. The model was step four. Almost everything that mattered happened before it.

  3. The 'real' half — FFHQ

    NVlabs' Flickr-Faces-HQ (FFHQ) is a GAN-benchmark dataset of real photographs. I used its portraits as the real class for this experiment.

    Collage of sample real faces from FFHQ (Flickr-Faces-HQ) by NVlabs — a single high-resolution portrait alongside a grid of diverse faces spanning age, ethnicity, lighting, and pose, originally a GAN benchmark dataset
    Real-photo examples from FFHQ.
  4. The 'fake' half — InsightFace

    I generated still-image face-swaps with InsightFace by selecting a source and target photo and saving the swapped frame. This created the fake-image class for the experiment; performance on broader deepfakes or video was not established.

    InsightFace face-swap example: a Tom Holland Spider-Man photo labeled 'Source' plus a Tobey Maguire Spider-Man photo labeled 'Target' arrowed into a 'Result' frame with Holland's face composited onto Maguire's body
    Source + target → result. The fake class, generated one frame at a time.
  5. Architecture

    Sequential CNN — four Conv2D blocks (32 → 64 → 128 → 128, 3×3, ReLU) with a MaxPool after each, Flatten, two Dropout(0.5) gates around a Dense(512) head, sigmoid out for binary. Standard shape, no surprises.

    CNN architecture diagram for the deep-fake detector — Sequential model with Conv2D(32,3x3,relu) + MaxPool, Conv2D(64) + MaxPool, Conv2D(128) + MaxPool, Conv2D(128) + MaxPool, Flatten, Dropout(0.5), Dense(512,relu), Dropout(0.5), Dense(1,sigmoid) for binary real-vs-fake classification
    The stack. Input on top, sigmoid verdict on the bottom.
  6. Trial and error — unbalanced data

    The 10-epoch run reported 60%, the 50-epoch run 75%, and the 100-epoch balanced-data run about 94%. The architecture stayed the same; the runs changed the data balance and training duration.

    Three pairs of training and validation accuracy/loss line graphs stacked vertically — top pair from a 10-epoch run topping out near 60%, middle pair from a 50-epoch run reaching 75%, bottom pair from a 100-epoch run climbing to 94% on a balanced dataset
    Three runs, same architecture. Different shape of data, different shape of curve.
  7. Final result

    The internal class-project evaluation reported about 94% accuracy. Performance beyond the evaluated images, including on video deepfakes, was not established.

  8. Browser deploy

    Converted the .h5/Keras weights into a TensorFlow.js JSON folder, dropped them into a React/Tailwind page, and put BlazeFace upstream of the CNN to crop the face out of any uploaded image. Drag a photo into the upload zone, get a verdict in the browser. Pushed to GitHub Pages as deepdetect.github.io.

    deepdetect.github.io drag-and-drop upload zone for testing real vs deepfake faces in the browser via TensorFlow.js + BlazeFace — large dashed-border drop area with 'Click to upload or drag and drop, PNG, JPG or GIF (MAX. 800x400px)' prompt and a 'Powered by TensorFlow.js and BlazeFace' footer
    The shipped page. CNN running in the browser, BlazeFace cropping the face before it ever sees the model.

Gallery

Final model result training charts — fourth attempt at 100 epochs and 94 percent accuracy, with training and validation accuracy rising toward 0.9 to 1.0 and training and validation loss dropping across the run
Fourth attempt. 100 epochs, 94 percent.

Result

~94% reported internal class-project evaluation

What I learned

The architecture stayed the same across the project runs, while the reported result changed with data balance and training duration. The internal class-project evaluation reported about 94%; performance on other image sources or video was not established. Most of the work sat before model definition: choosing a real-photo dataset, generating still-image swaps, and balancing the classes. Once the weights existed, they were a few megabytes of JSON the browser could load with TensorFlow.js.