[Machine Learning]Approximation d'une fonction de transfert à l'aide de la methode du gradient

Le problème exposé dans ce sujet a été résolu.

Bonjour, Je suis en train de me demander comment réaliser une approximation d’une fonction de transfert à l’aide de la méthode du gradient et de scikit learn et je me pose quelques questions sur comment faire, surtout au niveau du jeu de données. Le but de cela serait de simuler un système du premier ordre sans retard et je ne souhaite pas que le temps entre en paramètre dans la détermination de la fonction de transfert. J’ai pensé à donner en entrée dans un array de taille 3:la mesure de la sortie actuelle, la valeur de l’actionneur à t-1 et la valeur de l’actionneur à t. De cette manière je pense que je récupèrerais en sortie du modèle la sortie prédite pour t+1. Pensez vous que cela fonctionnerait ?

De plus je pense que si jamais cela fonctionne, ça ne marchera que pour un système du premier ordre et que si je souhaite obtenir un système d’ordre plus élevée, il faudra surement donner en paramètres d’entrée, d’autres variables tel que la valeur de l’actionneur à t-n et la valeur de sortie à t-n également, cela vous semble t’il correcte ?

Merci d’avance pour tous ces éclaircissements :)

+0 -0

Salut,

J’ai du ma à comprendre ce que tu souhaites faire.

  1. Est-ce que tu souhaites identifeir un modèle/estimer une fonction de transfert ? En gros, tu disposes d’un système et tu aimerais déterminer la forme et la paramétrisation de sa fonction de transfert en fonction de son comportement réel, pour ensuite faire ce que tu veux avec.
  2. Est-ce que tu souhaites simuler une fonction de transfert ? Si tu disposes déjà de la fonction de transfert, en fonction des outils que tu as, c’est plus ou moins immédiat.

Je vois que tu parles de premier ordre sans retard. Que ta fonction de transfert soit discrète ou continue, ça te fait deux paramètres (à estimer si tu veux faire de l’estimation). Ensuite, par définition, pour la version discrète, tu vas avoir juste un retard, l’entrée et la sortie. Ça revient à ce que tu as dit, et tu peux le vérifier par le calcul. Si tu montes l’ordre, tu auras besoin de plus d’historique (donc plus de valeurs retardées, mais tout ça c’est montré par la définition des fonctions de transfert).

En continu, c’est la même idée, mais ce sont des intégrateurs et pas des retards qui vont conserver l’historique. On peut passer du continu au discret avec différentes approximations.

je ne souhaite pas que le temps entre en paramètre dans la détermination de la fonction de transfert

Si tu fais de la simulation, tu vas être obligé d’avoir le temps quelque part. Si tu utilises les valeurs précédentes, c’est que tu as bien le temps quelque part implicitement. :) Si tu fais de l’estimation, il existe des techniques essentiellement dans le domaine fréquentiel, mais comme les domaines fréquentiels et temporels sont liés…

En tout cas, je ne vois pas trop le rapport direct avec l’apprentissage automatique. Il y a plein de méthodes efficaces pour faire de l’identification/estimation ou de la simulation de fonction de transferts, et qui existent depuis bien avant que le mot machine learning soit à la mode.

Après, c’est comme tout, qu’est-ce que tu veux vraiment faire ?

Bonjour, Merci beaucoup d’avoir pris le temps de me fournir réponse aussi détaillée :) , ce que j’aimerais faire serait d’identifier la fonction de transfert d’un procédé thermique grâce à un enregistrement de sa réponse à plusieurs échelons, puis d’embarquer le modèle obtenu par la méthode du gradient sur une raspberry pi pour comparer en temps réel la sortie prédite par le modèle et la sortie réelle pour le procédé gérant une température, pour faire cela j’aimerais travailler en temps discret avec une periode d’échantillonage de l’ordre de la seconde.

Si tu fais de la simulation, tu vas être obligé d’avoir le temps quelque part. Si tu utilises les valeurs précédentes, c’est que tu as bien le temps quelque part implicitement. :)

Ah oui effectivement, je n’avais pas pensé que le temps se cacherait par le biais des valeurs précédentes, honnêtement, j’avoue que ça me rassure un peu parce que j’avais du mal à comprendre comment réaliser une simulation du procédé sans le temps :D

Du coup, je vais essayé de réaliser une identification du premier ordre en temps discret comme tu me l’as expliqué.

Sinon j’avais parlé de machine learning car si je parviens à réaliser cela, j’aimerais bien remplacer la méthode du gradient par un réseau de neuronnes profond à l’aide de keras et de voir si en augmentant le nombre de valeurs d’entrée et de sortie précédentes pour remonter plus loin dans le temps, je peux obtenir une approximation d’un système non linéaire pour le procédé.

Penses tu qu’en procédant de la sorte ce serait possible ?

+0 -0

Sinon j’avais parlé de machine learning car si je parviens à réaliser cela, j’aimerais bien remplacer la méthode du gradient par un réseau de neuronnes profond à l’aide de keras et de voir si en augmentant le nombre de valeurs d’entrée et de sortie précédentes pour remonter plus loin dans le temps, je peux obtenir une approximation d’un système non linéaire pour le procédé.

Je ne suis pas sûr d’avoir tout compris de ta problématique mais si tu cherches à prédire une tendance d’une courbe temporelle regarde du coté des RNN/LSTM. Si tu veux faire un échantillonnage uniquement sache que les CNN sont capables d’en faire (c’est lié au faite que les CNNs possèdent des filtres et peuvent en apprenant retrouver un filtre FIR par exemple).

Salut,

Les modèles thermiques, du peu que j’ai vu, sont souvent linéaires (et à temps continu) et plus ou moins complexes en fonction de la complexité du problème, la complexité étant essentiellement guidée par le nombre de sources chaudes et froides, de sources de chaleur et les interfaces dans le système modélisé.

