Mengqinxue commited on
Commit
f24ba2e
·
verified ·
1 Parent(s): 856c683

Upload run_medium_experiment.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. run_medium_experiment.py +166 -0
run_medium_experiment.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Medium-length EQL experiment (10+10 epochs) to verify full pipeline."""
2
+ import os, sys, time
3
+ import numpy as np
4
+ from tqdm import tqdm
5
+ from scipy.io import loadmat
6
+ import tensorflow as tf
7
+ import matplotlib
8
+ matplotlib.use('Agg')
9
+ from matplotlib import pyplot as plt
10
+
11
+ from reproduce_eql import (
12
+ SymbolicNet, Constant, Identity, Square, Sin, Sigmoid, Product,
13
+ count_double, l12_smooth, get_folders_started, record_base_info,
14
+ append_text_to_summary, plot_train_vs_validation, plot_histogram,
15
+ plot_descaled_real_vs_prediction, generate_all_data, generate_variable_list,
16
+ save_weights, network
17
+ )
18
+
19
+ if __name__ == "__main__":
20
+ target_city = "Roskilde"
21
+ steps_ahead = 6
22
+ feature = "wind_speed"
23
+ target_cities = ["Esbjerg", "Odense", "Roskilde"]
24
+ city_index = target_cities.index(target_city)
25
+
26
+ data = loadmat('Denmark_data/wind_speed/step1.mat')
27
+ y_min = data["y_min_tr"][0][city_index]
28
+ y_max = data["y_max_tr"][0][city_index]
29
+
30
+ config = {
31
+ "use_rescaled_MSE": True,
32
+ "a_L_0.5": 5e-3,
33
+ "threshold_value": 7.5e-3,
34
+ "lambda_reg": 3.0,
35
+ "steps_ahead": 6,
36
+ "feature": feature,
37
+ "target_city": target_city,
38
+ "epochs1": 10,
39
+ "epochs2": 10,
40
+ "use_phase2": True,
41
+ "batch_size": 200,
42
+ "phase1_lr": 1e-4,
43
+ "phase2_lr": 1e-5,
44
+ "eql_number_layers": 2,
45
+ "optimizer": "rmsprop",
46
+ }
47
+
48
+ x_dim = 80
49
+ activation_funcs = [
50
+ *[Constant()] * 2, *[Identity()] * 4, *[Square()] * 4,
51
+ *[Sin()] * 2, *[Sigmoid()] * 2, *[Product()] * 2
52
+ ]
53
+ n_layers = 2
54
+ n_double = count_double(activation_funcs)
55
+ width = len(activation_funcs)
56
+
57
+ init_weights = [
58
+ tf.random.truncated_normal([x_dim, width + n_double], stddev=0.1),
59
+ tf.random.truncated_normal([width, width + n_double], stddev=0.5),
60
+ tf.random.truncated_normal([width, 1], stddev=1.0)
61
+ ]
62
+ model = SymbolicNet(n_layers, funcs=activation_funcs, initial_weights=init_weights)
63
+ phase1_optimizer = tf.keras.optimizers.RMSprop(learning_rate=1e-4)
64
+
65
+ experiment_number = get_folders_started()
66
+ print("\n" + "*" * 10 + " Experiment {} ".format(experiment_number) + "*" * 10 + "\n")
67
+ record_base_info(experiment_number, **config)
68
+
69
+ x_train, y_train = generate_all_data("train", steps_ahead, feature, city_index)
70
+ x_test, y_test = generate_all_data("test", steps_ahead, feature, city_index)
71
+ train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(200)
72
+ val_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(200)
73
+
74
+ # Phase 1
75
+ best_val_loss = float('inf')
76
+ best_val_weights = None
77
+ train_loss_results = []
78
+ valid_loss_results = []
79
+
80
+ for epoch in range(config["epochs1"]):
81
+ epoch_loss_avg = tf.keras.metrics.MeanSquaredError()
82
+ for xb, yb in tqdm(train_dataset, desc=f"P1 Epoch {epoch+1}", leave=False):
83
+ with tf.GradientTape() as tape:
84
+ yp = model(xb)
85
+ err = tf.keras.losses.MeanSquaredError()(yb * (y_max - y_min) + y_min, yp * (y_max - y_min) + y_min)
86
+ reg = l12_smooth(model.get_weights(), 5e-3)
87
+ loss = err + 3.0 * reg
88
+ grads = tape.gradient(loss, model.get_weights())
89
+ phase1_optimizer.apply_gradients(zip(grads, model.get_weights()))
90
+ epoch_loss_avg.update_state(yb, yp)
91
+
92
+ train_mse = epoch_loss_avg.result().numpy()
93
+ val_mse = tf.keras.metrics.MeanSquaredError()
94
+ for xv, yv in val_dataset:
95
+ val_mse.update_state(yv, model(xv))
96
+ val_mse = val_mse.result().numpy()
97
+
98
+ train_loss_results.append(train_mse)
99
+ valid_loss_results.append(val_mse)
100
+ if val_mse < best_val_loss:
101
+ best_val_loss = val_mse
102
+ best_val_weights = [w.numpy() for w in model.get_weights()]
103
+ print(f"P1 Epoch {epoch+1}: val MSE improved to {val_mse:.4e} (train {train_mse:.4e})")
104
+ else:
105
+ print(f"P1 Epoch {epoch+1}: val MSE {val_mse:.4e} (train {train_mse:.4e})")
106
+
107
+ save_weights(best_val_weights, experiment_number, "phase1", best_val_loss)
108
+ append_text_to_summary(experiment_number, f"phase 1 best MSE validation: {best_val_loss}\n")
109
+ plot_train_vs_validation(experiment_number, config["epochs1"], train_loss_results, valid_loss_results, "phase1")
110
+ plot_histogram(experiment_number, best_val_weights[0], "phase1", "weights1", 5e-3)
111
+ plot_histogram(experiment_number, best_val_weights[1], "phase1", "weights2", 5e-3)
112
+ plot_histogram(experiment_number, best_val_weights[2], "phase1", "weights3", 5e-3)
113
+
114
+ # Phase 2
115
+ masked_weights = []
116
+ for w_i in best_val_weights:
117
+ mask = tf.cast(tf.constant(tf.abs(w_i) > 7.5e-3), tf.float32)
118
+ masked_weights.append(tf.multiply(w_i, mask))
119
+
120
+ model2 = SymbolicNet(n_layers, funcs=activation_funcs, initial_weights=masked_weights)
121
+ opt2 = tf.keras.optimizers.RMSprop(learning_rate=1e-5)
122
+
123
+ train_loss_results2 = []
124
+ valid_loss_results2 = []
125
+ best_val_loss2 = float('inf')
126
+ best_val_weights2 = None
127
+
128
+ for epoch in range(config["epochs2"]):
129
+ epoch_loss_avg = tf.keras.metrics.MeanSquaredError()
130
+ for xb, yb in tqdm(train_dataset, desc=f"P2 Epoch {epoch+1}", leave=False):
131
+ with tf.GradientTape() as tape:
132
+ yp = model2(xb)
133
+ err = tf.keras.losses.MeanSquaredError()(yb * (y_max - y_min) + y_min, yp * (y_max - y_min) + y_min)
134
+ grads = tape.gradient(err, model2.get_weights())
135
+ opt2.apply_gradients(zip(grads, model2.get_weights()))
136
+ epoch_loss_avg.update_state(yb, yp)
137
+
138
+ train_mse = epoch_loss_avg.result().numpy()
139
+ val_mse = tf.keras.metrics.MeanSquaredError()
140
+ for xv, yv in val_dataset:
141
+ val_mse.update_state(yv, model2(xv))
142
+ val_mse = val_mse.result().numpy()
143
+
144
+ train_loss_results2.append(train_mse)
145
+ valid_loss_results2.append(val_mse)
146
+ if val_mse < best_val_loss2:
147
+ best_val_loss2 = val_mse
148
+ best_val_weights2 = [w.numpy() for w in model2.get_weights()]
149
+ print(f"P2 Epoch {epoch+1}: val MSE improved to {val_mse:.4e} (train {train_mse:.4e})")
150
+ else:
151
+ print(f"P2 Epoch {epoch+1}: val MSE {val_mse:.4e} (train {train_mse:.4e})")
152
+
153
+ save_weights(best_val_weights2, experiment_number, "phase2", best_val_loss2)
154
+ plot_train_vs_validation(experiment_number, config["epochs2"], train_loss_results2, valid_loss_results2, "phase2")
155
+
156
+ expr = network(best_val_weights2, activation_funcs, generate_variable_list(26, 80)[:80], threshold=0)
157
+ append_text_to_summary(experiment_number, f"Formula after phase2: {expr}\n")
158
+ print(f"\nExtracted formula: {expr}")
159
+
160
+ best_model = SymbolicNet(n_layers, funcs=activation_funcs,
161
+ initial_weights=[tf.constant(w) for w in best_val_weights2])
162
+ yp = best_model(x_test)
163
+ mae = plot_descaled_real_vs_prediction(experiment_number, y_test, yp, y_min, y_max)
164
+ append_text_to_summary(experiment_number, f"MAE: {mae}\n")
165
+ print(f"\nMAE: {mae}")
166
+ print("\nMedium experiment complete!")