File size: 5,029 Bytes
dfe0ad3
2ffd2c7
 
dfe0ad3
 
3a2ee1d
 
112a2a9
612bb58
2ffd2c7
 
 
 
 
4cc33c1
2ffd2c7
673f528
 
 
 
 
 
 
 
 
 
 
 
612bb58
673f528
 
 
 
 
 
 
 
 
 
 
612bb58
673f528
 
 
 
dfe0ad3
673f528
 
3a2ee1d
612bb58
3a2ee1d
 
 
 
673f528
3a2ee1d
 
 
 
6f1608e
673f528
6f1608e
3a2ee1d
6f1608e
 
 
 
 
 
612bb58
 
6f1608e
 
673f528
612bb58
 
 
3a2ee1d
 
 
6f1608e
 
3a2ee1d
6f1608e
 
 
 
 
 
3a2ee1d
 
673f528
612bb58
4cc33c1
 
c2a3a5d
 
 
 
 
 
 
 
 
4cc33c1
c2a3a5d
 
4cc33c1
c2a3a5d
4cc33c1
 
c2a3a5d
4cc33c1
 
 
 
c2a3a5d
4cc33c1
c2a3a5d
 
 
 
 
 
4cc33c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2a3a5d
4cc33c1
612bb58
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import matplotlib.pyplot as plt
import firebase_admin
from firebase_admin import credentials, firestore
import io
from PIL import Image
import os
import json

# === Initialize Firebase
if not firebase_admin._apps:
    cred = credentials.Certificate("firebase_key.json")
    firebase_admin.initialize_app(cred)
db = firestore.client()

# === πŸ—³οΈ Feedback Summary Plot (Solution 1 vs Solution 2)
def update_dashboard_plot():
    try:
        docs = db.collection("evo_feedback").stream()
        count_1, count_2 = 0, 0

        for doc in docs:
            winner = doc.to_dict().get("winner", "").strip()
            if winner == "1":
                count_1 += 1
            elif winner == "2":
                count_2 += 1

        total = count_1 + count_2
        fig, ax = plt.subplots()

        if total == 0:
            ax.text(0.5, 0.5, "No feedback collected yet.", ha="center", va="center", fontsize=12)
            ax.axis("off")
        else:
            ax.bar(["Solution 1", "Solution 2"], [count_1, count_2], color=["skyblue", "lightgreen"])
            ax.set_ylabel("Votes")
            ax.set_title(f"πŸ—³οΈ Feedback Summary (Total: {total})")
            for i, v in enumerate([count_1, count_2]):
                ax.text(i, v + 0.5, str(v), ha='center', fontweight='bold')

        plt.tight_layout()
        buf = io.BytesIO()
        plt.savefig(buf, format="png")
        buf.seek(0)
        return Image.open(buf)

    except Exception as e:
        return _fallback_plot(f"Error loading feedback chart: {e}")

# === πŸ“ˆ Evolution Accuracy Plot (Accuracy vs Generation)
def evolution_accuracy_plot():
    try:
        log_path = "trained_model/evolution_log.json"
        if not os.path.exists(log_path):
            return _fallback_plot("⚠️ No evolution log found")

        with open(log_path, "r") as f:
            log_data = json.load(f)

        if not log_data:
            return _fallback_plot("⚠️ Evolution log is empty")

        generations = list(range(1, len(log_data) + 1))
        accuracies = [round(entry.get("accuracy", 0), 4) for entry in log_data]
        tooltips = [
            f"L: {entry.get('num_layers', '?')}, H: {entry.get('num_heads', '?')}, FFN: {entry.get('ffn_dim', '?')}, Mem: {entry.get('use_memory', '?')}"
            for entry in log_data
        ]

        fig, ax = plt.subplots(figsize=(7, 4))
        ax.plot(generations, accuracies, marker='o', color="purple", label="Accuracy")

        for i, tooltip in enumerate(tooltips):
            offset = (i % 2) * 5 - 2
            ax.annotate(tooltip, (generations[i], accuracies[i]),
                        fontsize=7, xytext=(0, 8 + offset), textcoords='offset points',
                        ha='center')

        ax.set_xlabel("Generation")
        ax.set_ylabel("Accuracy")
        ax.set_title("πŸ“ˆ EvoTransformer Evolution Accuracy")
        ax.set_ylim([0, 1.05])
        ax.grid(True)
        plt.tight_layout()

        buf = io.BytesIO()
        plt.savefig(buf, format="png")
        buf.seek(0)
        return Image.open(buf)

    except Exception as e:
        return _fallback_plot(f"⚠️ Error loading evolution plot: {e}")

# === πŸ† Hall of Fame Plot (most frequent goals)
def leaderboard_plot():
    try:
        docs = db.collection("evo_feedback").stream()
        goal_counter = {}

        for doc in docs:
            goal = doc.to_dict().get("goal", "").strip()
            if goal:
                goal_counter[goal] = goal_counter.get(goal, 0) + 1

        sorted_goals = sorted(goal_counter.items(), key=lambda x: x[1], reverse=True)[:10]

        if not sorted_goals:
            return _fallback_plot("πŸ† No top goals yet.")

        labels = [g[0][:25] + "..." if len(g[0]) > 25 else g[0] for g, _ in sorted_goals]
        counts = [c for _, c in sorted_goals]

        fig, ax = plt.subplots(figsize=(8, 4))
        ax.barh(labels[::-1], counts[::-1], color="orange")
        ax.set_xlabel("Votes")
        ax.set_title("πŸ† Hall of Fame: Top 10 Goals")
        plt.tight_layout()

        buf = io.BytesIO()
        plt.savefig(buf, format="png")
        buf.seek(0)
        return Image.open(buf)

    except Exception as e:
        return _fallback_plot(f"⚠️ Error loading leaderboard: {e}")

# === πŸ”’ Real-time vote count for display
def get_vote_counts():
    try:
        docs = db.collection("evo_feedback").stream()
        count_1, count_2 = 0, 0

        for doc in docs:
            winner = doc.to_dict().get("winner", "").strip()
            if winner == "1":
                count_1 += 1
            elif winner == "2":
                count_2 += 1

        return {"1": count_1, "2": count_2}
    except:
        return {"1": 0, "2": 0}

# === πŸ› οΈ Fallback Plot
def _fallback_plot(message):
    fig, ax = plt.subplots()
    ax.text(0.5, 0.5, message, ha="center", va="center", fontsize=11)
    ax.axis('off')
    plt.tight_layout()
    buf = io.BytesIO()
    plt.savefig(buf, format="png")
    buf.seek(0)
    return Image.open(buf)