metadata
language:
- en
license: apache-2.0
tags:
- image-classification
- tflite
- flutter
- quickdraw
- doodle-recognition
- on-device-inference
- se-resnet
datasets:
- google/quickdraw
metrics:
- accuracy
library_name: tflite
pipeline_tag: image-classification
model-index:
- name: quickdraw-345-se-resnet
results:
- task:
type: image-classification
name: Image Classification
dataset:
name: Google Quick Draw
type: google/quickdraw
metrics:
- type: accuracy
value: 0.7619
name: Top-1 Accuracy
- type: accuracy
value: 0.8951
name: Top-3 Accuracy
- type: accuracy
value: 0.9226
name: Top-5 Accuracy
- type: accuracy
value: 0.9455
name: Top-10 Accuracy
- type: accuracy
value: 0.764
name: TFLite Float16 Accuracy
QuickDraw 345 Doodle Classifier — TFLite
A doodle recognition model trained on all 345 categories from Google's Quick Draw Dataset, exported as TFLite for Flutter on-device offline inference.
Model Performance
| Metric | Accuracy |
|---|---|
| Top-1 | 76.19% |
| Top-3 | 89.51% |
| Top-5 | 92.26% |
| Top-10 | 94.55% |
| TFLite (float16) | 76.40% |
State-of-the-art for 345-class Quick Draw classification is ~73-75% top-1. This model exceeds that.
Files
| File | Size | Description |
|---|---|---|
quickdraw_model.tflite |
8.44 MB | Float16 quantized — recommended for Flutter |
quickdraw_model_int8.tflite |
4.34 MB | Int8 quantized — smallest, fastest |
labels.txt |
2.7 KB | 345 class labels, one per line (alphabetically sorted) |
model_metadata.json |
6.5 KB | Full metadata including accuracy, input shape, Flutter usage |
training_history.json |
5.7 KB | Loss/accuracy per epoch |
categories.txt |
2.7 KB | Raw category list |
Architecture
- SE-ResNet (Squeeze-and-Excitation + ResNet blocks)
- 3 stages: 64 → 128 → 256 filters
- Input: 28×28 grayscale images
- Output: 345-class softmax
- ~3M parameters
Training
- Dataset: Google Quick Draw numpy bitmaps (GCS), 8,000 samples/class × 345 classes = 2.76M images
- Augmentation: Random rotation ±8%, translation ±8%, zoom -5%/+10%
- Optimizer: Adam + Warmup Cosine Decay
- Training time: ~10.9 hours on Kaggle GPU P100
Flutter Integration
pubspec.yaml
dependencies:
tflite_flutter: ^0.10.4
flutter:
assets:
- assets/quickdraw_model.tflite
- assets/labels.txt
Dart Usage
import 'package:tflite_flutter/tflite_flutter.dart';
class QuickDrawClassifier {
late Interpreter _interpreter;
late List<String> _labels;
Future<void> load() async {
_interpreter = await Interpreter.fromAsset('assets/quickdraw_model.tflite');
final labelsData = await rootBundle.loadString('assets/labels.txt');
_labels = labelsData.trim().split('\n');
}
/// [pixels] must be a 28x28 Float32List, values in [0.0, 1.0]
/// where 0.0 = black stroke, 1.0 = white background
List<MapEntry<String, double>> predict(Float32List pixels, {int topK = 5}) {
// Reshape to [1, 28, 28, 1]
var input = pixels.reshape([1, 28, 28, 1]);
var output = List.filled(1 * 345, 0.0).reshape([1, 345]);
_interpreter.run(input, output);
final probs = List<double>.from(output[0]);
final indexed = probs.asMap().entries.toList()
..sort((a, b) => b.value.compareTo(a.value));
return indexed.take(topK)
.map((e) => MapEntry(_labels[e.key], e.value))
.toList();
}
}
Preprocessing a drawing canvas
/// Convert your drawing canvas to a 28x28 normalized Float32List
Float32List canvasToInput(ui.Image image) async {
// Resize to 28x28
final recorder = ui.PictureRecorder();
final canvas = Canvas(recorder);
canvas.drawImageRect(
image,
Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble()),
Rect.fromLTWH(0, 0, 28, 28),
Paint(),
);
final resized = await recorder.endRecording().toImage(28, 28);
final bytes = await resized.toByteData(format: ui.ImageByteFormat.rawRgba);
// Convert RGBA to grayscale float32, normalize to [0,1]
// white background = 1.0, black strokes = 0.0
final pixels = Float32List(28 * 28);
for (int i = 0; i < 28 * 28; i++) {
final r = bytes!.getUint8(i * 4);
final g = bytes.getUint8(i * 4 + 1);
final b = bytes.getUint8(i * 4 + 2);
pixels[i] = (0.299 * r + 0.587 * g + 0.114 * b) / 255.0;
}
return pixels;
}
Input/Output Spec
| Property | Value |
|---|---|
| Input shape | [1, 28, 28, 1] |
| Input dtype | float32 |
| Input range | [0.0, 1.0] |
| Background | 1.0 (white) |
| Stroke | 0.0 (black) |
| Output shape | [1, 345] |
| Output dtype | float32 |
| Output | Softmax probabilities |
License
Model weights: Apache 2.0
Dataset: Creative Commons Attribution 4.0 (Google Quick Draw)