Auto-update confusion matrix after inference and align formula beside matrix (update 14)
Browse files- CHANGELOG.md +5 -0
- README.md +1 -0
- app.py +15 -15
CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
| 1 |
# Changelog
|
| 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
## Update ke-13 - 2026-04-15
|
| 4 |
- Tambah penanda versi kecil di UI: `Versi v0.9.0 | Minor Update ke-13`.
|
| 5 |
- Tambah build info di bagian bawah halaman untuk validasi versi saat demo.
|
|
|
|
| 1 |
# Changelog
|
| 2 |
|
| 3 |
+
## Update ke-14 - 2026-04-15
|
| 4 |
+
- Evaluasi confusion matrix sekarang otomatis berjalan setelah tombol cek/inferensi ditekan (tanpa tombol update manual).
|
| 5 |
+
- Layout Tahap 4 dirapikan: confusion matrix dan kolom rumus/metrik berada dalam satu baris (sejajar).
|
| 6 |
+
- Minor update dinaikkan ke-14 untuk konsistensi tracking versi UI.
|
| 7 |
+
|
| 8 |
## Update ke-13 - 2026-04-15
|
| 9 |
- Tambah penanda versi kecil di UI: `Versi v0.9.0 | Minor Update ke-13`.
|
| 10 |
- Tambah build info di bagian bawah halaman untuk validasi versi saat demo.
|
README.md
CHANGED
|
@@ -29,6 +29,7 @@ Versi ini difokuskan untuk tahap awal:
|
|
| 29 |
- `Ada Mahasiswa` jika jumlah terdeteksi > 0
|
| 30 |
- `Tidak Ada Mahasiswa` jika jumlah terdeteksi = 0
|
| 31 |
- grafik hasil pengecekan.
|
|
|
|
| 32 |
|
| 33 |
## Struktur UI
|
| 34 |
|
|
|
|
| 29 |
- `Ada Mahasiswa` jika jumlah terdeteksi > 0
|
| 30 |
- `Tidak Ada Mahasiswa` jika jumlah terdeteksi = 0
|
| 31 |
- grafik hasil pengecekan.
|
| 32 |
+
4. Setelah proses cek, confusion matrix dan rumus evaluasi diperbarui otomatis berdasarkan label aktual yang dipilih.
|
| 33 |
|
| 34 |
## Struktur UI
|
| 35 |
|
app.py
CHANGED
|
@@ -22,7 +22,7 @@ from ultralytics import YOLO
|
|
| 22 |
CM_INIT = {"tp": 0, "fp": 0, "fn": 0, "tn": 0}
|
| 23 |
EVAL_CLASSES = ["Sesuai", "Tidak Sesuai"]
|
| 24 |
APP_VERSION = os.getenv("APP_VERSION", "v0.9.0")
|
| 25 |
-
APP_MINOR_UPDATE = os.getenv("APP_MINOR_UPDATE", "
|
| 26 |
|
| 27 |
|
| 28 |
# Gradio/Spaces can trigger noisy asyncio cleanup traces ("Invalid file descriptor: -1")
|
|
@@ -1048,16 +1048,16 @@ with gr.Blocks(title="Pengecekan dan Klasifikasi Mahasiswa - YOLOv8") as demo:
|
|
| 1048 |
label="Label Aktual (untuk evaluasi/testing)",
|
| 1049 |
)
|
| 1050 |
with gr.Row():
|
| 1051 |
-
update_eval_btn = gr.Button("Update Evaluasi", variant="secondary")
|
| 1052 |
reset_eval_btn = gr.Button("Reset Evaluasi")
|
| 1053 |
eval_status = gr.Markdown("Belum ada update evaluasi.")
|
| 1054 |
-
|
| 1055 |
-
|
| 1056 |
-
|
| 1057 |
-
|
| 1058 |
-
|
| 1059 |
-
|
| 1060 |
-
|
|
|
|
| 1061 |
|
| 1062 |
with gr.Column(elem_classes=["section-box"]):
|
| 1063 |
with gr.Accordion("Tahap 5 - Pengembangan Model (Training)", open=False):
|
|
@@ -1090,22 +1090,22 @@ with gr.Blocks(title="Pengecekan dan Klasifikasi Mahasiswa - YOLOv8") as demo:
|
|
| 1090 |
)
|
| 1091 |
best_model_file = gr.File(label="best.pt hasil training")
|
| 1092 |
|
| 1093 |
-
run_btn.click(
|
| 1094 |
fn=run_check_and_classify,
|
| 1095 |
inputs=[image_input, conf_input, attendance_input, model_choice, inference_mode],
|
| 1096 |
outputs=[output_image, class_result_md, comparison_chart, predicted_state, predicted_label_md],
|
| 1097 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1098 |
inference_mode.change(
|
| 1099 |
fn=toggle_model_selector,
|
| 1100 |
inputs=[inference_mode],
|
| 1101 |
outputs=[model_choice],
|
| 1102 |
)
|
| 1103 |
|
| 1104 |
-
update_eval_btn.click(
|
| 1105 |
-
fn=update_evaluation,
|
| 1106 |
-
inputs=[cm_state, predicted_state, actual_label],
|
| 1107 |
-
outputs=[cm_state, cm_image, metric_md, eval_status],
|
| 1108 |
-
)
|
| 1109 |
reset_eval_btn.click(
|
| 1110 |
fn=reset_evaluation,
|
| 1111 |
inputs=[],
|
|
|
|
| 22 |
CM_INIT = {"tp": 0, "fp": 0, "fn": 0, "tn": 0}
|
| 23 |
EVAL_CLASSES = ["Sesuai", "Tidak Sesuai"]
|
| 24 |
APP_VERSION = os.getenv("APP_VERSION", "v0.9.0")
|
| 25 |
+
APP_MINOR_UPDATE = os.getenv("APP_MINOR_UPDATE", "14")
|
| 26 |
|
| 27 |
|
| 28 |
# Gradio/Spaces can trigger noisy asyncio cleanup traces ("Invalid file descriptor: -1")
|
|
|
|
| 1048 |
label="Label Aktual (untuk evaluasi/testing)",
|
| 1049 |
)
|
| 1050 |
with gr.Row():
|
|
|
|
| 1051 |
reset_eval_btn = gr.Button("Reset Evaluasi")
|
| 1052 |
eval_status = gr.Markdown("Belum ada update evaluasi.")
|
| 1053 |
+
with gr.Row():
|
| 1054 |
+
cm_image = gr.Image(
|
| 1055 |
+
label="Confusion Matrix",
|
| 1056 |
+
value=draw_confusion_matrix_from_state(CM_INIT),
|
| 1057 |
+
type="numpy",
|
| 1058 |
+
interactive=False,
|
| 1059 |
+
)
|
| 1060 |
+
metric_md = gr.Markdown(render_metric_markdown(CM_INIT))
|
| 1061 |
|
| 1062 |
with gr.Column(elem_classes=["section-box"]):
|
| 1063 |
with gr.Accordion("Tahap 5 - Pengembangan Model (Training)", open=False):
|
|
|
|
| 1090 |
)
|
| 1091 |
best_model_file = gr.File(label="best.pt hasil training")
|
| 1092 |
|
| 1093 |
+
run_btn_evt = run_btn.click(
|
| 1094 |
fn=run_check_and_classify,
|
| 1095 |
inputs=[image_input, conf_input, attendance_input, model_choice, inference_mode],
|
| 1096 |
outputs=[output_image, class_result_md, comparison_chart, predicted_state, predicted_label_md],
|
| 1097 |
)
|
| 1098 |
+
run_btn_evt.then(
|
| 1099 |
+
fn=update_evaluation,
|
| 1100 |
+
inputs=[cm_state, predicted_state, actual_label],
|
| 1101 |
+
outputs=[cm_state, cm_image, metric_md, eval_status],
|
| 1102 |
+
)
|
| 1103 |
inference_mode.change(
|
| 1104 |
fn=toggle_model_selector,
|
| 1105 |
inputs=[inference_mode],
|
| 1106 |
outputs=[model_choice],
|
| 1107 |
)
|
| 1108 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1109 |
reset_eval_btn.click(
|
| 1110 |
fn=reset_evaluation,
|
| 1111 |
inputs=[],
|