Files
FoodClassifier/CLAUDE.md
T

133 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目概述
本项目采用**度量学习(Metric Learning)**的方式进行菜品识别和食材识别。核心思路是用 ResNet50 提取图像嵌入向量,配合 FAISS 向量库进行相似度检索,而非传统的端到端分类,从而支持无需重新训练即可快速添加新类别。
**三个并行识别任务:**
- `DishClassification` — 菜品识别
- `WholeIngredientRecognition` — 整体食材识别(未处理)
- `ProcessedIngredientRecognition` — 处理后食材识别(切块等)
## 常用命令
**训练嵌入模型(CosFace 损失,主要方案):**
```bash
python train/train_cosface_embedding.py
```
**CosFace 超参数网格搜索(scale × margin 组合):**
```bash
python train/grid_search_cosface.py
```
**训练嵌入模型(Triplet + Center Loss,备用方案,目前没使用这个了,主要是未采集的图片和现有分类的相似度太高了):**
```bash
python train/train_triplet_embedding.py
```
**基于训练好的模型构建 FAISS 索引:**
```bash
python faiss_vector_db/build_faiss_index.py
```
**启动主识别界面(嵌入向量方案):**
```bash
python classifier/embedding_food_classifier_app.py
```
**启动数据管理与下载界面:**
```bash
python data_management/app.py
```
**训练 SegFormer 食物区域分割模型:**
```bash
python SegFormer/training/train_minimal.py
```
**测试 SegFormer 推理效果:**
```bash
python SegFormer/inference/test_model.py
```
## 架构说明
### 度量学习流水线
```
输入图像 → ResNet50 主干网络(ImageNet1K_V2 预训练)
→ 512 维嵌入向量 → L2 归一化
→ FAISS IndexFlatIP(余弦相似度检索)
→ 返回 Top-K 相似食物及置信度分数
```
**训练损失函数:**
- **CosFace**`train_cosface_embedding.py`):大间距余弦损失;scale ≈ 64margin ≈ 0.35–0.40(因任务而异)。泛化能力更强,为首选方案。
- **Triplet + Center Loss**`train_triplet_embedding.py`):在线难样本挖掘,margin = 0.5Center Loss 权重因任务而异(0.520)。
### 关键模块
| 路径 | 功能说明 |
|------|---------|
| `net/resnet_embedding.py` | ResNet50 嵌入主干网络(512 维,L2 归一化) |
| `net/food_net.py` | 遗留的自定义 CNN,用于端到端分类(4 类) |
| `faiss_vector_db/faiss_manager.py` | FAISS 索引的增删查存核心类 |
| `faiss_vector_db/build_faiss_index.py` | 遍历数据集、提取嵌入、构建索引 |
| `classifier/embedding_food_classifier_app.py` | 主 GUICustomTkinter,支持拖拽上传) |
| `exp_multimodal/vlm_classifier.py` | 实验性:VLMOllama/Kimi+ FAISS 开放集识别 |
| `data_management/app.py` | 数据采集 GUI,从 MySQL 后端下载图片 |
| `settings/settings.py` | 全局配置(NUM_CLASSES、MODEL_DIR、DEVICE 等) |
### FAISS 索引存储结构
每个任务在 `faiss_vector_db/<任务名>/faiss_index/` 下独立存储:
- `food_embeddings.index` — FAISS 二进制索引文件
- `labels.json` / `food_labels.json` — 标签到食物名称的映射
- `embeddings.npy` — 原始向量的 numpy 数组
### 数据集目录结构
```
dataset/<任务名>/
├── train/<类别名>/ (图片)
├── val/<类别名>/
└── test/<类别名>/
```
### VLM 多模态集成(实验性)
`exp_multimodal/` 包含一套绕过封闭类别列表的开放集识别流水线:
- `vlm_providers/ollama_provider.py` — 本地 Ollama 服务(Qwen2.5-VL、LLaVA),地址:`http://192.168.1.250:11434`
- `vlm_providers/kimi_provider.py` — Kimi/Moonshot API`moonshot-v1-128k-vision-preview`
- `build_dish_name_index.py` — 使用 `bge-large-zh-v1.5` 为菜品名称构建文本向量索引
- VLM 配置保存在 `vlm_config.json`(提供商选择、API Key、候选菜品列表)
### SegFormer 食物分割
`SegFormer/` 包含用于提取食物区域的微调 SegFormer:
- 两阶段训练:先冻结编码器训练,再全量微调
- 损失函数:CrossEntropy + 0.5 × Dice Loss
- 数据以 COCO 格式存放于 `SegFormer/data/`
## 模型文件
训练好的模型保存在 `model/` 下的版本子目录中:
- `best_cosface_model.pth` — CosFace 训练的嵌入模型
- `best_embedding_model.pth` — Triplet/Center Loss 训练的嵌入模型
- `grid_search_<时间戳>/best_model_s<scale>_m<margin>.pth` — 网格搜索最优结果
当前使用的模型路径通过 `settings/settings.py` 中的 `MODEL_DIR` 指定。
## 依赖安装
```bash
pip install -r requirements.txt
```
核心依赖:`torch==2.7.0``torchvision==0.22.0``faiss-cpu>=1.7.0``customtkinter==5.2.2``tkinterdnd2==0.4.3``opencv-python==4.11.0.86`
数据管理界面连接远端 MySQL 数据库(`192.168.1.250:3308`)获取图片元数据,同时使用本地 SQLite 记录下载历史。