Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
113 changes: 113 additions & 0 deletions explauto/models/gmrinf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import numpy as np
import numpy.linalg
import gmr as fabisch_gmr
import cma


from numpy.linalg import inv, eig
from numpy import ix_, array, inf, sqrt, linspace, zeros, arctan2, matrix, pi
from .gaussian import Gaussian


class GMR(fabisch_gmr.gmm.GMM):
def __init__(self, n_components):
fabisch_gmr.gmm.GMM.__init__(self, n_components)

def probability(self, value):
"""Compute the probability of x knowing y

Parameters
----------
value : array, shape(n_samples, n_features)
Y

Returns
-------
proba : float,
X
"""

proba = 0.
pmc = zip(self.priors, self.means, self.covariances)
for p,m,c in pmc:
proba += p * Gaussian(m.reshape(-1,), c).normal(value.reshape(-1,))
return proba

def regression(self, in_dims, out_dims, value, regression_method="slse", **kwargs):
""" Compute a prediction y knowing a value x

Parameters
----------
in_dims : array, shape (n_input_features,)
Indices of dimensions of the input

out_dims : array, shape (n_output_features,)
Indices of dimensions of the output

value : array, shape (n_input_features,)
Value of the input

regression_method : string

Returns
-------
y : array, shape(n_output_features,)
Value of the output

"""
if regression_method == "lse":
return self.predict(in_dims, value)[0]
elif regression_method == "slse":
return self.regression_slse(in_dims, out_dims, value)
elif regression_method == "optimization":
return self.regression_optimization(in_dims, out_dims, value, **kwargs)
elif regression_method == "stochastic_sampling":
return self.regression_stochastic_sampling(in_dims, out_dims, value)
else:
raise NotImplementedError


def regression_slse(self, in_dims, out_dims, value):
"""
SLSE is the Single component LSE and computes the most probably value of the most important gaussian
knowing an input value.
"""
conditional_gmm = self.condition(in_dims, value)
max_prior = np.max(conditional_gmm.priors)
max_ind = np.where(conditional_gmm.priors == max_prior)[0][0]
return conditional_gmm.means[max_ind]

def regression_optimization(self, in_dims, out_dims, value, x_guess,
optimization_parameters={"sigma":0.1, "maxfevals":200, "bounds":None},
optimization_method="CMAES"):
"""
This sampling is the obtained by the minimization of the error x knowing y by using an optimization method
as CMAES or BFGS
"""
conditional_gmm = self.condition(in_dims, value)
f = lambda x: - conditional_gmm.probablity(x)

if optimization_method=="CMAES":
res = cma.fmin(f, x_guess, optimization_parameters["sigma"],
options={'bounds':optimization_parameters["bounds"],
'verb_log':0,
'verb_disp':False,
'maxfevals':optimization_parameters["maxfevals"]})

elif optimization_method=="BFGS": #TODO
raise NotImplementedError

else:
raise NotImplementedError
# .......

return res[0] #index to check, it might be 1

def regression_stochastic_sampling(self, in_dims, out_dims, value):
"""
This method returns a random value according to the conditional probability
"""
conditional_gmm = self.condition(in_dims, value)
return conditional_gmm.sample(n_samples=1)[0]


101 changes: 101 additions & 0 deletions explauto/sensorimotor_model/ilo_gmr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import numpy as np

from numpy import array, hstack

from ..exceptions import ExplautoBootstrapError
from .sensorimotor_model import SensorimotorModel
from explauto.models.dataset import Dataset

from .inverse.cmamodel import CMAESInverseModel as CMAES
from ..models.gmrinf import GMR
from sklearn.linear_model.sgd_fast import Regression

class IloGmr(SensorimotorModel, GMR):
"""GMR adapted to sensori motor models"""

def __init__(self, conf, n_components=3): #choix methode dans init
SensorimotorModel.__init__(self, conf)
GMR.__init__(self, n_components)
self.n_neighbors = max(100, (conf.ndims) ** 2) # at least 100 neighbors
self.n_neighbors = min(1000, self.n_neighbors) # at most 1000 neighbors
self.min_n_neighbors = 20 # otherwise raise ExplautoBootstrapError
self.m_dims = conf.m_dims
self.s_dims = conf.s_dims

def infer(self, in_dims, out_dims, value, method="direct", regression="SLSE"):
if method=="direct":
res = self.infer_direct(in_dims, out_dims, value, regression)
elif method=="undirect":
res = self.infer_undirect(in_dims, out_dims, value, regression)
else:
pass
return res

def update(self, m, s):
self.dataset.add_xy(tuple(m), tuple(s))
pass


def infer_undirect(self, in_dims, out_dims, xq, regression = CMAES):

