Spaces:
Sleeping
Sleeping
devjas1
commited on
Commit
Β·
ff443f3
1
Parent(s):
56c06a1
(FEAT/UI): Streamline results display with enhanced metrics and consolidated confidence analysis
Browse files
app.py
CHANGED
|
@@ -718,8 +718,7 @@ def main():
|
|
| 718 |
if uploaded_files:
|
| 719 |
# --- START: Bug 1 Fix ---
|
| 720 |
# Use a dictionary to keep only unique files based on name and size
|
| 721 |
-
unique_files = {(file.name, file.size)
|
| 722 |
-
: file for file in uploaded_files}
|
| 723 |
unique_file_list = list(unique_files.values())
|
| 724 |
|
| 725 |
num_uploaded = len(uploaded_files)
|
|
@@ -849,8 +848,8 @@ def main():
|
|
| 849 |
|
| 850 |
# --- START: BUG 2 FIX (Button) ---
|
| 851 |
# This button will clear all results from col2 correctly.
|
| 852 |
-
st.button("Clear Results", on_click=clear_batch_results,
|
| 853 |
-
|
| 854 |
# --- END: BUG 2 FIX (Button) ---
|
| 855 |
|
| 856 |
ResultsManager.display_results_table()
|
|
@@ -960,150 +959,75 @@ def main():
|
|
| 960 |
)
|
| 961 |
|
| 962 |
if active_tab == "Details":
|
| 963 |
-
# MODIFIED: Wrap the expander in a div with the 'expander-results' class
|
| 964 |
st.markdown('<div class="expander-results">',
|
| 965 |
unsafe_allow_html=True)
|
| 966 |
-
|
| 967 |
-
|
| 968 |
-
|
| 969 |
-
|
| 970 |
-
|
| 971 |
-
|
| 972 |
-
|
| 973 |
-
|
| 974 |
-
|
| 975 |
-
|
| 976 |
-
|
| 977 |
-
|
| 978 |
-
|
| 979 |
-
|
| 980 |
-
|
| 981 |
-
|
| 982 |
-
|
| 983 |
-
|
| 984 |
-
|
| 985 |
-
|
| 986 |
-
|
| 987 |
-
|
| 988 |
-
|
| 989 |
-
|
| 990 |
-
|
| 991 |
-
|
| 992 |
-
|
| 993 |
-
|
| 994 |
-
|
| 995 |
-
|
| 996 |
-
#
|
| 997 |
-
|
| 998 |
-
|
| 999 |
-
|
| 1000 |
-
|
| 1001 |
-
|
| 1002 |
-
|
| 1003 |
-
|
| 1004 |
-
|
| 1005 |
-
|
| 1006 |
-
|
| 1007 |
-
|
| 1008 |
-
|
| 1009 |
-
|
| 1010 |
-
|
| 1011 |
-
|
| 1012 |
-
|
| 1013 |
-
|
| 1014 |
-
|
| 1015 |
-
|
| 1016 |
-
|
| 1017 |
-
|
| 1018 |
-
|
| 1019 |
-
|
| 1020 |
-
|
| 1021 |
-
|
| 1022 |
-
|
| 1023 |
-
|
| 1024 |
-
|
| 1025 |
-
|
| 1026 |
-
#
|
| 1027 |
-
#
|
| 1028 |
-
|
| 1029 |
-
|
| 1030 |
-
|
| 1031 |
-
|
| 1032 |
-
|
| 1033 |
-
def create_bullet_bar(probability, width=20, predicted=False):
|
| 1034 |
-
filled_count = int(probability * width)
|
| 1035 |
-
empty_count = width - filled_count
|
| 1036 |
-
|
| 1037 |
-
# Use professional symbols
|
| 1038 |
-
filled_symbol = "β " # Solid block
|
| 1039 |
-
empty_symbol = "β" # Light shade
|
| 1040 |
-
|
| 1041 |
-
# Create the bar
|
| 1042 |
-
bar = filled_symbol * filled_count + empty_symbol * empty_count
|
| 1043 |
-
|
| 1044 |
-
# Add percentage with scientific formatting
|
| 1045 |
-
percentage = f"{probability:.1%}"
|
| 1046 |
-
|
| 1047 |
-
# Add prediction indicator
|
| 1048 |
-
pred_marker = "β© Predicted" if predicted else ""
|
| 1049 |
-
|
| 1050 |
-
return f"{bar} {percentage} {pred_marker}"
|
| 1051 |
-
|
| 1052 |
-
# Get probabilities
|
| 1053 |
-
stable_prob = probs[0]
|
| 1054 |
-
weathered_prob = probs[1]
|
| 1055 |
-
is_stable_predicted = int(prediction) == 0
|
| 1056 |
-
is_weathered_predicted = int(prediction) == 1
|
| 1057 |
-
|
| 1058 |
-
# Clean 2-column layout for assessment and probabilities
|
| 1059 |
-
assess_col, prob_col = st.columns(
|
| 1060 |
-
[1, 2.5], gap="small", border=True)
|
| 1061 |
-
|
| 1062 |
-
# Left column: Assessment metrics
|
| 1063 |
-
with assess_col:
|
| 1064 |
-
st.markdown(
|
| 1065 |
-
"Assessment", unsafe_allow_html=True)
|
| 1066 |
-
|
| 1067 |
-
# Ground truth validation
|
| 1068 |
-
if true_label_idx is not None:
|
| 1069 |
-
is_correct = predicted_class == true_label_str
|
| 1070 |
-
accuracy_icon = "β
" if is_correct else ""
|
| 1071 |
-
status_text = "Correct" if is_correct else "Incorrect"
|
| 1072 |
-
st.metric(
|
| 1073 |
-
label="**Ground Truth**",
|
| 1074 |
-
value=f"{accuracy_icon} {status_text}",
|
| 1075 |
-
delta=f"{'100%' if is_correct else '0%'}"
|
| 1076 |
-
)
|
| 1077 |
-
else:
|
| 1078 |
-
st.metric(
|
| 1079 |
-
label="**Ground Truth**",
|
| 1080 |
-
value="N/A",
|
| 1081 |
-
delta="No reference"
|
| 1082 |
-
)
|
| 1083 |
-
|
| 1084 |
-
# Confidence level
|
| 1085 |
-
confidence_icon = "π’" if max_confidence >= 0.8 else "π‘" if max_confidence >= 0.6 else "π΄"
|
| 1086 |
-
st.metric(
|
| 1087 |
-
label="**Confidence Level**",
|
| 1088 |
-
value=f"{confidence_icon} {confidence_desc}",
|
| 1089 |
-
delta=f"{max_confidence:.1%}"
|
| 1090 |
-
)
|
| 1091 |
-
|
| 1092 |
-
# Right column: Probability distribution
|
| 1093 |
-
with prob_col:
|
| 1094 |
-
st.markdown("Probability Distribution")
|
| 1095 |
-
|
| 1096 |
-
st.markdown(f"""
|
| 1097 |
-
<div style="">
|
| 1098 |
-
Stable (Unweathered)<br>
|
| 1099 |
-
{create_bullet_bar(stable_prob, predicted=is_stable_predicted)}<br><br>
|
| 1100 |
-
Weathered (Degraded)<br>
|
| 1101 |
-
{create_bullet_bar(weathered_prob, predicted=is_weathered_predicted)}
|
| 1102 |
-
</div>
|
| 1103 |
-
|
| 1104 |
-
""", unsafe_allow_html=True)
|
| 1105 |
-
st.markdown(
|
| 1106 |
-
'</div>', unsafe_allow_html=True) # Close the wrapper div
|
| 1107 |
|
| 1108 |
elif active_tab == "Technical":
|
| 1109 |
with st.container():
|
|
|
|
| 718 |
if uploaded_files:
|
| 719 |
# --- START: Bug 1 Fix ---
|
| 720 |
# Use a dictionary to keep only unique files based on name and size
|
| 721 |
+
unique_files = {(file.name, file.size): file for file in uploaded_files}
|
|
|
|
| 722 |
unique_file_list = list(unique_files.values())
|
| 723 |
|
| 724 |
num_uploaded = len(uploaded_files)
|
|
|
|
| 848 |
|
| 849 |
# --- START: BUG 2 FIX (Button) ---
|
| 850 |
# This button will clear all results from col2 correctly.
|
| 851 |
+
# st.button("Clear Results", on_click=clear_batch_results,
|
| 852 |
+
# help="Clear all uploaded files and results.")
|
| 853 |
# --- END: BUG 2 FIX (Button) ---
|
| 854 |
|
| 855 |
ResultsManager.display_results_table()
|
|
|
|
| 959 |
)
|
| 960 |
|
| 961 |
if active_tab == "Details":
|
|
|
|
| 962 |
st.markdown('<div class="expander-results">',
|
| 963 |
unsafe_allow_html=True)
|
| 964 |
+
# Use a dynamic and informative title for the expander
|
| 965 |
+
with st.expander(f"Results for {filename}", expanded=True):
|
| 966 |
+
|
| 967 |
+
# --- START: STREAMLINED METRICS ---
|
| 968 |
+
# A single, powerful row for the most important results.
|
| 969 |
+
key_metric_cols = st.columns(3)
|
| 970 |
+
|
| 971 |
+
# Metric 1: The Prediction
|
| 972 |
+
key_metric_cols[0].metric(
|
| 973 |
+
"Prediction", predicted_class)
|
| 974 |
+
|
| 975 |
+
# Metric 2: The Confidence (with level in tooltip)
|
| 976 |
+
confidence_icon = "π’" if max_confidence >= 0.8 else "π‘" if max_confidence >= 0.6 else "π΄"
|
| 977 |
+
key_metric_cols[1].metric(
|
| 978 |
+
"Confidence",
|
| 979 |
+
f"{confidence_icon} {max_confidence:.1%}",
|
| 980 |
+
help=f"Confidence Level: {confidence_desc}"
|
| 981 |
+
)
|
| 982 |
+
|
| 983 |
+
# Metric 3: Ground Truth + Correctness (Combined)
|
| 984 |
+
if true_label_idx is not None:
|
| 985 |
+
is_correct = (predicted_class == true_label_str)
|
| 986 |
+
delta_text = "β
Correct" if is_correct else "β Incorrect"
|
| 987 |
+
# Use delta_color="normal" to let the icon provide the visual cue
|
| 988 |
+
key_metric_cols[2].metric(
|
| 989 |
+
"Ground Truth", true_label_str, delta=delta_text, delta_color="normal")
|
| 990 |
+
else:
|
| 991 |
+
key_metric_cols[2].metric("Ground Truth", "N/A")
|
| 992 |
+
|
| 993 |
+
st.divider()
|
| 994 |
+
# --- END: STREAMLINED METRICS ---
|
| 995 |
+
|
| 996 |
+
# --- START: CONSOLIDATED CONFIDENCE ANALYSIS ---
|
| 997 |
+
st.markdown("##### Probability Breakdown")
|
| 998 |
+
|
| 999 |
+
# This custom bullet bar logic remains as it is highly specific and valuable
|
| 1000 |
+
def create_bullet_bar(probability, width=20, predicted=False):
|
| 1001 |
+
filled_count = int(probability * width)
|
| 1002 |
+
bar = "β " * filled_count + \
|
| 1003 |
+
"β" * (width - filled_count)
|
| 1004 |
+
percentage = f"{probability:.1%}"
|
| 1005 |
+
pred_marker = "β© Predicted" if predicted else ""
|
| 1006 |
+
return f"{bar} {percentage} {pred_marker}"
|
| 1007 |
+
|
| 1008 |
+
stable_prob, weathered_prob = probs[0], probs[1]
|
| 1009 |
+
is_stable_predicted, is_weathered_predicted = (
|
| 1010 |
+
int(prediction) == 0), (int(prediction) == 1)
|
| 1011 |
+
|
| 1012 |
+
st.markdown(f"""
|
| 1013 |
+
<div style="font-family: 'Fira Code', monospace;">
|
| 1014 |
+
Stable (Unweathered)<br>
|
| 1015 |
+
{create_bullet_bar(stable_prob, predicted=is_stable_predicted)}<br><br>
|
| 1016 |
+
Weathered (Degraded)<br>
|
| 1017 |
+
{create_bullet_bar(weathered_prob, predicted=is_weathered_predicted)}
|
| 1018 |
+
</div>
|
| 1019 |
+
""", unsafe_allow_html=True)
|
| 1020 |
+
# --- END: CONSOLIDATED CONFIDENCE ANALYSIS ---
|
| 1021 |
+
|
| 1022 |
+
st.divider()
|
| 1023 |
+
|
| 1024 |
+
# --- START: CLEAN METADATA FOOTER ---
|
| 1025 |
+
# Secondary info is now a clean, single-line caption
|
| 1026 |
+
st.caption(
|
| 1027 |
+
f"Analyzed with **{model_choice}** in **{inference_time:.2f}s**.")
|
| 1028 |
+
# --- END: CLEAN METADATA FOOTER ---
|
| 1029 |
+
|
| 1030 |
+
st.markdown('</div>', unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1031 |
|
| 1032 |
elif active_tab == "Technical":
|
| 1033 |
with st.container():
|