| | --- |
| | tags: |
| | - ocr |
| | - pytorch |
| | license: mit |
| | datasets: |
| | - hammer888/captcha-data |
| | metrics: |
| | - accuracy |
| | - cer |
| | pipeline_tag: image-to-text |
| | library_name: transformers |
| | --- |
| | |
| | <div align="center"> |
| |
|
| | # ✨ DeepCaptcha-Conv-Transformer: Sequential Vision for OCR |
| | ### Convolutional Transformer Base |
| |
|
| | [](https://opensource.org/licenses/MIT) |
| | [](https://www.python.org/downloads/release/python-3130/) |
| | [](https://huggingface.co/Graf-J/captcha-crnn-finetuned) |
| |
|
| | --- |
| |
|
| | <img src="images/CAPTCHA.png" alt="Captcha Example" width="500"> |
| |
|
| | *Advanced sequence recognition using a Convolutional Transformer Encoder with Connectionist Temporal Classification (CTC) loss.* |
| |
|
| | </div> |
| |
|
| | --- |
| |
|
| | ## 📋 Model Details |
| | - **Task:** Alphanumeric Captcha Recognition |
| | - **Input:** Images |
| | - **Output:** String sequences (Length 1–8 characters) |
| | - **Vocabulary:** Alphanumeric (`a-z`, `A-Z`, `0-9`) |
| | - **Architecture:** Convolutional Transformer Encoder (CNN + Transformer Encoder) |
| |
|
| | --- |
| |
|
| | ## 📊 Performance Metrics |
| | This project features four models exploring the trade-offs between recurrent (LSTM) and attention-based (Transformer) architectures, as well as the effects of fine-tuning on capchas generated by the [Python Captcha Library](https://captcha.lepture.com/). |
| |
|
| |
|
| | | Metric | **CRNN (Base)** | **CRNN (Finetuned)** | **Conv-Transformer (Base)** | **Conv-Transformer (Finetuned)** | |
| | |--------|-----------------|----------------------|-----------------------------|----------------------------------| |
| | | Architecture | CRNN | CRNN | Convolutional Transformer | Convolutional Transformer | |
| | | Training Data | [hammer888/captcha-data](https://huggingface.co/datasets/hammer888/captcha-data) | [hammer888/captcha-data](https://huggingface.co/datasets/hammer888/captcha-data) <br> [Python Captcha Library](https://captcha.lepture.com/) | [hammer888/captcha-data](https://huggingface.co/datasets/hammer888/captcha-data) | [hammer888/captcha-data](https://huggingface.co/datasets/hammer888/captcha-data) <br> [Python Captcha Library](https://captcha.lepture.com/) | |
| | | # Parameters | **3,570,943** | **3,570,943** | 12,279,551 | 12,279,551 | |
| | | Model Size | **14.3 MB** | **14.3 MB** | 51.7 MB | 51.7 MB | |
| | | Sequence Accuracy <br> ([hammer888/captcha-data](https://huggingface.co/datasets/hammer888/captcha-data)) | 96.81% | 92.98% | **97.38%** | 95.36% | |
| | | Character Error Rate (CER) <br> ([hammer888/captcha-data](https://huggingface.co/datasets/hammer888/captcha-data)) | 0.70% | 1.59% | **0.57%** | 1.03% | |
| | | Sequence Accuracy <br> ([Python Captcha Library](https://captcha.lepture.com/)) | 9.65% | 86.20% | 11.59% | **88.42%** | |
| | | Character Error Rate (CER) <br> ([Python Captcha Library](https://captcha.lepture.com/)) | 43.98% | 2.53% | 38.63% | **2.08%** | |
| | | Throughput (img/sec) | 447.26 | 447.26 | **733.00** | **733.00** | |
| | | Compute Hardware | NVIDIA RTX A6000 | NVIDIA RTX A6000 | NVIDIA RTX A6000 | NVIDIA RTX A6000 | |
| | | Link | [Graf-J/captcha-crnn-base](https://huggingface.co/Graf-J/captcha-crnn-base) | [Graf-J/captcha-crnn-finetuned](https://huggingface.co/Graf-J/captcha-crnn-finetuned) | [Graf-J/captcha-conv-transformer-base](https://huggingface.co/Graf-J/captcha-conv-transformer-base) | [Graf-J/captcha-conv-transformer-finetuned](https://huggingface.co/Graf-J/captcha-conv-transformer-finetuned) |
| |
|
| | --- |
| |
|
| | ## 🧪 Try It With Sample Images |
| |
|
| | The following are images sampled of the test set of the [hammer888/captcha-data](https://huggingface.co/datasets/hammer888/captcha-data) dataset. Click any image below to download it and test the model locally. |
| |
|
| | <div align="center"> |
| | <table> |
| | <tr> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/46CN5W.jpg"><img src="images/46CN5W.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/5820.jpg"><img src="images/5820.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/6521.jpg"><img src="images/6521.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/abfsh.jpg"><img src="images/abfsh.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/67qas.jpg"><img src="images/67qas.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/75ke.jpg"><img src="images/75ke.jpg" width="120"/></a></td> |
| | </tr> |
| | <tr> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/8JKM.jpg"><img src="images/8JKM.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/8jpwt0.jpg"><img src="images/8jpwt0.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/B1QAZ6.jpg"><img src="images/B1QAZ6.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/CCX8.jpg"><img src="images/CCX8.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/EPOD.jpg"><img src="images/EPOD.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/ER6Y.jpg"><img src="images/ER6Y.jpg" width="120"/></a></td> |
| | </tr> |
| | <tr> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/EWSP.jpg"><img src="images/EWSP.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/GIOGp.jpg"><img src="images/GIOGp.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/HCDS.jpg"><img src="images/HCDS.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/JBWkEs.jpg"><img src="images/JBWkEs.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/kJtOfk.jpg"><img src="images/kJtOfk.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/MFMH.jpg"><img src="images/MFMH.jpg" width="120"/></a></td> |
| | </tr> |
| | <tr> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/NJSEX.jpg"><img src="images/NJSEX.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/R6AB.jpg"><img src="images/R6AB.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/TVHF.jpg"><img src="images/TVHF.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/Vb4cG.jpg"><img src="images/Vb4cG.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/XaNqQx.jpg"><img src="images/XaNqQx.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/YULM.jpg"><img src="images/YULM.jpg" width="120"/></a></td> |
| | </tr> |
| | <tr> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/b6yc.jpg"><img src="images/b6yc.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/bCWaLR.jpg"><img src="images/bCWaLR.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/d3no.jpg"><img src="images/d3no.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/3eplzv.jpg"><img src="images/3eplzv.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/iq1sZo.jpg"><img src="images/iq1sZo.jpg" width="120"/></a></td> |
| | <td><a href="https://huggingface.co/Graf-J/captcha-crnn-finetuned/resolve/main/images/KKh8Q.jpg"><img src="images/KKh8Q.jpg" width="120"/></a></td> |
| | </tr> |
| | </table> |
| | </div> |
| |
|
| | --- |
| |
|
| | ## 🚀 Quick Start (Pipeline - Recommended) |
| |
|
| | The easiest way to perform inference is using the custom Hugging Face pipeline. |
| |
|
| | ```python |
| | from transformers import pipeline |
| | from PIL import Image |
| | |
| | # Initialize the pipeline |
| | pipe = pipeline( |
| | task="captcha-recognition", |
| | model="Graf-J/captcha-conv-transformer-base", |
| | trust_remote_code=True |
| | ) |
| | |
| | # Load and predict |
| | img = Image.open("path/to/image.png") |
| | result = pipe(img) |
| | print(f"Decoded Text: {result['prediction']}") |
| | |
| | ``` |
| |
|
| | ## 🔬 Advanced Usage (Raw Logits & Custom Decoding) |
| |
|
| | Use this method if you need access to the raw logits or internal hidden states. |
| |
|
| | ```python |
| | import torch |
| | from PIL import Image |
| | from transformers import AutoModel, AutoProcessor |
| | |
| | # Load Model & Custom Processor |
| | repo_id = "Graf-J/captcha-conv-transformer-base" |
| | processor = AutoProcessor.from_pretrained(repo_id, trust_remote_code=True) |
| | model = AutoModel.from_pretrained(repo_id, trust_remote_code=True) |
| | |
| | model.eval() |
| | |
| | # Load and process image |
| | img = Image.open("path/to/image.png") |
| | inputs = processor(img) |
| | |
| | # Inference |
| | with torch.no_grad(): |
| | outputs = model(inputs["pixel_values"]) |
| | logits = outputs.logits |
| | |
| | # Decode the prediction via CTC logic |
| | prediction = processor.batch_decode(logits)[0] |
| | print(f"Prediction: '{prediction}'") |
| | |
| | ``` |
| |
|
| | --- |
| |
|
| | ## ⚙️ Training |
| | The base model was trained on a refined version of the [hammer888/captcha-data](https://huggingface.co/datasets/hammer888/captcha-data) (1,365,874 images). This dataset underwent a specialized cleaning process where multiple pre-trained models were used to identify and prune inconsistent data. Specifically, images where models were "confidently incorrect" regarding casing (upper/lower-case errors) were removed to ensure high-fidelity ground truth for the final training run. |
| |
|
| | ### **Parameters** |
| | - **Optimizer:** Adam (lr=0.0005) |
| | - **Scheduler:** ReduceLROnPlateau (factor=0.5, patience=3) |
| | - **Batch Size:** 128 |
| | - **Loss Function:** CTCLoss |
| | - **Augmentations:** ElasticTransform, Random Rotation, Grayscale Resize |
| |
|
| | --- |
| |
|
| | ## 🔍 Error Analysis |
| |
|
| | The following confusion matrices illustrate the character-level performance across the alphanumeric vocabulary for the test dataset of the images generated via Python. |
| |
|
| | ### **Full Confusion Matrix** |
| |  |
| |
|
| | ### **Misclassification Deep Dive** |
| |
|
| | This matrix highlights only the misclassification patterns, stripping away correct predictions to visualize which character pairs (such as '0' vs 'O' or '1' vs 'l') the model most frequently confuses. While the dataset underwent a specialized cleaning process to minimize noisy labels, the confusion matrix reveals a residual pattern of misclassifications between visually similar upper and lowercase characters. |
| |
|
| |  |
| |
|
| | --- |
| |
|
| | ## ⚖️ **License & Citation** |
| |
|
| | This project is licensed under the **MIT License**. If you use this model in your research, portfolio, or applications, please attribute the author. |
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|