Heron - Multimodal Phishing Detection
DualTowerFusionModel - a multimodal deep-learning model that classifies an email as legitimate or phishing from its text, embedded images (e.g. spoofed logos), and structural metadata.
Product face: Heron - "Nothing swims past." Live scanner + write-up at the project repo.
Architecture
Three towers fused into one classifier:
| Tower | Input | Output |
|---|---|---|
| Text CNN | Email subject + body (tokenized via vocab_text_1.json) |
256-d |
| Image CNN | Embedded images | 512-d |
| Metadata MLP | 20 structural signals | 20 โ 64-d |
Concatenated 832-d โ fusion classifier 512 โ 256 โ 128 โ 2 โ {legitimate, phishing}.
Results (test set)
| Metric | Value |
|---|---|
| Accuracy | 99.45% |
| AUC-ROC | 0.999 |
| Precision | 99.5% |
| Recall | 99.4% |
| F1 | 99.4% |
Fusion beats every single-modality baseline (Text CNN 98.96, ResNet18 97.43, Image CNN 76.30, KNN 81.71, LogReg 80.00).
Files
best_fusion_model.pth- trained weights (plainstate_dict).vocab_text_1.json- text-tower vocabulary (stoi).
Usage
Weights are a plain state_dict; load into the DualTowerFusionModel definition (see project src/fusion_models.py).
from huggingface_hub import hf_hub_download
import torch
weights = hf_hub_download("vishalpatil-18/heron-phishing", "best_fusion_model.pth")
vocab = hf_hub_download("vishalpatil-18/heron-phishing", "vocab_text_1.json")
model = DualTowerFusionModel() # from src/fusion_models.py
model.load_state_dict(torch.load(weights, weights_only=True, map_location="cpu"))
model.eval()
Or scan an email live via the Heron API / dashboard.
Intended use & limitations
Detects phishing in HTML/plain-text emails. Trained on a fixed dataset; performance may drop on email styles or attack patterns outside that distribution. Use as a signal, not a sole gate.