Les méthodes d’identification de modèle les plus simples consistent à faire l’hypothèse de la forme de la fonction de transfert (par exemple premier ordre) et à trouver ensuite les meilleurs paramètres selon des critères donnés. Ça marche très bien si on connaît la forme de la fonction de transfert ou si le modèle s’approxime bien avec la forme supposée. Les critères exacts peuvent être choisis différemment en fonction de l’objectif exact, mais prennent en compte l’écart du modèle avec la réalité.

Quand on ne connaît pas la forme, on peut essayer de deviner la meilleure fonction de transfert en augmentant l’ordre au fur et à mesure. On risque alors d’avoir un modèle avec un ordre trop élevé, parce qu’avoir plus de paramètres à régler permet en général de se s’approcher mieux de la fonction de transfert réelle qu’un nombre plus restreint. Il faut donc se méfier de l'overfitting.


Une fois que tu as une fonction de transfert continue, il y a plein de manières de procéder pour les simuler en temps discret, la plus simple étant la méthode d’Euler explicite. Tu n’auras probablement pas besoin de plus compliqué. Surtout que pour de l’embarqué, les méthodes explicites sont plus indiquées. Pour arriver à une équation récurrente que tu peux simuler, il y a plusieurs manières, la plus simple étant de convertir ta fonction de transfert continue en une fonction de transfert discrète puis à partir de là en suite récurrente.

Une fois que tu as faut tout ça, tu devrais être paré pour faire de la commande prédictive. 😁

Dans un sujet précédent, je me souviens que tu t’intéressais à un contrôleur capable de s’adapter à l’évolution du système dans le temps. Ce dont je parle-là ne permet pas de s’adapter en temps réel, parce qu’on détermine les meilleurs paramètres une fois pour toute.


Ensuite, je n’y connais rien en apprentissage automatique, mais on trouve pas mal d’articles qui parlent d’identification de systèmes non-linéaires à l’aide de réseaux de neurones, donc ça doit être tout à fait possible. :-) Par contre, je ne pense pas qu’il y ait beaucoup d’intérêt autre que pédagogique à le faire pour un système simple.

Salut, Merci encore pour tous ces éclaircissements :)

je vais suivre tes conseils et déterminer une fonction de transfert en continu, puis j’essayerais de passer en temps discret avec la methode d’euler explicite.

Une fois encore merci pour vos réponses à toutes les questions que je me suis posé,je vais mettre le sujet en résolu en espérant qu’il pourra aider d’autres personnes dans le futur.

Si jamais le deep learning interesse quelqu’un, j’ai réussi à écrire un bout de code faisant l’identification en me basant fortement sur ce projet github: https://github.com/ell-hol/mpc-DL-controller

Voici mon code:

from matplotlib.pyplot import * 
from scipy.signal import lti
from scipy.signal import lsim
from scipy.signal import square
import numpy as np
from sklearn.svm import SVR
import keras
# from keras.models import Sequential
from keras.models import *
from keras.layers import *

def nn_train(x_train, y_train, input_dimension, output_dimension, nb_epochs=35, nb_batch=64, nb_deeplayers=13, nb_neurons=100):
#50 nb_neurons and 6 nb_deeplayers
        # Creating the keras model
        model = Sequential()

        model.add(Dense(nb_neurons, input_dim=input_dimension, kernel_initializer='normal', activation='relu'))

        for _ in range(nb_deeplayers - 1):
            model.add(Dense(nb_neurons, kernel_initializer='normal', activation='relu'))
            # model.add(BatchNormalization())
            # model.add(LeakyReLU(alpha=0.001))
            # model.add(Dropout(0.2))

        model.add(Dense(output_dimension, kernel_initializer='normal', activation='linear'))


        # Configuring the learning process with .compile() function
        # This is where we decide the type of loss function (aka error function)
        # (in our case : mean squared error (MSE))
        # and also the optimizer (here it's s modified stochastic gradient descent)


        model.compile(loss='mse', optimizer='adam', metrics=['mae', 'mape', 'accuracy'])
        model.fit(x_train, y_train, epochs=nb_epochs, batch_size=nb_batch)

        return model
N=6000
t=np.linspace(0,N, num=N, endpoint=True,)
u=20*square(2 * np.pi * 0.003 * t)
H=lti([1],[30,1])
t,y,x=lsim(H,u,t)
#plot(t,y,u)
#show()
X = np.zeros((N,3))
for index, value in enumerate(t):
    if index > 0:
        X[index][0] = y[index-1]
        X[index][1] = u[index-1]
        X[index][2] = u[index]
    
X_train, X_test, y_train, y_test = X[:int(N/2)], X[int(N/2):],y[:int(N/2)],y[int(N/2):]

X_train=X_train.astype('float32')
#X_train = X_train.transform()
y_train=y_train.astype('float32')
#y_train=y_train.transform()
X_test=X_test.astype('float32')
y_test=y_test.astype('float32')

###y_train=y_train.reshape(-1, 1)
###y_test=y_test.reshape(-1, 1)
##
##appro = SVR(kernel='rbf', C=100, gamma='scale', epsilon=.1)
##appro.fit(X_train, y_train)
##prediction=appro.predict(X_test)



m=nn_train(X_train,y_train,input_dimension=X_train.shape[1], output_dimension=1, nb_epochs=100)
t2=np.linspace(0,int(N/2), num=int(N/2), endpoint=True,)
plot(t2,m.predict(X_test))
show()

Bien que le code soit fonctionnel, je ne pense pas que cette méthode ait un autre intérêt que pédagogique pour un tel système comme l’a indiqué Aabu car cela me parait être surdimensionné pour un premier ordre.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte