trohith89 commited on
Commit
5028ce0
·
verified ·
1 Parent(s): fa2f086

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +162 -149
app.py CHANGED
@@ -3,59 +3,75 @@ import networkx as nx
3
  import pandas as pd
4
  import numpy as np
5
  import matplotlib.pyplot as plt
6
- import seaborn as sns
7
- from IPython.display import clear_output
8
- import io
9
- from sklearn.model_selection import train_test_split
10
- from sklearn.metrics import log_loss
11
- from sklearn.datasets import make_classification, make_circles
12
  from sklearn.preprocessing import StandardScaler
13
  from mlxtend.plotting import plot_decision_regions
14
  import tensorflow as tf
15
- from keras.optimizers import SGD
16
  from keras.models import Sequential
17
  from keras.layers import Input, Dense
 
18
  from keras.losses import BinaryCrossentropy
19
  from keras.regularizers import l2, l1
20
  from keras.callbacks import Callback
21
 
22
- # Wide layout and dark theme CSS
23
  st.set_page_config(layout="wide")
24
  st.markdown("""
25
  <style>
26
- body {
27
  background-color: #252830;
28
  color: white;
 
29
  }
30
- .stApp {
31
- background-color: #252830;
32
  color: white;
 
 
 
33
  }
34
  .stButton>button {
35
  background-color: #555;
36
  color: white;
 
37
  border-radius: 5px;
38
  padding: 5px 10px;
 
 
 
 
39
  }
40
  .stSelectbox, .stSlider {
41
  background-color: #333;
42
  color: white;
43
  border-radius: 5px;
 
44
  }
45
  .stCheckbox label {
46
  color: white;
 
47
  font-weight: bold;
48
  }
 
 
 
 
 
 
 
 
 
 
 
49
  </style>
50
  """, unsafe_allow_html=True)
51
 
52
- # Session state initialization
53
  if "training" not in st.session_state:
54
  st.session_state.training = False
55
  if "num_hidden_layers" not in st.session_state:
56
- st.session_state.num_hidden_layers = 2 # Default from URL: 4,2
57
  if "hidden_layer_neurons" not in st.session_state:
58
- st.session_state.hidden_layer_neurons = [4, 2] # Default from URL
59
  if "prev_params" not in st.session_state:
60
  st.session_state.prev_params = {}
61
 
@@ -64,173 +80,170 @@ def reset_session():
64
  st.session_state.num_hidden_layers = 2
65
  st.session_state.hidden_layer_neurons = [4, 2]
66
 
67
- # Header bar with controls
68
- st.markdown("<h1 style='text-align: center; color: white;'>Neural Network Playground</h1>", unsafe_allow_html=True)
69
-
70
- # Top controls in columns
71
- col1, col2, col3, col4, col5 = st.columns([1, 1, 1, 1, 1])
72
- with col1:
73
- dataset_type = st.selectbox("Dataset", ["Circle", "Gaussian"], index=0) # Circle default
74
- with col2:
75
- learning_rate = st.selectbox("Learning Rate", [0.0001, 0.001, 0.03, 0.1, 0.3, 1], index=2) # 0.03 default
76
- with col3:
77
- activation_function = st.selectbox("Activation", ["ReLU", "Sigmoid", "Tanh"], index=2) # Tanh default
78
- with col4:
79
- batch_size = st.slider("Batch Size", 1, 30, 10) # 10 default
80
- with col5:
81
- noise_level_slider = st.slider("Noise", 0, 50, 0, step=5) # 0 default
82
-
83
- # Additional controls in a second row
84
- col6, col7, col8, col9 = st.columns([1, 1, 1, 1])
85
- with col6:
86
- regularization_type = st.selectbox("Regularization", ["None", "L1", "L2"], index=0) # None default
87
- with col7:
88
- regularization_rate = st.selectbox("Reg Rate", [0.0, 0.001, 0.01, 0.1, 1], index=0) # 0 default
89
- with col8:
90
- train_to_test_ratio = st.slider("Train %", 10, 90, 50, 10) / 100 # 50% default
91
- with col9:
92
- if st.button("Reset"):
93
- reset_session()
94
-
95
- # Noise scaling
96
- min_noise = 0.02
97
- noise_level = min_noise + (noise_level_slider / 50) * (0.2 - min_noise)
98
- flip_y = noise_level / 50
99
- class_sep = max(2.0 - 1.5 * flip_y, 0.5)
100
- cluster_std = min(1.0 + 3.0 * flip_y, 3.0)
101
-
102
- # Dataset generation
103
- if dataset_type == "Gaussian":
104
- fv, cv = make_classification(n_samples=800, n_features=2, n_informative=2, n_redundant=0, n_classes=2, class_sep=class_sep, flip_y=flip_y, n_clusters_per_class=1)
105
- else:
106
- fv, cv = make_circles(n_samples=800, shuffle=True, noise=noise_level, factor=0.2)
107
-
108
- # Feature selection
109
  std = StandardScaler()
