gajavegs commited on
Commit
52af76f
·
1 Parent(s): 7c50ef1

Add example images

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. Dockerfile +5 -0
  2. __pycache__/model_loader.cpython-39.pyc +0 -0
  3. app.py +76 -25
  4. confusion_matrix_examples.zip +3 -0
  5. confusion_matrix_examples/FN/Stable Diffusion_0001 (6).jpg +0 -0
  6. confusion_matrix_examples/FN/Stable Diffusion_0003 (3).jpg +0 -0
  7. confusion_matrix_examples/FN/Stable Diffusion_0004 (2).jpg +0 -0
  8. confusion_matrix_examples/FN/Stable Diffusion_0013 (10).jpg +0 -0
  9. confusion_matrix_examples/FN/Stable Diffusion_0013.jpg +0 -0
  10. confusion_matrix_examples/FN/Stable Diffusion_0017 (10).jpg +0 -0
  11. confusion_matrix_examples/FN/Stable Diffusion_0019 (10).jpg +0 -0
  12. confusion_matrix_examples/FN/Stable Diffusion_0019 (9).jpg +0 -0
  13. confusion_matrix_examples/FN/Stable Diffusion_0027 (7).jpg +0 -0
  14. confusion_matrix_examples/FN/Stable Diffusion_0030.jpg +0 -0
  15. confusion_matrix_examples/FP/Stable Diffusion_101 (3).jpg +0 -0
  16. confusion_matrix_examples/FP/Stable Diffusion_102 (10).jpg +0 -0
  17. confusion_matrix_examples/FP/Stable Diffusion_102 (9).jpg +0 -0
  18. confusion_matrix_examples/FP/Stable Diffusion_112 (3).jpg +0 -0
  19. confusion_matrix_examples/FP/Stable Diffusion_115 (4).jpg +0 -0
  20. confusion_matrix_examples/FP/Stable Diffusion_117 (3).jpg +0 -0
  21. confusion_matrix_examples/FP/Stable Diffusion_117 (9).jpg +0 -0
  22. confusion_matrix_examples/FP/Stable Diffusion_118 (4).jpg +0 -0
  23. confusion_matrix_examples/FP/Stable Diffusion_124 (3).jpg +0 -0
  24. confusion_matrix_examples/FP/Stable Diffusion_125 (8).jpg +0 -0
  25. confusion_matrix_examples/TN/Stable Diffusion_0 (10).jpg +0 -0
  26. confusion_matrix_examples/TN/Stable Diffusion_0 (2).jpg +0 -0
  27. confusion_matrix_examples/TN/Stable Diffusion_0 (3).jpg +0 -0
  28. confusion_matrix_examples/TN/Stable Diffusion_0 (4).jpg +0 -0
  29. confusion_matrix_examples/TN/Stable Diffusion_0 (5).jpg +0 -0
  30. confusion_matrix_examples/TN/Stable Diffusion_0 (6).jpg +0 -0
  31. confusion_matrix_examples/TN/Stable Diffusion_0 (7).jpg +0 -0
  32. confusion_matrix_examples/TN/Stable Diffusion_0 (8).jpg +0 -0
  33. confusion_matrix_examples/TN/Stable Diffusion_0 (9).jpg +0 -0
  34. confusion_matrix_examples/TN/Stable Diffusion_0.jpg +0 -0
  35. confusion_matrix_examples/TP/Stable Diffusion_0000 (10).jpg +0 -0
  36. confusion_matrix_examples/TP/Stable Diffusion_0000 (2).jpg +0 -0
  37. confusion_matrix_examples/TP/Stable Diffusion_0000 (3).jpg +0 -0
  38. confusion_matrix_examples/TP/Stable Diffusion_0000 (4).jpg +0 -0
  39. confusion_matrix_examples/TP/Stable Diffusion_0000 (5).jpg +0 -0
  40. confusion_matrix_examples/TP/Stable Diffusion_0000 (6).jpg +0 -0
  41. confusion_matrix_examples/TP/Stable Diffusion_0000 (7).jpg +0 -0
  42. confusion_matrix_examples/TP/Stable Diffusion_0000 (8).jpg +0 -0
  43. confusion_matrix_examples/TP/Stable Diffusion_0000 (9).jpg +0 -0
  44. confusion_matrix_examples/TP/Stable Diffusion_0000.jpg +0 -0
  45. confusion_matrix_examples/collection_summary.txt +19 -0
  46. images/FN.jpg +0 -0
  47. images/FP.jpg +0 -0
  48. images/TN.jpg +0 -0
  49. images/TP.jpg +0 -0
  50. requirements.txt +1 -0
