133 lines
4.9 KiB
Markdown
133 lines
4.9 KiB
Markdown
# 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 ≈ 64,margin ≈ 0.35–0.40(因任务而异)。泛化能力更强,为首选方案。
|
||
- **Triplet + Center Loss**(`train_triplet_embedding.py`):在线难样本挖掘,margin = 0.5,Center Loss 权重因任务而异(0.5–20)。
|
||
|
||
### 关键模块
|
||
|
||
| 路径 | 功能说明 |
|
||
|------|---------|
|
||
| `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` | 主 GUI(CustomTkinter,支持拖拽上传) |
|
||
| `exp_multimodal/vlm_classifier.py` | 实验性:VLM(Ollama/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 记录下载历史。
|