110
  X = std.fit_transform(fv)
111
  x1, x2 = X[:, 0], X[:, 1]
112
- x1_squared, x2_squared = x1**2, x2**2
113
- x1_x2 = x1 * x2
114
- cos_x1, sin_x1 = np.cos(x1), np.sin(x1)
115
- cos_x2, sin_x2 = np.cos(x2), np.sin(x2)
116
-
117
- feature_mapping = {
118
- "X1": x1, "X2": x2, "X1*X2": x1_x2, "X1^2": x1_squared, "X2^2": x2_squared,
119
- "cos(X1)": cos_x1, "sin(X1)": sin_x1, "cos(X2)": cos_x2, "sin(X2)": sin_x2
120
  }
121
- available_features = list(feature_mapping.keys())
122
- selected_features = [f for f in available_features if st.checkbox(f, value=f in ["X1", "X2"], key=f)]
123
- selected_data = np.column_stack([feature_mapping[f] for f in selected_features])
124
-
125
- # Hidden layer controls
126
- def add_layer():
127
- if st.session_state.num_hidden_layers < 6:
128
- st.session_state.num_hidden_layers += 1
129
- st.session_state.hidden_layer_neurons.append(1)
130
-
131
- def remove_layer():
132
- if st.session_state.num_hidden_layers > 0:
133
- st.session_state.num_hidden_layers -= 1
134
- st.session_state.hidden_layer_neurons.pop()
135
-
136
- def increase_neurons(idx):
137
- if st.session_state.hidden_layer_neurons[idx] < 8:
138
- st.session_state.hidden_layer_neurons[idx] += 1
139
-
140
- def decrease_neurons(idx):
141
- if st.session_state.hidden_layer_neurons[idx] > 1:
142
- st.session_state.hidden_layer_neurons[idx] -= 1
143
-
144
- # Main layout
145
  col_left, col_center, col_right = st.columns([1, 2, 1])
146
 
 
147
  with col_left:
148
- st.subheader("Dataset")
 
149
  fig, ax = plt.subplots(figsize=(3, 3))
150
  ax.scatter(fv[:, 0], fv[:, 1], c=cv, cmap="coolwarm", edgecolors="k", alpha=0.7)
151
  ax.set_xticks([])
152
  ax.set_yticks([])
153
  ax.set_facecolor("#333")
154
  st.pyplot(fig)
 
 
 
 
155
 
 
156
  with col_center:
157
- st.subheader("Network Architecture")
158
- def draw_nn(features, neurons, outputs=1):
 
 
159
  G = nx.DiGraph()
160
- layers = [features] + [[f"hl{i+1}_{j+1}" for j in range(n)] for i, n in enumerate(neurons)] + [["y1"]]
161
  node_colors = {}
162
  for layer_idx, layer in enumerate(layers):
163
  for node in layer:
164
  G.add_node(node, layer=layer_idx)
165
  node_colors[node] = "#90EE90" if layer_idx == 0 else "#87CEFA" if layer_idx < len(layers) - 1 else "#FFA07A"
