Офлайн-проект · ML + Android

Грибной определитель

Определение вида гриба по фотографии — полностью офлайн, на устройстве. EfficientNet-Lite0 → TFLite int8, 300–500 видов, интерфейс на русском. А на этой же странице — онлайн-карта грибных условий Беларуси с погодным прогнозом по видам.

384×384вход модели
int8квантизация
≤ 15 МБразмер модели
Top-5предсказаний
100%офлайн
0телеметрии
Онлайн-модуль · Live

Карта грибных условий Беларуси

Погодный прогноз вероятности плодоношения по видам: 0 лесных массивов, данные Open-Meteo за 14 дней.

Обзор

Два модуля: ML-пайплайн и Android-приложение

Python-скрипты готовят датасет, обучают и квантуют модель; Kotlin-приложение выполняет инференс на устройстве без сети.

Онлайн-модуль: карта условий РБ

Погода, лес, радиация, отчёты сообщества — интерактивный прогноз вероятности плодоношения по видам грибов на карте Беларуси.

Открыть карту
ML-пайплайн
Пять скриптов в каталоге ml/ — от сбора фотографий до готового TFLite-файла.
1

Выгрузка данных

download_inaturalist.py

Загрузка фотографий с iNaturalist по списку видов; принимаются только открытые лицензии cc0 / cc-by / cc-by-sa.

2

Подготовка датасета

prepare_dataset.py

Дедупликация по perceptual hash, отбраковка мусора, stratified-сплит 80/10/10, аугментации без hue-shift — цвет гриба является видовым признаком.

3

Обучение

train.py

Transfer learning на EfficientNet-Lite0 в две фазы (голова → fine-tune), class weights против дисбаланса классов.

4

Квантизация и экспорт

quantize_export.py

Квантизация int8 с representative dataset, экспорт model.tflite и labels.json для Android-приложения.

5

Оценка качества

evaluate.py

Top-1 / Top-5 на выборках val / test / field_test, confusion-пары самых путаемых видов, замер latency инференса.

Android-приложение
Каталог android/ — нативное приложение на Kotlin с Material 3.
KotlinJetpack ComposeCameraXRoomPhoto PickerTFLite GPU + CPU fallback
  • Онбординг

    Первый запуск с обязательным чекбоксом-подтверждением рисков.

  • Съёмка

    Камера через CameraX или выбор фото из галереи (Photo Picker).

  • Результат

    Top-5 предсказаний с вероятностями и предупреждением об ошибке.

  • Карточка вида

    Описание, съедобность «по литературным данным» и lookalikes-двойники.

  • Каталог

    Все виды из базы с поиском по русским и латинским названиям.

  • О приложении

    Версия модели, лицензии данных, дисклеймер.

Запуск

Инструкция запуска от данных до APK

Восемь шагов: подготовьте данные, прогоните ML-пайплайн, соберите базу видов и выпустите Android-приложение.

1

Подготовка данных

Список видов положите в data/species_list.csv (колонки species_id,latin,russian), фотографии — по папкам data/raw/<латинское имя вида>/.

# Список видов: species_id,latin,russian
cp data/samples/species_list_sample.csv data/species_list.csv
mkdir -p "data/raw/Amanita_muscaria"   # фото вида — в его папку

cp с образцом — это быстрый старт; для полного прогона подготовьте свой CSV.

2

Окружение Python

Виртуальное окружение и зависимости ML-пайплайна.

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r ml/requirements.txt
3

Сбор фотографий

Выгрузка фото с iNaturalist по списку видов. Это единственный шаг, который требует интернет — дальше всё работает офлайн.

python ml/download_inaturalist.py
4

Подготовка датасета

Дедупликация, отбраковка, сплит 80/10/10 и аугментации.

python ml/prepare_dataset.py
5

Обучение модели

Transfer learning EfficientNet-Lite0 в две фазы с class weights.

python ml/train.py
6

Квантизация и экспорт

int8-квантизация с representative dataset; артефакты пишутся прямо в assets Android-приложения.

python ml/quantize_export.py
# → android/app/src/main/assets/model.tflite
# → android/app/src/main/assets/labels.json
# → android/app/src/main/assets/model_meta.json
7

База видов

Сборка Room-совместимой SQLite-базы из CSV-источников.

python db/build_species_db.py   # → species.db
8

Сборка APK

Откройте каталог android/ в Android Studio (Hedgehog или новее) и соберите release-APK с включённым R8.

# Открыть папку android/ в Android Studio (Hedgehog+)
# Build → Generate Signed App Bundle / APK (release, R8 включён)

Gradle-wrapper не лежит в репозитории — Android Studio сгенерирует его при первом открытии проекта.

Безопасность

Грибы — не та область, где можно ошибаться молча

Шесть жёстких требований к поведению приложения, которые проверяются на приёмке.

Постоянный дисклеймер

На экране результата всегда отображается предупреждение: «Определение может быть ошибочным».

Формулировки съедобности

Только «по литературным данным относится к …» — никаких прямых рекомендаций «можно есть».

Порог уверенности

Если уверенность top-1 ниже 0.6, приложение отвечает: «Не удалось определить».

Равновероятные варианты

Если Δ(top1, top2) < 0.2, оба варианта подсвечиваются как равновероятные.

Смертельно ядовитые

Для видов с признаком deadly красный баннер показывается при любой уверенности модели.

Нет разрешения INTERNET

У приложения отсутствует разрешение на сеть — телеметрия невозможна архитектурно, данные не покидают устройство.

Приёмка

Критерии приёмки проекта

Чек-лист, по которому проверяется готовая сборка — от размера артефактов до unit-тестов.

  • APK размером не более 30 МБ
  • model.tflite размером не более 15 МБ
  • Инференс быстрее 500 мс на CPU (Redmi Note 12)
  • Все функции работают в airplane mode
  • Поворот экрана во время инференса не ломает результат
  • Битое фото и отказ камеры обрабатываются корректно
  • Unit-тесты: паритет препроцессинга Kotlin ↔ Python
  • Unit-тесты: парсер labels.json
  • Unit-тесты: Room-DAO