cyberandy commited on
Commit
8712c90
·
1 Parent(s): cee001d
Files changed (1) hide show
  1. app.py +256 -0
app.py ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import numpy as np
4
+ from dataclasses import dataclass
5
+ from typing import List, Dict, Optional
6
+ import logging
7
+ import os
8
+ from collections import defaultdict
9
+
10
+ logging.basicConfig(level=logging.INFO)
11
+ logger = logging.getLogger(__name__)
12
+
13
+ NEURONPEDIA_API_URL = "https://www.neuronpedia.org/api"
14
+
15
+
16
+ @dataclass
17
+ class FeatureResult:
18
+ """Structure to hold feature analysis results"""
19
+
20
+ feature_id: int
21
+ layer: str
22
+ name: str
23
+ description: str
24
+ activation_score: float
25
+ max_activation: float
26
+ category: str
27
+ interpretation: str
28
+
29
+
30
+ class MarketingAnalyzer:
31
+ def __init__(self, api_key: str = None):
32
+ """Initialize the analyzer with API credentials"""
33
+ self.api_key = api_key or os.getenv("NEURONPEDIA_API_KEY")
34
+ if not self.api_key:
35
+ raise ValueError("Neuronpedia API key is required")
36
+
37
+ self.headers = {"Content-Type": "application/json", "X-Api-Key": self.api_key}
38
+
39
+ def _search_features(
40
+ self, text: str, layer: str = "20-gemmascope-mlp-16k"
41
+ ) -> List[Dict]:
42
+ """Search for relevant features based on text content"""
43
+ url = f"{NEURONPEDIA_API_URL}/explanation/search"
44
+
45
+ payload = {"modelId": "gemma-2b", "layers": [layer], "query": text, "offset": 0}
46
+
47
+ try:
48
+ response = requests.post(url, headers=self.headers, json=payload)
49
+ response.raise_for_status()
50
+ return response.json().get("results", [])
51
+ except Exception as e:
52
+ logger.error(f"Error searching features: {str(e)}")
53
+ return []
54
+
55
+ def _get_activation_values(self, text: str, feature: Dict) -> Dict:
56
+ """Get activation values for specific text and feature"""
57
+ url = f"{NEURONPEDIA_API_URL}/activation/new"
58
+
59
+ payload = {
60
+ "feature": {
61
+ "modelId": "gemma-2b",
62
+ "layer": feature["layer"],
63
+ "index": int(feature["index"]),
64
+ },
65
+ "customText": text,
66
+ }
67
+
68
+ try:
69
+ response = requests.post(url, headers=self.headers, json=payload)
70
+ response.raise_for_status()
71
+ return response.json()
72
+ except Exception as e:
73
+ logger.error(f"Error getting activations: {str(e)}")
74
+ return None
75
+
76
+ def _interpret_activation(self, activation: float) -> str:
77
+ """Interpret activation level"""
78
+ if activation > 0.8:
79
+ return "Very strong match"
80
+ elif activation > 0.5:
81
+ return "Moderate match"
82
+ return "Limited match"
83
+
84
+ def analyze_content(self, text: str) -> Dict:
85
+ """Analyze content using Neuronpedia APIs"""
86
+ results = {
87
+ "text": text,
88
+ "features": {},
89
+ "categories": defaultdict(list),
90
+ "recommendations": [],
91
+ }
92
+
93
+ try:
94
+ # Search for relevant features
95
+ features = self._search_features(text)
96
+
97
+ # Analyze top features
98
+ for feature in features[:5]: # Analyze top 5 features
99
+ feature_id = int(feature["index"])
100
+
101
+ # Get activation values
102
+ activation_data = self._get_activation_values(text, feature)
103
+ if not activation_data:
104
+ continue
105
+
106
+ # Get maximum activation
107
+ max_activation = activation_data.get("activations", {}).get(
108
+ "maxValue", 0
109
+ )
110
+ mean_activation = np.mean(
111
+ activation_data.get("activations", {}).get("values", [0])
112
+ )
113
+
114
+ # Create feature result
115
+ feature_result = FeatureResult(
116
+ feature_id=feature_id,
117
+ layer=feature["layer"],
118
+ name=feature.get("description", f"Feature {feature_id}"),
119
+ description=feature.get("description", ""),
120
+ activation_score=mean_activation,
121
+ max_activation=max_activation,
122
+ category=self._categorize_feature(feature),
123
+ interpretation=self._interpret_activation(max_activation),
124
+ )
125
+
126
+ results["features"][feature_id] = feature_result
127
+ results["categories"][feature_result.category].append(feature_result)
128
+
129
+ # Generate recommendations
130
+ if results["features"]:
131
+ max_activation = max(
132
+ f.max_activation for f in results["features"].values()
133
+ )
134
+ if max_activation > 0.8:
135
+ results["recommendations"].append(
136
+ "Content shows strong alignment with marketing-relevant features. Consider emphasizing these elements."
137
+ )
138
+ elif max_activation < 0.3:
139
+ results["recommendations"].append(
140
+ "Content could benefit from more distinctive marketing elements."
141
+ )
142
+
143
+ except Exception as e:
144
+ logger.error(f"Error analyzing content: {str(e)}")
145
+ results["error"] = str(e)
146
+
147
+ return results
148
+
149
+ def _categorize_feature(self, feature: Dict) -> str:
150
+ """Categorize feature based on description and patterns"""
151
+ description = feature.get("description", "").lower()
152
+
153
+ categories = {
154
+ "marketing": ["brand", "product", "market", "customer"],
155
+ "technical": ["technical", "technology", "software"],
156
+ "emotional": ["emotion", "feeling", "sentiment"],
157
+ "seo": ["search", "keyword", "ranking"],
158
+ }
159
+
160
+ for category, keywords in categories.items():
161
+ if any(keyword in description for keyword in keywords):
162
+ return category
163
+
164
+ return "general"
165
+
166
+
167
+ def create_gradio_interface():
168
+ analyzer = MarketingAnalyzer()
169
+
170
+ def analyze(text):
171
+ results = analyzer.analyze_content(text)
172
+
173
+ output = "# Content Analysis Results\n\n"
174
+
175
+ # Category scores
176
+ output += "## Category Scores\n"
177
+ for category, features in results["categories"].items():
178
+ if features:
179
+ avg_score = np.mean([f.activation_score for f in features])
180
+ output += f"**{category.title()}**: {avg_score:.2f}\n"
181
+
182
+ # Feature details
183
+ output += "\n## Feature Details\n"
184
+ for feature_id, feature in results["features"].items():
185
+ output += f"\n### {feature.name}\n"
186
+ output += f"**Score**: {feature.activation_score:.2f}\n"
187
+ output += f"**Max Activation**: {feature.max_activation:.2f}\n"
188
+ output += f"**Interpretation**: {feature.interpretation}\n"
189
+ if feature.description:
190
+ output += f"**Description**: {feature.description}\n"
191
+ output += f"[View on Neuronpedia](https://neuronpedia.org/gemma-2b/{feature.layer}/{feature_id})\n"
192
+
193
+ # Recommendations
194
+ if results.get("recommendations"):
195
+ output += "\n## Recommendations\n"
196
+ for rec in results["recommendations"]:
197
+ output += f"- {rec}\n"
198
+
199
+ # Get dashboard URL for highest activating feature
200
+ if results["features"]:
201
+ feature_id = max(
202
+ results["features"].items(), key=lambda x: x[1].activation_score
203
+ )[0]
204
+ feature = results["features"][feature_id]
205
+ dashboard_url = f"https://neuronpedia.org/gemma-2b/{feature.layer}/{feature_id}?embed=true&embedexplanation=true&embedplots=true&embedtest=true&height=300"
206
+ else:
207
+ dashboard_url = ""
208
+ feature_id = None
209
+
210
+ return (
211
+ output,
212
+ dashboard_url,
213
+ f"Currently viewing Feature {feature_id}" if feature_id else "",
214
+ )
215
+
216
+ # Create Gradio interface
217
+ with gr.Blocks(theme=gr.themes.Default()) as interface:
218
+ gr.Markdown("# Marketing Content Analyzer")
219
+ gr.Markdown("Analyze your marketing content using neural features")
220
+
221
+ with gr.Row():
222
+ with gr.Column(scale=1):
223
+ input_text = gr.Textbox(
224
+ lines=5,
225
+ placeholder="Enter your marketing content here...",
226
+ label="Marketing Content",
227
+ )
228
+ analyze_btn = gr.Button("Analyze", variant="primary")
229
+ gr.Examples(
230
+ examples=[
231
+ "Our AI-powered solution revolutionizes workflow efficiency",
232
+ "Experience seamless integration with our platform",
233
+ "Transform your business with cutting-edge technology",
234
+ ],
235
+ inputs=input_text,
236
+ )
237
+
238
+ with gr.Column(scale=2):
239
+ output_text = gr.Markdown(label="Analysis Results")
240
+ with gr.Group():
241
+ gr.Markdown("## Feature Dashboard")
242
+ feature_id_text = gr.Text(show_label=False)
243
+ dashboard_frame = gr.HTML(label="Feature Dashboard")
244
+
245
+ analyze_btn.click(
246
+ fn=analyze,
247
+ inputs=input_text,
248
+ outputs=[output_text, dashboard_frame, feature_id_text],
249
+ )
250
+
251
+ return interface
252
+
253
+
254
+ if __name__ == "__main__":
255
+ iface = create_gradio_interface()
256
+ iface.launch()