166
- for i in range(len(layers) - 1):
167
- for n1 in layers[i]:
168
- for n2 in layers[i + 1]:
169
- G.add_edge(n1, n2)
170
  pos = nx.multipartite_layout(G, subset_key="layer")
171
  fig, ax = plt.subplots(figsize=(8, 4))
172
  ax.set_facecolor("#252830")
173
- nx.draw(G, pos, with_labels=True, node_color=[node_colors[n] for n in G.nodes], edge_color="white", node_size=800, font_size=8, ax=ax, width=0.4)
 
174
  return fig
175
-
176
  st.pyplot(draw_nn(selected_features, st.session_state.hidden_layer_neurons))
177
-
178
- # Layer controls
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  for i in range(st.session_state.num_hidden_layers):
180
  col1, col2, col3 = st.columns([1, 2, 1])
181
  with col1:
182
  st.button("-", key=f"dec_{i}", on_click=decrease_neurons, args=(i,))
183
  with col2:
184
- st.write(f"Layer {i+1}: {st.session_state.hidden_layer_neurons[i]} neurons")
185
  with col3:
186
  st.button("+", key=f"inc_{i}", on_click=increase_neurons, args=(i,))
187
- st.button("Add Layer", on_click=add_layer)
188
- st.button("Remove Layer", on_click=remove_layer)
189
-
 
 
 
 
 
190
  with col_right:
 
191
  st.subheader("Output")
192
- if st.button("▶️ Start"):
193
- st.session_state.training = True
194
- if st.button("⏹️ Stop"):
195
- st.session_state.training = False
196
-
197
- # Model training
198
- def create_ann_model(input_dim, hidden_layers, neurons_per_layer):
199
- model = Sequential()
200
- model.add(Input(shape=(input_dim,)))
201
- reg = l1(regularization_rate) if regularization_type == "L1" else l2(regularization_rate) if regularization_type == "L2" else None
202
- for neurons in neurons_per_layer:
203
- model.add(Dense(neurons, activation=activation_function.lower(), kernel_regularizer=reg))
204
- model.add(Dense(1, activation='sigmoid'))
205
- optimizer = SGD(learning_rate=learning_rate)
206
- model.compile(optimizer=optimizer, loss=BinaryCrossentropy(), metrics=['accuracy'])
207
- return model
208
-
209
- class LossPlotCallback(tf.keras.callbacks.Callback):
210
- def __init__(self, X, y):
211
- super().__init__()
212
- self.loss_df = pd.DataFrame(columns=["Epoch", "Train Loss", "Val Loss"])
213
- self.X, self.y = X, y
214
- self.plot_placeholder = st.empty()
215
-
216
- def on_epoch_end(self, epoch, logs=None):
217
- new_row = pd.DataFrame({"Epoch": [epoch + 1], "Train Loss": [logs['loss']], "Val Loss": [logs['val_loss']]})
218
- self.loss_df = pd.concat([self.loss_df, new_row], ignore_index=True)
219
- with self.plot_placeholder.container():
220
- col1, col2 = st.columns(2)
221
- with col1:
222
- plt.figure(figsize=(3, 3))
223
- plot_decision_regions(self.X, self.y, clf=self.model)
224
- st.pyplot(plt)
225
- with col2:
226
- fig, ax = plt.subplots(figsize=(3, 3))
227
- ax.plot(self.loss_df["Epoch"], self.loss_df["Train Loss"], 'b-', label="Train")
228
- ax.plot(self.loss_df["Epoch"], self.loss_df["Val Loss"], 'r--', label="Val")
229
- ax.legend()
230
- ax.set_facecolor("#333")
231
- st.pyplot(fig)
232
-
233
- if st.session_state.training:
234
- ann_model = create_ann_model(len(selected_features), st.session_state.num_hidden_layers, st.session_state.hidden_layer_neurons)
235
- loss_plot_callback = LossPlotCallback(selected_data, cv)
236
- ann_model.fit(selected_data, cv, epochs=999999, validation_split=1-train_to_test_ratio, batch_size=batch_size, callbacks=[loss_plot_callback], verbose=0)
 
 
 
 
 
 
 
 
3
  import pandas as pd
