{"id":32929162,"url":"https://github.com/camchambers/number-classifier","last_synced_at":"2026-04-15T19:38:57.532Z","repository":{"id":323337545,"uuid":"1092326734","full_name":"camchambers/number-classifier","owner":"camchambers","description":"A full-stack handwritten digit classification system that allows users to draw digits (0-9) on a canvas and get real-time predictions using a custom-trained PyTorch CNN model.","archived":false,"fork":false,"pushed_at":"2025-11-18T13:02:26.000Z","size":3740,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-18T15:57:50.521Z","etag":null,"topics":["cnn","fastapi","machine-learning","neural-network","pytorch","react"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/camchambers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-08T12:22:53.000Z","updated_at":"2025-11-18T13:02:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/camchambers/number-classifier","commit_stats":null,"previous_names":["camchambers/number-classifier"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/camchambers/number-classifier","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camchambers%2Fnumber-classifier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camchambers%2Fnumber-classifier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camchambers%2Fnumber-classifier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camchambers%2Fnumber-classifier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/camchambers","download_url":"https://codeload.github.com/camchambers/number-classifier/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camchambers%2Fnumber-classifier/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31857615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"ssl_error","status_checked_at":"2026-04-15T15:24:39.138Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cnn","fastapi","machine-learning","neural-network","pytorch","react"],"created_at":"2025-11-11T11:10:44.815Z","updated_at":"2026-04-15T19:38:57.524Z","avatar_url":"https://github.com/camchambers.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Number Classifier\n\nA handwritten digit classification system with a PyTorch CNN model, FastAPI backend, and React frontend.\n\n\u003cimg src=\"screenshots/ui.png\" alt=\"Number Classifier UI\" height=\"500\"\u003e\n\n## Features\n\n- PyTorch CNN trained on handwritten digits\n- FastAPI backend for model inference\n- React UI with canvas for drawing digits\n- ~98% validation accuracy\n\n## Project Status\n\n- Model training and testing complete\n- FastAPI backend operational\n- React frontend with canvas drawing\n- End-to-end integration working\n\n## Dataset\n\nUses the [Handwritten Digits 0-9 dataset from Kaggle](https://www.kaggle.com/datasets/olafkrastovski/handwritten-digits-0-9?resource=download).\n\n- ~21,555 grayscale images\n- 10 classes (digits 0-9)\n- Located in `data/numbers/`\n\n## Project Structure\n\n```\nnumber-classifier/\n├── training/             # Training scripts and utilities\n│   ├── train.py         # Model training script\n│   ├── test_model.py    # Model testing script\n│   └── README.md        # Training documentation\n├── api/                  # FastAPI backend\n│   ├── main.py          # API endpoints\n│   ├── model.py         # Model architecture\n│   ├── requirements.txt # API dependencies\n│   ├── run.sh           # API startup script\n│   └── README.md        # API documentation\n├── ui/                   # React frontend (Vite)\n│   ├── src/\n│   │   ├── components/  # React components\n│   │   │   ├── App.tsx\n│   │   │   ├── Canvas.tsx\n│   │   │   └── ClassificationResult.tsx\n│   │   ├── pages/       # Page components\n│   │   │   └── Home.tsx\n│   │   ├── api/         # API client\n│   │   │   └── classifier.ts\n│   │   ├── utils/       # Utility functions\n│   │   │   └── imageUtils.ts\n│   │   └── styles/      # CSS styles\n│   └── package.json\n├── data/\n│   └── numbers/         # Training dataset (0-9 folders)\n├── models/\n│   ├── model_best.pth   # Best trained model checkpoint\n│   └── model_final.pth  # Final model after all epochs\n├── requirements.txt     # Python dependencies\n└── README.md            # This file\n```\n\n## Getting Started\n\n### Prerequisites\n\n- Python 3.8+\n- Node.js 16+ (for UI)\n- pip\n\n### Installation\n\n1. **Clone the repository**\n   ```bash\n   git clone https://github.com/camchambers/number-classifier.git\n   cd number-classifier\n   ```\n\n2. **Install Python dependencies**\n   ```bash\n   pip install -r requirements.txt\n   ```\n\n3. **Download the dataset**\n   - Download from [Kaggle](https://www.kaggle.com/datasets/olafkrastovski/handwritten-digits-0-9?resource=download)\n   - Extract to `data/numbers/` directory\n\n## Training\n\nTrain the CNN model on the digit dataset:\n\n```bash\npython3 training/train.py\n```\n\n**Training Details:**\n- Architecture: 3 Conv layers + 3 FC layers (defined in `api/model.py`)\n- Input: 28x28 grayscale images\n- Batch size: 64\n- Epochs: 10\n- Optimizer: Adam (lr=0.001)\n- Validation split: 80/20\n\n**Output:**\n- `models/model_best.pth` - Best model checkpoint (highest validation accuracy during training)\n- `models/model_final.pth` - Final model state after all epochs complete\n\n**Note:** The API uses `model_best.pth` for inference as it typically generalizes better than the final model.\n\n## Testing\n\nTest the trained model on individual images:\n\n```bash\npython3 training/test_model.py data/numbers/5/img_1.jpg\n```\n\n**Output:**\n```\n==================================================\nPredicted Digit: 5\nConfidence: 99.87%\n==================================================\n\nAll class probabilities:\n  0:  0.01% \n  1:  0.02% \n  2:  0.03% \n  3:  0.01% \n  4:  0.04% \n  5: 99.87% ██████████████████████████████████████████████████\n  6:  0.01% \n  7:  0.00% \n  8:  0.01% \n  9:  0.00% \n```\n\n## Running the Application\n\n### 1. Start the API (FastAPI)\n\n```bash\ncd api\n./run.sh\n```\n\nOr manually:\n```bash\ncd api\npython3 -m uvicorn main:app --reload\n```\n\nAPI will be available at `http://localhost:8000`  \nAPI Documentation: `http://localhost:8000/docs`\n\n### 2. Start the UI (React + Vite)\n\n```bash\ncd ui\nnpm install\nnpm run dev\n```\n\nUI will be available at `http://localhost:5173`\n\n### 3. Use the Application\n\n1. Open `http://localhost:5173` in your browser\n2. Draw a digit (0-9) on the canvas using your mouse\n3. Click \"Classify\" to send the drawing to the API\n4. View the predicted digit with confidence score and probability distribution\n5. Click \"Clear\" to reset and try another digit\n\n## Model Architecture\n\n```\nDigitClassifier(\n  (conv1): Conv2d(1, 32, kernel_size=(3, 3), padding=1)\n  (conv2): Conv2d(32, 64, kernel_size=(3, 3), padding=1)\n  (conv3): Conv2d(64, 128, kernel_size=(3, 3), padding=1)\n  (pool): MaxPool2d(kernel_size=2, stride=2)\n  (dropout): Dropout(p=0.5)\n  (fc1): Linear(in_features=1152, out_features=256)\n  (fc2): Linear(in_features=256, out_features=128)\n  (fc3): Linear(in_features=128, out_features=10)\n)\n```\n\n**Total Parameters**: ~550,000\n\n## Dependencies\n\n### Python\n- torch \u003e= 2.0.0\n- torchvision \u003e= 0.15.0\n- fastapi \u003e= 0.104.0\n- uvicorn \u003e= 0.24.0\n- pillow \u003e= 10.0.0\n- numpy \u003e= 1.24.0\n\n### JavaScript\n- React 18\n- TypeScript\n- Vite\n- (See `ui/package.json` for full list)\n\n## UI Features\n\n- Canvas for drawing digits\n- Real-time classification\n- Confidence scores and probability distribution\n- Error handling\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is open source and available under the [MIT License](LICENSE).\n\n## Author\n\n**Cam Chambers**\n- GitHub: [@camchambers](https://github.com/camchambers)\n\n## Acknowledgments\n\nDataset: [Olaf Krastovski's Handwritten Digits 0-9](https://www.kaggle.com/datasets/olafkrastovski/handwritten-digits-0-9)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcamchambers%2Fnumber-classifier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcamchambers%2Fnumber-classifier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcamchambers%2Fnumber-classifier/lists"}