--- license: cc-by-4.0 library_name: tflite pipeline_tag: image-classification tags: - tflite - edge-tpu - google-coral - mobilenetv2 - int8 - quantized - phishing-detection - cybersecurity - security - image-classification - binary-classification - knowledge-distillation - raspberry-pi - on-device language: - en metrics: - accuracy datasets: - custom base_model: - google/mobilenet_v2_1.0_224 model-index: - name: desant-phishing-detector-google-coral-int8 results: - task: type: image-classification name: Phishing Screenshot Detection metrics: - type: accuracy value: 0.8895 name: Validation Accuracy --- # Desant Phishing Detector — MobileNetV2 INT8 for Google Coral Edge TPU **A fully quantized (INT8) MobileNetV2 model for real-time phishing screenshot detection on Google Coral Edge TPU devices.** Distilled from the [Desant CLIP-based phishing classifier](https://huggingface.co/desant-ai/desant-phishing-inference) by **[Desant.ai](https://desant.ai)** for ultra-low-latency edge deployment. > Feed any web page screenshot and the model classifies it as **SAFE** (class 0) or **MALICIOUS / Phishing** (class 1) — entirely on-device, with no cloud round-trip. --- ## Model Details | Property | Value | |---|---| | **Architecture** | MobileNetV2 (ImageNet backbone) + custom dense classifier head | | **Base model** | [MobileNetV2 1.0 224](https://www.tensorflow.org/api_docs/python/tf/keras/applications/MobileNetV2) via `tf.keras.applications` | | **Teacher model** | [Desant CLIP ViT-B/32 Phishing Classifier](https://huggingface.co/desant-ai/desant-phishing-inference) | | **Task** | Binary image classification (safe vs. phishing) | | **Input** | Web page screenshot → `[1, 224, 224, 3]` uint8 | | **Output** | `[1, 2]` uint8 softmax probabilities `[safe, malicious]` | | **Quantization** | Full INT8 post-training quantization (300 representative samples) | | **Edge TPU ops mapped** | **100%** (68/68 operators) — fully compiled for Coral | | **Edge TPU Compiler** | v16.0.384591198 | | **Model size** | **2.93 MB** (Edge TPU) · 2.75 MB (CPU int8 fallback) | | **Framework** | TensorFlow / TFLite | | **Target hardware** | Google Coral USB Accelerator · Coral Dev Board · Raspberry Pi + Coral | | **License** | CC-BY-4.0 | ## Architecture ``` Input Image (web page screenshot) │ ▼ Aspect-ratio-preserving resize + CLIP-mean padding → 224×224 ┌──────────────────────────────┐ │ MobileNetV2 1.0 │ ← ImageNet-pretrained, fine-tuned │ Depthwise Separable Convs │ │ Input: 224×224×3 (uint8) │ │ Inverted Residual Blocks │ └──────────┬───────────────────┘ │ 1280-dim feature map ▼ ┌──────────────────────────────┐ │ GlobalAveragePooling2D │ │ Dropout(0.3) │ │ Dense(128, ReLU) │ │ Dropout(0.2) │ │ Dense(2, Softmax) │ ← [safe, malicious] probabilities └──────────┬───────────────────┘ │ ▼ uint8 output → dequantize → prediction ``` ### Edge TPU Operator Mapping (100% on-chip) All operators execute on the Edge TPU — zero fallback to CPU: | Operator | Count | |---|---| | CONV_2D | 35 | | DEPTHWISE_CONV_2D | 17 | | ADD | 10 | | FULLY_CONNECTED | 2 | | QUANTIZE | 2 | | MEAN | 1 | | SOFTMAX | 1 | | **Total** | **68** | ## Quantization Details | Property | Input Tensor | Output Tensor | |---|---|---| | **Name** | `serving_default_image:0` | `StatefulPartitionedCall_1:0` | | **Shape** | `[1, 224, 224, 3]` | `[1, 2]` | | **Dtype** | uint8 | uint8 | | **Scale** | 0.00784314 | 0.00390625 | | **Zero point** | 127 | 0 | ## Performance Evaluated on a held-out stratified validation set (20% of dataset, 570 images): | Metric | Score | |---|---| | **Validation Accuracy** | 88.95% | | **Validation Loss** | 0.287 | > **Note:** This is a distilled edge model optimized for speed and size. For maximum accuracy, use the [CLIP-based teacher model](https://huggingface.co/desant-ai/desant-phishing-inference) (92–96% accuracy, ~335 MB). ## Training ### Knowledge Distillation Pipeline This model was trained as a **student** in a knowledge distillation pipeline: 1. **Teacher:** CLIP ViT-B/32 fine-tuned phishing classifier (~335 MB, 92–96% accuracy) 2. **Student:** MobileNetV2 trained on the same labeled dataset with class-weighted loss 3. **Export:** Full INT8 post-training quantization with representative calibration dataset 4. **Compile:** Edge TPU compiler maps all operations to the Coral accelerator ### Data | Property | Value | |---|---| | **Total images** | 2,846 | | **Train set** | 2,276 (1,138 safe + 1,138 malicious) | | **Validation set** | 570 (285 safe + 285 malicious) | | **Class balance** | Perfectly balanced (50/50) | - **Malicious class (1):** Real phishing login page screenshots from [PhishTank](https://phishtank.org/), [OpenPhish](https://openphish.com/), [URLhaus](https://urlhaus.abuse.ch/), [AlienVault OTX](https://otx.alienvault.com/) - **Safe class (0):** Legitimate web pages — real login pages (Google, Microsoft, banks), search engines, normal web pages ### Training Configuration | Parameter | Phase 1 (Frozen Backbone) | Phase 2 (Fine-tuning) | |---|---|---| | **Optimizer** | Adam (lr=1e-3) | Adam (lr=1e-5) | | **Epochs** | Up to 20 | Up to 5 | | **Backbone** | Frozen | Last 30 layers unfrozen | | **Loss** | SparseCategoricalCrossentropy | SparseCategoricalCrossentropy | | **Class balancing** | Inverse-frequency class weights | Inverse-frequency class weights | | **Scheduler** | ReduceLROnPlateau (patience=2, factor=0.5) | ReduceLROnPlateau | | **Early stopping** | patience=6 on val_loss | patience=6 on val_loss | | **Batch size** | 32 | 32 | ### Preprocessing Pipeline ```python # 1. Load screenshot (any resolution) # 2. Aspect-ratio-preserving resize to 224×224 # 3. Pad with CLIP-mean color: (123, 117, 104) # 4. MobileNetV2 normalization: [0, 255] → [-1.0, 1.0] # 5. INT8 quantization: scale=0.00784314, zero_point=127 ``` ### Augmentation (training only) - Random horizontal flip (50%) - Brightness jitter ×0.85–1.15 (80%) - Contrast jitter ×0.85–1.15 (80%) - Color/saturation jitter ×0.85–1.15 (50%) ## Usage ### Files in this Repository | File | Description | |---|---| | `student_best_int8_edgetpu_edgetpu.tflite` | Edge TPU compiled model (use with Coral devices) | | `student_best_int8_edgetpu.tflite` | CPU-compatible INT8 TFLite (fallback, no Coral needed) | | `labels.txt` | Class labels (`SAFE`, `MALICIOUS`) | | `metadata.json` | Training metadata and hyperparameters | | `training_history.csv` | Epoch-by-epoch training curves | ### Quick Start — Edge TPU Inference (Python) ```python import numpy as np from PIL import Image from pycoral.adapters import classify, common from pycoral.utils.edgetpu import make_interpreter CLIP_MEAN_PAD = (123, 117, 104) def preprocess(image_path, size=224): """Aspect-ratio-preserving resize with CLIP-mean padding.""" img = Image.open(image_path).convert("RGB") w, h = img.size scale = min(size / w, size / h) new_w, new_h = int(w * scale), int(h * scale) img = img.resize((new_w, new_h), Image.LANCZOS) canvas = Image.new("RGB", (size, size), CLIP_MEAN_PAD) canvas.paste(img, ((size - new_w) // 2, (size - new_h) // 2)) return np.array(canvas, dtype=np.uint8) # Load Edge TPU model interpreter = make_interpreter("student_best_int8_edgetpu_edgetpu.tflite") interpreter.allocate_tensors() # Preprocess and run inference image = preprocess("screenshot.png") common.set_input(interpreter, image) interpreter.invoke() # Get results output = common.output_tensor(interpreter, 0) safe_score = output[0] malicious_score = output[1] label = "MALICIOUS" if malicious_score > safe_score else "SAFE" print(f"{label} — safe: {safe_score}, malicious: {malicious_score}") ``` ### CPU-only Inference (no Coral hardware) ```python import numpy as np from PIL import Image import tflite_runtime.interpreter as tflite CLIP_MEAN_PAD = (123, 117, 104) def preprocess(image_path, size=224): img = Image.open(image_path).convert("RGB") w, h = img.size scale = min(size / w, size / h) new_w, new_h = int(w * scale), int(h * scale) img = img.resize((new_w, new_h), Image.LANCZOS) canvas = Image.new("RGB", (size, size), CLIP_MEAN_PAD) canvas.paste(img, ((size - new_w) // 2, (size - new_h) // 2)) return np.expand_dims(np.array(canvas, dtype=np.uint8), axis=0) interpreter = tflite.Interpreter(model_path="student_best_int8_edgetpu.tflite") interpreter.allocate_tensors() input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() image = preprocess("screenshot.png") interpreter.set_tensor(input_details[0]["index"], image) interpreter.invoke() output = interpreter.get_tensor(output_details[0]["index"])[0] scale = output_details[0]["quantization_parameters"]["scales"][0] zero_point = output_details[0]["quantization_parameters"]["zero_points"][0] probs = (output.astype(np.float32) - zero_point) * scale label = "MALICIOUS" if probs[1] > probs[0] else "SAFE" print(f"{label} — safe: {probs[0]:.4f}, malicious: {probs[1]:.4f}") ``` ### Raspberry Pi 5 + Coral USB Setup ```bash # Install Coral runtime echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" \ | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - sudo apt update && sudo apt install libedgetpu1-std python3-pycoral # Run inference python3 inference.py --model student_best_int8_edgetpu_edgetpu.tflite --image screenshot.png ``` ## Model Family | Model | Size | Accuracy | Hardware | Use Case | |---|---|---|---|---| | [desant-phishing-inference](https://huggingface.co/desant-ai/desant-phishing-inference) | ~335 MB | 92–96% | GPU / CPU | Cloud inference, maximum accuracy | | **desant-phishing-detector-google-coral-int8** (this) | **2.93 MB** | **88.95%** | **Edge TPU / CPU** | **On-device, real-time edge deployment** | ## Intended Use - **Primary use:** Real-time on-device phishing detection on edge hardware (Coral USB, Raspberry Pi) - **Input:** Screenshots of web pages, especially login pages - **Users:** IoT security appliances, edge gateways, browser-integrated hardware, SOC edge nodes, security researchers ## Limitations - Trained primarily on **English-language** phishing pages; reduced accuracy on non-Latin scripts - Optimized for **login form detection** — non-login phishing (e.g. fake download pages) may have lower recall - Accuracy is lower than the CLIP teacher model due to the distillation/quantization tradeoff (~89% vs ~95%) - Very low-resolution or heavily compressed screenshots may reduce accuracy - Detects **visual similarity** to known phishing patterns; novel zero-day designs may evade detection ## Ethical Considerations This model is designed for **defensive cybersecurity** — protecting users from phishing attacks. It should not be used to: - Create or improve phishing pages - Bypass security systems - Conduct adversarial attacks against phishing detection ## Citation ```bibtex @misc{desant2026phishing_edgetpu, title={Desant Phishing Detector: MobileNetV2 INT8 for Google Coral Edge TPU}, author={Desant.ai}, year={2026}, url={https://huggingface.co/desant-ai/desant-phishing-detector-google-coral-int8} } ``` ## Contact - **Company:** [Desant.ai](https://desant.ai) - **Teacher model:** [desant-phishing-inference](https://huggingface.co/desant-ai/desant-phishing-inference) - **Demo:** [Hugging Face Space](https://huggingface.co/spaces/desant-ai/desant-anti-phishing-inferencing)