4
  import numpy as np
5
  import matplotlib.pyplot as plt
6
+ from sklearn.datasets import make_circles
 
 
 
 
 
7
  from sklearn.preprocessing import StandardScaler
8
  from mlxtend.plotting import plot_decision_regions
9
  import tensorflow as tf
 
10
  from keras.models import Sequential
11
  from keras.layers import Input, Dense
12
+ from keras.optimizers import SGD
13
  from keras.losses import BinaryCrossentropy
14
  from keras.regularizers import l2, l1
15
  from keras.callbacks import Callback
16
 
17
+ # Set wide layout and apply TensorFlow Playground-inspired CSS
18
  st.set_page_config(layout="wide")
19
  st.markdown("""
20
  <style>
21
+ .stApp {
22
  background-color: #252830;
23
  color: white;
24
+ font-family: Arial, sans-serif;
25
  }
26
+ h1, h2, h3 {
 
27
  color: white;
28
+ font-weight: bold;
29
+ margin: 0;
30
+ padding: 5px 0;
31
  }
32
  .stButton>button {
33
  background-color: #555;
34
  color: white;
35
+ border: none;
36
  border-radius: 5px;
37
  padding: 5px 10px;
38
+ font-size: 14px;
39
+ }
40
+ .stButton>button:hover {
41
+ background-color: #777;
42
  }
43
  .stSelectbox, .stSlider {
44
  background-color: #333;
45
  color: white;
46
  border-radius: 5px;
47
+ padding: 5px;
48
  }
49
  .stCheckbox label {
50
  color: white;
51
+ font-size: 14px;
52
  font-weight: bold;
53
  }
54
+ .control-bar {
55
+ background-color: #1e2126;
56
+ padding: 10px;
57
+ border-bottom: 2px solid #333;
58
+ }
59
+ .panel {
60
+ background-color: #2e3238;
61
+ padding: 10px;
62
+ border-radius: 5px;
63
+ margin: 10px 0;
64
+ }
65
  </style>
66
  """, unsafe_allow_html=True)
67
 
68
+ # Session state initialization (matching URL defaults)
69
  if "training" not in st.session_state:
70
  st.session_state.training = False
71
  if "num_hidden_layers" not in st.session_state:
72
+ st.session_state.num_hidden_layers = 2 # Default: 4,2
73
  if "hidden_layer_neurons" not in st.session_state:
74
+ st.session_state.hidden_layer_neurons = [4, 2]
75
  if "prev_params" not in st.session_state:
76
  st.session_state.prev_params = {}
77
 
 
80
  st.session_state.num_hidden_layers = 2
81
  st.session_state.hidden_layer_neurons = [4, 2]
82
 
