-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathlorenz.py
More file actions
161 lines (128 loc) · 5.58 KB
/
Copy pathlorenz.py
File metadata and controls
161 lines (128 loc) · 5.58 KB
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
155
156
157
158
159
160
161
import numpy as np
import os
import sys
import hydra
import torch
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from dotmap import DotMap
import logging
from evaluate import test_models
# adapeted from https://scipython.com/blog/the-lorenz-attractor/
log = logging.getLogger(__name__)
def sim_lorenz(X, t, sigma, beta, rho):
"""The Lorenz equations."""
u, v, w = X
up = -sigma * (u - v)
vp = rho * u - v - u * w
wp = -beta * w + u * v
return up, vp, wp
def collect_data(cfg):
num_traj = cfg.num_trials
sigma = cfg.lorenz.sigma
beta = cfg.lorenz.beta
rho = cfg.lorenz.rho
tmax, n = cfg.lorenz.tmax, cfg.lorenz.n
t = np.linspace(0, tmax, n)
data_Seq = []
new_init = np.random.uniform(low=[5, 5, 5], high=[10, 10, 10], size=(num_traj, 3))
for row in new_init:
u, v, w = row # row[0], row[1], row[2]
f = odeint(sim_lorenz, (u, v, w), t, args=(sigma, beta, rho))
x, y, z = f.T
l = DotMap()
l.states = f
# Add parameters the way that the generation object is
# TODO take generic parameters rather than only PD Target
l.P = beta
l.D = rho
l.target = sigma
data_Seq.append(l)
return data_Seq
@hydra.main(config_path='conf/lorenz.yaml')
def lorenz(cfg):
from plot import plot_lorenz, plot_mse, plot_mse_err, plot_states, setup_plotting, plot_loss
from dynamics_model import DynamicsModel
mode = cfg.mode
name = cfg.env.label
if mode == 'collect':
train_data = collect_data(cfg)
test_data = collect_data(cfg)
model = DynamicsModel(cfg)
# TODO: fix this, setup_plotting needs model
if cfg.plot:
setup_plotting({cfg.model.str: model})
plot_lorenz(train_data, cfg, predictions=None)
log.info("Saving new default data")
torch.save((train_data, test_data),
hydra.utils.get_original_cwd() + '/trajectories/lorenz/' + 'raw' + cfg.data_dir)
log.info(f"Saved trajectories to raw{cfg.data_dir}")
else:
log.info(f"Loading default data")
(train_data, test_data) = torch.load(
hydra.utils.get_original_cwd() + '/trajectories/lorenz/' + 'raw' + cfg.data_dir)
# Analysis
if mode == 'train':
from reacher_pd import create_dataset_step, create_dataset_traj
prob = cfg.model.prob
traj = cfg.model.traj
ens = cfg.model.ensemble
delta = cfg.model.delta
log.info(f"Training model P:{prob}, T:{traj}, E:{ens}")
if traj:
dataset = torch.load(hydra.utils.get_original_cwd() + '/trajectories/lorenz/' + 'temp_traj.dat')
# dataset = create_dataset_traj(train_data, control_params=cfg.model.training.control_params,
# train_target=cfg.model.training.train_target)
# torch.save(dataset, hydra.utils.get_original_cwd() + '/trajectories/lorenz/' + 'temp_traj.dat')
else:
dataset = create_dataset_step(train_data, delta=delta)
model = DynamicsModel(cfg, env="Lorenz")
train_logs, test_logs = model.train(dataset, cfg)
log.info("Saving new default models")
torch.save(model,
hydra.utils.get_original_cwd() + '/models/lorenz/' + cfg.model.str + '.dat')
setup_plotting({cfg.model.str: model})
plot_loss(train_logs, test_logs, cfg, save_loc=cfg.env.name + '-' + cfg.model.str, show=True)
# log.info(f"Loading default data")
# (train_data, test_data) = torch.load(
# hydra.utils.get_original_cwd() + '/trajectories/lorenz/' + 'raw' + cfg.data_dir)
# setup_plotting({cfg.model.str: model})
# plot_lorenz(train_data, cfg, predictions=None)
elif mode == 'plot':
# TODO add plotting code for predictions
# Load test data
log.info(f"Loading default data")
(test_data, _) = torch.load(
hydra.utils.get_original_cwd() + '/trajectories/' + cfg.env.label + '/' + 'raw' + cfg.data_dir)
# Load models
log.info("Loading models")
model_types = cfg.plotting.models
models = {}
f = hydra.utils.get_original_cwd() + '/models/' + cfg.env.label + '/'
for model_type in model_types:
models[model_type] = torch.load(f + model_type + ".dat")
graph_file = 'Plots'
os.mkdir(graph_file)
setup_plotting(models)
# Select a random subset of training data
# idx = np.random.randint(0, len(data), num)
idx = np.random.choice(np.arange(len(test_data)), size=min(len(test_data), cfg.plotting.num_eval_test),
replace=False)
dat = [test_data[i] for i in idx]
for entry in dat:
entry.states = entry.states[0:cfg.plotting.t_range]
# entry.rewards = entry.rewards[0:cfg.plotting.t_range]
# entry.actions = entry.actions[0:cfg.plotting.t_range]
MSEs, predictions = test_models(dat, models, env=name)
from plot import plot_mse_err, plot_lorenz
plot_lorenz(test_data, cfg, predictions=predictions)
mse_evald = []
for i, id in list(enumerate(idx)):
mse = {key: MSEs[key][i].squeeze() for key in MSEs}
mse_sub = {key: [(x if x < 10 ** 5 else float("nan")) for x in mse[key]] for key in mse}
mse_evald.append(mse)
plot_mse_err(mse_evald, log_scale=True, title="Average MSE", save_loc=graph_file + '/mse.pdf', show=True,
legend=True)
if __name__ == '__main__':
sys.exit(lorenz())