diff --git a/rapport.tex b/rapport.tex index 2bdcf03..c3a1841 100644 --- a/rapport.tex +++ b/rapport.tex @@ -1,793 +1,793 @@ -% !TEX encoding = UTF-8 Unicode -% -*- coding: UTF-8; -*- -% vim: set fenc=utf-8 -\documentclass[a4paper,12pt,french]{article} - -\usepackage{ensps} - -\hypersetup{ - pdftitle={Titre}, - pdfauthor={Léopold Clément}, - pdfsubject={Sujet}, - pdfproducer={Conversion PDF}, - pdfkeywords={Quelques mots-clés} % -} - -\DeclareGraphicsRule{.ai}{pdf}{.ai}{} % Pour insérer des documents .ai -\graphicspath{{./img/} {./eps/} {./fig/}} % Pour ne pas avoir à ajouter eps/ton-image.jpg - -% ------------- Packages spéciaux, nécessaires pour ce rapport, à insérer ici ------------- -\usepackage{minted} -\usepackage{lscape} - -\usepackage[toc]{glossaries} -\makeglossaries - -\newglossaryentry{iot} -{ - name=IoT, - description={Internet of Things, internet des objets} -} - -\newcommand{\iot}{\gls{iot}} - -\newglossaryentry{tcp} -{ - name=TCP, - description={Transmission Control Protocol, protocole avancé de la couche \osi{} 4} -} - -\newcommand{\tcp}{\gls{tcp}} - -\newglossaryentry{udp} -{ - name=UDP, - description={User Datagram Protocol, protocole basique de la couche \osi{} 4} -} - -\newcommand{\udp}{\gls{udp}} - -\newglossaryentry{coap} -{ - name=CoAP, - description={Constrained Application Protocol, protocole de la couche \osi{} 7} -} - -\newcommand{\coap}{\gls{coap}} - -\newglossaryentry{cocoa} -{ - name=Cocoa+, - description={Evolution de \coap{}, protocole de la couche \osi{} 7} -} - -\newcommand{\cocoa}{\gls{cocoa}} - -\newglossaryentry{ns} -{ - name=ns-3, - description={Simulateur réseau puissant. \url{https://www.nsnam.org/}} -} - -\newcommand{\ns}{\gls{ns}} - -\newglossaryentry{keras} -{ - name=keras, - description={Module Python pour la manipulation de réseaux de neurones} -} - -\newcommand{\keras}{\gls{keras}} - -\newglossaryentry{tensorflow} -{ - name=TensorFlow, - description={Module Python pour l'apprentissage machine} -} - -\newcommand{\TF}{\gls{tensorflow}} - -\newglossaryentry{coapthon} -{ - name=CoAPthon, - description={Module Python implémentant les clients et serveurs \coap} -} - -\newcommand{\coapthon}{\gls{coapthon}} - -\newglossaryentry{rasp} -{ - name=RaspberryPi, - description={Modèle de micro-ordinateur} -} - -\newcommand{\rasp}{\gls{rasp}} - -\newglossaryentry{osi} -{ - name=OSI, - description={Open Systems Interconnection, modèle des réseaux} -} - -\newcommand{\osi}{\gls{osi}} - -\newglossaryentry{cc} -{ - name=CC, - description={Contrôle de congestion} -} - -\newcommand{\CC}{\gls{cc}} - -\newglossaryentry{cca} -{ - name=CCA, - description={Algorithme de contrôle de congestion} -} - -\newcommand{\CCA}{\gls{cca}} - -\newglossaryentry{mac} -{ - name=MAC, - description={Media Access Control, Contrôle de l'accès à médium de communication} -} - -\newcommand{\mac}{\gls{mac}} - -\newglossaryentry{ip} -{ - name=IP, - description={Internet Protocol} -} - -\newcommand{\ip}{\gls{ip}} - -\newglossaryentry{http} -{ - name=HTTP, - description={Hypertext Transfer Protocol, protocole de la couche \osi{} 7} -} - -\newcommand{\http}{\gls{http}} - -\newcommand{\qlearn}{Q-learning} -\newcommand{\dqlearn}{Deep-Q-learning} -\newcommand{\cubic}{TCP-Cubic} -\newcommand{\newreno}{TCP-NewReno} -\newcommand{\cpp}{C++} - -\newglossaryentry{rtt} -{ - name=RTT, - description={Round Trip Time, temps d'aller-retour} -} - -\newcommand{\rtt}{\gls{rtt}} - -\newglossaryentry{rto} -{ - name=RTO, - description={Return TimeOut, temps d'attente maximal} -} - -\newcommand{\rto}{\gls{rto}} - -\begin{document} - -% -------------------------------------------------------------- -% Page de garde -% -------------------------------------------------------------- - -\begin{titlepage} - \begin{center} - - \includegraphics[height = 3 cm]{logo_ENSPS_UPS.png}\\[1cm] - - {\large Département \emph{EEA}}\\[0.5cm] - - {\large Stage de \emph{M1}}\\[0.5cm] - - % Titre - \rule{\linewidth}{0.5mm} \\[0.4cm] - { \huge \bfseries Titre du rapport éventuellement en plusieurs lignes. \\[0.4cm] } - \rule{\linewidth}{0.5mm} \\[1.5cm] - - % Auteur(es) et encadrant(es) - \noindent - \begin{minipage}{0.4\textwidth} - \begin{flushleft} \large - \emph{Auteurs :}\\ - M.~Léopold \textsc{Clément} - \end{flushleft} - \end{minipage}% - \begin{minipage}{0.4\textwidth} - \begin{flushright} \large - \emph{Encadrants :} \\ - M\up{me} Lynda \textsc{Zitoune}\\ - M\up{me} Véronique \textsc{Vèque} - \end{flushright} - \end{minipage} - - \vfill - - % Date en fin de page - {\large Version du\\ \today} - - \end{center} -\end{titlepage} - -% -------------------------------------------------------------- -% Table des matières -% -------------------------------------------------------------- - -\thispagestyle{empty} -\tableofcontents -\pagebreak - -% -------------------------------------------------------------- -% Début du corps -% -------------------------------------------------------------- -\printglossary[title=Glossaire, toctitle=Glossaire] - -\section{Introduction} - -\subsection{Présentation de l'environnement de travail} - -\subsection{Qu'est-ce qu'un réseau \iot{} ?} - -Un réseau \iot{} est un réseau de machines informatiques embarquées. -Les machines qui composent ce réseau sont en majorité des machines peu puissantes : des capteurs, des actionneurs \dots, ils réalisent chacun une tâche simple, et sont soumis à de multiples contraintes, en particulier en termes de consommation énergétique. -Les réseaux \iot{} présentent donc des thématiques propres aux réseaux classiques (débit, latence, pertes de données \dots), qui ont déjà été étudiées par le passé pour lesquelles des solutions exisent, et des thématique nouvelles qui ne s'intègrent pas dans le modèle classique. - -\subsubsection{Qu'est-ce qu'un réseau ?} - -Un réseau informatique est un groupe de machines indépendantes que l'on connecte entre elles pour qu'elles échangent des informations. -Ces connexions se font au moyen de normes et de protocoles organisés dans un modèle à $7$ couches, le modèle \osi{}: - -\begin{table}[htp] - \centering - \caption[modèle \osi{} général]{Le modèle \osi{} pour Internet, les couches principales.} - \begin{tabular}{lll} - \toprule - Couche & Rôle & Protocole\\ - \midrule - 7 - Application & Utilisation finale & http, ssh...\\ - 4 - Transport & \CC{} \& multiplexage & \tcp{}, \udp{}\\ - 3 - Réseau & Routage & IP\\ - 1 \& 2 - Physique & Support des communications & Ethernet, Wi-Fi...\\ - \bottomrule - \end{tabular} -\end{table} - -Les couches $1$ et $2$ permettent la communication entre deux machines directement reliées. -C'est ici qu'intervient l'adresse \mac{}. -La couches $3$ décrit le routage pour passer par des machines intermédiaires afin de voyager dans l'ensemble du réseau. -C'est ici qu'intervient l'adresse \ip{}. -La couches $4$ décrit les protocoles permettant d'établir une connexion entre deux applications sur les machines hôtes. -Cela inclut donc le multiplexage des données (c'est le port sur la machine hôte), ainsi que la gestion de la congestion. -Les couches $5$ et $6$ n'ont pas d'influence sur la suite, et sont donc négligées. -Elles permettent par exemple d'encrypter la connexion avec le \emph{SSL}. -La couche $7$ est la couche applicative, c'est-à-dire l'utilisation finale que l'on fait de la connexion. -Il peut s'agir de charger une page Internet, lire ses mails, regarder une vidéo, ou bien transmetre les mesures d'un capteur. -C'est cette dernière utilisation qui nous intéresse ici. - -La qualité d'une connexion entre deux points peut être évaluée grâce à deux valeurs : \begin{itemize} - \item Le délai, qui correspond à la durée écoulée entre le moment où l'application émettrice veut émettre le message, et le moment où le message est reçu par l'application cliente. - \item Le débit, qui correspond à la quantité de bits pouvant être envoyés chaque seconde entre les deux applications. -\end{itemize} - -Ces deux grandeurs n'ont pas la même importance selon l'application. -Par exemple, pour envoyer une pièce jointe dans un mail, le délai n'est pas très important : c'est le débit qui compte pour que la transaction ne soit pas trop longue. -Par contre, dans le cas d'un jeu en ligne il y a peu de données à echanger mais il faut le faire avec le moins de délai possible pour que le jeu reste fluide. -Suivant l'application, il faut favoriser l'un ou l'autre, ou trouver un compromis satifaisant. - -\subsubsection{Qu'est-ce que la congestion ?} - -Malheureusement, les réseaux étant hétérogènes, on ne contrôle pas tout les paramètres lorsqu'on les utilise. -En effet, pour envoyer un paquet à une autre machine, il faut (dans le cas général) passer par plusieurs intermédiaires, les routeurs. -Lesdits routeurs ne doivent pas gérer qu'un seul flux, et tous les liens entre les routeurs n'ont pas la même capacité ; ainsi on se retrouve avec des accumulations de paquets dans certains routeurs. -L'accumulation se produit au niveau des goulots d'étranglement. -Les routeurs n'ont pas une mémoire infinie, ils ne peuvent donc pas laisser les queues d'envoi grandir à l'infini. -Elles ont donc une taille limite, et il faut donc parfois ne pas traiter certains paquets lorsque le réseau est trop chargé. -Ce phénomène est appelé congestion. -On cherche à l'éviter, car un paquet non traité est un paquet perdu, donc le message n'est pas complet pour le client. -La gestion de la congestion sera expliquée plus en détail dans la partie \ref{part_cc}. -La détection de la congestion se fait souvent à l'aide d'un accusé de réception : si l'accusé n'est pas reçu au bout d'un certain temps, on considère le message comme perdu. -Lorsque des paquets sont perdus à cause de la congestion, il faut les réenvoyer, en faisant attention de ne pas recongestionner le réseau. -Une grande partie des optimisations du \CC a lieu au niveau de ce temps d'attente, le \rto. - -\subsubsection{Quelles sont les spécificités des réseaux \iot{} ?} - -Dans un réseau \iot, les contraintes et applications sont différentes : \begin{itemize} - \item On échange des messages courts, - \item on veut minimiser la consommation énergétique des machines, - \item les machines sont peu puissantes, et ne peuvent pas réaliser de calculs complexes. -\end{itemize} - -Les technologies employées sont surtout des connexions sans fil à basse consommation, et à bas débit. -On peut citer les technologies %manque référence - -De plus, pour accéder aux ressources d'une autre machine, on ne peut pas utiliser l'\http{} comme sur un ordinateur de bureau ou un téléphone. -En effet, \http{} s'appuie sur \tcp{}, et induit donc beaucoup de messages supplémentaires. -Ainsi, puisqu'on échange de petits messages, on se retrouve avec plus d'en-tête que de contenu dans les couches physiques, et on consomme beaucoup de ressources pour rien. -Un nouveau protocole a donc été développé pour proposer des fonctionnalités similaires à \http{}, mais adaptées aux contraintes de l'\iot{}, le protocole \coap{}. - -\subsection{Quelles sont les particularités du \coap{} ?} - -\coap{} est un protocole de la couche $7$ de l'\emph{IETF} (Internet Engineering Task Force) offrant une interface similaire à l'\http. -L'interface en question est une interface \emph{RestFull} :\begin{itemize} - \item Les ressources sont identifiées par des url, par exemple \url{coap://exemple.com/ressource/en/ligne}, - \item On peut interagir avec les ressources au moyen de plusieurs méthodes: \begin{itemize} - \item GET : On demande le contenu de la ressource distante, - \item POST, PUT : On crée ou remplace le contenu de la ressource distante, - \item DELETE : on supprime la ressource. - \end{itemize} -\end{itemize} -En plus de ces méthodes, qui ont leur équivalent chez \http{}, il y a la méthode OBSERVE. -Si un client demande à observer une ressource sur un serveur, le serveur lui enverrait automatiquement la ressource à chaque fois qu'elle est modifiée. -Les ressources utilisées avec \coap{} ne sont pas les mêmes qu'en \http{}, on ne cherche pas à transférer une suite de centaines voire de milliers de paquets mais un seul. -A la congestion classique s'ajoute le risque de perte de paquets à cause des liaisons physiques, car les infrastructures sans fil sont soumises à de la perte aléatoire. - -D'un point de vue technique, \coap{} a la particularité de reposer sur l'\udp{} et non sur le \tcp{}. -Ainsi le \CC{} est réalisé par la couche applicative et non par la couche transport. - -Lorsque l'on envoie un message, il peut être de deux types : \begin{itemize} - \item CON : confirmable, on demande un accusé de réception du message, - \item NCON, non confirmable, on ne demande pas d'accusé de réception. -\end{itemize} -Les messages NCON ne sont donc pas réenvoyés s'ils sont perdus à cause de la congestion, car il n'y a pas moyen de la détecter. -Cela peut ne pas être un problème pour certaines applications. -Il y a aussi les messages de type ACK, qui acquittent les messages CON. -L'association entre le message CON et ACK se fait grâce à un token (ACK[0xe4] qui acquitte le message CON[oxe4]). - -Ces derniers temps, de nouvelles solutions basées sur l'apprentissage machine se sont développées pour le \CC{} en \tcp{}. -Notre problèmatique est donc de savoir si de telles solutions sont applicables à \coap{}. - -\subsection{Qu'est-ce que l'apprentissage par renforcement ?} - -L'apprentissage par renforcement est une solution d'apprentissage machine pour les processus markoviens. -Le système est constitué d'un environnement et d'un acteur. -On suppose que le temps est discontinu. -Ainsi à l'instant $t$, l'environnement est dans un état $e \in \mathbb{E}$. -L'acteur observe l'environnement au travers d'un interpréteur qui lui renvoie un vecteur $s \in \mathbb{S}$, le vecteur d'observation. -L'acteur a la possibilité de réaliser une action $a in \mathbb{A}$ pour influencer l'environnement. -Suite à cette action, l'environnement change d'état et renvoie à l'acteur un nouveau vecteur d'observation et une récompense $r \in \R$. -Cette récompense permet de quantifier la qualité de l'action et du nouvel état. -Pour la suite, on notera $x ^ i$ la i-ème grandeur, et $x_t$ la grandeur à l'instant $t$. -Le but de l'acteur est de maximiser la récompense totale qu'il va recevoir au cours d'un épisode, c'est-à-dire une succession de pas de temps. -Pour cela, l'acteur doit créer une fonction $\pi : \mathbb{S} \rightarrow \mathbb{A}$ permettant de donner l'action optimale à réaliser pour chaque état. - -La méthode de base pour construire cette fonction est le \qlearn{}. -C'est un processus itératif où l'on va construire un tableau (la Q-table), noté $\mathbb{Q} : \mathbb{S} \times \mathbb{A} \rightarrow \R$ associant une valeur à chaque couple observation/action. -On parcourt l'environnement et à chaque pas de temps on met à jour la valeur de $\mathbb{Q}(s_t, a_t)$ grâce à la formule suivante : \begin{equation} - \mathbb{Q}\left(s_t, a_t \right) := \left(1 - \alpha\right) \cdot \mathbb{Q}\left(s_t, a_t \right) + \alpha \cdot \left( r_t + \gamma \cdot max _ {a \in \mathbb{A}} \mathbb{Q} \left((s_{t+1}, a \right) \right) - \label{eq:qlearn_update} -\end{equation} -Les deux paramètres sont : \begin{itemize} - \item $\alpha$ le taux d'apprentissage, c'est-à-dire à quel point les nouvelles informations écrasent les anciennes, - \item $\gamma$ l'horizon, qui permet de contrôler à quel point l'algorithme se préoccupe du futur. -\end{itemize} -La méthode pour déterminer l'action appropriée à chaque pas de temps est juste de prendre $argmax_{a in \mathbb{A}} \mathbb{Q}\left(s_t, a \right) $. -En réalité, on fait des actions aléatoires avec une probabilité faible pour explorer l'environnement. -Deux des limites de cette solution sont la taille en mémoire d'un tel tableau quand les ensembles $mathbb{S}$ et $\mathbb{A}$ sont grands, et le temps qu'il faut pour que la convergence des valeurs du tableau ait lieu. -Pour pallier à cela, on peut approximer la fonction par un réseau de neurones, c'est le principe du \dqlearn{}. - -\section{État de l'art\label{part_cc}} -Le \CC{} est un problème qui date du début des réseaux. -La première version de \tcp{} date de 1983, mais de nouveaux \CCA{} sont régulièrement publiés et mis en production. -Comme ordre d'idées, le \CCA{} le plus utilisé de nos jours, \cubic{}, a été inclus dans Linux en 2006, dans MacOS en 2014 et dans Windows en 2017. -Chaque \CCA{} présente des avantages et des inconvénients, et ne fait pas le même compromis entre délai et débit. - -\begin{figure}[htp] - \centering - \includegraphics[width = 0.8\textwidth]{png_img/comp_tcp_xiao.png} - \caption[Comparaison des \CCA{} en \tcp{}]{Comparaison de différents \CCA{} en \tcp{}. Figure issue de \cite{xiaoTCPDrincSmartCongestion2019}.} - \label{fig:comp_cca_tcp} -\end{figure} - -\subsection{Comment gère-t-on la congestion en \tcp{} ?} - -Le \tcp{} suppose qu'il y a un grand nombre de paquets à transmettre. -Ainsi on décide d'une fenêtre de congestion, c'est-à-dire le nombre de paquets en attente d'acquittement. -Si un paquet n'est pas acquitté avant la fin d'un \rto{} fixe, on le renvoie. -Les \CCA{} ont pour rôle de gérer la taille de la fenêtre, et le \rto{} celui d'optimiser la connexion. - -Les \CCA{} de \tcp{} sont nombreux (une classification partielle est lisible dans \cite{haileEndtoendCongestionControl2021}), je ne vais donc pas tous les décrire. -Le principe de base de la plupart des algorithmes est l'AIMD (additive-increase-multiplicative-decrease). -Par exemple \newreno{}, le prédecesseur de \cubic{}, augmente la taille de la fenêtre par pas de $1$ tous les \rtt{}, et multiplie la taille par $\frac{1}{2}$ en cas de détection de congestion. -L'évolution proposée par \cubic{} est de ne pas croître linéairement mais de suivre une courbe cubique pour revenir en douceur à la taille de fenêtre qui avait causé la congestion. -Dans les deux cas, à chaque retransmission d'un message, le \rto qui lui est accordé double. - -D'autres \CCA{} utilisent les variations du \rtt{} pour estimer l'état de congestion du réseau. -Le \rtt{} est le temps qui sépare l'émission d'un paquet de la réception de l'acquittement. -Le \rtt{} est composé de deux parties : \begin{itemize} - \item le temps de propagation, qui correspond au temps que met le signal à faire le trajet ; il est incompressible (sauf changement de route), - \item le temps d'attente dans les queues, qui est le temps passé dans les queues des différents routeurs et qui dépend dirrectement de la congestion du réseau. -\end{itemize} -Ainsi l'augmentation du \rtt{} est souvent signe que le réseau se congestionne. -Mais interpréter ces variations de \rtt{} et prendre la décision adéquate est trop complexe pour un algorithme classique, et certains ont déjà proposé des solutions utilisant de l'IA \cite{xiaoTCPDrincSmartCongestion2019,liQTCPAdaptiveCongestion2019} . -%%%%%%%% -\subsection{Comment gère-t-on la congestion avec l’implémentation classique de \coap{} ?} - -Pour le \coap{}, la gestion de la congestion est différente, car on utilise une fenetre unitaire, c'est sur le \rto que se fait le travail. -Dans la version de base, le \rto{} de base est tiré aléatoirement entre $2 s$ et $3 s$, et est doublé à chaque retransmission. -C'est un protocole simple mais peu performant, car si le delai de transition est déjà de l'ordre du \rto, alors il risque d'avoir des retransmission systèmatique. - -Une des évolution du \coap{} est \cocoa{}, qui ne change que le \CCA{}\cite{ancillottiRTTBasedCongestionControl2018}. -C'est une algorithme inspiré de FAST-\tcp{} et Compound-\tcp{}. -Ici on met en place une estimation du \rtt{} à partir de la mesures du \rtt{} de chaque message. -A chaque reception d'un nouveau \rtt{} $r$, on met à jour l'estimation grace aux formules suivantes : -\begin{equation} - \begin{aligned} - RTT_S &:= \alpha_S r + \left( 1 - \alpha_S \right) \cdot RTT_S\\ - RTT_L &:= \alpha_L r + \left( 1 - \alpha_L \right) \cdot RTT_S\\ - RTTVAR_L &:= \beta_L \left\| RTT_L - r \right\| + \left( 1 - \beta_L \right) \cdot RTTVAR_L - \end{aligned} - \label{eq:cocoa:estimateur} -\end{equation} -Ensuite, on crée une fonction $T$ permetant de prendre une decision : -\begin{equation} - T\left( \gamma \right) = RTT_L + \gamma RTTVAR_L - \label{eq:cocoa:decision} -\end{equation} -On a donc $4$ cas pour prendre un décision : \begin{itemize} - \item $RTT_S < T\left( -1 \right)$ : pas de congestion, on peut etre beaucoup plus agressif, - \item $T\left( -1 \right) \le RTT_S < T\left( +1 \right)$ : congestion faible, on se trouve à un point de fonctionement correct, on ne change rien, mais on peut aussi etre un peu plus agressif si besoin, - \item $T\left( +1 \right) \le RTT_S < T\left( +2 \right)$ : congestion normal, la congestion augmente, il faut etre moins agressif pour ne pas congestioner le réseau, - \item $T\left( +2 \right) \le RTT_S$ : congestion importante, le réseau est totalement congestioner, il faut etre beaucoup moins agressif. -\end{itemize} -La seule contrainte est que $\alpha_S \gg \alpha_L$. -Le choix des autres valeurs, les seuils est les actions prisent sont choisit empiriquement, on ne sais pas si elles sont optimale. - -\subsection{Comment l'apprentissage machine prend place dans les \CCA{}?} -Pour palier à ces problèmes, plusieurs \CCA{} utilisant de l'apprentissage machines sont apparut : Q-\tcp{}\cite{liQTCPAdaptiveCongestion2019}, \tcp{}-Drinc\cite{xiaoTCPDrincSmartCongestion2019}\dots -L'idée derriere ses algorithme est de délégé la prise de decision à une IA qui serais capable de reconnaitre les signe de la congestion bien plus efficassement que une algorithme "fait-main" classique. -Plusieurs problèmatique se présentent : \begin{itemize} - \item La modélisation de l'environement : \begin{itemize} - \item quel est $\mathbb{S}$, c'est à dire comment représenter l'environement pour l'acteur, - \item quel est $\mathbb{A}$, c'est à dire qu'es ce que l'acteur doit donner comme consigne, - \item quel est $r_t$, c'est à dire qu'es ce qu'une bonne action - \end{itemize} - \item mais aussi des problèmes de compétition multi-agents: \begin{itemize} - \item comment etre sûr que les ressource réseau sont équitablement répartie entre les agents, - \item comment etre sûur que les agent IA ne vont pas perturber les agents non-IA, - \end{itemize} - \item ainsi que des problèmes d'implémentation, car tout cela toi tourner sur une machine très peu puissante et incapable de faire des calcul complexe. -\end{itemize} -Les intégration de l'IA dans le \CC{} n'est encore qu'a l'état de test, de balbutiment, et pourtant des résultats notables et encouragant sont déjà disponible, voir figure \ref{fig:comp_cca_tcp}, ce qui nous motive à tenter de développer des solutions similaire pour \coap{}. - -\section{Modélisation choisit} -La première étape est de modélisé le système. -Pour la modélisation, je m'appuis sur la modélisation de \cite{xiaoTCPDrincSmartCongestion2019}. - -\subsection{Quels cas d'utilisations nous est le plus favorable ?} -Pour notre travail, on se positionne dans une situation où un serveur centrale puissant voudrait récupérer des données sur un ensemble de capteur. -Les contraites pour les codes s'éxécutant sur le serveur centrale (un serveur cloud généralement) et sur les capteur sont radicalement différentes. -Le cloud peut exécuter le code qu'il veux avec beaucoup de puissance, alors que les capteur doivent se limité au maximum. -Le could à acces au données de toutes les connexion, alors que les capteurs n'ont à priori que les données de leur connexion. -On choisit de se placer dans le cas où on intéragie avec un nombre fixe de capteur, $N$. - -\begin{figure}[htp] - \centering - \includegraphics[width=0.5\textwidth]{puml/cas_utilisation_coap.png} - \caption[Diagramme de séquance de transaction \coap{}, cas 1]{Diagramme de séquance entre le capteur et le serveur \coap{} avec déclanchement de la transaction par le capteur.} - \label{fig:seq_coap:1} -\end{figure} -\begin{figure}[htp] - \centering - \includegraphics[width=0.5\textwidth]{puml/cas_utilisation_coap_001.png} - \caption[Diagramme de séquance de transaction \coap{}, cas 2]{Diagramme de séquance entre le capteur et le serveur \coap{} avec déclanchement de la transaction par le cloud, et réponse dans l'aquitement.} - \label{fig:seq_coap:2} -\end{figure} -\begin{figure}[htp] - \centering - \includegraphics[width=0.5\textwidth]{puml/cas_utilisation_coap_002.png} - \caption[Diagramme de séquance de transaction \coap{}, cas 3]{Diagramme de séquance entre le capteur et le serveur \coap{} avec déclanchement de la transaction par le could, et réponse dans un message sépparré.} - \label{fig:seq_coap:3} -\end{figure} - -Lorsque on veux établir une connexion avec un capteur, il y a trois cas de figure, il nous faut donc choisir celui qui nous avantage le plus. Le cas 1 (figure \ref{fig:seq_coap:1}) permet de réagir à un evenement, mais ne demande au capteur de prendre le rôle de gestionaire du \CC{}, ce qui n'est pas le plus simple. -Le cas 2 (figure \ref{fig:seq_coap:2}) et 3 (figure \ref{fig:seq_coap:3}) permet tout deux au cloud de prendre en charge le \CC{}, mais le cas 3 demande l'échange de bien plus message, il sature plus vite le réseau. -On choisit dans de travailler dans le cas 2, qui permet d'avoir à la fois toutes les informations au niveau de l'acteur, et de la puissance de calcul. -Pour ce qui est de la gestion des evenement, on peu imaginé que le could envoie régulièrement au capteur des consigne siple pour le \CC{}, même si nous n'allons pas taiter cette problèmatique. - -\subsection{Quelle sont les variables que nous pouvons observer ?} - -La grandeur la plus simple à se représenter est le \rtt{}. -Chaque envoie de message permet de récupérer un echantillion de \rtt{}. -Mais un problème se pose lorsque le \rto{} de base est plus faible que le \rtt{} à cause des retransmissions : on ne sais pas si l'aquitement vient de l'original ou de la rentransmition, car ils ont le même token. -Par exemple, dans la figure \ref{fig:temp_coap:valide}, on à sans ambiguité un \rto{} de $25$, mais dans la figure \ref{fig:temp_coap:invalide}, le \rto{} semble etre $5$ alors que il est de $30$. -Ce problème peut etre contourné en changeant le token dans les retransmissions, mais nous ne metterons pas en place cette solution pour l'instant. - -\begin{figure}[htp] - \centering - \includegraphics[scale = 0.7]{puml/temporal_transaction_valide.png} - \caption{Diagramme temporelle d'un transaction sans ambiguité du \rtt{}.} - \label{fig:temp_coap:valide} -\end{figure} - -\begin{figure}[htp] - \centering - \includegraphics[scale = 0.7]{puml/temporal_transaction_invalide.png} - \caption{Diagramme temporelle d'un transaction avec ambiguité du \rtt{}.} - \label{fig:temp_coap:invalide} -\end{figure} - -L'autre grandeur que l'ont peur facilement mesuré est le nombre de retransmission de chaque message. -C'est retransmission peuvent etre dû à la congestion, mais aussi à des erreures de routage ou des couches réseau physique. - -\subsection{Comment représenter un état du système ?} - -Une fois que l'on a mesurer une grandeur, il faut la transmetre à l'acteur. -Le premier problème est que l'acteur vois un temps discontinu, alors que les nouvelles mesures arrive à des instants irréguliers. -On choisit donc de couper le temps en une série d'interval de longueur fixe. -Dans ces intervals, on supose que l'état du réseau est constant, et les valeur utilisé par le \coap{} le sont aussi. -Il faut prendre une durée de l'interval qui soit plus longue que le \rtt{}, car ainsi on ne se retrouve pas dans un cas limite où un message part pendant l'intervale $t$, avec les consignes de l'instant $t$, mais arrive dans l'instant $t+1$ et influe $s_{t+1}$ ou lieu de $s_t$. -Mais il faut aussi que cette durée ne soit pas trop importante, car on ne change les consignes que à la fin de ces intervales. -On nomme cet interval "interval de controle". - -De plus, on travail sur un réseau de capteur qui renvoie leurs informations à un serveur cloud unique. -Puisque le serveur cloud centralise toutes les connexions, on choisit d'avoir un seul agent, qui donne des consignes pour toutes les connexions. - -Pour la suite, on appel "serveur \coap{}" la partie de programme s'executant sur les capteurs, et "clients \coap{}" les programmes s'éxecutant sur le serveur cloud afin de récupérer les données des capteurs. -On remarque aussi que on ne fait pas la différence entre l'état du réseau et l'observation que l'on en fait. - -\subsubsection{État d'un client seul.} -Pour commencer, il faut que chaque client \coap{} soit capable de représenter sa connexion. -Pour cela, on dispose de : \begin{itemize} - \item le nombre de messages envoyer penant l'interval de control, - \item et pour chaque message : \begin{itemize} - \item le nombre de retransmission, - \item le \rtt{} mesurer. - \end{itemize} -\end{itemize} -On construit ensuite les valeurs suivantes : \begin{itemize} - \item $RTT_{min}$, le minimum du \rtt{} pendant les $n_m$ derniers interval de control, - \item $\overline{RTT}$, la moyenne du \rtt{} sur l'interval de control, - \item $\eta = \frac{RTT_{min}}{\overline{RTT}}$ - \item $\nu = \frac{n_{retransmission}}{n_{message}}$ - \item $VARRTT = \frac{RTT_S}{RTT_L}$ à partir des deux valeurs suivantes, que on met à jour à chaque nouvel mesure du \rtt{} $r$ :\begin{align*} - RTT_S &:= \alpha_S \cdot r + \left( 1 - \alpha_S \right) \cdot RTT_S \\ - RTT_L &:= \alpha_L \cdot r + \left( 1 - \alpha_L \right) \cdot RTT_L \\ - \alpha_S &\gg \alpha_L -\end{align*} -\end{itemize} - -Ces valeurs sont plus représentative que les mesures brutes. -$RTT_{min}$ permet d'estimé le temps de propagation des messages (on rappel que $RTT = \tau_{propagation} + \tau_{queue}$). -Ainsi, $\eta$ permet d'estimer le pourcentage du temps passer dans les queues par les messages au cours de leur voyage. -Lorsque $\eta$ est proche de $1$, c'est que les queues sont presque vide, et losque il est proche de $0$, c'est qu'elle represente la majorité de temps de trajet, ce qui est signe de congestion. -$\nu$ represente le taux de redondane des messages, il doit etre le plus faible possible. -$\nu$ élevé signifi que on revoie des messages et donc que les consignes ne sont pas adapté. -Mais $\nu$ est aussi influancé par les défauts du réseau, donc ce n'est pas un indicateur parfait. -$VARRTT$ permet d'estimer l'évolution du \rtt{} en comparant deux filtrages des \rtt{} sur des echelles différentes. -$VARRTT > 1$ indique que la tendance est à la hausse des \rtt{}, et donc que la longueur des queues augmente, et $VARRTT < 1$ que la tendance est à la baisse. -Il faut tout de même que le filtrage $RTT_S$ se fasse sûr plusieurs echantillions du \rtt{} (donc $\alpha_S \sim 0.1$) car la mesure du \rtt{} est très bruité. - -Une fois ces valeur calculer, on construit le vecteur suivant, qui represente l'état du client $i$ : \begin{equation} - s ^ {\left( i \right)}= \begin{bmatrix} \nu\\ \eta \\ VARRTT \end{bmatrix} -\label{eq:modele:vec} -\end{equation} - -\subsubsection{État de l'ensemble des clients.} -Une fois que chaque client a generé sont vecteur, il suffit de les concaténés pour crée une matrice où chaque ligne représente une des trois valeurs, et chaque colonne un client. -\begin{equation} - S = \begin{bmatrix} s ^ {(0)} & \cdots & s^{(N)} \end{bmatrix} - \label{eq:modele:mat} -\end{equation} -L'avantage d'une tel matrice est que on pourra utiliser une convolution dans le réseau de nerrone. -Une autre possibilité, que je n'ais pas pu tester est de concaténer les matrices de plusieur echantillion de temps successif pour crée un tenseur à trois dimension, qui permetrait d'avoir plus d'informations sur l'évolution temporelle des valeurs. - -\subsection{Comment l'acteur influance le client \coap{} ?} -La principales valeur permetant de controler le comportement du client est le \rto{}. -On choisit une solution où $\mathbb{A} = \R ^ N$. -Si on note $c_t$ le vecteur des $N$ \rto{} à l'instant $t$, et $a_t$ le vecteur d'action généré par l'acteur, alors : -\begin{equation} - c_{t+1} ^ {\left( i \right) }= c_t ^{\left( i \right)}\cdot \begin{cases} - 1 + a _ t ^ {\left( i \right)} & \text{si } a _ t ^{\left( i \right)} \ge 0 \\ - \frac{1}{1 - a _ t ^ {\left( i \right)}} & \text{si } a _ t ^{\left( i \right)} < 0 - \end{cases} -\end{equation} -L'effet de cette action est visible dans la figure \ref{fig:modele:action}. -Cette action permet d'avoir la capacité de réagir rapidement avec des grandes actions, mais aussi d'avoir de la précision pour s'ajuster autour du point de fonctionement. - -\begin{figure}[htp] - \centering - \includegraphics[width = 0.7\textwidth]{png_img/gain_action.png} - \caption[Modification du \rto{} par l'action.]{Modification du \rto{} par l'action, pour un seul client, en échelle logaritmique.} - \label{fig:modele:action} -\end{figure} - -D'autre choix sont possibles, par exemple $\mathbb{A} = \left\lbrace 0.1, 0.5, 0.8, 1, 1.25, 2, 10 \right\rbrace ^ N$, et $c ^ {\left( i \right))} _{t+1} c_t ^ {\left( i \right))} \cdot a _ t ^ {\left( i \right))} $ - -\subsection{Comment quantifier la réussite de l'agent ?} -Une fois que l'on sais représenter l'état du réseau, il faut déterminer si cette état est favorable ou non. -Pour cela, il faut se demander ce que l'on veux comme caractéristique. -Je choisit comme critaire : \begin{itemize} - \item Le delai est le plus petit possible, pour avoir un système réactif, - \item il y a peu de retransmission, pour ne pas encombrer le réseau et abusé des ressources energetiques des capteurs, - \item il y a tres peu d'echec, c'est à dire de message qui dépasse le nombre de retransmission maximal, - \item le nombre de message envoyé est equitablement répartie entre les clients. -\end{itemize} - -L'équité est une grandeur permetant de mesurer si certain capteurs utilise plus le réseau que d'autre. -Elle est définie pas \cite{jainQuantitativeMeasureFairness1998} pour un grandeur quelconque $\left( x_i \right) \in {\left(\R ^ {+}\right)} ^ N$: -\begin{equation} - f_A (x_i) = \frac{\left[ \sum_{k = 1}^N x_k \right] ^ 2 }{N \cdot \sum_{k = 1}^N x_k^2 } - \label{eq:modele_fair_base} -\end{equation} -Ainsi un système totalement équitable (où tout les $x_i$ sont égaux) à une équité de $1$ et un système non-équitable à une équité d'autant proche de $0$ qu'il est inéquitable. -Mais cette indice d'équité ne prend pas en compte que certain utilisateur on besoin de plus de ressource que d'autre. -Ainsi on modifie l'équation \ref{eq:modele_fair_base} pour prende un compte un besoin $\left( b_i \right) \in {\left(\R ^ {+}\right)} ^ N$ : -\begin{equation} - f_A (x_i, b_i) = \frac{\left[ \sum_{k = 1}^N \frac{x_k}{b_k} \right] ^ 2 }{N \cdot \sum_{k = 1}^N \left( \frac{x_k}{b_k} \right)^2 } - \label{eq:modele_fair_pond} -\end{equation} - -Le schéma de récompence est donc, à partir des données du derniers interval de control : -\begin{equation} - r = - \beta _ \nu \frac{\sum_{k=1}^N x^e _ k}{\sum_{k=1}^N x^t_k} - \beta_\text{echec} n_\text{echec} - \beta_{RTT} max_{k} \overline{RTT} _ k + \beta_\text{equite} \frac{\left[ \sum_{k = 1}^N \frac{n^e_k}{n^t_k} \right] ^ 2 }{N \cdot \sum_{k = 1}^N \left( \frac{n^e_k}{n^t_k} \right)^2 } - \label{eq:modele:recompence} -\end{equation} -Où $n^e$ est le nombre de message envoyé, emition initial et retransmission, et $n^t$ le nombre de transaction, c'est à dire uniquement les émitions initiales. -$n_\text{echec}$ est le nombre de transaction ayant échouée. -Les facteurs $\beta$ permetent de pondérer l'effet des différentes composante. - -\subsection{Quel type d'agent utilisé ?} -Maintenant que l'environement est fixé, on peut déterminer comment l'acteur va s'intégrer. -On choisit le fonctionement suivant : \begin{itemize} - \item L'acteur détermine $a_t$ en fonction de $s_t$, - \item les clients utilise cet $a_t$ pour trouver leur consigne $c_t$, - \item ils traitent toutes les transactions avec ses consigne pendant l'interval de control, - \item a la fin de l'interval de control, on fait la synthèse des données, on calcule $s_{t+1}$ et $r_t$, - \item on enregistre $\left( s_t, a_t, r_t, s_{t+1} \right)$, - \item on recommence avec $s_{t+1}$ -\end{itemize} -Cela represente le fonctionnement normal du système. - -Mais en plus de cela, il faut que l'on fasse s'optimisé la politique. -Pour cela on va procédé en deux temps : \begin{enumerate} - \item Le pré-entrainement, - \item l'entrainement en position. -\end{enumerate} -Le pré-entrainement se déroule avant le déploiment du réseau de capteur. -Il consiste à rendre la politique proche de ce qui est attendu pour que elle soit exploitable, même si elle n'est pas encore optimal. -Pour cela, il faut généré de l'expérience (les transitions $\left( s_t, a_t, r_t, s_{t+1} \right)$ que on a vu plus haut), et l'utilisé pour optimisé la politique. -Cette génération peut se faire de plusieur manière que on évoquera plus tard. -Une fois que la politique est correct, on peut la déployer sur le réseau de capteur réel. -Mais elle n'est pas fixe, puisque on continue à l'optimisé avec de l'exprérence récolté sur le réseau réel. - -\subsection{Quelle politique $\pi$ est utilisé ?} -Au vu de la taille des espaces $\mathbb{S}$ et $\mathbb{A}$, on ne peut pas utilisé un Q-table car elle demanderais bien trop d'espaces mémoire. -On utilise donc un réseau de neurrones pour approximé la Q-table. -Les subtilités de cette approximation, ainsi que la discretisation de $\mathbb{S}$ et $\mathbb{A}$ sont pris en charge par \TF{}. - -Puisque on est en apprentissage permanant, il faut utilisé une politique $\epsilon$-glouton. -C'est à dire que pendant la majorité du temps, on se trouve en phase d'exploitation, et on execute l'action optimal. -Mais avec une probabilité $\epsilon$, on réalise une action aléatoire, afin de tester de nouvelle possibilité. -C'est important car on ne se trouve pas dans un système déterministe, donc il ne suffit pas de tester une fois toutes les transitions. - -Pour ce qui est du réseau de neurrones, on ne travaille pour l'instant que avec un réseau feed-forward, mais on peut envisagé d'utilisé des réseaux plus complexes. - -\subsection{Comment récolté de l'expérience ?} - -La recolte de transition est indipensable pour pouvoir optimisé la politique. -La récolte in situ est lente, en effet, il faut généralement $10000$ transitions pour réalisé un pas d'optimisation. -On peut descendre jusqu'à $1000$, mais le résultats est moins stable. -De plus, avec une durée d'interval de controle de $30$s, on se retrouve à devoir attendre $8h$ par pas d'optimisation. -Il faut donc trouver des solutions plus rapide que l'exploration simple si on veux pouvoir faire une centaine de pas d'apprentissage pour atteindre une convergence. - -\subsubsection{Par exploration en simulateur} -Une solution simple, en théorie, est d'utilisé un simulateur. -Le plus utilisé est \ns{}. -C'est un simulateur à envenement discret, destiné à la simulation de réseau informatique permetant de travaillier sur toute les couches du modèle \osi{}. -Ainsi on peut entrainer le simulateur avec la topologie du réseau que l'on veux, et la qualité des connexions sans fils que l'on veux. -Malheureusment, c'est un simulateur complexe à utilisé : tout les scripts de simulation sont écrit en \cpp{}. -Par manque de temps et de compétence, je n'ais pas réalisé de simulation \ns{}, mais ca peut etre une piste à étudier pour le pré-entrainement. - -\subsubsection{Par création artificiel de transition} - -Une autre méthode possible est de créer des transitions artificiellement. -Pour cela, je commence par fixer une charge sur le réseau $f$, c'est à dire la fréquence à laquelle chaque client intéroge le capteur associé. -Celon cette charge, le réseau est plus ou moins congestioner. -Ensuite je prend plusieurs consigne de \rto{} $c_n$, et pour chaque consigne, je l'applique à l'agent, et je mesure le vecteur d'observation associé $s_n$ ainsi que $r_n$. -Puis pour chaque couple $(s_n, s_m)$, je calcule l'action $a_{n , m}$ pour passer de $c_n$ à $c_m$. -Je peu ainsi construire une série de trnasition $s_n, a_{n, m}, r_m, s_m$. -On recommence avec un autre $f$ - -Ces transitions sont uniquements des approximation, car elles ne tiennent pas réelement compte des effets de $s_t$ sur $s_{t+1}$ liée au temps de probagation des message dans le système. -De plus elles supposent que la charge ne change pas sur le système. -Malgrès cela, elle permet d'aller plus vite dans la génération de transition pour le pré-entrainement, car en $n$ interval de contrôl à $f$ fixe, on génère $n^2$ transitions. - -\section{Implémentation de l'algorithme} - -\subsection{Librairie uilisé} - -\subsubsection{\TF{} et \keras{}} - -\subsubsection{\coapthon{}} - -\subsection{Structure du code} - -\subsection{Maquette utilisée\label{part_maquette}} - -\subsection{Astuce pour simuler une congestion} - - -\section{Expérience et résultats} - -\subsection{Montage simple} - -\subsection{Multiplication des clients} - -\subsection{Multiplication des \rasp{}} - -\clearpage - -\section{Conclusion} -\lipsum[3] - -\clearpage - -\listoffigures - -\listoftables - - -% --- Biblio par .bib -\bibliography{rapport.bib} -%\bibliographystyle{plain-fr.bst} -%\selectlanguage{french} - -% --- Biblio écrite à la main -%\begin{thebibliography}{7} -%\bibitem[Bastien 2019]{id-de-la-source} -%Auteurs : \emph{Un titre}, une date. -%\end{thebibliography} - -% -------------------------------------------------------------- -% Appendices -% -------------------------------------------------------------- - -\clearpage - -\appendix -\begin{appendices} - - \section{Structure du code} - - \begin{landscape} - \begin{figure}[htp] - \centering - \includegraphics[height=\vsize, width=\hsize, keepaspectratio]{puml/call_stack_envoie.png} - \caption[Appel de fonction pour une transaction]{Appel de fontion pour une transaction avec \coapthon{} et mes modifications. Chaque couleur représente un thread d'execution.} - \end{figure} - \end{landscape} - -\end{appendices} - - -% -------------------------------------------------------------- -% Abstract -% -------------------------------------------------------------- -\pagebreak -\thispagestyle{empty} - -\vspace*{\fill} -\noindent\rule[2pt]{\textwidth}{0.5pt}\\ -{\textbf{Résumé :}} -\lipsum[1] - -{\noindent\textbf{Mots clés :}} -Insérez ici, des mots-clés, pour décrire, votre rapport. -\\ -\noindent\rule[2pt]{\textwidth}{0.5pt} -\begin{center} - \ens \\ - 4, avenue des Sciences\\ - 91190 Gif-sur-Yvette -\end{center} -\vspace*{\fill} - -\end{document} +% !TEX encoding = UTF-8 Unicode +% -*- coding: UTF-8; -*- +% vim: set fenc=utf-8 +\documentclass[a4paper,12pt,french]{article} + +\usepackage{ensps} + +\hypersetup{ + pdftitle={Titre}, + pdfauthor={Léopold Clément}, + pdfsubject={Sujet}, + pdfproducer={Conversion PDF}, + pdfkeywords={Quelques mots-clés} % +} + +\DeclareGraphicsRule{.ai}{pdf}{.ai}{} % Pour insérer des documents .ai +\graphicspath{{./img/} {./eps/} {./fig/}} % Pour ne pas avoir à ajouter eps/ton-image.jpg + +% ------------- Packages spéciaux, nécessaires pour ce rapport, à insérer ici ------------- +\usepackage{minted} +\usepackage{lscape} + +\usepackage[toc]{glossaries} +\makeglossaries + +\newglossaryentry{iot} +{ + name=IoT, + description={Internet of Things, internet des objets} +} + +\newcommand{\iot}{\gls{iot}} + +\newglossaryentry{tcp} +{ + name=TCP, + description={Transmission Control Protocol, protocole avancé de la couche \osi{} 4} +} + +\newcommand{\tcp}{\gls{tcp}} + +\newglossaryentry{udp} +{ + name=UDP, + description={User Datagram Protocol, protocole basique de la couche \osi{} 4} +} + +\newcommand{\udp}{\gls{udp}} + +\newglossaryentry{coap} +{ + name=CoAP, + description={Constrained Application Protocol, protocole de la couche \osi{} 7} +} + +\newcommand{\coap}{\gls{coap}} + +\newglossaryentry{cocoa} +{ + name=Cocoa+, + description={Evolution de \coap{}, protocole de la couche \osi{} 7} +} + +\newcommand{\cocoa}{\gls{cocoa}} + +\newglossaryentry{ns} +{ + name=ns-3, + description={Simulateur réseau puissant. \url{https://www.nsnam.org/}} +} + +\newcommand{\ns}{\gls{ns}} + +\newglossaryentry{keras} +{ + name=keras, + description={Module Python pour la manipulation de réseaux de neurones} +} + +\newcommand{\keras}{\gls{keras}} + +\newglossaryentry{tensorflow} +{ + name=TensorFlow, + description={Module Python pour l'apprentissage machine} +} + +\newcommand{\TF}{\gls{tensorflow}} + +\newglossaryentry{coapthon} +{ + name=CoAPthon, + description={Module Python implémentant les clients et serveurs \coap} +} + +\newcommand{\coapthon}{\gls{coapthon}} + +\newglossaryentry{rasp} +{ + name=RaspberryPi, + description={Modèle de micro-ordinateur} +} + +\newcommand{\rasp}{\gls{rasp}} + +\newglossaryentry{osi} +{ + name=OSI, + description={Open Systems Interconnection, modèle des réseaux} +} + +\newcommand{\osi}{\gls{osi}} + +\newglossaryentry{cc} +{ + name=CC, + description={Contrôle de congestion} +} + +\newcommand{\CC}{\gls{cc}} + +\newglossaryentry{cca} +{ + name=CCA, + description={Algorithme de contrôle de congestion} +} + +\newcommand{\CCA}{\gls{cca}} + +\newglossaryentry{mac} +{ + name=MAC, + description={Media Access Control, Contrôle de l'accès à médium de communication} +} + +\newcommand{\mac}{\gls{mac}} + +\newglossaryentry{ip} +{ + name=IP, + description={Internet Protocol} +} + +\newcommand{\ip}{\gls{ip}} + +\newglossaryentry{http} +{ + name=HTTP, + description={Hypertext Transfer Protocol, protocole de la couche \osi{} 7} +} + +\newcommand{\http}{\gls{http}} + +\newcommand{\qlearn}{Q-learning} +\newcommand{\dqlearn}{Deep-Q-learning} +\newcommand{\cubic}{TCP-Cubic} +\newcommand{\newreno}{TCP-NewReno} +\newcommand{\cpp}{C++} + +\newglossaryentry{rtt} +{ + name=RTT, + description={Round Trip Time, temps d'aller-retour} +} + +\newcommand{\rtt}{\gls{rtt}} + +\newglossaryentry{rto} +{ + name=RTO, + description={Return TimeOut, temps d'attente maximal} +} + +\newcommand{\rto}{\gls{rto}} + +\begin{document} + +% -------------------------------------------------------------- +% Page de garde +% -------------------------------------------------------------- + +\begin{titlepage} + \begin{center} + + \includegraphics[height = 3 cm]{logo_ENSPS_UPS.png}\\[1cm] + + {\large Département \emph{EEA}}\\[0.5cm] + + {\large Stage de \emph{M1}}\\[0.5cm] + + % Titre + \rule{\linewidth}{0.5mm} \\[0.4cm] + { \huge \bfseries Titre du rapport éventuellement en plusieurs lignes. \\[0.4cm] } + \rule{\linewidth}{0.5mm} \\[1.5cm] + + % Auteur(es) et encadrant(es) + \noindent + \begin{minipage}{0.4\textwidth} + \begin{flushleft} \large + \emph{Auteurs :}\\ + M.~Léopold \textsc{Clément} + \end{flushleft} + \end{minipage}% + \begin{minipage}{0.4\textwidth} + \begin{flushright} \large + \emph{Encadrants :} \\ + M\up{me} Lynda \textsc{Zitoune}\\ + M\up{me} Véronique \textsc{Vèque} + \end{flushright} + \end{minipage} + + \vfill + + % Date en fin de page + {\large Version du\\ \today} + + \end{center} +\end{titlepage} + +% -------------------------------------------------------------- +% Table des matières +% -------------------------------------------------------------- + +\thispagestyle{empty} +\tableofcontents +\pagebreak + +% -------------------------------------------------------------- +% Début du corps +% -------------------------------------------------------------- +\printglossary[title=Glossaire, toctitle=Glossaire] + +\section{Introduction} + +\subsection{Présentation de l'environnement de travail} + +\subsection{Qu'est-ce qu'un réseau \iot{} ?} + +Un réseau \iot{} est un réseau de machines informatiques embarquées. +Les machines qui composent ce réseau sont en majorité des machines peu puissantes : des capteurs, des actionneurs \dots, ils réalisent chacun une tâche simple, et sont soumis à de multiples contraintes, en particulier en termes de consommation énergétique. +Les réseaux \iot{} présentent donc des thématiques propres aux réseaux classiques (débit, latence, pertes de données \dots), qui ont déjà été étudiées par le passé pour lesquelles des solutions exisent, et des thématique nouvelles qui ne s'intègrent pas dans le modèle classique. + +\subsubsection{Qu'est-ce qu'un réseau ?} + +Un réseau informatique est un groupe de machines indépendantes que l'on connecte entre elles pour qu'elles échangent des informations. +Ces connexions se font au moyen de normes et de protocoles organisés dans un modèle à $7$ couches, le modèle \osi{}: + +\begin{table}[htp] + \centering + \caption[modèle \osi{} général]{Le modèle \osi{} pour Internet, les couches principales.} + \begin{tabular}{lll} + \toprule + Couche & Rôle & Protocole\\ + \midrule + 7 - Application & Utilisation finale & http, ssh...\\ + 4 - Transport & \CC{} \& multiplexage & \tcp{}, \udp{}\\ + 3 - Réseau & Routage & IP\\ + 1 \& 2 - Physique & Support des communications & Ethernet, Wi-Fi...\\ + \bottomrule + \end{tabular} +\end{table} + +Les couches $1$ et $2$ permettent la communication entre deux machines directement reliées. +C'est ici qu'intervient l'adresse \mac{}. +La couches $3$ décrit le routage pour passer par des machines intermédiaires afin de voyager dans l'ensemble du réseau. +C'est ici qu'intervient l'adresse \ip{}. +La couches $4$ décrit les protocoles permettant d'établir une connexion entre deux applications sur les machines hôtes. +Cela inclut donc le multiplexage des données (c'est le port sur la machine hôte), ainsi que la gestion de la congestion. +Les couches $5$ et $6$ n'ont pas d'influence sur la suite, et sont donc négligées. +Elles permettent par exemple d'encrypter la connexion avec le \emph{SSL}. +La couche $7$ est la couche applicative, c'est-à-dire l'utilisation finale que l'on fait de la connexion. +Il peut s'agir de charger une page Internet, lire ses mails, regarder une vidéo, ou bien transmetre les mesures d'un capteur. +C'est cette dernière utilisation qui nous intéresse ici. + +La qualité d'une connexion entre deux points peut être évaluée grâce à deux valeurs : \begin{itemize} + \item Le délai, qui correspond à la durée écoulée entre le moment où l'application émettrice veut émettre le message, et le moment où le message est reçu par l'application cliente. + \item Le débit, qui correspond à la quantité de bits pouvant être envoyés chaque seconde entre les deux applications. +\end{itemize} + +Ces deux grandeurs n'ont pas la même importance selon l'application. +Par exemple, pour envoyer une pièce jointe dans un mail, le délai n'est pas très important : c'est le débit qui compte pour que la transaction ne soit pas trop longue. +Par contre, dans le cas d'un jeu en ligne il y a peu de données à echanger mais il faut le faire avec le moins de délai possible pour que le jeu reste fluide. +Suivant l'application, il faut favoriser l'un ou l'autre, ou trouver un compromis satifaisant. + +\subsubsection{Qu'est-ce que la congestion ?} + +Malheureusement, les réseaux étant hétérogènes, on ne contrôle pas tout les paramètres lorsqu'on les utilise. +En effet, pour envoyer un paquet à une autre machine, il faut (dans le cas général) passer par plusieurs intermédiaires, les routeurs. +Lesdits routeurs ne doivent pas gérer qu'un seul flux, et tous les liens entre les routeurs n'ont pas la même capacité ; ainsi on se retrouve avec des accumulations de paquets dans certains routeurs. +L'accumulation se produit au niveau des goulots d'étranglement. +Les routeurs n'ont pas une mémoire infinie, ils ne peuvent donc pas laisser les queues d'envoi grandir à l'infini. +Elles ont donc une taille limite, et il faut donc parfois ne pas traiter certains paquets lorsque le réseau est trop chargé. +Ce phénomène est appelé congestion. +On cherche à l'éviter, car un paquet non traité est un paquet perdu, donc le message n'est pas complet pour le client. +La gestion de la congestion sera expliquée plus en détail dans la partie \ref{part_cc}. +La détection de la congestion se fait souvent à l'aide d'un accusé de réception : si l'accusé n'est pas reçu au bout d'un certain temps, on considère le message comme perdu. +Lorsque des paquets sont perdus à cause de la congestion, il faut les réenvoyer, en faisant attention de ne pas recongestionner le réseau. +Une grande partie des optimisations du \CC a lieu au niveau de ce temps d'attente, le \rto. + +\subsubsection{Quelles sont les spécificités des réseaux \iot{} ?} + +Dans un réseau \iot, les contraintes et applications sont différentes : \begin{itemize} + \item On échange des messages courts, + \item on veut minimiser la consommation énergétique des machines, + \item les machines sont peu puissantes, et ne peuvent pas réaliser de calculs complexes. +\end{itemize} + +Les technologies employées sont surtout des connexions sans fil à basse consommation, et à bas débit. +On peut citer les technologies %manque référence + +De plus, pour accéder aux ressources d'une autre machine, on ne peut pas utiliser l'\http{} comme sur un ordinateur de bureau ou un téléphone. +En effet, \http{} s'appuie sur \tcp{}, et induit donc beaucoup de messages supplémentaires. +Ainsi, puisqu'on échange de petits messages, on se retrouve avec plus d'en-tête que de contenu dans les couches physiques, et on consomme beaucoup de ressources pour rien. +Un nouveau protocole a donc été développé pour proposer des fonctionnalités similaires à \http{}, mais adaptées aux contraintes de l'\iot{}, le protocole \coap{}. + +\subsection{Quelles sont les particularités du \coap{} ?} + +\coap{} est un protocole de la couche $7$ de l'\emph{IETF} (Internet Engineering Task Force) offrant une interface similaire à l'\http. +L'interface en question est une interface \emph{RestFull} :\begin{itemize} + \item Les ressources sont identifiées par des url, par exemple \url{coap://exemple.com/ressource/en/ligne}, + \item On peut interagir avec les ressources au moyen de plusieurs méthodes: \begin{itemize} + \item GET : On demande le contenu de la ressource distante, + \item POST, PUT : On crée ou remplace le contenu de la ressource distante, + \item DELETE : on supprime la ressource. + \end{itemize} +\end{itemize} +En plus de ces méthodes, qui ont leur équivalent chez \http{}, il y a la méthode OBSERVE. +Si un client demande à observer une ressource sur un serveur, le serveur lui enverrait automatiquement la ressource à chaque fois qu'elle est modifiée. +Les ressources utilisées avec \coap{} ne sont pas les mêmes qu'en \http{}, on ne cherche pas à transférer une suite de centaines voire de milliers de paquets mais un seul. +A la congestion classique s'ajoute le risque de perte de paquets à cause des liaisons physiques, car les infrastructures sans fil sont soumises à de la perte aléatoire. + +D'un point de vue technique, \coap{} a la particularité de reposer sur l'\udp{} et non sur le \tcp{}. +Ainsi le \CC{} est réalisé par la couche applicative et non par la couche transport. + +Lorsque l'on envoie un message, il peut être de deux types : \begin{itemize} + \item CON : confirmable, on demande un accusé de réception du message, + \item NCON, non confirmable, on ne demande pas d'accusé de réception. +\end{itemize} +Les messages NCON ne sont donc pas réenvoyés s'ils sont perdus à cause de la congestion, car il n'y a pas moyen de la détecter. +Cela peut ne pas être un problème pour certaines applications. +Il y a aussi les messages de type ACK, qui acquittent les messages CON. +L'association entre le message CON et ACK se fait grâce à un token (ACK[0xe4] qui acquitte le message CON[oxe4]). + +Ces derniers temps, de nouvelles solutions basées sur l'apprentissage machine se sont développées pour le \CC{} en \tcp{}. +Notre problèmatique est donc de savoir si de telles solutions sont applicables à \coap{}. + +\subsection{Qu'est-ce que l'apprentissage par renforcement ?} + +L'apprentissage par renforcement est une solution d'apprentissage machine pour les processus markoviens. +Le système est constitué d'un environnement et d'un acteur. +On suppose que le temps est discontinu. +Ainsi à l'instant $t$, l'environnement est dans un état $e \in \mathbb{E}$. +L'acteur observe l'environnement au travers d'un interpréteur qui lui renvoie un vecteur $s \in \mathbb{S}$, le vecteur d'observation. +L'acteur a la possibilité de réaliser une action $a in \mathbb{A}$ pour influencer l'environnement. +Suite à cette action, l'environnement change d'état et renvoie à l'acteur un nouveau vecteur d'observation et une récompense $r \in \R$. +Cette récompense permet de quantifier la qualité de l'action et du nouvel état. +Pour la suite, on notera $x ^ i$ la i-ème grandeur, et $x_t$ la grandeur à l'instant $t$. +Le but de l'acteur est de maximiser la récompense totale qu'il va recevoir au cours d'un épisode, c'est-à-dire une succession de pas de temps. +Pour cela, l'acteur doit créer une fonction $\pi : \mathbb{S} \rightarrow \mathbb{A}$ permettant de donner l'action optimale à réaliser pour chaque état. + +La méthode de base pour construire cette fonction est le \qlearn{}. +C'est un processus itératif où l'on va construire un tableau (la Q-table), noté $\mathbb{Q} : \mathbb{S} \times \mathbb{A} \rightarrow \R$ associant une valeur à chaque couple observation/action. +On parcourt l'environnement et à chaque pas de temps on met à jour la valeur de $\mathbb{Q}(s_t, a_t)$ grâce à la formule suivante : \begin{equation} + \mathbb{Q}\left(s_t, a_t \right) := \left(1 - \alpha\right) \cdot \mathbb{Q}\left(s_t, a_t \right) + \alpha \cdot \left( r_t + \gamma \cdot max _ {a \in \mathbb{A}} \mathbb{Q} \left((s_{t+1}, a \right) \right) + \label{eq:qlearn_update} +\end{equation} +Les deux paramètres sont : \begin{itemize} + \item $\alpha$ le taux d'apprentissage, c'est-à-dire à quel point les nouvelles informations écrasent les anciennes, + \item $\gamma$ l'horizon, qui permet de contrôler à quel point l'algorithme se préoccupe du futur. +\end{itemize} +La méthode pour déterminer l'action appropriée à chaque pas de temps est juste de prendre $argmax_{a in \mathbb{A}} \mathbb{Q}\left(s_t, a \right) $. +En réalité, on fait des actions aléatoires avec une probabilité faible pour explorer l'environnement. +Deux des limites de cette solution sont la taille en mémoire d'un tel tableau quand les ensembles $mathbb{S}$ et $\mathbb{A}$ sont grands, et le temps qu'il faut pour que la convergence des valeurs du tableau ait lieu. +Pour pallier à cela, on peut approximer la fonction par un réseau de neurones, c'est le principe du \dqlearn{}. + +\section{État de l'art\label{part_cc}} +Le \CC{} est un problème qui date du début des réseaux. +La première version de \tcp{} date de 1983, mais de nouveaux \CCA{} sont régulièrement publiés et mis en production. +Comme ordre d'idées, le \CCA{} le plus utilisé de nos jours, \cubic{}, a été inclus dans Linux en 2006, dans MacOS en 2014 et dans Windows en 2017. +Chaque \CCA{} présente des avantages et des inconvénients, et ne fait pas le même compromis entre délai et débit. + +\begin{figure}[htp] + \centering + \includegraphics[width = 0.8\textwidth]{png_img/comp_tcp_xiao.png} + \caption[Comparaison des \CCA{} en \tcp{}]{Comparaison de différents \CCA{} en \tcp{}. Figure issue de \cite{xiaoTCPDrincSmartCongestion2019}.} + \label{fig:comp_cca_tcp} +\end{figure} + +\subsection{Comment gère-t-on la congestion en \tcp{} ?} + +Le \tcp{} suppose qu'il y a un grand nombre de paquets à transmettre. +Ainsi on décide d'une fenêtre de congestion, c'est-à-dire le nombre de paquets en attente d'acquittement. +Si un paquet n'est pas acquitté avant la fin d'un \rto{} fixe, on le renvoie. +Les \CCA{} ont pour rôle de gérer la taille de la fenêtre, et le \rto{} celui d'optimiser la connexion. + +Les \CCA{} de \tcp{} sont nombreux (une classification partielle est lisible dans \cite{haileEndtoendCongestionControl2021}), je ne vais donc pas tous les décrire. +Le principe de base de la plupart des algorithmes est l'AIMD (additive-increase-multiplicative-decrease). +Par exemple \newreno{}, le prédecesseur de \cubic{}, augmente la taille de la fenêtre par pas de $1$ tous les \rtt{}, et multiplie la taille par $\frac{1}{2}$ en cas de détection de congestion. +L'évolution proposée par \cubic{} est de ne pas croître linéairement mais de suivre une courbe cubique pour revenir en douceur à la taille de fenêtre qui avait causé la congestion. +Dans les deux cas, à chaque retransmission d'un message, le \rto qui lui est accordé double. + +D'autres \CCA{} utilisent les variations du \rtt{} pour estimer l'état de congestion du réseau. +Le \rtt{} est le temps qui sépare l'émission d'un paquet de la réception de l'acquittement. +Le \rtt{} est composé de deux parties : \begin{itemize} + \item le temps de propagation, qui correspond au temps que met le signal à faire le trajet ; il est incompressible (sauf changement de route), + \item le temps d'attente dans les queues, qui est le temps passé dans les queues des différents routeurs et qui dépend dirrectement de la congestion du réseau. +\end{itemize} +Ainsi l'augmentation du \rtt{} est souvent signe que le réseau se congestionne. +Mais interpréter ces variations de \rtt{} et prendre la décision adéquate est trop complexe pour un algorithme classique, et certains ont déjà proposé des solutions utilisant de l'IA \cite{xiaoTCPDrincSmartCongestion2019,liQTCPAdaptiveCongestion2019} . +%%%%%%%% +\subsection{Comment gère-t-on la congestion avec l’implémentation classique de \coap{} ?} + +Pour le \coap{}, la gestion de la congestion est différente, car on utilise une fenetre unitaire, c'est sur le \rto que se fait le travail. +Dans la version de base, le \rto{} de base est tiré aléatoirement entre $2 s$ et $3 s$, et est doublé à chaque retransmission. +C'est un protocole simple mais peu performant, car si le delai de transition est déjà de l'ordre du \rto, alors il risque d'avoir des retransmission systèmatique. + +Une des évolution du \coap{} est \cocoa{}, qui ne change que le \CCA{}\cite{ancillottiRTTBasedCongestionControl2018}. +C'est une algorithme inspiré de FAST-\tcp{} et Compound-\tcp{}. +Ici on met en place une estimation du \rtt{} à partir de la mesures du \rtt{} de chaque message. +A chaque reception d'un nouveau \rtt{} $r$, on met à jour l'estimation grace aux formules suivantes : +\begin{equation} + \begin{aligned} + RTT_S &:= \alpha_S r + \left( 1 - \alpha_S \right) \cdot RTT_S\\ + RTT_L &:= \alpha_L r + \left( 1 - \alpha_L \right) \cdot RTT_S\\ + RTTVAR_L &:= \beta_L \left\| RTT_L - r \right\| + \left( 1 - \beta_L \right) \cdot RTTVAR_L + \end{aligned} + \label{eq:cocoa:estimateur} +\end{equation} +Ensuite, on crée une fonction $T$ permetant de prendre une decision : +\begin{equation} + T\left( \gamma \right) = RTT_L + \gamma RTTVAR_L + \label{eq:cocoa:decision} +\end{equation} +On a donc $4$ cas pour prendre un décision : \begin{itemize} + \item $RTT_S < T\left( -1 \right)$ : pas de congestion, on peut etre beaucoup plus agressif, + \item $T\left( -1 \right) \le RTT_S < T\left( +1 \right)$ : congestion faible, on se trouve à un point de fonctionement correct, on ne change rien, mais on peut aussi etre un peu plus agressif si besoin, + \item $T\left( +1 \right) \le RTT_S < T\left( +2 \right)$ : congestion normal, la congestion augmente, il faut etre moins agressif pour ne pas congestioner le réseau, + \item $T\left( +2 \right) \le RTT_S$ : congestion importante, le réseau est totalement congestioner, il faut etre beaucoup moins agressif. +\end{itemize} +La seule contrainte est que $\alpha_S \gg \alpha_L$. +Le choix des autres valeurs, les seuils est les actions prisent sont choisit empiriquement, on ne sais pas si elles sont optimale. + +\subsection{Comment l'apprentissage machine prend place dans les \CCA{}?} +Pour palier à ces problèmes, plusieurs \CCA{} utilisant de l'apprentissage machines sont apparut : Q-\tcp{}\cite{liQTCPAdaptiveCongestion2019}, \tcp{}-Drinc\cite{xiaoTCPDrincSmartCongestion2019}\dots +L'idée derriere ses algorithme est de délégé la prise de decision à une IA qui serais capable de reconnaitre les signe de la congestion bien plus efficassement que une algorithme "fait-main" classique. +Plusieurs problèmatique se présentent : \begin{itemize} + \item La modélisation de l'environement : \begin{itemize} + \item quel est $\mathbb{S}$, c'est à dire comment représenter l'environement pour l'acteur, + \item quel est $\mathbb{A}$, c'est à dire qu'es ce que l'acteur doit donner comme consigne, + \item quel est $r_t$, c'est à dire qu'es ce qu'une bonne action + \end{itemize} + \item mais aussi des problèmes de compétition multi-agents: \begin{itemize} + \item comment etre sûr que les ressource réseau sont équitablement répartie entre les agents, + \item comment etre sûur que les agent IA ne vont pas perturber les agents non-IA, + \end{itemize} + \item ainsi que des problèmes d'implémentation, car tout cela toi tourner sur une machine très peu puissante et incapable de faire des calcul complexe. +\end{itemize} +Les intégration de l'IA dans le \CC{} n'est encore qu'a l'état de test, de balbutiment, et pourtant des résultats notables et encouragant sont déjà disponible, voir figure \ref{fig:comp_cca_tcp}, ce qui nous motive à tenter de développer des solutions similaire pour \coap{}. + +\section{Modélisation choisit} +La première étape est de modélisé le système. +Pour la modélisation, je m'appuis sur la modélisation de \cite{xiaoTCPDrincSmartCongestion2019}. + +\subsection{Quels cas d'utilisations nous est le plus favorable ?} +Pour notre travail, on se positionne dans une situation où un serveur centrale puissant voudrait récupérer des données sur un ensemble de capteur. +Les contraites pour les codes s'éxécutant sur le serveur centrale (un serveur cloud généralement) et sur les capteur sont radicalement différentes. +Le cloud peut exécuter le code qu'il veux avec beaucoup de puissance, alors que les capteur doivent se limité au maximum. +Le could à acces au données de toutes les connexion, alors que les capteurs n'ont à priori que les données de leur connexion. +On choisit de se placer dans le cas où on intéragie avec un nombre fixe de capteur, $N$. + +\begin{figure}[htp] + \centering + \includegraphics[width=0.5\textwidth]{puml/cas_utilisation_coap.png} + \caption[Diagramme de séquance de transaction \coap{}, cas 1]{Diagramme de séquance entre le capteur et le serveur \coap{} avec déclanchement de la transaction par le capteur.} + \label{fig:seq_coap:1} +\end{figure} +\begin{figure}[htp] + \centering + \includegraphics[width=0.5\textwidth]{puml/cas_utilisation_coap_001.png} + \caption[Diagramme de séquance de transaction \coap{}, cas 2]{Diagramme de séquance entre le capteur et le serveur \coap{} avec déclanchement de la transaction par le cloud, et réponse dans l'aquitement.} + \label{fig:seq_coap:2} +\end{figure} +\begin{figure}[htp] + \centering + \includegraphics[width=0.5\textwidth]{puml/cas_utilisation_coap_002.png} + \caption[Diagramme de séquance de transaction \coap{}, cas 3]{Diagramme de séquance entre le capteur et le serveur \coap{} avec déclanchement de la transaction par le could, et réponse dans un message sépparré.} + \label{fig:seq_coap:3} +\end{figure} + +Lorsque on veux établir une connexion avec un capteur, il y a trois cas de figure, il nous faut donc choisir celui qui nous avantage le plus. Le cas 1 (figure \ref{fig:seq_coap:1}) permet de réagir à un evenement, mais ne demande au capteur de prendre le rôle de gestionaire du \CC{}, ce qui n'est pas le plus simple. +Le cas 2 (figure \ref{fig:seq_coap:2}) et 3 (figure \ref{fig:seq_coap:3}) permet tout deux au cloud de prendre en charge le \CC{}, mais le cas 3 demande l'échange de bien plus message, il sature plus vite le réseau. +On choisit dans de travailler dans le cas 2, qui permet d'avoir à la fois toutes les informations au niveau de l'acteur, et de la puissance de calcul. +Pour ce qui est de la gestion des evenement, on peu imaginé que le could envoie régulièrement au capteur des consigne siple pour le \CC{}, même si nous n'allons pas taiter cette problèmatique. + +\subsection{Quelle sont les variables que nous pouvons observer ?} + +La grandeur la plus simple à se représenter est le \rtt{}. +Chaque envoie de message permet de récupérer un echantillion de \rtt{}. +Mais un problème se pose lorsque le \rto{} de base est plus faible que le \rtt{} à cause des retransmissions : on ne sais pas si l'aquitement vient de l'original ou de la rentransmition, car ils ont le même token. +Par exemple, dans la figure \ref{fig:temp_coap:valide}, on à sans ambiguité un \rto{} de $25$, mais dans la figure \ref{fig:temp_coap:invalide}, le \rto{} semble etre $5$ alors que il est de $30$. +Ce problème peut etre contourné en changeant le token dans les retransmissions, mais nous ne metterons pas en place cette solution pour l'instant. + +\begin{figure}[htp] + \centering + \includegraphics[scale = 0.7]{puml/temporal_transaction_valide.png} + \caption{Diagramme temporelle d'un transaction sans ambiguité du \rtt{}.} + \label{fig:temp_coap:valide} +\end{figure} + +\begin{figure}[htp] + \centering + \includegraphics[scale = 0.7]{puml/temporal_transaction_invalide.png} + \caption{Diagramme temporelle d'un transaction avec ambiguité du \rtt{}.} + \label{fig:temp_coap:invalide} +\end{figure} + +L'autre grandeur que l'ont peur facilement mesuré est le nombre de retransmission de chaque message. +C'est retransmission peuvent etre dû à la congestion, mais aussi à des erreures de routage ou des couches réseau physique. + +\subsection{Comment représenter un état du système ?} + +Une fois que l'on a mesurer une grandeur, il faut la transmetre à l'acteur. +Le premier problème est que l'acteur vois un temps discontinu, alors que les nouvelles mesures arrive à des instants irréguliers. +On choisit donc de couper le temps en une série d'interval de longueur fixe. +Dans ces intervals, on supose que l'état du réseau est constant, et les valeur utilisé par le \coap{} le sont aussi. +Il faut prendre une durée de l'interval qui soit plus longue que le \rtt{}, car ainsi on ne se retrouve pas dans un cas limite où un message part pendant l'intervale $t$, avec les consignes de l'instant $t$, mais arrive dans l'instant $t+1$ et influe $s_{t+1}$ ou lieu de $s_t$. +Mais il faut aussi que cette durée ne soit pas trop importante, car on ne change les consignes que à la fin de ces intervales. +On nomme cet interval "interval de controle". + +De plus, on travail sur un réseau de capteur qui renvoie leurs informations à un serveur cloud unique. +Puisque le serveur cloud centralise toutes les connexions, on choisit d'avoir un seul agent, qui donne des consignes pour toutes les connexions. + +Pour la suite, on appel "serveur \coap{}" la partie de programme s'executant sur les capteurs, et "clients \coap{}" les programmes s'éxecutant sur le serveur cloud afin de récupérer les données des capteurs. +On remarque aussi que on ne fait pas la différence entre l'état du réseau et l'observation que l'on en fait. + +\subsubsection{État d'un client seul.} +Pour commencer, il faut que chaque client \coap{} soit capable de représenter sa connexion. +Pour cela, on dispose de : \begin{itemize} + \item le nombre de messages envoyer penant l'interval de control, + \item et pour chaque message : \begin{itemize} + \item le nombre de retransmission, + \item le \rtt{} mesurer. + \end{itemize} +\end{itemize} +On construit ensuite les valeurs suivantes : \begin{itemize} + \item $RTT_{min}$, le minimum du \rtt{} pendant les $n_m$ derniers interval de control, + \item $\overline{RTT}$, la moyenne du \rtt{} sur l'interval de control, + \item $\eta = \frac{RTT_{min}}{\overline{RTT}}$ + \item $\nu = \frac{n_{retransmission}}{n_{message}}$ + \item $VARRTT = \frac{RTT_S}{RTT_L}$ à partir des deux valeurs suivantes, que on met à jour à chaque nouvel mesure du \rtt{} $r$ :\begin{align*} + RTT_S &:= \alpha_S \cdot r + \left( 1 - \alpha_S \right) \cdot RTT_S \\ + RTT_L &:= \alpha_L \cdot r + \left( 1 - \alpha_L \right) \cdot RTT_L \\ + \alpha_S &\gg \alpha_L +\end{align*} +\end{itemize} + +Ces valeurs sont plus représentative que les mesures brutes. +$RTT_{min}$ permet d'estimé le temps de propagation des messages (on rappel que $RTT = \tau_{propagation} + \tau_{queue}$). +Ainsi, $\eta$ permet d'estimer le pourcentage du temps passer dans les queues par les messages au cours de leur voyage. +Lorsque $\eta$ est proche de $1$, c'est que les queues sont presque vide, et losque il est proche de $0$, c'est qu'elle represente la majorité de temps de trajet, ce qui est signe de congestion. +$\nu$ represente le taux de redondane des messages, il doit etre le plus faible possible. +$\nu$ élevé signifi que on revoie des messages et donc que les consignes ne sont pas adapté. +Mais $\nu$ est aussi influancé par les défauts du réseau, donc ce n'est pas un indicateur parfait. +$VARRTT$ permet d'estimer l'évolution du \rtt{} en comparant deux filtrages des \rtt{} sur des echelles différentes. +$VARRTT > 1$ indique que la tendance est à la hausse des \rtt{}, et donc que la longueur des queues augmente, et $VARRTT < 1$ que la tendance est à la baisse. +Il faut tout de même que le filtrage $RTT_S$ se fasse sûr plusieurs echantillions du \rtt{} (donc $\alpha_S \sim 0.1$) car la mesure du \rtt{} est très bruité. + +Une fois ces valeur calculer, on construit le vecteur suivant, qui represente l'état du client $i$ : \begin{equation} + s ^ {\left( i \right)}= \begin{bmatrix} \nu\\ \eta \\ VARRTT \end{bmatrix} +\label{eq:modele:vec} +\end{equation} + +\subsubsection{État de l'ensemble des clients.} +Une fois que chaque client a generé sont vecteur, il suffit de les concaténés pour crée une matrice où chaque ligne représente une des trois valeurs, et chaque colonne un client. +\begin{equation} + S = \begin{bmatrix} s ^ {(0)} & \cdots & s^{(N)} \end{bmatrix} + \label{eq:modele:mat} +\end{equation} +L'avantage d'une tel matrice est que on pourra utiliser une convolution dans le réseau de nerrone. +Une autre possibilité, que je n'ais pas pu tester est de concaténer les matrices de plusieur echantillion de temps successif pour crée un tenseur à trois dimension, qui permetrait d'avoir plus d'informations sur l'évolution temporelle des valeurs. + +\subsection{Comment l'acteur influance le client \coap{} ?} +La principales valeur permetant de controler le comportement du client est le \rto{}. +On choisit une solution où $\mathbb{A} = \R ^ N$. +Si on note $c_t$ le vecteur des $N$ \rto{} à l'instant $t$, et $a_t$ le vecteur d'action généré par l'acteur, alors : +\begin{equation} + c_{t+1} ^ {\left( i \right) }= c_t ^{\left( i \right)}\cdot \begin{cases} + 1 + a _ t ^ {\left( i \right)} & \text{si } a _ t ^{\left( i \right)} \ge 0 \\ + \frac{1}{1 - a _ t ^ {\left( i \right)}} & \text{si } a _ t ^{\left( i \right)} < 0 + \end{cases} +\end{equation} +L'effet de cette action est visible dans la figure \ref{fig:modele:action}. +Cette action permet d'avoir la capacité de réagir rapidement avec des grandes actions, mais aussi d'avoir de la précision pour s'ajuster autour du point de fonctionement. + +\begin{figure}[htp] + \centering + \includegraphics[width = 0.7\textwidth]{png_img/gain_action.png} + \caption[Modification du \rto{} par l'action.]{Modification du \rto{} par l'action, pour un seul client, en échelle logaritmique.} + \label{fig:modele:action} +\end{figure} + +D'autre choix sont possibles, par exemple $\mathbb{A} = \left\lbrace 0.1, 0.5, 0.8, 1, 1.25, 2, 10 \right\rbrace ^ N$, et $c ^ {\left( i \right))} _{t+1} c_t ^ {\left( i \right))} \cdot a _ t ^ {\left( i \right))} $ + +\subsection{Comment quantifier la réussite de l'agent ?} +Une fois que l'on sais représenter l'état du réseau, il faut déterminer si cette état est favorable ou non. +Pour cela, il faut se demander ce que l'on veux comme caractéristique. +Je choisit comme critaire : \begin{itemize} + \item Le delai est le plus petit possible, pour avoir un système réactif, + \item il y a peu de retransmission, pour ne pas encombrer le réseau et abusé des ressources energetiques des capteurs, + \item il y a tres peu d'echec, c'est à dire de message qui dépasse le nombre de retransmission maximal, + \item le nombre de message envoyé est equitablement répartie entre les clients. +\end{itemize} + +L'équité est une grandeur permetant de mesurer si certain capteurs utilise plus le réseau que d'autre. +Elle est définie pas \cite{jainQuantitativeMeasureFairness1998} pour un grandeur quelconque $\left( x_i \right) \in {\left(\R ^ {+}\right)} ^ N$: +\begin{equation} + f_A (x_i) = \frac{\left[ \sum_{k = 1}^N x_k \right] ^ 2 }{N \cdot \sum_{k = 1}^N x_k^2 } + \label{eq:modele_fair_base} +\end{equation} +Ainsi un système totalement équitable (où tout les $x_i$ sont égaux) à une équité de $1$ et un système non-équitable à une équité d'autant proche de $0$ qu'il est inéquitable. +Mais cette indice d'équité ne prend pas en compte que certain utilisateur on besoin de plus de ressource que d'autre. +Ainsi on modifie l'équation \ref{eq:modele_fair_base} pour prende un compte un besoin $\left( b_i \right) \in {\left(\R ^ {+}\right)} ^ N$ : +\begin{equation} + f_A (x_i, b_i) = \frac{\left[ \sum_{k = 1}^N \frac{x_k}{b_k} \right] ^ 2 }{N \cdot \sum_{k = 1}^N \left( \frac{x_k}{b_k} \right)^2 } + \label{eq:modele_fair_pond} +\end{equation} + +Le schéma de récompence est donc, à partir des données du derniers interval de control : +\begin{equation} + r = - \beta _ \nu \frac{\sum_{k=1}^N x^e _ k}{\sum_{k=1}^N x^t_k} - \beta_\text{echec} n_\text{echec} - \beta_{RTT} max_{k} \overline{RTT} _ k + \beta_\text{equite} \frac{\left[ \sum_{k = 1}^N \frac{n^e_k}{n^t_k} \right] ^ 2 }{N \cdot \sum_{k = 1}^N \left( \frac{n^e_k}{n^t_k} \right)^2 } + \label{eq:modele:recompence} +\end{equation} +Où $n^e$ est le nombre de message envoyé, emition initial et retransmission, et $n^t$ le nombre de transaction, c'est à dire uniquement les émitions initiales. +$n_\text{echec}$ est le nombre de transaction ayant échouée. +Les facteurs $\beta$ permetent de pondérer l'effet des différentes composante. + +\subsection{Quel type d'agent utilisé ?} +Maintenant que l'environement est fixé, on peut déterminer comment l'acteur va s'intégrer. +On choisit le fonctionement suivant : \begin{itemize} + \item L'acteur détermine $a_t$ en fonction de $s_t$, + \item les clients utilise cet $a_t$ pour trouver leur consigne $c_t$, + \item ils traitent toutes les transactions avec ses consigne pendant l'interval de control, + \item a la fin de l'interval de control, on fait la synthèse des données, on calcule $s_{t+1}$ et $r_t$, + \item on enregistre $\left( s_t, a_t, r_t, s_{t+1} \right)$, + \item on recommence avec $s_{t+1}$ +\end{itemize} +Cela represente le fonctionnement normal du système. + +Mais en plus de cela, il faut que l'on fasse s'optimisé la politique. +Pour cela on va procédé en deux temps : \begin{enumerate} + \item Le pré-entrainement, + \item l'entrainement en position. +\end{enumerate} +Le pré-entrainement se déroule avant le déploiment du réseau de capteur. +Il consiste à rendre la politique proche de ce qui est attendu pour que elle soit exploitable, même si elle n'est pas encore optimal. +Pour cela, il faut généré de l'expérience (les transitions $\left( s_t, a_t, r_t, s_{t+1} \right)$ que on a vu plus haut), et l'utilisé pour optimisé la politique. +Cette génération peut se faire de plusieur manière que on évoquera plus tard. +Une fois que la politique est correct, on peut la déployer sur le réseau de capteur réel. +Mais elle n'est pas fixe, puisque on continue à l'optimisé avec de l'exprérence récolté sur le réseau réel. + +\subsection{Quelle politique $\pi$ est utilisé ?} +Au vu de la taille des espaces $\mathbb{S}$ et $\mathbb{A}$, on ne peut pas utilisé un Q-table car elle demanderais bien trop d'espaces mémoire. +On utilise donc un réseau de neurrones pour approximé la Q-table. +Les subtilités de cette approximation, ainsi que la discretisation de $\mathbb{S}$ et $\mathbb{A}$ sont pris en charge par \TF{}. + +Puisque on est en apprentissage permanant, il faut utilisé une politique $\epsilon$-glouton. +C'est à dire que pendant la majorité du temps, on se trouve en phase d'exploitation, et on execute l'action optimal. +Mais avec une probabilité $\epsilon$, on réalise une action aléatoire, afin de tester de nouvelle possibilité. +C'est important car on ne se trouve pas dans un système déterministe, donc il ne suffit pas de tester une fois toutes les transitions. + +Pour ce qui est du réseau de neurrones, on ne travaille pour l'instant que avec un réseau feed-forward, mais on peut envisagé d'utilisé des réseaux plus complexes. + +\subsection{Comment récolté de l'expérience ?} + +La recolte de transition est indipensable pour pouvoir optimisé la politique. +La récolte in situ est lente, en effet, il faut généralement $10000$ transitions pour réalisé un pas d'optimisation. +On peut descendre jusqu'à $1000$, mais le résultats est moins stable. +De plus, avec une durée d'interval de controle de $30$s, on se retrouve à devoir attendre $8h$ par pas d'optimisation. +Il faut donc trouver des solutions plus rapide que l'exploration simple si on veux pouvoir faire une centaine de pas d'apprentissage pour atteindre une convergence. + +\subsubsection{Par exploration en simulateur} +Une solution simple, en théorie, est d'utilisé un simulateur. +Le plus utilisé est \ns{}. +C'est un simulateur à envenement discret, destiné à la simulation de réseau informatique permetant de travaillier sur toute les couches du modèle \osi{}. +Ainsi on peut entrainer le simulateur avec la topologie du réseau que l'on veux, et la qualité des connexions sans fils que l'on veux. +Malheureusment, c'est un simulateur complexe à utilisé : tout les scripts de simulation sont écrit en \cpp{}. +Par manque de temps et de compétence, je n'ais pas réalisé de simulation \ns{}, mais ca peut etre une piste à étudier pour le pré-entrainement. + +\subsubsection{Par création artificiel de transition} + +Une autre méthode possible est de créer des transitions artificiellement. +Pour cela, je commence par fixer une charge sur le réseau $f$, c'est à dire la fréquence à laquelle chaque client intéroge le capteur associé. +Celon cette charge, le réseau est plus ou moins congestioner. +Ensuite je prend plusieurs consigne de \rto{} $c_n$, et pour chaque consigne, je l'applique à l'agent, et je mesure le vecteur d'observation associé $s_n$ ainsi que $r_n$. +Puis pour chaque couple $(s_n, s_m)$, je calcule l'action $a_{n , m}$ pour passer de $c_n$ à $c_m$. +Je peu ainsi construire une série de trnasition $s_n, a_{n, m}, r_m, s_m$. +On recommence avec un autre $f$ + +Ces transitions sont uniquements des approximation, car elles ne tiennent pas réelement compte des effets de $s_t$ sur $s_{t+1}$ liée au temps de probagation des message dans le système. +De plus elles supposent que la charge ne change pas sur le système. +Malgrès cela, elle permet d'aller plus vite dans la génération de transition pour le pré-entrainement, car en $n$ interval de contrôl à $f$ fixe, on génère $n^2$ transitions. + +\section{Implémentation de l'algorithme} + +\subsection{Librairie uilisé} + +\subsubsection{\TF{} et \keras{}} + +\subsubsection{\coapthon{}} + +\subsection{Structure du code} + +\subsection{Maquette utilisée\label{part_maquette}} + +\subsection{Astuce pour simuler une congestion} + + +\section{Expérience et résultats} + +\subsection{Montage simple} + +\subsection{Multiplication des clients} + +\subsection{Multiplication des \rasp{}} + +\clearpage + +\section{Conclusion} +\lipsum[3] + +\clearpage + +\listoffigures + +\listoftables + + +% --- Biblio par .bib +\bibliography{rapport.bib} +%\bibliographystyle{plain-fr.bst} +%\selectlanguage{french} + +% --- Biblio écrite à la main +%\begin{thebibliography}{7} +%\bibitem[Bastien 2019]{id-de-la-source} +%Auteurs : \emph{Un titre}, une date. +%\end{thebibliography} + +% -------------------------------------------------------------- +% Appendices +% -------------------------------------------------------------- + +\clearpage + +\appendix +\begin{appendices} + + \section{Structure du code} + + \begin{landscape} + \begin{figure}[htp] + \centering + \includegraphics[height=\vsize, width=\hsize, keepaspectratio]{puml/call_stack_envoie.png} + \caption[Appel de fonction pour une transaction]{Appel de fontion pour une transaction avec \coapthon{} et mes modifications. Chaque couleur représente un thread d'execution.} + \end{figure} + \end{landscape} + +\end{appendices} + + +% -------------------------------------------------------------- +% Abstract +% -------------------------------------------------------------- +\pagebreak +\thispagestyle{empty} + +\vspace*{\fill} +\noindent\rule[2pt]{\textwidth}{0.5pt}\\ +{\textbf{Résumé :}} +\lipsum[1] + +{\noindent\textbf{Mots clés :}} +Insérez ici, des mots-clés, pour décrire, votre rapport. +\\ +\noindent\rule[2pt]{\textwidth}{0.5pt} +\begin{center} + \ens \\ + 4, avenue des Sciences\\ + 91190 Gif-sur-Yvette +\end{center} +\vspace*{\fill} + +\end{document}