83
+ # Top control bar
84
+ with st.container():
85
+ st.markdown('<div class="control-bar">', unsafe_allow_html=True)
86
+ col1, col2, col3, col4, col5, col6, col7, col8 = st.columns(8)
87
+ with col1:
88
+ dataset_type = st.selectbox("Dataset", ["Circle", "Gaussian"], index=0, label_visibility="collapsed")
89
+ with col2:
90
+ learning_rate = st.selectbox("Learning Rate", [0.0001, 0.001, 0.03, 0.1, 0.3, 1], index=2, label_visibility="collapsed")
91
+ with col3:
92
+ activation = st.selectbox("Activation", ["ReLU", "Sigmoid", "Tanh"], index=2, label_visibility="collapsed")
93
+ with col4:
94
+ batch_size = st.slider("Batch Size", 1, 30, 10, label_visibility="collapsed")
95
+ with col5:
96
+ noise_level = st.slider("Noise", 0, 50, 0, step=5, label_visibility="collapsed")
97
+ with col6:
98
+ reg_type = st.selectbox("Regularization", ["None", "L1", "L2"], index=0, label_visibility="collapsed")
99
+ with col7:
100
+ reg_rate = st.selectbox("Reg Rate", [0.0, 0.001, 0.01, 0.1, 1], index=0, label_visibility="collapsed")
101
+ with col8:
102
+ train_ratio = st.slider("Train %", 10, 90, 50, 10, label_visibility="collapsed") / 100
103
+ st.markdown('</div>', unsafe_allow_html=True)
104
+
105
+ # Dataset generation (Circle as default)
106
+ fv, cv = make_circles(n_samples=800, shuffle=True, noise=noise_level / 250, factor=0.2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  std = StandardScaler()
108
  X = std.fit_transform(fv)
109
  x1, x2 = X[:, 0], X[:, 1]
110
+ features = {
111
+ "X1": x1, "X2": x2, "X1*X2": x1 * x2, "X1^2": x1**2, "X2^2": x2**2,
112
+ "cos(X1)": np.cos(x1), "sin(X1)": np.sin(x1), "cos(X2)": np.cos(x2), "sin(X2)": np.sin(x2)
 
 
 
 
 
113
  }
114
+ selected_features = [f for f in features.keys() if st.session_state.get(f, f in ["X1", "X2"])]
115
+ selected_data = np.column_stack([features[f] for f in selected_features])
116
+
117
+ # Main layout with three panels
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  col_left, col_center, col_right = st.columns([1, 2, 1])
119
 
120
+ # Left panel: Dataset and Features
121
  with col_left:
122
+ st.markdown('<div class="panel">', unsafe_allow_html=True)
123
+ st.subheader("Data")
124
  fig, ax = plt.subplots(figsize=(3, 3))
125
  ax.scatter(fv[:, 0], fv[:, 1], c=cv, cmap="coolwarm", edgecolors="k", alpha=0.7)
126
  ax.set_xticks([])
127
  ax.set_yticks([])
128
  ax.set_facecolor("#333")
129
  st.pyplot(fig)
130
+ st.subheader("Features")
131
+ for feature in features.keys():
132
+ st.checkbox(feature, value=feature in ["X1", "X2"], key=feature)
133
+ st.markdown('</div>', unsafe_allow_html=True)
134
 
135
+ # Center panel: Network Visualization and Controls
136
  with col_center:
137
+ st.markdown('<div class="panel">', unsafe_allow_html=True)
138
+ st.subheader("Network")
139
+
140
+ def draw_nn(features, neurons):
141
  G = nx.DiGraph()
142
+ layers = [features] + [[f"h{i+1}_{j+1}" for j in range(n)] for i, n in enumerate(neurons)] + [["Output"]]
143
  node_colors = {}
144
  for layer_idx, layer in enumerate(layers):
145
  for node in layer:
146
  G.add_node(node, layer=layer_idx)
147
  node_colors[node] = "#90EE90" if layer_idx == 0 else "#87CEFA" if layer_idx < len(layers) - 1 else "#FFA07A"
148
+ for i in range(len(layers) - 1):
149
+ for n1 in layers[i]:
150
+ for n2 in layers[i + 1]:
151
+ G.add_edge(n1, n2)
152
  pos = nx.multipartite_layout(G, subset_key="layer")
153
  fig, ax = plt.subplots(figsize=(8, 4))
154
  ax.set_facecolor("#252830")
155
+ nx.draw(G, pos, with_labels=True, node_color=[node_colors[n] for n in G.nodes], edge_color="white", edgecolors="black",
156
+ node_size=600, font_size=8, font_color="black", width=0.4)
157
  return fig
158
+
159
  st.pyplot(draw_nn(selected_features, st.session_state.hidden_layer_neurons))
160
+
161
+ def add_layer():
162
+ if st.session_state.num_hidden_layers < 6:
163
+ st.session_state.num_hidden_layers += 1
164
+ st.session_state.hidden_layer_neurons.append(1)
165
+
166
+ def remove_layer():
167
+ if st.session_state.num_hidden_layers > 0:
168
+ st.session_state.num_hidden_layers -= 1
169
+ st.session_state.hidden_layer_neurons.pop()
170
+
171
+ def increase_neurons(i):
172
+ if st.session_state.hidden_layer_neurons[i] < 8:
173
+ st.session_state.hidden_layer_neurons[i] += 1
174
+
175
+ def decrease_neurons(i):
176
+ if st.session_state.hidden_layer_neurons[i] > 1:
177
+ st.session_state.hidden_layer_neurons[i] -= 1
178
+
179
  for i in range(st.session_state.num_hidden_layers):
180
  col1, col2, col3 = st.columns([1, 2, 1])
181
  with col1:
182
  st.button("-", key=f"dec_{i}", on_click=decrease_neurons, args=(i,))
183
  with col2:
184
+ st.write(f"Layer {i+1}: {st.session_state.hidden_layer_neurons[i]}")
185
  with col3:
186
  st.button("+", key=f"inc_{i}", on_click=increase_neurons, args=(i,))
187
+ col_btn1, col_btn2 = st.columns(2)
188
+ with col_btn1:
189
+ st.button("Add Layer", on_click=add_layer)
190
+ with col_btn2:
191
+ st.button("Remove Layer", on_click=remove_layer)
192
+ st.markdown('</div>', unsafe_allow_html=True)
193
+
194
+ # Right panel: Output and Training
195
  with col_right:
196
+ st.markdown('<div class="panel">', unsafe_allow_html=True)
197
  st.subheader("Output")
198
+ col_start, col_stop = st.columns(2)
199
+ with col_start:
200
+ if st.button("▶️ Play"):
201
+ st.session_state.training = True
202
+ with col_stop:
203
+ if st.button("⏹️ Stop"):
204
+ st.session_state.training = False
205
+
206
+ def create_model(input_dim, neurons):
207
+ model = Sequential()
208
+ model.add(Input(shape=(input_dim,)))
209
+ reg = l1(reg_rate) if reg_type == "L1" else l2(reg_rate) if reg_type == "L2" else None
210
+ for n in neurons:
211
+ model.add(Dense(n, activation=activation.lower(), kernel_regularizer=reg))
212
+ model.add(Dense(1, activation="sigmoid"))
213
+ model.compile(optimizer=SGD(learning_rate=learning_rate), loss=BinaryCrossentropy(), metrics=["accuracy"])
214
+ return model
215
+
216
+ class LossPlotCallback(tf.keras.callbacks.Callback):
217
+ def __init__(self, X, y):
218
+ super().__init__()
219
+ self.X, self.y = X, y
220
+ self.losses = {"Epoch": [], "Train Loss": [], "Val Loss": []}
221
+ self.placeholder = st.empty()
222
+
223
+ def on_epoch_end(self, epoch, logs=None):
224
+ self.losses["Epoch"].append(epoch + 1)
225
+ self.losses["Train Loss"].append(logs["loss"])
226
+ self.losses["Val Loss"].append(logs["val_loss"])
227
+ with self.placeholder.container():
228
+ col1, col2 = st.columns(2)
229
+ with col1:
230
+ plt.figure(figsize=(3, 3))
231
+ plot_decision_regions(self.X, self.y, clf=self.model)
232
+ plt.gca().set_facecolor("#333")
233
+ st.pyplot(plt)
234
+ with col2:
235
+ fig, ax = plt.subplots(figsize=(3, 3))
236
+ ax.plot(self.losses["Epoch"], self.losses["Train Loss"], "b-", label="Train")
237
+ ax.plot(self.losses["Epoch"], self.losses["Val Loss"], "r--", label="Val")
238
+ ax.legend()
239
+ ax.set_facecolor("#333")
240
+ st.pyplot(fig)
241
+
242
+ if st.session_state.training:
243
+ model = create_model(len(selected_features), st.session_state.hidden_layer_neurons)
244
+ callback = LossPlotCallback(selected_data, cv)
245
+ model.fit(selected_data, cv, epochs=999999, batch_size=batch_size, validation_split=1-train_ratio, callbacks=[callback], verbose=0)
246
+ st.markdown('</div>', unsafe_allow_html=True)
247
+
248
+ if st.button("Reset", key="reset_global"):
249
+ reset_session()