Initial commit: Trashpanzee TFLite model weights, card, and inference script
Browse files- README.md +95 -0
- __pycache__/example_inference.cpython-313.pyc +0 -0
- example_inference.py +71 -0
- labels.txt +2 -0
- model_unquant.tflite +3 -0
README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language:
|
| 3 |
+
- en
|
| 4 |
+
license: mit
|
| 5 |
+
tags:
|
| 6 |
+
- image-classification
|
| 7 |
+
- tflite
|
| 8 |
+
- teachable-machine
|
| 9 |
+
- mobilenet
|
| 10 |
+
- waste-management
|
| 11 |
+
pipeline_tag: image-classification
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# Trashpanzee: Trash Can vs. Not Trash Classifier
|
| 15 |
+
|
| 16 |
+
Trashpanzee is a lightweight, edge-ready computer vision model designed to detect waste receptacles and trash cans in images.
|
| 17 |
+
|
| 18 |
+
## Model Summary
|
| 19 |
+
- **Architecture**: MobileNetV2
|
| 20 |
+
- **Format**: TensorFlow Lite (`model_unquant.tflite`, Float32)
|
| 21 |
+
- **Model Size**: ~2.09 MB
|
| 22 |
+
- **Input Resolution**: 224 x 224 RGB
|
| 23 |
+
- **Input Normalization**: `(pixel_value / 127.5) - 1.0` (Values scaled to `[-1.0, 1.0]`)
|
| 24 |
+
- **Classes**:
|
| 25 |
+
- `0`: `Trash Can`
|
| 26 |
+
- `1`: `Not Trash`
|
| 27 |
+
|
| 28 |
+
## Files Included
|
| 29 |
+
- `model_unquant.tflite`: Unquantized floating-point TFLite model weights.
|
| 30 |
+
- `labels.txt`: Class index mapping.
|
| 31 |
+
- `example_inference.py`: Python script for loading and testing inference.
|
| 32 |
+
|
| 33 |
+
## Quickstart (Python)
|
| 34 |
+
|
| 35 |
+
### 1. Install Dependencies
|
| 36 |
+
```bash
|
| 37 |
+
pip install huggingface_hub ai-edge-litert pillow numpy
|
| 38 |
+
```
|
| 39 |
+
|
| 40 |
+
### 2. Run Inference
|
| 41 |
+
```python
|
| 42 |
+
import numpy as np
|
| 43 |
+
from PIL import Image
|
| 44 |
+
from huggingface_hub import hf_hub_download
|
| 45 |
+
|
| 46 |
+
# Multi-fallback interpreter import
|
| 47 |
+
try:
|
| 48 |
+
from ai_edge_litert.interpreter import Interpreter
|
| 49 |
+
except ImportError:
|
| 50 |
+
try:
|
| 51 |
+
from tflite_runtime.interpreter import Interpreter
|
| 52 |
+
except ImportError:
|
| 53 |
+
import tensorflow as tf
|
| 54 |
+
Interpreter = tf.lite.Interpreter
|
| 55 |
+
|
| 56 |
+
# Download from Hugging Face Hub
|
| 57 |
+
repo_id = "HalfDemon09I/trashpanzee-classifier" # Replace with target repo if different
|
| 58 |
+
model_path = hf_hub_download(repo_id=repo_id, filename="model_unquant.tflite")
|
| 59 |
+
labels_path = hf_hub_download(repo_id=repo_id, filename="labels.txt")
|
| 60 |
+
|
| 61 |
+
# Read labels (with typo cleanup: 'Not Tash' -> 'Not Trash')
|
| 62 |
+
labels = []
|
| 63 |
+
with open(labels_path, "r", encoding="utf-8") as f:
|
| 64 |
+
for line in f:
|
| 65 |
+
line = line.strip()
|
| 66 |
+
if line:
|
| 67 |
+
name = line.split(" ", 1)[-1]
|
| 68 |
+
labels.append("Not Trash" if name.lower() == "not tash" else name)
|
| 69 |
+
|
| 70 |
+
# Initialize interpreter
|
| 71 |
+
interpreter = Interpreter(model_path=model_path)
|
| 72 |
+
interpreter.allocate_tensors()
|
| 73 |
+
input_details = interpreter.get_input_details()
|
| 74 |
+
output_details = interpreter.get_output_details()
|
| 75 |
+
|
| 76 |
+
# Load and preprocess input image
|
| 77 |
+
image = Image.open("sample.jpg").convert("RGB").resize((224, 224))
|
| 78 |
+
input_data = (np.array(image, dtype=np.float32) / 127.5) - 1.0
|
| 79 |
+
input_data = np.expand_dims(input_data, axis=0)
|
| 80 |
+
|
| 81 |
+
# Run inference
|
| 82 |
+
interpreter.set_tensor(input_details[0]["index"], input_data)
|
| 83 |
+
interpreter.invoke()
|
| 84 |
+
output_data = interpreter.get_tensor(output_details[0]["index"])[0]
|
| 85 |
+
|
| 86 |
+
# Display predictions
|
| 87 |
+
results = {labels[i]: float(output_data[i]) for i in range(len(labels))}
|
| 88 |
+
for label, score in sorted(results.items(), key=lambda x: x[1], reverse=True):
|
| 89 |
+
print(f"{label}: {score * 100:.2f}%")
|
| 90 |
+
```
|
| 91 |
+
|
| 92 |
+
## Intended Use & Applications
|
| 93 |
+
- Mobile and edge IoT waste collection and tracking devices.
|
| 94 |
+
- Robotic sorting and autonomous cleaning robots.
|
| 95 |
+
- Educational and smart city recycling awareness applications.
|
__pycache__/example_inference.cpython-313.pyc
ADDED
|
Binary file (4.31 kB). View file
|
|
|
example_inference.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Trashpanzee - Local / Hub Inference Verification Script
|
| 3 |
+
"""
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
import numpy as np
|
| 7 |
+
from PIL import Image
|
| 8 |
+
|
| 9 |
+
# Multi-fallback interpreter import
|
| 10 |
+
try:
|
| 11 |
+
from ai_edge_litert.interpreter import Interpreter
|
| 12 |
+
except ImportError:
|
| 13 |
+
try:
|
| 14 |
+
from tflite_runtime.interpreter import Interpreter
|
| 15 |
+
except ImportError:
|
| 16 |
+
try:
|
| 17 |
+
import tensorflow as tf
|
| 18 |
+
Interpreter = tf.lite.Interpreter
|
| 19 |
+
except ImportError:
|
| 20 |
+
sys.exit(
|
| 21 |
+
"Error: No TFLite runtime found. Please install ai-edge-litert or tflite-runtime or tensorflow:\n"
|
| 22 |
+
" pip install ai-edge-litert pillow numpy"
|
| 23 |
+
)
|
| 24 |
+
|
| 25 |
+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 26 |
+
DEFAULT_MODEL = os.path.join(SCRIPT_DIR, "model_unquant.tflite")
|
| 27 |
+
DEFAULT_LABELS = os.path.join(SCRIPT_DIR, "labels.txt")
|
| 28 |
+
|
| 29 |
+
def load_labels(labels_file=DEFAULT_LABELS):
|
| 30 |
+
labels = []
|
| 31 |
+
if not os.path.exists(labels_file):
|
| 32 |
+
return ["Trash Can", "Not Trash"]
|
| 33 |
+
with open(labels_file, "r", encoding="utf-8") as f:
|
| 34 |
+
for line in f:
|
| 35 |
+
line = line.strip()
|
| 36 |
+
if line:
|
| 37 |
+
name = line.split(" ", 1)[-1]
|
| 38 |
+
labels.append("Not Trash" if name.lower() == "not tash" else name)
|
| 39 |
+
return labels
|
| 40 |
+
|
| 41 |
+
def classify_image(image_path, model_path=DEFAULT_MODEL, labels_path=DEFAULT_LABELS):
|
| 42 |
+
labels = load_labels(labels_path)
|
| 43 |
+
|
| 44 |
+
interpreter = Interpreter(model_path=model_path)
|
| 45 |
+
interpreter.allocate_tensors()
|
| 46 |
+
input_details = interpreter.get_input_details()
|
| 47 |
+
output_details = interpreter.get_output_details()
|
| 48 |
+
|
| 49 |
+
# Load and resize
|
| 50 |
+
image = Image.open(image_path).convert("RGB").resize((224, 224))
|
| 51 |
+
input_data = (np.array(image, dtype=np.float32) / 127.5) - 1.0
|
| 52 |
+
input_data = np.expand_dims(input_data, axis=0)
|
| 53 |
+
|
| 54 |
+
# Inference
|
| 55 |
+
interpreter.set_tensor(input_details[0]["index"], input_data)
|
| 56 |
+
interpreter.invoke()
|
| 57 |
+
output_data = interpreter.get_tensor(output_details[0]["index"])[0]
|
| 58 |
+
|
| 59 |
+
results = {labels[i]: float(output_data[i]) for i in range(len(labels))}
|
| 60 |
+
return results
|
| 61 |
+
|
| 62 |
+
if __name__ == "__main__":
|
| 63 |
+
if len(sys.argv) < 2:
|
| 64 |
+
print("Usage: python example_inference.py <path_to_image>")
|
| 65 |
+
sys.exit(1)
|
| 66 |
+
|
| 67 |
+
img_path = sys.argv[1]
|
| 68 |
+
scores = classify_image(img_path)
|
| 69 |
+
print(f"\nClassification results for '{img_path}':")
|
| 70 |
+
for lbl, prob in sorted(scores.items(), key=lambda x: x[1], reverse=True):
|
| 71 |
+
print(f" {lbl:12s}: {prob * 100:.2f}%")
|
labels.txt
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
0 Trash Can
|
| 2 |
+
1 Not Tash
|
model_unquant.tflite
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:958bfe72816d72be1a4d81076d32681452ab8c32d900304b4240f5b57ce82e86
|
| 3 |
+
size 2090332
|