CosmickVisions commited on
Commit
cb10183
·
verified ·
1 Parent(s): 865ed05

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +210 -194
app.py CHANGED
@@ -15,13 +15,13 @@ from langchain.text_splitter import RecursiveCharacterTextSplitter
15
  from langchain_huggingface import HuggingFaceEmbeddings
16
  from langchain_community.document_loaders import TextLoader
17
  from langchain_community.tools.tavily_search import TavilySearchResults
 
18
  import os
19
  import tempfile
 
20
 
21
- # Initialize Groq client
22
  client = Groq(api_key=os.getenv("GROQ_API_KEY"))
23
-
24
- # Initialize embeddings for FAISS
25
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
26
 
27
  # Set page config
@@ -38,6 +38,8 @@ st.markdown("""
38
  --light-grey: #F3F4F6;
39
  --white: #FFFFFF;
40
  --border-grey: #E5E7EB;
 
 
41
  }
42
  .stApp {
43
  background-color: var(--light-grey);
@@ -64,6 +66,20 @@ st.markdown("""
64
  font-size: 1rem;
65
  margin-top: 5px;
66
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  .sidebar .sidebar-content {
68
  background-color: var(--white);
69
  border-radius: 12px;
@@ -95,6 +111,53 @@ st.markdown("""
95
  max-width: 80%;
96
  margin-bottom: 10px;
97
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  </style>
99
  """, unsafe_allow_html=True)
100
 
@@ -105,9 +168,96 @@ if 'chat_history' not in st.session_state:
105
  st.session_state.chat_history = []
106
  if 'vector_store' not in st.session_state:
107
  st.session_state.vector_store = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  # Helper Functions
110
  def convert_df_to_text(df):
 
111
  text = f"Dataset Summary: {df.shape[0]} rows, {df.shape[1]} columns\n"
112
  text += f"Missing Values: {df.isna().sum().sum()}\n"
113
  text += "Columns:\n"
@@ -121,6 +271,7 @@ def convert_df_to_text(df):
121
  return text
122
 
123
  def create_vector_store(df_text):
 
124
  with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as temp_file:
125
  temp_file.write(df_text)
126
  temp_path = temp_file.name
@@ -132,7 +283,8 @@ def create_vector_store(df_text):
132
  os.unlink(temp_path)
133
  return vector_store
134
 
135
- def get_groq_response(prompt, mode, use_web_search=False):
 
136
  context = ""
137
  sources = []
138
 
@@ -145,29 +297,31 @@ def get_groq_response(prompt, mode, use_web_search=False):
145
  # Tavily web search if toggled
146
  if use_web_search:
147
  tavily_api_key = os.environ.get("TAVILY_API_KEY")
148
- if not tavily_api_key:
149
- return "Please provide a Tavily API key in the sidebar to enable web search."
150
- try:
151
- # Set the API key for Tavily explicitly
152
- tavily = TavilySearchResults(max_results=3, api_key=tavily_api_key)
153
- web_results = tavily.invoke(prompt)
154
- context += "\n\nWeb Search Results (Tavily):\n" + "\n".join([f"- {res['content'][:200]}..." for res in web_results])
155
- sources.append("Tavily Web Search")
156
- except Exception as e:
157
- return f"Error with Tavily web search: {str(e)}. Ensure your API key is valid."
158
-
159
- # If no context is available
160
- if not context:
161
- context = "\n\nNo uploaded data available. I’ll provide a general response based on my knowledge."
162
 
 
 
 
 
163
  # Domain-specific prompt
164
  prompts = {
165
  "Legal": "You are an expert in legal data analysis, providing insights and predictions based on available data and web information if enabled.",
166
  "Financial": "You are an expert in financial data analysis, providing insights and predictions based on available data and web information if enabled.",
167
  "Academic": "You are an expert in academic data analysis, providing insights and predictions based on available data and web information if enabled.",
168
- "Technical": "You are an expert in technical data analysis, providing insights and predictions based on available data and web information if enabled."
 
 
169
  }
170
- system_prompt = prompts.get(mode, prompts["Legal"]) + "\n" + context
171
 
172
  try:
173
  response = client.chat.completions.create(
@@ -183,181 +337,43 @@ def get_groq_response(prompt, mode, use_web_search=False):
183
  except Exception as e:
184
  return f"Error generating response: {str(e)}"
185
 
186
- # Visualization Functions
187
- def plot_confusion_matrix(y_true, y_pred):
188
- cm = confusion_matrix(y_true, y_pred)
189
- fig = px.imshow(cm, text_auto=True, color_continuous_scale='Blues', title="Confusion Matrix")
190
- return fig
191
-
192
- def plot_feature_importance(model, X):
193
- if hasattr(model, 'feature_importances_'):
194
- importance = model.feature_importances_
195
- else:
196
- importance = np.abs(model.coef_) if hasattr(model, 'coef_') else np.ones(X.shape[1])
197
- fig = px.bar(x=X.columns, y=importance, title="Feature Importance")
198
- return fig
199
-
200
- def plot_residuals(y_true, y_pred):
201
- residuals = y_true - y_pred
202
- fig = px.scatter(x=y_pred, y=residuals, title="Residual Plot", labels={"x": "Predicted", "y": "Residuals"})
203
- return fig
204
-
205
- def plot_clusters(X, labels):
206
- fig = px.scatter(X, x=X.columns[0], y=X.columns[1], color=labels, title="Cluster Visualization")
207
- return fig
208
-
209
- # Pages
210
- def data_upload_page():
211
- st.header("📤 Data Upload & Analysis")
212
- uploaded_file = st.file_uploader("Upload Dataset", type=["csv"])
213
-
214
- if uploaded_file:
215
- df = pd.read_csv(uploaded_file)
216
- st.session_state.df = df
217
- st.session_state.vector_store = create_vector_store(convert_df_to_text(df))
218
- st.session_state.metrics = {}
219
-
220
- st.subheader("Dataset Health Check")
221
- col1, col2, col3 = st.columns(3)
222
- col1.metric("Total Samples", df.shape[0])
223
- col2.metric("Features", df.shape[1])
224
- col3.metric("Missing Values", df.isna().sum().sum())
225
-
226
- if st.button("Generate Full EDA Report"):
227
- with st.spinner("Generating comprehensive analysis..."):
228
- profile = ProfileReport(df, explorative=True)
229
- st_profile_report(profile)
230
-
231
- def model_training_page():
232
- st.header("🧠 Neural Network Training Studio")
233
-
234
- if 'df' not in st.session_state:
235
- st.warning("Upload data first!")
236
- return
237
-
238
- df = st.session_state.df
239
- problem_type = st.selectbox("Select Problem Type", ["Classification", "Regression", "Clustering"])
240
- mode = st.selectbox("Domain Specialization", ["Legal", "Financial", "Academic", "Technical"])
241
 
242
- if problem_type != "Clustering":
243
- target = st.selectbox("Select Target Variable", df.columns)
244
- X = df.drop(columns=[target])
245
- y = df[target]
 
 
 
246
  else:
247
- X = df
248
- y = None
249
-
250
- if st.button("Train Neural Network"):
251
- with st.spinner("Training in progress..."):
252
- X_scaled = StandardScaler().fit_transform(X)
253
- X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42) if y is not None else (X_scaled, None, None, None)
254
-
255
- if problem_type == "Classification":
256
- model = MLPClassifier(hidden_layer_sizes=(100, 50), max_iter=500, random_state=42)
257
- model.fit(X_train, y_train)
258
- y_pred = model.predict(X_test)
259
- st.session_state.metrics = {
260
- "Accuracy": accuracy_score(y_test, y_pred),
261
- "Classification Report": classification_report(y_test, y_pred, output_dict=True)
262
- }
263
- elif problem_type == "Regression":
264
- model = MLPRegressor(hidden_layer_sizes=(100, 50), max_iter=500, random_state=42)
265
- model.fit(X_train, y_train)
266
- y_pred = model.predict(X_test)
267
- st.session_state.metrics = {
268
- "R2 Score": r2_score(y_test, y_pred),
269
- "Mean Squared Error": mean_squared_error(y_test, y_pred)
270
- }
271
- else: # Clustering
272
- model = KMeans(n_clusters=3, random_state=42)
273
- labels = model.fit_predict(X_scaled)
274
- st.session_state.metrics = {
275
- "Silhouette Score": silhouette_score(X_scaled, labels)
276
- }
277
-
278
- st.session_state.best_model = model
279
- st.session_state.X_test = X_test
280
- st.session_state.y_test = y_test
281
- st.session_state.y_pred = y_pred if y is not None else labels
282
- st.session_state.problem_type = problem_type
283
- st.success(f"Model trained successfully in {mode} mode!")
284
-
285
- def visualization_page():
286
- st.header("🔍 Neural Network Evaluation Center")
287
-
288
- if 'best_model' not in st.session_state:
289
- st.warning("Train a model first!")
290
- return
291
-
292
- st.subheader("Performance Analysis")
293
- if st.session_state.problem_type == "Classification":
294
- st.plotly_chart(plot_confusion_matrix(st.session_state.y_test, st.session_state.y_pred))
295
- st.plotly_chart(plot_feature_importance(st.session_state.best_model, pd.DataFrame(st.session_state.X_test, columns=st.session_state.df.columns[:-1])))
296
- elif st.session_state.problem_type == "Regression":
297
- st.plotly_chart(plot_residuals(st.session_state.y_test, st.session_state.y_pred))
298
- st.plotly_chart(plot_feature_importance(st.session_state.best_model, pd.DataFrame(st.session_state.X_test, columns=st.session_state.df.columns[:-1])))
299
- else: # Clustering
300
- st.plotly_chart(plot_clusters(pd.DataFrame(st.session_state.X_test, columns=st.session_state.df.columns), st.session_state.y_pred))
301
-
302
- st.subheader("Metrics")
303
- st.write(st.session_state.metrics)
304
-
305
- # Chatbot Interface
306
- def ai_assistant():
307
- st.markdown('<div class="chat-container">', unsafe_allow_html=True)
308
- st.subheader("🧠 Neural Insight Assistant (RAG + Web Search)")
309
-
310
- use_web_search = st.checkbox("Enable Tavily Web Search", value=False)
311
- mode = st.selectbox("Domain Mode", ["Legal", "Financial", "Academic", "Technical"], key="chat_mode")
312
-
313
- for msg in st.session_state.chat_history:
314
- with st.chat_message(msg["role"]):
315
- st.markdown(f'<div class="{msg["role"]}-message">{msg["content"]}</div>', unsafe_allow_html=True)
316
-
317
- if prompt := st.chat_input("Ask about data, models, or web insights..."):
318
- st.session_state.chat_history.append({"role": "user", "content": prompt})
319
- with st.chat_message("user"):
320
- st.markdown(f'<div class="user-message">{prompt}</div>', unsafe_allow_html=True)
321
-
322
- with st.spinner("Processing..."):
323
- response = get_groq_response(prompt, mode, use_web_search)
324
- st.session_state.chat_history.append({"role": "assistant", "content": response})
325
 
326
- with st.chat_message("assistant"):
327
- st.markdown(f'<div class="bot-message">{response}</div>', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
 
329
- st.markdown('</div>', unsafe_allow_html=True)
330
-
331
- # Main App Layout
332
- st.markdown("""
333
- <div class="header">
334
- <h1 class="header-title">Neural-Vision Enhanced</h1>
335
- <div class="header-subtitle">Neural Network Development for Domain-Specialized Analysis</div>
336
- </div>
337
- """, unsafe_allow_html=True)
338
-
339
- with st.sidebar:
340
- st.title("🔮 Neural-Vision Enhanced")
341
- page = st.selectbox("Navigation", [
342
- "Data Upload & Analysis",
343
- "Neural Network Training Studio",
344
- "Neural Network Evaluation Center"
345
- ])
346
- st.session_state.active_page = page
347
- st.markdown("---")
348
- st.markdown("**Environment Setup**")
349
- tavily_api_key = st.text_input("Tavily API Key", type="password", help="For web search functionality")
350
- if tavily_api_key:
351
- os.environ["TAVILY_API_KEY"] = tavily_api_key # Set the API key dynamically
352
- st.markdown("---")
353
- st.markdown("v5.1 | © 2025 Neural-Vision")
354
-
355
- # Page Routing
356
- if "Data Upload & Analysis" in page:
357
- data_upload_page()
358
- elif "Neural Network Training Studio" in page:
359
- model_training_page()
360
- else:
361
- visualization_page()
362
-
363
- ai_assistant()
 
15
  from langchain_huggingface import HuggingFaceEmbeddings
16
  from langchain_community.document_loaders import TextLoader
17
  from langchain_community.tools.tavily_search import TavilySearchResults
18
+ import torch
19
  import os
20
  import tempfile
21
+ import json
22
 
23
+ # Initialize clients
24
  client = Groq(api_key=os.getenv("GROQ_API_KEY"))
 
 
25
  embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
26
 
27
  # Set page config
 
38
  --light-grey: #F3F4F6;
39
  --white: #FFFFFF;
40
  --border-grey: #E5E7EB;
41
+ --success-green: #10B981;
42
+ --warning-yellow: #F59E0B;
43
  }
44
  .stApp {
45
  background-color: var(--light-grey);
 
66
  font-size: 1rem;
67
  margin-top: 5px;
68
  }
69
+ .card {
70
+ background-color: var(--white);
71
+ border-radius: 12px;
72
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
73
+ padding: 20px;
74
+ margin-bottom: 20px;
75
+ }
76
+ .layer-card {
77
+ background-color: var(--light-blue);
78
+ border-radius: 8px;
79
+ padding: 15px;
80
+ margin-bottom: 10px;
81
+ border-left: 4px solid var(--primary-blue);
82
+ }
83
  .sidebar .sidebar-content {
84
  background-color: var(--white);
85
  border-radius: 12px;
 
111
  max-width: 80%;
112
  margin-bottom: 10px;
113
  }
114
+ .model-card {
115
+ border: 1px solid var(--border-grey);
116
+ border-radius: 8px;
117
+ padding: 15px;
118
+ margin-bottom: 15px;
119
+ transition: all 0.3s ease;
120
+ cursor: pointer;
121
+ }
122
+ .model-card:hover {
123
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
124
+ border-color: var(--primary-blue);
125
+ }
126
+ .selected-model {
127
+ border-color: var(--primary-blue);
128
+ background-color: var(--light-blue);
129
+ }
130
+ .stButton>button {
131
+ background-color: var(--primary-blue);
132
+ color: white;
133
+ border-radius: 6px;
134
+ padding: 8px 16px;
135
+ border: none;
136
+ font-weight: 500;
137
+ transition: all 0.3s ease;
138
+ }
139
+ .stButton>button:hover {
140
+ background-color: var(--dark-blue);
141
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
142
+ }
143
+ .status-bar {
144
+ height: 10px;
145
+ width: 100%;
146
+ background-color: var(--light-grey);
147
+ border-radius: 5px;
148
+ margin-top: 10px;
149
+ overflow: hidden;
150
+ }
151
+ .status-progress {
152
+ height: 100%;
153
+ background-color: var(--primary-blue);
154
+ transition: width 0.5s ease;
155
+ }
156
+ .feature-desc {
157
+ font-size: 0.9rem;
158
+ color: var(--medium-grey);
159
+ margin-top: 5px;
160
+ }
161
  </style>
162
  """, unsafe_allow_html=True)
163
 
 
168
  st.session_state.chat_history = []
169
  if 'vector_store' not in st.session_state:
170
  st.session_state.vector_store = None
171
+ if 'custom_layers' not in st.session_state:
172
+ st.session_state.custom_layers = []
173
+ if 'prebuilt_selection' not in st.session_state:
174
+ st.session_state.prebuilt_selection = None
175
+ if 'model_config' not in st.session_state:
176
+ st.session_state.model_config = {}
177
+ if 'model_builder_mode' not in st.session_state:
178
+ st.session_state.model_builder_mode = "prebuilt" # Options: "prebuilt" or "custom"
179
+ if 'custom_model_type' not in st.session_state:
180
+ st.session_state.custom_model_type = "classification" # Options: "classification", "regression", "clustering"
181
+
182
+ # Prebuilt model templates
183
+ PREBUILT_MODELS = {
184
+ "Legal Document Classifier": {
185
+ "description": "Neural network optimized for legal document classification with special features for contract analysis.",
186
+ "architecture": {
187
+ "type": "classification",
188
+ "hidden_layers": [(128, "relu"), (64, "relu")],
189
+ "dropout": 0.3,
190
+ "optimizer": "adam",
191
+ "learning_rate": 0.001
192
+ },
193
+ "domain": "Legal",
194
+ "use_case": "Document classification"
195
+ },
196
+ "Financial Fraud Detector": {
197
+ "description": "Deep learning model designed to detect anomalies in financial transactions with high accuracy.",
198
+ "architecture": {
199
+ "type": "classification",
200
+ "hidden_layers": [(256, "relu"), (128, "relu"), (64, "relu")],
201
+ "dropout": 0.4,
202
+ "optimizer": "adam",
203
+ "learning_rate": 0.0005
204
+ },
205
+ "domain": "Financial",
206
+ "use_case": "Fraud detection"
207
+ },
208
+ "Academic Paper Topic Classifier": {
209
+ "description": "Neural model for categorizing academic papers by subject area.",
210
+ "architecture": {
211
+ "type": "classification",
212
+ "hidden_layers": [(100, "relu"), (50, "tanh")],
213
+ "dropout": 0.2,
214
+ "optimizer": "adam",
215
+ "learning_rate": 0.001
216
+ },
217
+ "domain": "Academic",
218
+ "use_case": "Topic classification"
219
+ },
220
+ "Customer Churn Predictor": {
221
+ "description": "Regression model that predicts likelihood of customer churn based on engagement metrics.",
222
+ "architecture": {
223
+ "type": "regression",
224
+ "hidden_layers": [(64, "relu"), (32, "relu")],
225
+ "dropout": 0.2,
226
+ "optimizer": "adam",
227
+ "learning_rate": 0.001
228
+ },
229
+ "domain": "Business",
230
+ "use_case": "Churn prediction"
231
+ },
232
+ "Medical Diagnosis Assistant": {
233
+ "description": "Classification model for preliminary medical diagnosis based on patient symptoms and metrics.",
234
+ "architecture": {
235
+ "type": "classification",
236
+ "hidden_layers": [(128, "relu"), (64, "relu"), (32, "relu")],
237
+ "dropout": 0.3,
238
+ "optimizer": "adam",
239
+ "learning_rate": 0.0005
240
+ },
241
+ "domain": "Healthcare",
242
+ "use_case": "Diagnosis assistance"
243
+ },
244
+ "Customer Segmentation Engine": {
245
+ "description": "Clustering model for advanced customer segmentation based on behavioral patterns.",
246
+ "architecture": {
247
+ "type": "clustering",
248
+ "n_clusters": 5,
249
+ "algorithm": "kmeans",
250
+ "init": "k-means++",
251
+ "n_init": 10
252
+ },
253
+ "domain": "Marketing",
254
+ "use_case": "Customer segmentation"
255
+ }
256
+ }
257
 
258
  # Helper Functions
259
  def convert_df_to_text(df):
260
+ """Convert dataframe to text format for RAG system"""
261
  text = f"Dataset Summary: {df.shape[0]} rows, {df.shape[1]} columns\n"
262
  text += f"Missing Values: {df.isna().sum().sum()}\n"
263
  text += "Columns:\n"
 
271
  return text
272
 
273
  def create_vector_store(df_text):
274
+ """Create FAISS vector store from dataframe text"""
275
  with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as temp_file:
276
  temp_file.write(df_text)
277
  temp_path = temp_file.name
 
283
  os.unlink(temp_path)
284
  return vector_store
285
 
286
+ def get_groq_response(prompt, mode, context_type="model_building", use_web_search=False):
287
+ """Get response from Groq LLM with different context types"""
288
  context = ""
289
  sources = []
290
 
 
297
  # Tavily web search if toggled
298
  if use_web_search:
299
  tavily_api_key = os.environ.get("TAVILY_API_KEY")
300
+ if tavily_api_key:
301
+ try:
302
+ tavily = TavilySearchResults(max_results=3, api_key=tavily_api_key)
303
+ web_results = tavily.invoke(prompt)
304
+ context += "\n\nWeb Search Results (Tavily):\n" + "\n".join([f"- {res['content'][:200]}..." for res in web_results])
305
+ sources.append("Tavily Web Search")
306
+ except Exception as e:
307
+ return f"Error with Tavily web search: {str(e)}. Ensure your API key is valid."
308
+ else:
309
+ context += "\n\nWeb search requested but no Tavily API key provided."
 
 
 
 
310
 
311
+ # Model building context
312
+ if context_type == "model_building":
313
+ context += "\n\nYou are advising on neural network architecture and implementation. Provide specific layer recommendations, parameters, and explain your reasoning. Be specific with activation functions, layer sizes, and learning approaches."
314
+
315
  # Domain-specific prompt
316
  prompts = {
317
  "Legal": "You are an expert in legal data analysis, providing insights and predictions based on available data and web information if enabled.",
318
  "Financial": "You are an expert in financial data analysis, providing insights and predictions based on available data and web information if enabled.",
319
  "Academic": "You are an expert in academic data analysis, providing insights and predictions based on available data and web information if enabled.",
320
+ "Technical": "You are an expert in technical data analysis, providing insights and predictions based on available data and web information if enabled.",
321
+ "Healthcare": "You are an expert in healthcare data analysis, providing medical insights based on available data and web information if enabled.",
322
+ "Marketing": "You are an expert in marketing data analysis, providing customer insights based on available data and web information if enabled."
323
  }
324
+ system_prompt = prompts.get(mode, prompts["Technical"]) + "\n" + context
325
 
326
  try:
327
  response = client.chat.completions.create(
 
337
  except Exception as e:
338
  return f"Error generating response: {str(e)}"
339
 
340
+ def build_model_from_config(config, X, y=None):
341
+ """Build a model from configuration dictionary"""
342
+ problem_type = config.get("type", "classification")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
 
344
+ if problem_type == "clustering":
345
+ model = KMeans(
346
+ n_clusters=config.get("n_clusters", 3),
347
+ init=config.get("init", "k-means++"),
348
+ n_init=config.get("n_init", 10),
349
+ random_state=42
350
+ )
351
  else:
352
+ # Extract hidden layer sizes and activations
353
+ hidden_layers = config.get("hidden_layers", [(100, "relu")])
354
+ layer_sizes = [size for size, _ in hidden_layers]
355
+ activation = hidden_layers[0][1] if hidden_layers else "relu"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
 
357
+ # Create appropriate model based on problem type
358
+ if problem_type == "classification":
359
+ model = MLPClassifier(
360
+ hidden_layer_sizes=layer_sizes,
361
+ activation=activation,
362
+ solver=config.get("optimizer", "adam"),
363
+ alpha=config.get("regularization", 0.0001),
364
+ learning_rate_init=config.get("learning_rate", 0.001),
365
+ max_iter=config.get("max_iter", 500),
366
+ random_state=42
367
+ )
368
+ else: # regression
369
+ model = MLPRegressor(
370
+ hidden_layer_sizes=layer_sizes,
371
+ activation=activation,
372
+ solver=config.get("optimizer", "adam"),
373
+ alpha=config.get("regularization", 0.0001),
374
+ learning_rate_init=config.get("learning_rate", 0.001),
375
+ max_iter=config.get("max_iter", 500),
376
+ random_state=42
377
+ )
378
 
379
+ return model