Dockerfile CHANGED
@@ -25,6 +25,11 @@ COPY . /app
25
  # Hugging Face sets $PORT; Gunicorn will bind to it.
26
  ENV PORT=7860
27
  ENV MODEL_PATH=models/alexnext_vsf_bext.pth
 
 
 
 
 
28
  ENV FLASK_DEBUG=0
29
 
30
  # Single worker (GPU inference), thread worker for simplicity
 
25
  # Hugging Face sets $PORT; Gunicorn will bind to it.
26
  ENV PORT=7860
27
  ENV MODEL_PATH=models/alexnext_vsf_bext.pth
28
+ ENV CONFUSion_PATH=images/TP.jpg
29
+ ENV TP_PATH=images/TP.jpg
30
+ ENV TN_PATH=images/TN.jpg
31
+ ENV FN_PATH=images/FN.jpg
32
+ ENV FP_PATH=images/FP.jpg
33
  ENV FLASK_DEBUG=0
34
 
35
  # Single worker (GPU inference), thread worker for simplicity
__pycache__/model_loader.cpython-39.pyc ADDED
Binary file (1.25 kB). View file
 
app.py CHANGED
@@ -1,11 +1,12 @@
1
  import os
2
- from typing import Any
3
- from flask import Flask, jsonify, request, send_from_directory
4
  from PIL import Image
5
  import torch
6
  import torch.nn.functional as F
7
  from dotenv import load_dotenv
8
  from model_loader import load_alexnet_model, preprocess_image
 
9
 
10
  load_dotenv(override=True)
11
 
@@ -14,11 +15,25 @@ PORT = int(os.getenv("PORT", os.getenv("FLASK_PORT", "7860")))
14
  HOST = "0.0.0.0"
15
  MODEL_PATH = os.getenv("MODEL_PATH", "models/alexnext_vsf_bext.pth")
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  # Single worker is safest for GPU inference
18
  torch.set_num_threads(1)
19
 
20
  # Create app and static hosting
21
  app = Flask(__name__, static_folder="static", static_url_path="")
 
22
 
23
  # Device selection
24
  DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
@@ -29,48 +44,84 @@ model.to(DEVICE).eval()
29
 
30
  @app.get("/")
31
  def root() -> Any:
32
- # serve your frontend
33
  return send_from_directory(app.static_folder, "index.html")
34
 
35
  @app.get("/health")
36
  def health() -> Any:
37
  return jsonify({"status": "ok", "device": str(DEVICE)})
38
 
39
- def load_image(file_stream):
40
- return Image.open(file_stream).convert("RGB")
41
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  @app.post("/predict_AlexNet")
43
  def predict_alexnet() -> Any:
44
  if "image" not in request.files:
45
  return jsonify({"error": "Missing file field 'image'."}), 400
46
-
47
  file = request.files["image"]
48
  if not file:
49
  return jsonify({"error": "Empty file."}), 400
50
-
51
  try:
52
  img = load_image(file.stream)
53
- input_tensor = preprocess_image(img).to(DEVICE)
54
-
55
- with torch.no_grad():
56
- output = model(input_tensor)
57
- probabilities = F.softmax(output[0], dim=0).detach().cpu()
58
-
59
- pred_prob, pred_idx = torch.max(probabilities, dim=0)
60
- predicted_class = classes[int(pred_idx)]
61
-
62
- result = {
63
- "class": predicted_class,
64
- "confidence": float(pred_prob),
65
- "probabilities": {
66
- cls: float(prob) for cls, prob in zip(classes, probabilities.tolist())
67
- },
68
- }
69
  return jsonify(result)
70
-
71
  except Exception as e:
72
  return jsonify({"error": f"Failed to process image: {e}"}), 400
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  if __name__ == "__main__":
75
  debug = bool(int(os.getenv("FLASK_DEBUG", "0")))