cma = CMAES(in_dims, out_dims, fmodel=None, cmaes_sigma=0.05, maxfevals=20)

def infer_direct(self,in_dims, out_dims, xq, regression = CMAES):
pass


#===================================================================================
#BROUILLON
def predict_direct(self, in_dims, out_dims, xq, method):
"""dire ce que fait la fct et d'ou elle vient"""

#local_gmrinf = (3, local_gmm.priors_, local_gmm.means_, local_gmm.covars_)

#conditional_gmm = local_gmrinf.condition(xq)

#def infer_direct(self, in_dims, out_dims, xq, method == 1):
"""utilise directement methode sur modele inverse"""



#manque optimisation


#faire des fonctions pour chaque méthode i), ii), iii), iv) dans GMR
#faire update et infer ici
#toutes les méthodes (inverse direct et 4 étapes) + 4 méthodes i), ... fonctionnent avec GMM classique et GMM local donc les mettre dans classe GMR
# => mettre les fonctions une classe GMM mais différent de GMMinf avec seulement ce qui est utile (appelé différent : GMR . GMR dans models
#Mettre classe GMR dans models
# sciopt et optimize à aller chercher pour implémenter méthode iii)
#CMAES prend f(x) en entrée qu'on va définir avec GMM(x,y) ou |
#Récupérer code de infer de CMAESInverseModel dans classe GMR après avoir construit le f(x) = GMM(x,y)
#pour l'instant faire que avec CMAES et pas avec BFGS, etc.
#dans inverse, sciopt, sciopt.optimize.minimize de infer_x , on pourra changer algo (plus tard)

#GMR doit pouvoir faire des GMM conditionnelles (infer ou
#robuste inverse/direct
#CMAES fmin utilisé dans méthode optimilisation (iii) )

# Paramètre nombre de gaussienne de GMR

#ILOGMR
#il faut écrire une fonction par méthode ( 1) 4étapes ou 2) inverse directement. Je sépare comment pour faire inverse et direct ?
#GMR
#j' ai encore du mal a voir différence entre ii) et iii) :

















3 changes: 2 additions & 1 deletion explauto/sensorimotor_model/inverse/cmamodel.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import explauto.models.cma

from .optimize import OptimizedInverseModel
from . import cma



class CMAESInverseModel(OptimizedInverseModel):
Expand Down
8 changes: 4 additions & 4 deletions explauto/sensorimotor_model/non_parametric.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ class NonParametric(SensorimotorModel):
Original code available at https://github.com/humm/models
Adapted by Sebastien Forestier at https://github.com/sebastien-forestier/models
"""
def __init__(self, conf, sigma_explo_ratio=0.1, fwd='LWLR', inv='L-BFGS-B', **learner_kwargs):
def __init__(self, conf, sigma_explo_ratio=0.1, fwd='LWLR', inv='L-BFGS-B', mode = 'explore', **learner_kwargs):

SensorimotorModel.__init__(self, conf)
for attr in ['m_ndims', 's_ndims', 'm_dims', 's_dims', 'bounds', 'm_mins', 'm_maxs']:
setattr(self, attr, getattr(conf, attr))

self.sigma_expl = (conf.m_maxs - conf.m_mins) * float(sigma_explo_ratio)
self.mode = 'explore'
self.mode = mode
mfeats = tuple(range(self.m_ndims))
sfeats = tuple(range(-self.s_ndims, 0))
mbounds = tuple((self.bounds[0, d], self.bounds[1, d]) for d in range(self.m_ndims))
Expand Down Expand Up @@ -92,8 +92,8 @@ def size(self):


sensorimotor_models = {
'nearest_neighbor': (NonParametric, {'default': {'fwd': 'NN', 'inv': 'NN', 'sigma_explo_ratio':0.1},
'exact': {'fwd': 'NN', 'inv': 'NN', 'sigma_explo_ratio':0.}}),
'nearest_neighbor': (NonParametric, {'default': {'fwd': 'NN', 'inv': 'NN', 'sigma_explo_ratio':0.1, 'mode':'explore'},
'exact': {'fwd': 'NN', 'inv': 'NN', 'sigma_explo_ratio':0., 'mode':'exploit'}}),
'WNN': (NonParametric, {'default': {'fwd': 'WNN', 'inv': 'WNN', 'k':20, 'sigma':0.1}}),
'LWLR-BFGS': (NonParametric, {'default': {'fwd': 'LWLR', 'k':10, 'sigma':0.1, 'inv': 'L-BFGS-B', 'maxfun':50}}),
'LWLR-CMAES': (NonParametric, {'default': {'fwd': 'LWLR', 'k':10, 'sigma':0.1, 'inv': 'CMAES', 'cmaes_sigma':0.05, 'maxfevals':20}}),
Expand Down
Loading