AsamiYukiko commited on
Commit
1082fc8
·
1 Parent(s): f69f2cb

Switch model to ResNet18, update app and dependencies

Browse files
.gitattributes CHANGED
@@ -33,4 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
36
  *.onnx.data filter=lfs diff=lfs merge=lfs -text
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.data filter=lfs diff=lfs merge=lfs -text
37
+ models/resnet18.onnx.data filter=lfs diff=lfs merge=lfs -text
38
  *.onnx.data filter=lfs diff=lfs merge=lfs -text
Dockerfile CHANGED
@@ -1,13 +1,26 @@
 
1
  FROM python:3.11-slim
 
 
2
  RUN useradd -m -u 1000 user
 
3
  WORKDIR /app
 
 
4
  COPY requirements.txt .
5
  RUN pip install --no-cache-dir -r requirements.txt
6
  RUN pip install --no-cache-dir gunicorn
 
 
7
  COPY --chown=user app.py .
8
  COPY --chown=user templates/ templates/
9
  COPY --chown=user models/ models/
 
 
10
  USER user
11
  ENV HOME=/home/user \
12
  PATH=/home/user/.local/bin:$PATH
 
 
 
13
  CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "1", "--timeout", "120", "app:app"]
 
1
+ # PV Defect Classifier — HuggingFace Spaces
2
  FROM python:3.11-slim
3
+
4
+ # HuggingFace requirement: UID 1000 non-root user
5
  RUN useradd -m -u 1000 user
6
+
7
  WORKDIR /app
8
+
9
+ # Install dependencies (cache layer)
10
  COPY requirements.txt .
11
  RUN pip install --no-cache-dir -r requirements.txt
12
  RUN pip install --no-cache-dir gunicorn
13
+
14
+ # Copy application code (--chown avoids permission issues)
15
  COPY --chown=user app.py .
16
  COPY --chown=user templates/ templates/
17
  COPY --chown=user models/ models/
18
+
19
+ # Switch to non-root user
20
  USER user
21
  ENV HOME=/home/user \
22
  PATH=/home/user/.local/bin:$PATH
23
+
24
+ # HuggingFace Spaces requires port 7860
25
+ # 1 worker = 1 model copy in memory; timeout 120s for cold start
26
  CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "1", "--timeout", "120", "app:app"]
app.py CHANGED
@@ -4,11 +4,6 @@ PV Defect Classification — Flask Demo
4
  Loads the best ONNX model and serves a web interface for
5
  real-time photovoltaic panel defect classification.
6
 
7
- Usage:
8
- 1. Put your .onnx model file in the /models folder
9
- 2. pip install flask onnxruntime pillow numpy
10
- 3. python app.py
11
- 4. Open http://localhost:7860 in your browser
12
  """
13
 
14
  import os
@@ -18,7 +13,7 @@ from PIL import Image
18
  from flask import Flask, render_template, request, jsonify
19
  import onnxruntime as ort
20
 
21
- # ── Config ────────────────────────────────────────────────────
22
  MODEL_DIR = os.path.join(os.path.dirname(__file__), "models")
23
  CLASS_NAMES = ["DEFECTIVE", "NORMAL"]
24
  IMG_SIZE = 224
@@ -27,7 +22,7 @@ STD = np.array([0.229, 0.224, 0.225], dtype=np.float32)
27
 
28
  app = Flask(__name__)
29
 
30
- # ── Load ONNX model ──────────────────────────────────────────
31
  def find_onnx_model():
32
  """Auto-detect the first .onnx file in /models."""
33
  for f in os.listdir(MODEL_DIR):
@@ -39,13 +34,13 @@ model_path = find_onnx_model()
39
  if model_path:
40
  session = ort.InferenceSession(model_path)
41
  input_name = session.get_inputs()[0].name
42
- print(f"Loaded model: {os.path.basename(model_path)}")
43
  else:
44
  session = None
45
- print("⚠️ No .onnx file found in /models — place your model there and restart.")
46
 
47
 
48
- # ── Preprocessing (same as val_tf in your notebook) ──────────
49
  def preprocess(image: Image.Image) -> np.ndarray:
50
  """Resize, normalise, and convert PIL image to ONNX input tensor."""
51
  img = image.convert("RGB").resize((IMG_SIZE, IMG_SIZE))
@@ -60,7 +55,7 @@ def softmax(x):
60
  return e / e.sum()
61
 
62
 
63
- # ── Routes ────────────────────────────────────────────────────
64
  @app.route("/")
65
  def index():
66
  model_name = os.path.basename(model_path) if model_path else "No model loaded"
@@ -117,4 +112,4 @@ def health():
117
 
118
 
119
  if __name__ == "__main__":
120
- app.run(debug=False, host="0.0.0.0", port=7860)
 
4
  Loads the best ONNX model and serves a web interface for
5
  real-time photovoltaic panel defect classification.
6
 
 
 
 
 
 
7
  """
8
 
9
  import os
 
13
  from flask import Flask, render_template, request, jsonify
14
  import onnxruntime as ort
15
 
16
+ # Config
17
  MODEL_DIR = os.path.join(os.path.dirname(__file__), "models")
18
  CLASS_NAMES = ["DEFECTIVE", "NORMAL"]
19
  IMG_SIZE = 224
 
22
 
23
  app = Flask(__name__)
24
 
25
+ # Load ONNX model
26
  def find_onnx_model():
27
  """Auto-detect the first .onnx file in /models."""
28
  for f in os.listdir(MODEL_DIR):
 
34
  if model_path:
35
  session = ort.InferenceSession(model_path)
36
  input_name = session.get_inputs()[0].name
37
+ print(f"Loaded model: {os.path.basename(model_path)}")
38
  else:
39
  session = None
40
+ print(" No .onnx file found in /models — place your model there and restart.")
41
 
42
 
43
+ # Preprocessing
44
  def preprocess(image: Image.Image) -> np.ndarray:
45
  """Resize, normalise, and convert PIL image to ONNX input tensor."""
46
  img = image.convert("RGB").resize((IMG_SIZE, IMG_SIZE))
 
55
  return e / e.sum()
56
 
57
 
58
+ # Routes
59
  @app.route("/")
60
  def index():
61
  model_name = os.path.basename(model_path) if model_path else "No model loaded"
 
112
 
113
 
114
  if __name__ == "__main__":
115
+ app.run(debug=True, host="0.0.0.0", port=5000)
models/resnet18.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0c17d9def594a5c33a89d6331b6497f9c145e40dd4aa44a728b8a82bd9119c46
3
+ size 88415
models/resnet18.onnx.data ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:498153c0a1da770809f354285351ccdc58a36818d0e5dbfe13127e4cac4c0b6d
3
+ size 44695552
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
  flask==3.0.0
2
- onnxruntime>=1.18.1
3
  Pillow==10.2.0
4
  numpy==1.26.3
 
1
  flask==3.0.0
2
+ onnxruntime>=1.20.0
3
  Pillow==10.2.0
4
  numpy==1.26.3