76
  app.run(host=HOST, port=PORT, debug=debug)
 
1
  import os
2
+ from typing import Any, Dict
3
+ from flask import Flask, jsonify, request, send_from_directory, abort
4
  from PIL import Image
5
  import torch
6
  import torch.nn.functional as F
7
  from dotenv import load_dotenv
8
  from model_loader import load_alexnet_model, preprocess_image
9
+ from flask_cors import CORS
10
 
11
  load_dotenv(override=True)
12
 
 
15
  HOST = "0.0.0.0"
16
  MODEL_PATH = os.getenv("MODEL_PATH", "models/alexnext_vsf_bext.pth")
17
 
18
+ # Preset image paths via ENV
19
+ TP_PATH = os.getenv("TP_PATH", "images/TP.jpg")
20
+ TN_PATH = os.getenv("TN_PATH", "images/TN.jpg")
21
+ FN_PATH = os.getenv("FN_PATH", "images/FN.jpg")
22
+ FP_PATH = os.getenv("FP_PATH", "images/FP.jpg")
23
+
24
+ PRESET_MAP: Dict[str, str] = {
25
+ "TP": TP_PATH,
26
+ "TN": TN_PATH,
27
+ "FN": FN_PATH,
28
+ "FP": FP_PATH,
29
+ }
30
+
31
  # Single worker is safest for GPU inference
32
  torch.set_num_threads(1)
33
 
34
  # Create app and static hosting
35
  app = Flask(__name__, static_folder="static", static_url_path="")
36
+ CORS(app)
37
 
38
  # Device selection
39
  DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 
44
 
45
  @app.get("/")
46
  def root() -> Any:
 
47
  return send_from_directory(app.static_folder, "index.html")
48
 
49
  @app.get("/health")
50
  def health() -> Any:
51
  return jsonify({"status": "ok", "device": str(DEVICE)})
52
 
53
+ def load_image(file_stream_or_path):
54
+ if isinstance(file_stream_or_path, str):
55
+ return Image.open(file_stream_or_path).convert("RGB")
56
+ return Image.open(file_stream_or_path).convert("RGB")
57
+
58
+ def run_inference(img: Image.Image) -> Dict[str, Any]:
59
+ input_tensor = preprocess_image(img).to(DEVICE)
60
+ with torch.no_grad():
61
+ output = model(input_tensor)
62
+ probabilities = F.softmax(output[0], dim=0).detach().cpu()
63
+ pred_prob, pred_idx = torch.max(probabilities, dim=0)
64
+ predicted_class = classes[int(pred_idx)]
65
+ return {
66
+ "class": predicted_class,
67
+ "confidence": float(pred_prob),
68
+ "probabilities": {cls: float(prob) for cls, prob in zip(classes, probabilities.tolist())},
69
+ }
70
+
71
+ # --- Existing upload classification ---
72
  @app.post("/predict_AlexNet")
73
  def predict_alexnet() -> Any:
74
  if "image" not in request.files:
75
  return jsonify({"error": "Missing file field 'image'."}), 400
 
76
  file = request.files["image"]
77
  if not file:
78
  return jsonify({"error": "Empty file."}), 400
 
79
  try:
80
  img = load_image(file.stream)
81
+ result = run_inference(img)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  return jsonify(result)
 
83
  except Exception as e:
84
  return jsonify({"error": f"Failed to process image: {e}"}), 400
85
 
