Update my_pages/ica.py
Browse files- my_pages/ica.py +83 -98
my_pages/ica.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
| 1 |
import streamlit as st
|
| 2 |
-
import matplotlib.pyplot as plt
|
| 3 |
import numpy as np
|
|
|
|
|
|
|
| 4 |
from utils import add_navigation, add_instruction_text, add_red_text
|
| 5 |
|
| 6 |
-
plt.style.use('dark_background')
|
| 7 |
|
| 8 |
def render():
|
| 9 |
add_navigation("txt_ica", "txt_multiverse")
|
|
@@ -11,7 +11,7 @@ def render():
|
|
| 11 |
add_instruction_text(
|
| 12 |
"""
|
| 13 |
Explore the intention-convention-arbitrariness (ICA) framework.<br>
|
| 14 |
-
|
| 15 |
"""
|
| 16 |
)
|
| 17 |
|
|
@@ -22,108 +22,93 @@ def render():
|
|
| 22 |
"Arbitrary": 0.34
|
| 23 |
}
|
| 24 |
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
others = [k for k in w.keys() if k != control_choice]
|
| 44 |
-
total_other = w[others[0]] + w[others[1]]
|
| 45 |
-
|
| 46 |
-
if total_other > 0:
|
| 47 |
-
w[others[0]] -= diff * (w[others[0]] / total_other)
|
| 48 |
-
w[others[1]] -= diff * (w[others[1]] / total_other)
|
| 49 |
-
|
| 50 |
-
w[control_choice] = new_value
|
| 51 |
-
|
| 52 |
-
# Clamp small floating point errors
|
| 53 |
-
for k in w:
|
| 54 |
-
w[k] = max(0.0, min(1.0, round(w[k], 4)))
|
| 55 |
-
|
| 56 |
-
# Normalize back to sum=1
|
| 57 |
-
total = sum(w.values())
|
| 58 |
-
if total != 0:
|
| 59 |
-
for k in w:
|
| 60 |
-
w[k] = round(w[k] / total, 4)
|
| 61 |
-
|
| 62 |
-
# Triangle vertices
|
| 63 |
-
vertices = np.array([
|
| 64 |
-
[0.5, np.sqrt(3)/2], # Intentional
|
| 65 |
-
[0, 0], # Conventional
|
| 66 |
-
[1, 0] # Arbitrary
|
| 67 |
-
])
|
| 68 |
|
| 69 |
-
#
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
)
|
| 75 |
|
| 76 |
-
#
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
|
|
|
| 107 |
|
| 108 |
-
|
| 109 |
-
|
| 110 |
explanations = []
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
| 114 |
if dist <= torch_radius:
|
| 115 |
-
|
| 116 |
-
ax.text(x, y + 0.03, label, ha=ha, va=va, color="red", zorder=6, weight="heavy")
|
| 117 |
-
explanations.append((label, labeltext))
|
| 118 |
-
else:
|
| 119 |
-
ax.scatter(x, y, c="red", s=50, zorder=6, alpha=0.3)
|
| 120 |
-
|
| 121 |
-
col1, col2, col3 = st.columns([0.3, 1, 0.3])
|
| 122 |
-
with col2:
|
| 123 |
-
st.pyplot(fig)
|
| 124 |
|
|
|
|
| 125 |
if len(explanations) > 0:
|
| 126 |
text_to_show = ""
|
| 127 |
for label, labeltext in explanations:
|
| 128 |
-
text_to_show += "<b>
|
| 129 |
-
add_red_text(text_to_show)
|
|
|
|
| 1 |
import streamlit as st
|
|
|
|
| 2 |
import numpy as np
|
| 3 |
+
import plotly.graph_objects as go
|
| 4 |
+
from streamlit_plotly_events import plotly_events
|
| 5 |
from utils import add_navigation, add_instruction_text, add_red_text
|
| 6 |
|
|
|
|
| 7 |
|
| 8 |
def render():
|
| 9 |
add_navigation("txt_ica", "txt_multiverse")
|
|
|
|
| 11 |
add_instruction_text(
|
| 12 |
"""
|
| 13 |
Explore the intention-convention-arbitrariness (ICA) framework.<br>
|
| 14 |
+
Click inside the ICA triangle to move the torch and uncover examples.
|
| 15 |
"""
|
| 16 |
)
|
| 17 |
|
|
|
|
| 22 |
"Arbitrary": 0.34
|
| 23 |
}
|
| 24 |
|
| 25 |
+
# --- Locations (examples) ---
|
| 26 |
+
locations = [
|
| 27 |
+
(0.1, 0.1, 0.8, "Random Seeds",
|
| 28 |
+
"Random Seeds are highly arbitrary, without any convention or intentionality."),
|
| 29 |
+
(0.6, 0.3, 0.1, "Neural networks for Tabular Data",
|
| 30 |
+
"Using neural networks of some arbitrary size (hidden layers) for a setting "
|
| 31 |
+
"where they are not needed is highly conventional, a bit arbitrary, and has very low intentionality."),
|
| 32 |
+
(0.2, 0.6, 0.2, "Pre-trained LLM for a Complex Task",
|
| 33 |
+
"Using a high performing LLM for a complex task is intentional, however, it also has "
|
| 34 |
+
"conventionality to it. No arbitrariness."),
|
| 35 |
+
(0.7, 0.25, 0.05, "Best Bias Mitigation for a Particular Setup",
|
| 36 |
+
"Choosing the most appropriate bias mitigation technique, specialized for the particular context, is highly intentional."),
|
| 37 |
+
(0.45, 0.05, 0.5, "Randomly chosen Regularization Technique",
|
| 38 |
+
"Adding regularization to improve robustness, but choosing the regularization technique randomly, "
|
| 39 |
+
"creates a decision that is intentional and arbitrary, while avoiding conventionality."),
|
| 40 |
+
(0.05, 0.9, 0.05, "ReLU Activation as Default",
|
| 41 |
+
"Choosing ReLU activation without testing what other activations might also work, is a highly conventional decision."),
|
| 42 |
+
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
+
# Torch radius
|
| 45 |
+
torch_radius = 0.2
|
| 46 |
+
|
| 47 |
+
# --- Create Plotly Figure ---
|
| 48 |
+
fig = go.Figure()
|
| 49 |
+
|
| 50 |
+
# Triangle border (ternary axes are already a triangle)
|
| 51 |
+
fig.update_layout(
|
| 52 |
+
ternary=dict(
|
| 53 |
+
sum=1,
|
| 54 |
+
aaxis=dict(title="Intentional", min=0.0, linewidth=2, ticks='outside'),
|
| 55 |
+
baxis=dict(title="Conventional", min=0.0, linewidth=2, ticks='outside'),
|
| 56 |
+
caxis=dict(title="Arbitrary", min=0.0, linewidth=2, ticks='outside'),
|
| 57 |
+
bgcolor="black"
|
| 58 |
+
),
|
| 59 |
+
paper_bgcolor="rgba(0,0,0,0)",
|
| 60 |
+
plot_bgcolor="rgba(0,0,0,0)",
|
| 61 |
+
showlegend=False,
|
| 62 |
+
margin=dict(l=50, r=50, b=50, t=50)
|
| 63 |
)
|
| 64 |
|
| 65 |
+
# Add example points (faded by default)
|
| 66 |
+
for (a, b, c, label, _) in locations:
|
| 67 |
+
fig.add_trace(go.Scatterternary(
|
| 68 |
+
a=[a], b=[b], c=[c],
|
| 69 |
+
mode='markers+text',
|
| 70 |
+
marker=dict(size=8, color='red', opacity=0.3),
|
| 71 |
+
text=[label],
|
| 72 |
+
textposition="top center",
|
| 73 |
+
hoverinfo="text"
|
| 74 |
+
))
|
| 75 |
+
|
| 76 |
+
# Torch (initial position)
|
| 77 |
+
w = st.session_state.weights
|
| 78 |
+
fig.add_trace(go.Scatterternary(
|
| 79 |
+
a=[w["Intentional"]], b=[w["Conventional"]], c=[w["Arbitrary"]],
|
| 80 |
+
mode='markers',
|
| 81 |
+
marker=dict(size=20, color="orange", opacity=0.6, line=dict(width=2, color="white")),
|
| 82 |
+
name="Torch"
|
| 83 |
+
))
|
| 84 |
+
|
| 85 |
+
# --- Capture Click Events ---
|
| 86 |
+
selected = plotly_events(fig, click_event=True, hover_event=False, select_event=False)
|
| 87 |
+
|
| 88 |
+
if selected:
|
| 89 |
+
# Ternary coords returned as a,b,c
|
| 90 |
+
point = selected[0]["pointData"]
|
| 91 |
+
st.session_state.weights = {
|
| 92 |
+
"Intentional": round(point["a"], 4),
|
| 93 |
+
"Conventional": round(point["b"], 4),
|
| 94 |
+
"Arbitrary": round(point["c"], 4)
|
| 95 |
+
}
|
| 96 |
+
w = st.session_state.weights
|
| 97 |
|
| 98 |
+
# --- Torch highlighting logic ---
|
|
|
|
| 99 |
explanations = []
|
| 100 |
+
for (a, b, c, label, text) in locations:
|
| 101 |
+
dist = np.sqrt(
|
| 102 |
+
(a - w["Intentional"])**2 +
|
| 103 |
+
(b - w["Conventional"])**2 +
|
| 104 |
+
(c - w["Arbitrary"])**2
|
| 105 |
+
)
|
| 106 |
if dist <= torch_radius:
|
| 107 |
+
explanations.append((label, text))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
|
| 109 |
+
# Show explanations if any
|
| 110 |
if len(explanations) > 0:
|
| 111 |
text_to_show = ""
|
| 112 |
for label, labeltext in explanations:
|
| 113 |
+
text_to_show += f"<b>{label}:</b> {labeltext}<br>"
|
| 114 |
+
add_red_text(text_to_show)
|