Преглед на файлове

fix(ai): 情绪识别 DeepFace 置信度归一化 + 权重预置

- emotion.py: DeepFace 返回 0-100 百分比,归一化为 0.0-1.0(修复 schema le=1 校验失败 500)
- detector_backend 用 opencv(内置 Haar Cascade,无需额外 mediapipe 依赖)
- Dockerfile: 预置 DeepFace FER 权重到镜像(避开 GitHub 下载限速)
- docker-compose.yml: pin 镜像 v3
- 新增 .dockerignore 加速构建
Xiaogang Liao преди 1 седмица
родител
ревизия
cd03a0e288
променени са 4 файла, в които са добавени 32 реда и са изтрити 6 реда
  1. 15 0
      cfc-langgraph/.dockerignore
  2. 5 0
      cfc-langgraph/Dockerfile
  3. 1 0
      cfc-langgraph/docker-compose.yml
  4. 11 6
      cfc-langgraph/src/graphs/emotion.py

+ 15 - 0
cfc-langgraph/.dockerignore

@@ -0,0 +1,15 @@
+.git
+.gitignore
+.venv/bin
+.venv/lib/python3.12/site-packages/__pycache__
+__pycache__
+*.pyc
+*.pyo
+.env
+.env.production
+data/chroma_db
+data/chroma_db_memory
+node_modules
+tests
+docs
+README.md

+ 5 - 0
cfc-langgraph/Dockerfile

@@ -24,6 +24,11 @@ RUN useradd -m -u 1000 appuser && \
     mkdir -p /data/chroma_db && \
     chown -R appuser:appuser /data
 
+# 预置 DeepFace 情绪识别模型(避开 GitHub 下载限速)
+RUN mkdir -p /home/appuser/.deepface/weights && \
+    cp /app/data/deepface-weights/*.h5 /home/appuser/.deepface/weights/ 2>/dev/null || true && \
+    chown -R appuser:appuser /home/appuser/.deepface
+
 USER appuser
 
 EXPOSE 9000

+ 1 - 0
cfc-langgraph/docker-compose.yml

@@ -21,6 +21,7 @@ services:
       retries: 3
 
   langgraph-svc:
+    image: cfc-langgraph-langgraph-svc:v3
     build:
       context: .
       dockerfile: Dockerfile

+ 11 - 6
cfc-langgraph/src/graphs/emotion.py

@@ -92,7 +92,7 @@ def analyze_emotion(state: GraphState) -> GraphState:
         result = DeepFace.analyze(
             img_path=state["image_path"],
             actions=["emotion"],
-            detector_backend="mediapipe",   # 比 opencv 快 3x
+            detector_backend="opencv",   # 内置 Haar Cascade,无需额外模型
             enforce_detection=False,
             silent=True,
         )
@@ -113,22 +113,27 @@ def format_result(state: GraphState) -> GraphState:
         return state
 
     emo = state["emotion_result"]
-    # emo 格式:{'emotion': {'happy': 0.85, 'neutral': 0.10, ...}, ...}
+    # DeepFace 返回 0-100 百分比(如 {'happy': 85.0, ...}),需归一化为 0.0-1.0
     raw_emotions = emo.get("emotion", {})
 
+    # 归一化:值 >1 视为百分比,除以 100
+    norm = {}
+    for k, v in raw_emotions.items():
+        norm[k] = round(v / 100.0, 4) if v > 1.0 else round(v, 4)
+
     # 找出主导情绪
-    dominant = max(raw_emotions, key=raw_emotions.get) if raw_emotions else "neutral"
+    dominant = max(norm, key=norm.get) if norm else "neutral"
     dominant_zh = EMOTION_ZH.get(dominant, dominant)
 
     # 结构化列表
     emotions = [
-        {"emotion": k, "confidence": round(v, 4)}
-        for k, v in sorted(raw_emotions.items(), key=lambda x: -x[1])
+        {"emotion": k, "confidence": v}
+        for k, v in sorted(norm.items(), key=lambda x: -x[1])
     ]
 
     state["dominant_emotion"] = dominant
     state["dominant_label_zh"] = dominant_zh
-    state["all_emotions"] = {k: round(v, 4) for k, v in raw_emotions.items()}
+    state["all_emotions"] = norm
     state["emotions"] = emotions
     return state