86
+ # --- NEW: classify a preset image ---
87
+ @app.post("/predict_preset")
88
+ def predict_preset() -> Any:
89
+ try:
90
+ payload = request.get_json(force=True, silent=False)
91
+ except Exception:
92
+ payload = None
93
+ if not payload or "preset" not in payload:
94
+ return jsonify({"error": "Missing JSON field 'preset' (TP|TN|FN|FP)."}), 400
95
+
96
+ key = str(payload["preset"]).upper()
97
+ if key not in PRESET_MAP:
98
+ return jsonify({"error": f"Invalid preset '{key}'. Use one of: TP, TN, FN, FP."}), 400
99
+
100
+ path = PRESET_MAP[key]
101
+ if not os.path.exists(path):
102
+ return jsonify({"error": f"Preset image not found on server: {path}"}), 404
103
+
104
+ try:
105
+ img = load_image(path)
106
+ result = run_inference(img)
107
+ result.update({"preset": key, "path": path})
108
+ return jsonify(result)
109
+ except Exception as e:
110
+ return jsonify({"error": f"Failed to process preset image: {e}"}), 400
111
+
112
+ # --- NEW: serve preset thumbnails safely ---
113
+ @app.get("/preset_image/<label>")
114
+ def preset_image(label: str):
115
+ key = str(label).upper()
116
+ if key not in PRESET_MAP:
117
+ abort(404)
118
+ path = PRESET_MAP[key]
119
+ if not os.path.exists(path):
120
+ abort(404)
121
+ directory, filename = os.path.split(os.path.abspath(path))
122
+ # Let Flask serve the actual file bytes
123
+ return send_from_directory(directory, filename)
124
+
125
  if __name__ == "__main__":
126
  debug = bool(int(os.getenv("FLASK_DEBUG", "0")))
127
  app.run(host=HOST, port=PORT, debug=debug)
confusion_matrix_examples.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:75665f0fda9ce346e3d4ef1a4ed3d774b4a2581394ae784829d27be1df1cb7b6
3
+ size 42369
confusion_matrix_examples/FN/Stable Diffusion_0001 (6).jpg ADDED
confusion_matrix_examples/FN/Stable Diffusion_0003 (3).jpg ADDED
confusion_matrix_examples/FN/Stable Diffusion_0004 (2).jpg ADDED
confusion_matrix_examples/FN/Stable Diffusion_0013 (10).jpg ADDED
confusion_matrix_examples/FN/Stable Diffusion_0013.jpg ADDED
confusion_matrix_examples/FN/Stable Diffusion_0017 (10).jpg ADDED
confusion_matrix_examples/FN/Stable Diffusion_0019 (10).jpg ADDED
confusion_matrix_examples/FN/Stable Diffusion_0019 (9).jpg ADDED
confusion_matrix_examples/FN/Stable Diffusion_0027 (7).jpg ADDED
confusion_matrix_examples/FN/Stable Diffusion_0030.jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_101 (3).jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_102 (10).jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_102 (9).jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_112 (3).jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_115 (4).jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_117 (3).jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_117 (9).jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_118 (4).jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_124 (3).jpg ADDED
confusion_matrix_examples/FP/Stable Diffusion_125 (8).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0 (10).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0 (2).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0 (3).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0 (4).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0 (5).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0 (6).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0 (7).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0 (8).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0 (9).jpg ADDED
confusion_matrix_examples/TN/Stable Diffusion_0.jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000 (10).jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000 (2).jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000 (3).jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000 (4).jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000 (5).jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000 (6).jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000 (7).jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000 (8).jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000 (9).jpg ADDED
confusion_matrix_examples/TP/Stable Diffusion_0000.jpg ADDED
confusion_matrix_examples/collection_summary.txt ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Confusion Matrix Example Collection Summary
2
+ ======================================================================
3
+ Model: /work/cssema416/202610/22/Gurinder/alexnet_vsf_best.pth
4
+
5
+ Datasets Searched:
6
+ Stable Diffusion:
7
+ - /work/cssema416/202610/22/test
8
+ - /work/cssema416/202610/22/train
9
+ Midjourney:
10
+ - /work/cssema416/202610/22/Midjourney_Exp2/test
11
+ - /work/cssema416/202610/22/Midjourney_Exp2/train
12
+ DALLE:
13
+ - /work/cssema416/202610/22/dalle
14
+
15
+ Results:
16
+ True Positives (TP): 10/10
17
+ True Negatives (TN): 10/10
18
+ False Positives (FP): 10/10
19
+ False Negatives (FN): 10/10
images/FN.jpg ADDED
images/FP.jpg ADDED
images/TN.jpg ADDED
images/TP.jpg ADDED
requirements.txt CHANGED
@@ -2,3 +2,4 @@ flask>=3.0.0
2
  pillow>=10.0.0
3
  gunicorn>=21.2.0
4
  python-dotenv>=1.0.0
 
 
2
  pillow>=10.0.0
3
  gunicorn>=21.2.0
4
  python-dotenv>=1.0.0
5
+ Flask-Cors>=4.0.0