Zeqh Claude Sonnet 4.5 commited on
Commit
e06c4c9
·
1 Parent(s): ebdf66c

Update to more accurate model with scaler normalization

Browse files

- Updated to new trained model (more accurate)
- Added scaler.bin for feature normalization
- Updated to 10 gesture classes (removed 'hi')
- Increased sequence length from 10 to 30 frames
- Raised confidence threshold from 0.5 to 0.7
- Added joblib dependency for scaler loading

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Files changed (5) hide show
  1. Dockerfile +1 -0
  2. app.py +18 -3
  3. requirements.txt +2 -1
  4. scaler.bin +3 -0
  5. trained_model.pth +2 -2
Dockerfile CHANGED
@@ -21,6 +21,7 @@ COPY app.py .
21
  COPY model.py .
22
  COPY preprocessing.py .
23
  COPY trained_model.pth .
 
24
 
25
  # Expose port 7860 (Hugging Face Spaces default)
26
  EXPOSE 7860
 
21
  COPY model.py .
22
  COPY preprocessing.py .
23
  COPY trained_model.pth .
24
+ COPY scaler.bin .
25
 
26
  # Expose port 7860 (Hugging Face Spaces default)
27
  EXPOSE 7860
app.py CHANGED
@@ -4,6 +4,7 @@ FastAPI application for Sign Language Recognition API
4
  import os
5
  import torch
6
  import numpy as np
 
7
  from fastapi import FastAPI, HTTPException
8
  from fastapi.middleware.cors import CORSMiddleware
9
  from pydantic import BaseModel
@@ -33,7 +34,7 @@ app.add_middleware(
33
  # Gesture classes
34
  GESTURES = [
35
  'minum', 'berjalan', 'berlari', 'bola', 'dari',
36
- 'hi', 'jangan', 'mohon', 'pen', 'teh tarik', 'tolong'
37
  ]
38
 
39
  # Configuration
@@ -41,7 +42,7 @@ INPUT_SIZE = 258
41
  HIDDEN_SIZE = 64
42
  NUM_CLASSES = len(GESTURES)
43
  SEQUENCE_LENGTH = 30
44
- CONFIDENCE_THRESHOLD = 0.5
45
 
46
  # Device configuration
47
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
@@ -50,6 +51,7 @@ print(f"Using device: {device}")
50
  # Load model
51
  model = CustomLSTM(INPUT_SIZE, HIDDEN_SIZE, NUM_CLASSES).to(device)
52
  model_path = "trained_model.pth"
 
53
 
54
  try:
55
  model.load_state_dict(torch.load(model_path, map_location=device))
@@ -59,6 +61,14 @@ except Exception as e:
59
  print(f"Error loading model: {e}")
60
  raise
61
 
 
 
 
 
 
 
 
 
62
  # Initialize MediaPipe
63
  mp_holistic = mp.solutions.holistic
64
  holistic = mp_holistic.Holistic(
@@ -161,8 +171,13 @@ async def predict(request: FrameRequest):
161
 
162
  # Make prediction
163
  sequence = sequences[request.session_id][-SEQUENCE_LENGTH:]
 
 
 
 
 
164
  input_tensor = torch.tensor(
165
- np.expand_dims(sequence, axis=0),
166
  dtype=torch.float32
167
  ).to(device)
168
 
 
4
  import os
5
  import torch
6
  import numpy as np
7
+ import joblib
8
  from fastapi import FastAPI, HTTPException
9
  from fastapi.middleware.cors import CORSMiddleware
10
  from pydantic import BaseModel
 
34
  # Gesture classes
35
  GESTURES = [
36
  'minum', 'berjalan', 'berlari', 'bola', 'dari',
37
+ 'jangan', 'mohon', 'pen', 'teh tarik', 'tolong'
38
  ]
39
 
40
  # Configuration
 
42
  HIDDEN_SIZE = 64
43
  NUM_CLASSES = len(GESTURES)
44
  SEQUENCE_LENGTH = 30
45
+ CONFIDENCE_THRESHOLD = 0.7
46
 
47
  # Device configuration
48
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 
51
  # Load model
52
  model = CustomLSTM(INPUT_SIZE, HIDDEN_SIZE, NUM_CLASSES).to(device)
53
  model_path = "trained_model.pth"
54
+ scaler_path = "scaler.bin"
55
 
56
  try:
57
  model.load_state_dict(torch.load(model_path, map_location=device))
 
61
  print(f"Error loading model: {e}")
62
  raise
63
 
64
+ # Load scaler
65
+ try:
66
+ scaler = joblib.load(scaler_path)
67
+ print(f"Scaler loaded successfully from {scaler_path}")
68
+ except Exception as e:
69
+ print(f"Error loading scaler: {e}")
70
+ raise
71
+
72
  # Initialize MediaPipe
73
  mp_holistic = mp.solutions.holistic
74
  holistic = mp_holistic.Holistic(
 
171
 
172
  # Make prediction
173
  sequence = sequences[request.session_id][-SEQUENCE_LENGTH:]
174
+ sequence_array = np.array(sequence)
175
+
176
+ # Apply scaler transformation
177
+ sequence_scaled = scaler.transform(sequence_array)
178
+
179
  input_tensor = torch.tensor(
180
+ np.expand_dims(sequence_scaled, axis=0),
181
  dtype=torch.float32
182
  ).to(device)
183
 
requirements.txt CHANGED
@@ -8,6 +8,7 @@ pydantic==2.5.0
8
  torch==2.1.0
9
  torchvision==0.16.0
10
  numpy==1.26.4
 
11
 
12
  # Computer Vision & MediaPipe
13
  opencv-python-headless==4.10.0.84
@@ -17,4 +18,4 @@ mediapipe==0.10.21
17
  Pillow==10.1.0
18
 
19
  # CORS support
20
- # FastAPI includes CORS middleware via Starlette; no extra package needed.
 
8
  torch==2.1.0
9
  torchvision==0.16.0
10
  numpy==1.26.4
11
+ joblib==1.3.2
12
 
13
  # Computer Vision & MediaPipe
14
  opencv-python-headless==4.10.0.84
 
18
  Pillow==10.1.0
19
 
20
  # CORS support
21
+ python-cors==1.0.0
scaler.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b7c9eeb95ab696a19b0a68a4c04f8b892f95dc527a3ac2284ea6fd2530f9c29c
3
+ size 6807
trained_model.pth CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:c7d97b7dcaea6c08b904d37264641b699af89b8e4347042668b9805371dd06a5
3
- size 489131
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:91c78878580fd5637c8e3d9314ccdd97a150074234453d9f0d10e54d7651ac62
3
+ size 487643