-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathdemo_learn_seDS.m
executable file
·200 lines (179 loc) · 9.86 KB
/
demo_learn_seDS.m
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Demo Code for SEDS Learning Comparison for paper: %
% 'A Physically-Consistent Bayesian Non-Parametric Mixture Model for %
% Dynamical System Learning.'; N. Figueroa and A. Billard; CoRL 2018 %
% With this script you can load 2D toy trajectories or even real-world %
% trajectories acquired via kinesthetic taching and test se-DS approach %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Copyright (C) 2018 Learning Algorithms and Systems Laboratory, %
% EPFL, Switzerland %
% Author: Nadia Figueroa %
% email: nadia.figueroafernandez@epfl.ch %
% website: http://lasa.epfl.ch %
% %
% This work was supported by the EU project Cogimon H2020-ICT-23-2014. %
% %
% Permission is granted to copy, distribute, and/or modify this program %
% under the terms of the GNU General Public License, version 2 or any %
% later version published by the Free Software Foundation. %
% %
% This program is distributed in the hope that it will be useful, but %
% WITHOUT ANY WARRANTY; without even the implied warranty of %
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General%
% Public License for more details %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Step 1 - OPTION 1 (DATA LOADING): Load CORL-paper Datasets %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
close all; clear all; clc
%%%%%%%%%%%%%%%%%%%%%%%%% Select a Dataset %%%%%%%%%%%%%%%%%%%%%%%%%%
% 1: Messy Snake Dataset (2D)
% 2: L-shape Dataset (2D)
% 3: A-shape Dataset (2D)
% 4: S-shape Dataset (2D)
% 5: Dual-behavior Dataset (2D)
% 6: Via-point Dataset (3D) -- 9 trajectories recorded at 100Hz
% 7: Sink Dataset (3D) -- 21 trajectories recorded at 100Hz
% 8: CShape bottom (3D) -- 16 trajectories recorded at 100Hz
% 9: CShape top (3D) -- 16 trajectories recorded at 100Hz
% 10: CShape all (3D) -- 20 trajectories recorded at 100Hz
% 11: Bumpy Surface (3D) -- x trajectories recorded at 100Hz
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pkg_dir = pwd;
chosen_dataset = 3;
sub_sample = 1; % '>2' for real 3D Datasets, '1' for 2D toy datasets
nb_trajectories = 4; % Only for real 3D data
[Data, Data_sh, att, x0_all, data, dt] = load_dataset_DS(pkg_dir, chosen_dataset, sub_sample, nb_trajectories);
% Position/Velocity Trajectories
vel_samples = 10; vel_size = 0.5;
[h_data, h_att, h_vel] = plot_reference_trajectories_DS(Data, att, vel_samples, vel_size);
limits = axis;
% Extract Position and Velocities
M = size(Data,1)/2;
Xi_ref = Data_sh(1:M,:);
Xi_dot_ref = Data_sh(M+1:end,:);
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Step 1 - OPTION 2 (DATA LOADING): Load Motions from LASA Handwriting Dataset %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% UNCOMMENT BLOCK IF YOU WANT TO USE DATA FROM LASA HANDWRITING DATASET
% Choose DS LASA Dataset to load
% clear all; close all; clc
%
% % Select one of the motions from the LASA Handwriting Dataset
% sub_sample = 2; % Each trajectory has 1000 samples when set to '1'
% nb_trajectories = 7; % Maximum 7, will select randomly if <7
% [Data, Data_sh, att, x0_all, ~, dt] = load_LASA_dataset_DS(sub_sample, nb_trajectories);
%
% % Position/Velocity Trajectories
% vel_samples = 15; vel_size = 0.5;
% [h_data, h_att, h_vel] = plot_reference_trajectories_DS(Data, att, vel_samples, vel_size);
%
% % Extract Position and Velocities
% M = size(Data,1)/2;
% Xi_ref = Data_sh(1:M,:);
% Xi_dot_ref = Data_sh(M+1:end,:);
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Step 2 (GMM FITTING): Fit GMM to Trajectory Data %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 'seds-init': follows the initialization given in the SEDS code
% 0: Manually set the # of Gaussians
% 1: Do Model Selection with BIC
do_ms_bic = 1;
if do_ms_bic
est_options = [];
est_options.type = 1; % GMM Estimation Alorithm Type
est_options.maxK = 10; % Maximum Gaussians for Type 1/2
est_options.do_plots = 1; % Plot Estimation Statistics
est_options.fixed_K = []; % Fix K and estimate with EM
est_options.sub_sample = 1; % Size of sub-sampling of trajectories
[Priors0, Mu0, Sigma0] = fit_gmm([Xi_ref; Xi_dot_ref], [], est_options);
nb_gaussians = length(Priors0);
else
% Select manually the number of Gaussian components
nb_gaussians = 4;
end
% Finding an initial guess for GMM's parameter
[Priors0, Mu0, Sigma0] = initialize_SEDS([Xi_ref; Xi_dot_ref],nb_gaussians);
%% Visualize Gaussian Components and labels on clustered trajectories
% Plot Initial Estimate
[~, est_labels] = my_gmm_cluster([Xi_ref; Xi_dot_ref], Priors0, Mu0, Sigma0, 'hard', []);
% Visualize Estimated Parameters
[h_gmm] = visualizeEstimatedGMM(Xi_ref, Priors0, Mu0(1:M,:), Sigma0(1:M,1:M,:), est_labels, est_options);
title('GMM $\theta_{\gamma}=\{\pi_k,\mu^k,\Sigma^k\}$ Initial Estimate','Interpreter','LaTex');
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%% Step 3 (DS ESTIMATION): RUN SEDS SOLVER %%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear options;
options.tol_mat_bias = 10^-6; % A very small positive scalar to avoid
% instabilities in Gaussian kernel [default: 10^-1]
options.display = 1; % An option to control whether the algorithm
% displays the output of each iterations [default: true]
options.tol_stopping = 10^-6; % A small positive scalar defining the stoppping
% tolerance for the optimization solver [default: 10^-10]
options.max_iter = 500; % Maximum number of iteration forthe solver [default: i_max=1000]
options.objective = 'mse'; % 'mse'/'likelihood'
sub_sample = 1;
%running SEDS optimization solver
[Priors, Mu, Sigma]= SEDS_Solver(Priors0,Mu0,Sigma0,[Xi_ref(:,1:sub_sample:end); Xi_dot_ref(:,1:sub_sample:end)],options);
ds_seds = @(x) GMR_SEDS(Priors,Mu,Sigma,x-repmat(att,[1 size(x,2)]),1:M,M+1:2*M);
%% %%%%%%%%%%%% Plot Resulting DS %%%%%%%%%%%%%%%%%%%
% Fill in plotting options
ds_plot_options = [];
ds_plot_options.sim_traj = 1; % To simulate trajectories from x0_all
ds_plot_options.x0_all = x0_all; % Intial Points
ds_plot_options.init_type = 'ellipsoid'; % For 3D DS, to initialize streamlines
% 'ellipsoid' or 'cube'
ds_plot_options.nb_points = 30; % No of streamlines to plot (3D)
ds_plot_options.plot_vol = 1; % Plot volume of initial points (3D)
[hd, hs, hr, x_sim] = visualizeEstimatedDS(Data(1:M,:), ds_seds, ds_plot_options);
limits = axis;
switch options.objective
case 'mse'
title('SEDS Dynamics with $J(\theta_{\gamma})$=MSE', 'Interpreter','LaTex','FontSize',20)
case 'likelihood'
title('SEDS Dynamics with $J(\theta_{\gamma})$= log-Likelihood', 'Interpreter','LaTex','FontSize',20)
end
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Step 4 (Evaluation): Compute Metrics and Visualize Velocities %%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Compute Errors
clc;
% Compute RMSE on training data
rmse = mean(rmse_error(ds_seds, Xi_ref, Xi_dot_ref));
fprintf('SEDS got prediction RMSE on training set: %d \n', rmse);
% Compute e_dot on training data
edot = mean(edot_error(ds_seds, Xi_ref, Xi_dot_ref));
fprintf('SEDS got prediction e_dot on training set: %d \n', edot);
% Compute DTWD between train trajectories and reproductions
if ds_plot_options.sim_traj
nb_traj = size(x_sim,3);
ref_traj_leng = size(Xi_ref,2)/nb_traj;
dtwd = zeros(1,nb_traj);
for n=1:nb_traj
start_id = round(1+(n-1)*ref_traj_leng);
end_id = round(n*ref_traj_leng);
dtwd(1,n) = dtw(x_sim(:,:,n)',Data(1:M,start_id:end_id)',20);
end
end
fprintf('SEDS got reproduction DTWD on training set: %2.4f +/- %2.4f \n', mean(dtwd),std(dtwd));
% Compare Velocities from Demonstration vs DS
h_vel = visualizeEstimatedVelocities(Data, ds_seds);
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Step 5 (Optional - Stability Check 2D-only): Plot Lyapunov Function and derivative %%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Type of plot
contour = 1; % 0: surf, 1: contour
clear lyap_fun_comb lyap_der
P = eye(2);
% Lyapunov function
lyap_fun = @(x)lyapunov_function_PQLF(x, att, P);
title_string = {'$V(\xi) = (\xi-\xi^*)^T(\xi-\xi^*)$'};
% Derivative of Lyapunov function (gradV*f(x))
lyap_der = @(x)lyapunov_derivative_PQLF(x, att, P, ds_seds);
title_string_der = {'Lyapunov Function Derivative $\dot{V}(\xi)$'};
% Plots
h_lyap = plot_lyap_fct(lyap_fun, contour, limits, title_string, 0);
[hd] = scatter(Data(1,:),Data(2,:),10,[1 1 0],'filled'); hold on;
h_lyap_der = plot_lyap_fct(lyap_der, contour, limits, title_string_der, 1);
[hd] = scatter(Data(1,:),Data(2,:),10,[1 1 0],'filled'); hold on;