{"id":9130,"date":"2026-10-14T18:02:27","date_gmt":"2026-10-14T18:02:27","guid":{"rendered":"http:\/\/french.arabpsychology.com\/statistics\/comment-calculer-fonction-sigmoide-python-exemples\/"},"modified":"2026-10-14T18:02:27","modified_gmt":"2026-10-14T18:02:27","slug":"comment-calculer-fonction-sigmoide-python-exemples","status":"publish","type":"psych_stat","link":"https:\/\/french.arabpsychology.com\/?psych_stat=comment-calculer-fonction-sigmoide-python-exemples","title":{"rendered":"Comment calculer une fonction sigmo\u00efde en Python (avec des exemples)"},"content":{"rendered":"<p>La mod\u00e9lisation math\u00e9matique des transitions continues, des probabilit\u00e9s conditionnelles et des dynamiques de saturation constitue l&rsquo;un des piliers de l&rsquo;analyse computationnelle moderne. Au c\u0153ur de cette d\u00e9marche se trouve la courbe logistique, commun\u00e9ment d\u00e9sign\u00e9e sous le nom de fonction sigmo\u00efde. Pr\u00e9sente aussi bien dans les mod\u00e8les d&rsquo;accroissement d\u00e9mographique con\u00e7us au XIXe si\u00e8cle que dans les architectures contemporaines de r\u00e9seaux de neurones profonds, la sigmo\u00efde op\u00e8re une transformation non lin\u00e9aire essentielle : elle comprime un continuum infini de valeurs r\u00e9elles dans un intervalle strictement born\u00e9 entre z\u00e9ro et un. Cette propri\u00e9t\u00e9 fondamentale en fait l&rsquo;outil d&rsquo;\u00e9lection pour convertir des scores lin\u00e9aires arbitraires en mesures de probabilit\u00e9 rigoureusement calibr\u00e9es.<\/p>\n<p>Dans l&rsquo;\u00e9cosyst\u00e8me de programmation <a rel=\"noopener noreferrer\" href=\"https:\/\/www.python.org\/\">Python<\/a>, devenu le standard de facto pour l&rsquo;ing\u00e9nierie des donn\u00e9es et l&rsquo;apprentissage automatique, le calcul de la fonction sigmo\u00efde semble \u00e0 premi\u00e8re vue trivial. Une simple ligne de code transcrivant la formule analytique standard semble suffire. Pourtant, la r\u00e9alit\u00e9 du calcul num\u00e9rique haute performance impose des exigences bien plus strictes. Entre les ph\u00e9nom\u00e8nes d&rsquo;\u00e9vanescence du gradient, les risques de d\u00e9passement de capacit\u00e9 arithm\u00e9tique (d\u00e9passement sup\u00e9rieur ou inf\u00e9rieur en virgule flottante sous la norme IEEE 754), et les imp\u00e9ratifs d&rsquo;acc\u00e9l\u00e9ration vectorielle sur de volumineux ensembles de donn\u00e9es, le choix de l&rsquo;impl\u00e9mentation algorithmique rev\u00eat une importance capitale pour la stabilit\u00e9 et l&rsquo;efficience des syst\u00e8mes logiciels.<\/p>\n<p>Ce guide exhaustif propose une exploration th\u00e9orique, algorithmique et pratique du calcul de la fonction sigmo\u00efde en Python. Nous aborderons ses fondements math\u00e9matiques rigoureux avant de diss\u00e9quer ses diverses impl\u00e9mentations, depuis les approches scalaires manuelles via la biblioth\u00e8que standard jusqu&rsquo;aux optimisations bas niveau offertes par <a rel=\"noopener noreferrer\" href=\"https:\/\/scipy.org\/\">SciPy<\/a> et <a rel=\"noopener noreferrer\" href=\"https:\/\/numpy.org\/\">NumPy<\/a>. Enfin, nous examinerons son d\u00e9ploiement \u00e0 grande \u00e9chelle au sein des cadriciels modernes d&rsquo;apprentissage profond tels que <a rel=\"noopener noreferrer\" href=\"https:\/\/pytorch.org\/\">PyTorch<\/a> et <a rel=\"noopener noreferrer\" href=\"https:\/\/www.tensorflow.org\/\">TensorFlow<\/a>, en accordant une attention m\u00e9ticuleuse \u00e0 la stabilit\u00e9 num\u00e9rique, au profilage des performances et aux cas d&rsquo;usage industriels r\u00e9els.<\/p>\n<figure class=\"wpt-preserved-image\"><img fetchpriority=\"high\" decoding=\"async\" src=\"http:\/\/french.arabpsychology.com\/wp-content\/uploads\/2026\/09\/sigmoid_python.jpg\" alt=\"sigmoid function in Python\" \/><figcaption>sigmoid function in Python<\/figcaption><\/figure>\n<h2>1. Fondements math\u00e9matiques et th\u00e9oriques de la fonction sigmo\u00efde<\/h2>\n<h3>1.1 D\u00e9finition formelle et \u00e9quation logistique standard<\/h3>\n<p>D&rsquo;un point de vue analytique, la fonction sigmo\u00efde standard, couramment qualifi\u00e9e de fonction logistique, est une fonction r\u00e9elle d&rsquo;une variable r\u00e9elle d\u00e9finie sur l&rsquo;ensemble complet des r\u00e9els <span class=\"arabpsy-math-inline\" data-latex=\"\\mathbb{R}\">$\\mathbb{R}$<\/span> et \u00e0 valeurs dans l&rsquo;intervalle ouvert <span class=\"arabpsy-math-inline\" data-latex=\"]0, 1[\">$]0, 1[$<\/span>. Son expression analytique canonique est formul\u00e9e comme suit :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"F(x) = \\frac{1}{1 + e^{-x}} = \\frac{e^x}{e^x + 1}\">$$F(x) = \\frac{1}{1 + e^{-x}} = \\frac{e^x}{e^x + 1}$$<\/span><\/p>\n<p>Cette expression engendre une courbe caract\u00e9ristique en forme de \u00ab S \u00bb (d&rsquo;o\u00f9 son \u00e9tymologie issue de la lettre grecque sigma). La transition progressive entre les r\u00e9gimes asymptotiques conf\u00e8re \u00e0 cette fonction une g\u00e9om\u00e9trie d&rsquo;une grande r\u00e9gularit\u00e9. L&rsquo;un des traits structurels les plus d\u00e9terminants de cette fonction r\u00e9side dans sa sym\u00e9trie centrale parfaite autour de son point d&rsquo;inflexion situ\u00e9 aux coordonn\u00e9es <span class=\"arabpsy-math-inline\" data-latex=\"(0, 0{,}5)\">$(0, 0{,}5)$<\/span>. Alg\u00e9briquement, cette propri\u00e9t\u00e9 se traduit par l&rsquo;identit\u00e9 remarquable <span class=\"arabpsy-math-inline\" data-latex=\"F(-x) = 1 - F(x)\">$F(-x) = 1 &#8211; F(x)$<\/span> pour tout r\u00e9el <span class=\"arabpsy-math-inline\" data-latex=\"x\">$x$<\/span>. Cette relation d&rsquo;invariance par rapport au centre de sym\u00e9trie simplifie grandement les calculs analytiques et les optimisations logicielles.<\/p>\n<p>Il importe de distinguer rigoureusement la fonction logistique d&rsquo;autres fonctions sigmo\u00efdales classiques appartenant \u00e0 la m\u00eame famille topologique. Par exemple, la tangente hyperbolique (<span class=\"arabpsy-math-inline\" data-latex=\"tanh\">$tanh$<\/span>) projette l&rsquo;espace r\u00e9el sur l&rsquo;intervalle ouvert <span class=\"arabpsy-math-inline\" data-latex=\"]-1, 1[\">$]-1, 1[$<\/span> et se trouve li\u00e9e \u00e0 la logistique standard par la transformation affine <span class=\"arabpsy-math-inline\" data-latex=\"tanh(x) = 2F(2x) - 1\">$tanh(x) = 2F(2x) &#8211; 1$<\/span>. De m\u00eame, la fonction arc-tangente (<span class=\"arabpsy-math-inline\" data-latex=\"arctan\">$arctan$<\/span>) ou la fonction alg\u00e9brique <span class=\"arabpsy-math-inline\" data-latex=\"x \/ \\sqrt{1 + x^2}\">$x \/ \\sqrt{1 + x^2}$<\/span> g\u00e9n\u00e8rent des courbes en esse, mais pr\u00e9sentent des vitesses de convergence asymptotique polynomiales nettement plus lentes que la convergence exponentielle stricte r\u00e9gie par le terme <span class=\"arabpsy-math-inline\" data-latex=\"e^{-x}\">$e^{-x}$<\/span>.<\/p>\n<h3>1.2 Propri\u00e9t\u00e9s analytiques et comportement asymptotique<\/h3>\n<p>L&rsquo;analyse infinit\u00e9simale de la fonction logistique r\u00e9v\u00e8le des propri\u00e9t\u00e9s de r\u00e9gularit\u00e9 remarquables. La fonction est ind\u00e9finiment d\u00e9rivable sur son domaine de d\u00e9finition, ce qui la classe dans l&rsquo;espace des fonctions lisses <span class=\"arabpsy-math-inline\" data-latex=\"\\mathcal{C}^\\infty(\\mathbb{R})\">$\\mathcal{C}^\\infty(\\mathbb{R})$<\/span>. Son comportement aux limites constitue le socle de sa robustesse pour la normalisation de grandeurs physiques ou probabilistes :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\lim_{x to -\\infty} F(x) = 0 \\quad \\text{et} \\quad \\lim_{x to +\\infty} F(x) = 1\">$$\\lim_{x to -\\infty} F(x) = 0 \\quad \\text{et} \\quad \\lim_{x to +\\infty} F(x) = 1$$<\/span><\/p>\n<p>Cette convergence asymptotique bilat\u00e9rale garantit une stricte monotonicit\u00e9 croissante, dans la mesure o\u00f9 sa d\u00e9riv\u00e9e premi\u00e8re demeure strictement positive pour toute valeur finie de l&rsquo;argument <span class=\"arabpsy-math-inline\" data-latex=\"x\">$x$<\/span>. Le taux de variation instantan\u00e9 atteint son maximum absolu pr\u00e9cis\u00e9ment au point d&rsquo;inflexion <span class=\"arabpsy-math-inline\" data-latex=\"x = 0\">$x = 0$<\/span>, o\u00f9 la pente de la tangente vaut exactement <span class=\"arabpsy-math-inline\" data-latex=\"0{,}25\">$0{,}25$<\/span>. \u00c0 mesure que l&rsquo;on s&rsquo;\u00e9loigne de l&rsquo;origine vers les r\u00e9gions extr\u00eames du domaine r\u00e9el, la pente d\u00e9cro\u00eet exponentiellement vers z\u00e9ro, engendrant des plateaux de saturation o\u00f9 la fonction devient quasi insensible aux variations incr\u00e9mentales de la variable explicative.<\/p>\n<p>Cette dynamique de saturation asymptotique joue un r\u00f4le protecteur contre les valeurs aberrantes (outliers) dans les mod\u00e8les statistiques, en \u00e9vitant qu&rsquo;une observation extr\u00eame ne d\u00e9forme excessivement le signal global. En contrepartie, cette m\u00eame caract\u00e9ristique pose des d\u00e9fis computationnels majeurs lors de l&rsquo;application d&rsquo;algorithmes d&rsquo;optimisation bas\u00e9s sur le calcul diff\u00e9rentiel, en raison de l&rsquo;\u00e9crasement des gradients dans les zones \u00e9loign\u00e9es de l&rsquo;origine.<\/p>\n<h3>1.3 R\u00f4le de la fonction dans la mod\u00e9lisation math\u00e9matique et cognitive<\/h3>\n<p>Historiquement formul\u00e9e par le math\u00e9maticien belge <a rel=\"noopener noreferrer\" href=\"https:\/\/en.wikipedia.org\/wiki\/Pierre_Fran%C3%A7ois_Verhulst\">Pierre-Fran\u00e7ois Verhulst<\/a> dans ses m\u00e9moires publi\u00e9s entre 1838 et 1845 pour d\u00e9crire l&rsquo;accroissement continu des populations confront\u00e9es \u00e0 des ressources limit\u00e9es, la sigmo\u00efde s&rsquo;est impos\u00e9e bien au-del\u00e0 de l&rsquo;\u00e9cologie quantitative. En psychophysique et en sciences cognitives, elle mod\u00e9lise avec fid\u00e9lit\u00e9 la loi de transition perceptuelle entre l&rsquo;absence de d\u00e9tection et la perception consciente d&rsquo;un stimulus sensoriel. Les travaux fondamentaux de Gustav Fechner et les mod\u00e8les psychophysiques modernes exploitent cette courbe pour d\u00e9crire la fonction psychom\u00e9trique, liant l&rsquo;intensit\u00e9 physique continue d&rsquo;une stimulation \u00e0 la fr\u00e9quence d&rsquo;activation des potentiels d&rsquo;action au sein des r\u00e9seaux neuronaux corticaux.<\/p>\n<p>Dans le domaine de la psychom\u00e9trie contemporaine et de la docimologie, la sigmo\u00efde logistique constitue la pierre angulaire de la <a rel=\"noopener noreferrer\" href=\"https:\/\/en.wikipedia.org\/wiki\/Item_response_theory\">th\u00e9orie de r\u00e9ponse aux items<\/a> (mod\u00e8le de Rasch \u00e0 un ou plusieurs param\u00e8tres). Elle permet d&rsquo;\u00e9tablir une correspondance math\u00e9matiquement coh\u00e9rente entre une variable latente inobservable (telle que l&rsquo;aptitude cognitive d&rsquo;un individu ou l&rsquo;intensit\u00e9 d&rsquo;un trait de personnalit\u00e9) et la probabilit\u00e9 empirique d&rsquo;observer une r\u00e9ponse positive \u00e0 une \u00e9preuve donn\u00e9e.<\/p>\n<p>Cette conversion d&rsquo;une \u00e9chelle sous-jacente infinie en probabilit\u00e9s d&rsquo;occurrence strictement comprises entre 0 et 1 fait le pont naturel entre la mod\u00e9lisation th\u00e9orique des processus d\u00e9cisionnels et la formalisation statistique du choix binaire dans les architectures de calcul modernes.<\/p>\n<h2>2. Environnement de d\u00e9veloppement Python et pr\u00e9requis techniques<\/h2>\n<h3>2.1 Configuration de l&rsquo;interpr\u00e9teur Python et gestion des d\u00e9pendances<\/h3>\n<p>Pour ex\u00e9cuter et analyser les diff\u00e9rentes d\u00e9clinaisons algorithmiques de la fonction sigmo\u00efde, il est imp\u00e9ratif d&rsquo;\u00e9tablir un environnement d&rsquo;ex\u00e9cution stable et reproductible. Nous pr\u00e9conisons l&rsquo;usage de Python en version 3.8 ou sup\u00e9rieure, les versions ant\u00e9rieures ne b\u00e9n\u00e9ficiant plus du support de s\u00e9curit\u00e9 officiel de la <a rel=\"noopener noreferrer\" href=\"https:\/\/www.python.org\/psf\/\">Python Software Foundation<\/a> et pr\u00e9sentant des disparit\u00e9s potentielles dans l&rsquo;optimisation des biblioth\u00e8ques C sous-jacentes. L&rsquo;isolation des d\u00e9pendances logicielles garantit l&rsquo;int\u00e9grit\u00e9 de l&rsquo;environnement syst\u00e8me et pr\u00e9vient les conflits entre versions binaires compil\u00e9es.<\/p>\n<p>L&rsquo;initialisation d&rsquo;un environnement virtuel standard s&rsquo;effectue via le terminal \u00e0 l&rsquo;aide des commandes fondamentales de l&rsquo;interpr\u00e9teur :<\/p>\n<p>python3 -m venv env_sigmoide<br \/>source env_sigmoide\/bin\/activate<\/p>\n<p>Sous les syst\u00e8mes d&rsquo;exploitation Windows, l&rsquo;activation s&rsquo;op\u00e8re par le script <code>.env_sigmoideScriptsactivate<\/code>. Une fois l&rsquo;environnement isol\u00e9 activ\u00e9, il convient de proc\u00e9der \u00e0 l&rsquo;installation des paquets n\u00e9cessaires au calcul num\u00e9rique, \u00e0 la mod\u00e9lisation avanc\u00e9e et au rendu visuel. L&rsquo;utilisation du gestionnaire de paquets <code>pip<\/code> permet de d\u00e9ployer de mani\u00e8re d\u00e9terministe les modules de r\u00e9f\u00e9rence :<\/p>\n<p>pip install &#8211;upgrade pip<br \/>pip install numpy scipy matplotlib<\/p>\n<p>Il est recommand\u00e9 de consigner explicitement les versions install\u00e9es au sein d&rsquo;un fichier <code>requirements.txt<\/code> afin de garantir la portabilit\u00e9 stricte des analyses pr\u00e9sent\u00e9es \u00e0 travers diff\u00e9rents syst\u00e8mes informatiques.<\/p>\n<h3>2.2 Pr\u00e9sentation de l&rsquo;\u00e9cosyst\u00e8me scientifique<\/h3>\n<p>Le traitement des calculs math\u00e9matiques en Python repose sur une stratification logicielle optimis\u00e9e, articul\u00e9e autour de trois piliers principaux :<\/p>\n<ul>\n<li><strong>Le module standard math :<\/strong> Fourni nativement avec l&rsquo;interpr\u00e9teur CPython, il expose directement en Python les fonctions de la biblioth\u00e8que math\u00e9matique C standard (<code>libm<\/code>). Il op\u00e8re exclusivement sur des types scalaires natifs (flottants et entiers) et ne requiert aucune d\u00e9pendance tierce.<\/li>\n<li><strong>NumPy (Numerical Python) :<\/strong> Constitue le socle fondamental du calcul scientifique matriciel. En encapsulant des structures de donn\u00e9es contigu\u00ebs en m\u00e9moire (<code>ndarray<\/code>) \u00e9crites en C et Fortran, il autorise l&rsquo;ex\u00e9cution d&rsquo;op\u00e9rations vectoris\u00e9es hautement parall\u00e9lisables sans subir le surco\u00fbt d&rsquo;interpr\u00e9tation des boucles Python.<\/li>\n<li><strong>SciPy (Scientific Python) :<\/strong> B\u00e2ti au-dessus de NumPy, SciPy regroupe des algorithmes sp\u00e9cialis\u00e9s pour l&rsquo;optimisation, l&rsquo;int\u00e9gration num\u00e9rique et les statistiques. Son sous-module <code>scipy.special<\/code> contient des impl\u00e9mentations de niveau industriel de fonctions transcendantes et sp\u00e9ciales, con\u00e7ues pour pr\u00e9server la pr\u00e9cision analytique aux limites du domaine de calcul.<\/li>\n<\/ul>\n<h3>2.3 Pr\u00e9cision num\u00e9rique et repr\u00e9sentation des nombres \u00e0 virgule flottante<\/h3>\n<p>La mise en \u0153uvre logicielle de fonctions exponentielles n\u00e9cessite une compr\u00e9hension rigoureuse du standard de calcul en virgule flottante <a rel=\"noopener noreferrer\" href=\"https:\/\/en.wikipedia.org\/wiki\/IEEE_754\">IEEE 754<\/a>, impl\u00e9ment\u00e9 par les types flottants natifs de Python (repr\u00e9sent\u00e9s en double pr\u00e9cision sur 64 bits). Dans cette norme, un nombre flottant se compose de trois segments binaires distincts : un bit de signe, 11 bits d&rsquo;exposant biais\u00e9 et 52 bits de fraction (ou mantisse effective), fournissant approximativement 15 \u00e0 17 chiffres d\u00e9cimaux significatifs.<\/p>\n<p>L&rsquo;\u00e9valuation num\u00e9rique de l&rsquo;expression <span class=\"arabpsy-math-inline\" data-latex=\"e^{-x}\">$e^{-x}$<\/span> se heurte \u00e0 des contraintes physiques fondamentales dict\u00e9es par l&rsquo;intervalle dynamique des nombres repr\u00e9sentables. En double pr\u00e9cision standard, le plus grand exposant positif calculable avant d\u00e9passement de capacit\u00e9 (overflow) s&rsquo;\u00e9l\u00e8ve \u00e0 approximativement <span class=\"arabpsy-math-inline\" data-latex=\"\\ln(1{,}79769 \\times 10^{308}) \\approx 709{,}78\">$\\ln(1{,}79769 \\times 10^{308}) \\approx 709{,}78$<\/span>. Inversement, toute tentative d&rsquo;\u00e9valuation d&rsquo;un terme exponentiel n\u00e9gatif dont l&rsquo;amplitude exc\u00e8de <span class=\"arabpsy-math-inline\" data-latex=\"-745{,}13\">$-745{,}13$<\/span> provoque un sous-d\u00e9passement arithm\u00e9tique (underflow), tronquant purement et simplement le r\u00e9sultat \u00e0 z\u00e9ro absolu (<span class=\"arabpsy-math-inline\" data-latex=\"0{,}0\">$0{,}0$<\/span>).<\/p>\n<p>Par cons\u00e9quent, l&rsquo;\u00e9valuation na\u00efve de la fonction sigmo\u00efde sur des r\u00e9els tr\u00e8s n\u00e9gatifs (par exemple <span class=\"arabpsy-math-inline\" data-latex=\"x = -1000\">$x = -1000$<\/span>) impose le calcul de <span class=\"arabpsy-math-inline\" data-latex=\"e^{-(-1000)} = e^{1000}\">$e^{-(-1000)} = e^{1000}$<\/span>, ce qui surpasse instantan\u00e9ment les capacit\u00e9s de la mantisse mat\u00e9rielle et d\u00e9clenche des exceptions arithm\u00e9tiques ou la production de valeurs sp\u00e9ciales infinies (<code>inf<\/code>). La validation rigoureuse des algorithmes requiert donc la mise en place de crit\u00e8res de tol\u00e9rance relative (<code>rtol<\/code>) et absolue (<code>atol<\/code>), garantissant que l&rsquo;invariance math\u00e9matique th\u00e9orique est respect\u00e9e au sein des marges de pr\u00e9cision machine (la constante <span class=\"arabpsy-math-inline\" data-latex=\"epsilon\">$epsilon$<\/span> valant approximativement <span class=\"arabpsy-math-inline\" data-latex=\"2{,}22 \\times 10^{-16}\">$2{,}22 \\times 10^{-16}$<\/span>).<\/p>\n<h2>3. Calcul scalaire \u00e9l\u00e9mentaire avec la biblioth\u00e8que standard Python<\/h2>\n<h3>3.1 Impl\u00e9mentation manuelle avec le module math<\/h3>\n<p>L&rsquo;approche la plus intuitive pour \u00e9valuer la fonction sigmo\u00efde sans introduire de d\u00e9pendances externes consiste \u00e0 mobiliser la fonction exponentielle <code>math.exp<\/code> pr\u00e9sente dans le module standard de Python. Cette fonction fait office de passerelle directe vers la fonction <code>exp()<\/code> de la biblioth\u00e8que standard C du syst\u00e8me h\u00f4te, garantissant une ex\u00e9cution rapide pour les scalaires individuels.<\/p>\n<p>L&rsquo;impl\u00e9mentation algorithmique se structure en d\u00e9composant scrupuleusement la formule analytique \u00e9l\u00e9mentaire :<\/p>\n<p>import math<\/p>\n<p>def sigmoide_scalaire(x):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;neg_x = -x<br \/>&nbsp;&nbsp;&nbsp;&nbsp;exp_val = math.exp(neg_x)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;resultat = 1.0 \/ (1.0 + exp_val)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;return resultat<\/p>\n<p>Sur le plan du flux d&rsquo;ex\u00e9cution s\u00e9quentiel, l&rsquo;interpr\u00e9teur commence par \u00e9valuer la n\u00e9gation unaire de l&rsquo;argument scalaire. La valeur r\u00e9sultante est ensuite transmise \u00e0 la routine de calcul transcendant <code>math.exp<\/code>, qui applique des approximations polynomiales de Tchebychev ou des fractions continues de Pad\u00e9 selon l&rsquo;architecture du processeur. Une fois la valeur interm\u00e9diaire obtenue, l&rsquo;interpr\u00e9teur alloue un flottant repr\u00e9sentant l&rsquo;addition unitaire du d\u00e9nominateur, avant de r\u00e9aliser la division en virgule flottante finale. Ce flux s\u00e9quentiel simple permet une compr\u00e9hension transparente de chaque \u00e9tape du calcul.<\/p>\n<h3>3.2 Exemple pratique : \u00e9valuation pour une valeur unique<\/h3>\n<p>Afin d&rsquo;examiner le comportement concret de cette impl\u00e9mentation unitaire, nous proc\u00e9dons \u00e0 l&rsquo;\u00e9valuation num\u00e9rique pas \u00e0 pas pour un point scalaire arbitraire, par exemple <span class=\"arabpsy-math-inline\" data-latex=\"x = 2{,}5\">$x = 2{,}5$<\/span>.<\/p>\n<p>D\u00e9composons les op\u00e9rations \u00e9l\u00e9mentaires ex\u00e9cut\u00e9es par l&rsquo;interpr\u00e9teur :<\/p>\n<ul>\n<li>\u00c9tape 1 : Calcul de l&rsquo;oppos\u00e9 de la variable d&rsquo;entr\u00e9e : <span class=\"arabpsy-math-inline\" data-latex=\"-x = -2{,}5\">$-x = -2{,}5$<\/span>.<\/li>\n<li>\u00c9tape 2 : \u00c9valuation du terme exponentiel n\u00e9gatif : <span class=\"arabpsy-math-inline\" data-latex=\"e^{-2{,}5} \\approx 0{,}0820849986238988\">$e^{-2{,}5} \\approx 0{,}0820849986238988$<\/span>.<\/li>\n<li>\u00c9tape 3 : Calcul du d\u00e9nominateur logistique : <span class=\"arabpsy-math-inline\" data-latex=\"1{,}0 + 0{,}0820849986238988 = 1{,}0820849986238988\">$1{,}0 + 0{,}0820849986238988 = 1{,}0820849986238988$<\/span>.<\/li>\n<li>\u00c9tape 4 : Inversion finale : <span class=\"arabpsy-math-inline\" data-latex=\"\\frac{1{,}0}{1{,}0820849986238988} \\approx 0{,}9241418199787566\">$\\frac{1{,}0}{1{,}0820849986238988} \\approx 0{,}9241418199787566$<\/span>.<\/li>\n<\/ul>\n<p>Ce r\u00e9sultat th\u00e9orique peut \u00eatre valid\u00e9 imm\u00e9diatement dans un script Python en int\u00e9grant des v\u00e9rifications d&rsquo;int\u00e9grit\u00e9 strictes :<\/p>\n<p>valeur_entree = 2.5<br \/>valeur_calculee = sigmoide_scalaire(valeur_entree)<br \/>valeur_attendue = 0.9241418199787566<\/p>\n<p>assert math.isclose(valeur_calculee, valeur_attendue, rel_tol=1e-15), \u00ab\u00a0\u00c9chec de validation de la pr\u00e9cision scalaire\u00a0\u00bb<br \/>print(\u00ab\u00a0R\u00e9sultat obtenu pour x=2.5 :\u00a0\u00bb, valeur_calculee)<\/p>\n<p>L&rsquo;ex\u00e9cution confirme que la fonction native restitue une pr\u00e9cision remarquable sur des arguments mod\u00e9r\u00e9s, respectant scrupuleusement les exigences des calculs d\u00e9terministes.<\/p>\n<h3>3.3 Limites de la biblioth\u00e8que standard pour le calcul scientifique<\/h3>\n<p>Malgr\u00e9 sa limpidit\u00e9 et sa disponibilit\u00e9 universelle, l&rsquo;impl\u00e9mentation bas\u00e9e sur le module standard <code>math<\/code> pr\u00e9sente des lacunes r\u00e9dhibitoires pour un usage professionnel en science des donn\u00e9es. En premier lieu, elle souffre d&rsquo;une absence cong\u00e9nitale de vectorisation. Si l&rsquo;on souhaite appliquer cette fonction \u00e0 un jeu de donn\u00e9es contenant des millions d&rsquo;observations, l&rsquo;utilisateur est contraint d&rsquo;it\u00e9rer explicitement via des structures de contr\u00f4le de type <code>for<\/code> ou des compr\u00e9hensions de listes. Ce mode de traitement it\u00e9ratif induit un surco\u00fbt logiciel colossal li\u00e9 \u00e0 l&rsquo;encapsulation dynamique des objets flottants en m\u00e9moire (le m\u00e9canisme de <em>boxing\/unboxing<\/em> des objets <code>PyObject<\/code>) et au dispatch dynamique du bytecode par la machine virtuelle CPython.<\/p>\n<p>En second lieu, cette fonction native se r\u00e9v\u00e8le extr\u00eamement vuln\u00e9rable aux anomalies num\u00e9riques. Lorsque l&rsquo;argument <span class=\"arabpsy-math-inline\" data-latex=\"x\">$x$<\/span> prend une valeur n\u00e9gative substantielle, par exemple <span class=\"arabpsy-math-inline\" data-latex=\"x = -800\">$x = -800$<\/span>, le terme <span class=\"arabpsy-math-inline\" data-latex=\"-x\">$-x$<\/span> devient <span class=\"arabpsy-math-inline\" data-latex=\"+800\">$+800$<\/span>. Lors de l&rsquo;\u00e9valuation de <code>math.exp(800)<\/code>, l&rsquo;interpr\u00e9teur CPython constate l&rsquo;incapacit\u00e9 mat\u00e9rielle de stocker ce nombre et interrompt brutalement l&rsquo;ex\u00e9cution du programme en levant une exception bloquante :<\/p>\n<p>OverflowError: math range error<\/p>\n<p>Cette incapacit\u00e9 structurelle \u00e0 traiter gracieusement les cas limites sans provoquer de d\u00e9faillance fatale disqualifie l&rsquo;approche scalaire standard pour les pipelines de production automatis\u00e9s manipulant des donn\u00e9es non normalis\u00e9es.<\/p>\n<h2>4. Calcul optimis\u00e9 avec SciPy et la fonction expit<\/h2>\n<h3>4.1 Architecture et avantages de scipy.special.expit<\/h3>\n<p>Pour surmonter les limitations intrins\u00e8ques des impl\u00e9mentations manuelles, la biblioth\u00e8que scientifique SciPy met \u00e0 disposition une routine hautement sp\u00e9cialis\u00e9e au sein de son sous-module <code>scipy.special<\/code> : la fonction <a rel=\"noopener noreferrer\" href=\"https:\/\/docs.scipy.org\/doc\/scipy\/reference\/generated\/scipy.special.expit.html\">expit<\/a>. Le vocable <em>expit<\/em> constitue le terme technique universellement employ\u00e9 en biostatistique pour d\u00e9signer la fonction logistique standard, formalis\u00e9e comme l&rsquo;inverse direct de la fonction logit (<span class=\"arabpsy-math-inline\" data-latex=\"\\text{logit}(p) = \\ln(p \/ (1 - p))\">$\\text{logit}(p) = \\ln(p \/ (1 &#8211; p))$<\/span>).<\/p>\n<p>L&rsquo;architecture interne de <code>expit<\/code> repose sur des routines \u00e9crites directement en langage C, issues historiquement de la c\u00e9l\u00e8bre biblioth\u00e8que math\u00e9matique <a rel=\"noopener noreferrer\" href=\"https:\/\/www.netlib.org\/cephes\/\">Cephes<\/a> d\u00e9velopp\u00e9e par Stephen L. Moshier. Contrairement \u00e0 une simple transcription de la formule classique, <code>expit<\/code> int\u00e8gre des m\u00e9canismes d&rsquo;\u00e9valuation conditionnelle et des approximations par fractions rationnelles qui emp\u00eachent syst\u00e9matiquement l&rsquo;apparition de d\u00e9bordements arithm\u00e9tiques, tout en assurant une vitesse d&rsquo;ex\u00e9cution proche des limites th\u00e9oriques du processeur h\u00f4te. Elle est nativement con\u00e7ue pour accepter aussi bien des scalaires que des structures de donn\u00e9es multidimensionnelles complexes.<\/p>\n<h3>4.2 Exemple pratique : calcul pour un point scalaire unique<\/h3>\n<p>L&rsquo;utilisation de la fonction <code>expit<\/code> se caract\u00e9rise par une grande concision syntaxique. Son importation et son \u00e9valuation scalaire s&rsquo;effectuent sans aucune configuration pr\u00e9liminaire :<\/p>\n<p>from scipy.special import expit<\/p>\n<p>point_evaluation = 2.5<br \/>resultat_scipy = expit(point_evaluation)<\/p>\n<p>print(\u00ab\u00a0R\u00e9sultat calcul\u00e9 par scipy.special.expit :\u00a0\u00bb, resultat_scipy)<\/p>\n<p>Le r\u00e9sultat obtenu est rigoureusement identique \u00e0 la valeur de r\u00e9f\u00e9rence <span class=\"arabpsy-math-inline\" data-latex=\"0{,}9241418199787566\">$0{,}9241418199787566$<\/span>. Au-del\u00e0 de cette conformit\u00e9 analytique, c&rsquo;est sur le plan des performances temporelles et de la r\u00e9silience logicielle que la fonction se d\u00e9marque. M\u00eame sur une valeur scalaire isol\u00e9e, le fait d&rsquo;ex\u00e9cuter un code C pr\u00e9compil\u00e9 permet d&rsquo;\u00e9liminer la surcharge inh\u00e9rente aux op\u00e9rations interm\u00e9diaires de n\u00e9gation, d&rsquo;addition et de division dans la machine virtuelle Python.<\/p>\n<p>Une analyse comparative du temps de traitement au moyen du module <code>timeit<\/code> d\u00e9montre que l&rsquo;appel direct \u00e0 <code>expit<\/code> offre une stabilit\u00e9 d&rsquo;ex\u00e9cution sup\u00e9rieure face aux variations de l&rsquo;\u00e9tat de l&rsquo;interpr\u00e9teur, constituant la solution de r\u00e9f\u00e9rence pour les calculs de haute pr\u00e9cision.<\/p>\n<h3>4.3 Comportement de expit face aux cas limites scalaires<\/h3>\n<p>L&rsquo;un des atouts pr\u00e9\u00e9minents de <code>scipy.special.expit<\/code> r\u00e9side dans sa gestion intrins\u00e8que des cas limites et des valeurs aberrantes. Alors que la formule na\u00efve provoque des pannes logicielles, <code>expit<\/code> r\u00e9agit de fa\u00e7on continue et d\u00e9terministe conform\u00e9ment aux r\u00e8gles de fermeture de l&rsquo;arithm\u00e9tique flottante :<\/p>\n<ul>\n<li><strong>Origine exacte (<span class=\"arabpsy-math-inline\" data-latex=\"x = 0{,}0\">$x = 0{,}0$<\/span>) :<\/strong> L&rsquo;\u00e9valuation <code>expit(0.0)<\/code> retourne rigoureusement <span class=\"arabpsy-math-inline\" data-latex=\"0{,}5\">$0{,}5$<\/span>, respectant le centre de sym\u00e9trie avec une exactitude bit-\u00e0-bit sans la moindre d\u00e9rive d&rsquo;arrondi.<\/li>\n<li><strong>Valeurs positives massives (<span class=\"arabpsy-math-inline\" data-latex=\"x ge 500\">$x ge 500$<\/span>) :<\/strong> Lorsque l&rsquo;on \u00e9value <code>expit(1000.0)<\/code>, la fonction n&rsquo;essuie aucun dysfonctionnement. Le terme exponentiel <span class=\"arabpsy-math-inline\" data-latex=\"e^{-1000}\">$e^{-1000}$<\/span> \u00e9tant infinit\u00e9simalement n\u00e9gligeable devant <span class=\"arabpsy-math-inline\" data-latex=\"1{,}0\">$1{,}0$<\/span>, la routine sature de mani\u00e8re fluide et renvoie exactement la valeur flottante <span class=\"arabpsy-math-inline\" data-latex=\"1{,}0\">$1{,}0$<\/span>.<\/li>\n<li><strong>Valeurs n\u00e9gatives massives (<span class=\"arabpsy-math-inline\" data-latex=\"x le -500\">$x le -500$<\/span>) :<\/strong> Soumis \u00e0 l&rsquo;argument critique <code>expit(-1000.0)<\/code> \u2014 qui d\u00e9clenchait pr\u00e9c\u00e9demment une exception bloquante <code>OverflowError<\/code> avec <code>math.exp<\/code> \u2014 l&rsquo;algorithme sous-jacent de SciPy contourne le calcul direct de <span class=\"arabpsy-math-inline\" data-latex=\"e^{1000}\">$e^{1000}$<\/span>. Il identifie instantan\u00e9ment la r\u00e9gion de saturation inf\u00e9rieure et retourne imm\u00e9diatement le flottant r\u00e9gulier <span class=\"arabpsy-math-inline\" data-latex=\"0{,}0\">$0{,}0$<\/span>.<\/li>\n<li><strong>Non-nombres et infinis :<\/strong> Transmis avec la valeur <code>float('inf')<\/code>, il renvoie <span class=\"arabpsy-math-inline\" data-latex=\"1{,}0\">$1{,}0$<\/span> ; avec <code>float('-inf')<\/code>, il restitue <span class=\"arabpsy-math-inline\" data-latex=\"0{,}0\">$0{,}0$<\/span> ; et avec une valeur ind\u00e9termin\u00e9e <code>float('nan')<\/code>, il propage proprement un r\u00e9sultat <code>nan<\/code>, conform\u00e9ment \u00e0 la norme IEEE 754.<\/li>\n<\/ul>\n<h2>5. Calcul de la fonction sigmo\u00efde sur des ensembles de donn\u00e9es multiples<\/h2>\n<h3>5.1 Traitement de collections s\u00e9quentielles et de listes<\/h3>\n<p>Dans la pratique courante du traitement de donn\u00e9es, les valeurs ne sont que tr\u00e8s rarement isol\u00e9es ; elles se pr\u00e9sentent sous forme de collections s\u00e9quentielles, telles que des listes natives Python, des s\u00e9ries temporelles ou des colonnes d&rsquo;\u00e9chantillons statistiques. L&rsquo;application d&rsquo;une fonction sigmo\u00efde scalaire \u00e0 une liste ordinaire exigeait traditionnellement la formulation de compr\u00e9hensions de listes :<\/p>\n<p>donnees_brutes = [-2.0, -1.0, 0.0, 1.0, 2.0]<br \/>resultats_liste = [sigmoide_scalaire(val) for val in donnees_brutes]<\/p>\n<p>Cette approche pr\u00e9sente une double inefficacit\u00e9 : une empreinte m\u00e9moire dispers\u00e9e due \u00e0 la nature h\u00e9t\u00e9rog\u00e8ne des listes Python (qui stockent des pointeurs vers des objets flottants fragment\u00e9s en m\u00e9moire tas), et une ex\u00e9cution purement s\u00e9quentielle. \u00c0 l&rsquo;inverse, <code>scipy.special.expit<\/code> impl\u00e9mente le protocole de typage dynamique universel de NumPy. D\u00e8s lors qu&rsquo;une collection standard lui est transmise, elle effectue une conversion transparente de la structure de donn\u00e9es vers un tampon contigu de m\u00e9moire num\u00e9rique et ex\u00e9cute le traitement \u00e0 la vitesse native du processeur, restituant instantan\u00e9ment un tableau optimis\u00e9 de r\u00e9sultats sans n\u00e9cessiter la moindre boucle explicite.<\/p>\n<h3>5.2 Exemple pratique : \u00e9valuation d&rsquo;une s\u00e9quence de valeurs distribu\u00e9es<\/h3>\n<p>Pour illustrer la puissance du traitement vectoris\u00e9 sur des s\u00e9ries de donn\u00e9es, d\u00e9finissons un vecteur de points r\u00e9partis sym\u00e9triquement le long de l&rsquo;axe r\u00e9el entre <span class=\"arabpsy-math-inline\" data-latex=\"-5{,}0\">$-5{,}0$<\/span> et <span class=\"arabpsy-math-inline\" data-latex=\"+5{,}0\">$+5{,}0$<\/span>, repr\u00e9sentant diff\u00e9rentes amplitudes de signal :<\/p>\n<p>import numpy as np<br \/>from scipy.special import expit<\/p>\n<p>vecteur_echantillons = [-5.0, -2.5, 0.0, 2.5, 5.0]<br \/>probabilites_calculees = expit(vecteur_echantillons)<\/p>\n<p>print(\u00ab\u00a0Tableau des r\u00e9sultats vectoris\u00e9s :\u00a0\u00bb)<br \/>print(probabilites_calculees)<\/p>\n<p>L&rsquo;inspection du tableau g\u00e9n\u00e9r\u00e9 r\u00e9v\u00e8le des sorties rigoureusement ordonn\u00e9es et sym\u00e9triques :<\/p>\n<ul>\n<li>Pour <span class=\"arabpsy-math-inline\" data-latex=\"x = -5{,}0\">$x = -5{,}0$<\/span> : <span class=\"arabpsy-math-inline\" data-latex=\"F(x) \\approx 0{,}00669285\">$F(x) \\approx 0{,}00669285$<\/span><\/li>\n<li>Pour <span class=\"arabpsy-math-inline\" data-latex=\"x = -2{,}5\">$x = -2{,}5$<\/span> : <span class=\"arabpsy-math-inline\" data-latex=\"F(x) \\approx 0{,}07585818\">$F(x) \\approx 0{,}07585818$<\/span><\/li>\n<li>Pour <span class=\"arabpsy-math-inline\" data-latex=\"x = 0{,}0\">$x = 0{,}0$<\/span> : <span class=\"arabpsy-math-inline\" data-latex=\"F(x) = 0{,}50000000\">$F(x) = 0{,}50000000$<\/span><\/li>\n<li>Pour <span class=\"arabpsy-math-inline\" data-latex=\"x = 2{,}5\">$x = 2{,}5$<\/span> : <span class=\"arabpsy-math-inline\" data-latex=\"F(x) \\approx 0{,}92414182\">$F(x) \\approx 0{,}92414182$<\/span><\/li>\n<li>Pour <span class=\"arabpsy-math-inline\" data-latex=\"x = 5{,}0\">$x = 5{,}0$<\/span> : <span class=\"arabpsy-math-inline\" data-latex=\"F(x) \\approx 0{,}99330715\">$F(x) \\approx 0{,}99330715$<\/span><\/li>\n<\/ul>\n<p>Nous pouvons v\u00e9rifier empiriquement la conservation de l&rsquo;ordre ordinal strict : si <span class=\"arabpsy-math-inline\" data-latex=\"x_i &lt; x_j\">$x_i &lt; x_j$<\/span>, alors <span class=\"arabpsy-math-inline\" data-latex=\"\\text{expit}(x_i) &lt; \\text{expit}(x_j)\">$\\text{expit}(x_i) &lt; \\text{expit}(x_j)$<\/span>, attestant que la fonction respecte int\u00e9gralement la topologie de l&#039;espace source. De plus, la compl\u00e9mentarit\u00e9 est parfaitement conserv\u00e9e : la somme <span class=\"arabpsy-math-inline\" data-latex=\"\\text{expit}(-2{,}5) + \\text{expit}(2{,}5)\">$\\text{expit}(-2{,}5) + \\text{expit}(2{,}5)$<\/span> \u00e9quivaut exactement \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"1{,}0\">$1{,}0$<\/span>.<\/p>\n<h3>5.3 Gestion des matrices et tenseurs multidimensionnels<\/h3>\n<p>Dans les pipelines industriels de mod\u00e9lisation pr\u00e9dictive ou d&rsquo;apprentissage automatique, les donn\u00e9es sont organis\u00e9es sous forme de tenseurs de rang 2 ou sup\u00e9rieur, tels que des matrices d&rsquo;observations-caract\u00e9ristiques (de dimensions <span class=\"arabpsy-math-inline\" data-latex=\"N \\times P\">$N \\times P$<\/span>, o\u00f9 <span class=\"arabpsy-math-inline\" data-latex=\"N\">$N$<\/span> d\u00e9signe le nombre d&rsquo;individus et <span class=\"arabpsy-math-inline\" data-latex=\"P\">$P$<\/span> le nombre de variables descriptives).<\/p>\n<p>La fonction <code>expit<\/code> excelle dans cette configuration structurelle en op\u00e9rant directement sur des matrices bidimensionnelles sans alt\u00e9rer la topologie matricielle :<\/p>\n<p>matrice_observations = np.array([<br \/>&nbsp;&nbsp;&nbsp;&nbsp;[-1.5, 0.5, 2.0],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;[3.0, -0.2, -4.0]<br \/>])<\/p>\n<p>matrice_probabilites = expit(matrice_observations)<br \/>print(\u00ab\u00a0Dimensions d&rsquo;entr\u00e9e :\u00a0\u00bb, matrice_observations.shape)<br \/>print(\u00ab\u00a0Dimensions de sortie :\u00a0\u00bb, matrice_probabilites.shape)<\/p>\n<p>L&rsquo;algorithme garantit la pr\u00e9servation absolue de la dimensionnalit\u00e9 matricielle (<code>shape<\/code> initiale <span class=\"arabpsy-math-inline\" data-latex=\"(2, 3)\">$(2, 3)$<\/span> parfaitement maintenue en sortie). Les calculs sont r\u00e9alis\u00e9s \u00e9l\u00e9ment par \u00e9l\u00e9ment (<em>element-wise<\/em>) au sein de la m\u00e9moire tampon contigu\u00eb en C (organisation <code>C-contiguous<\/code>), assurant une exploitation maximale des lignes de cache L1\/L2 des microprocesseurs actuels. Cette coh\u00e9rence structurelle autorise l&rsquo;int\u00e9gration fluide de la fonction au sein de calculs matriciels complexes impliquant des produits de Kronecker, des convolutions ou des factorisations tensorielles.<\/p>\n<h2>6. Impl\u00e9mentation vectoris\u00e9e native avec la biblioth\u00e8que NumPy<\/h2>\n<h3>6.1 Conception d&rsquo;une fonction sigmo\u00efde personnalis\u00e9e avec numpy.exp<\/h3>\n<p>Bien que SciPy constitue une r\u00e9f\u00e9rence incontournable, de nombreux ing\u00e9nieurs logiciels pr\u00e9f\u00e8rent limiter le nombre de d\u00e9pendances externes de leurs applications en s&rsquo;appuyant exclusivement sur NumPy. Il est alors fr\u00e9quent d&rsquo;impl\u00e9menter soi-m\u00eame une fonction sigmo\u00efde vectoris\u00e9e en mobilisant la primitive transcendantale <a rel=\"noopener noreferrer\" href=\"https:\/\/numpy.org\/doc\/stable\/reference\/generated\/numpy.exp.html\">numpy.exp<\/a> :<\/p>\n<p>import numpy as np<\/p>\n<p>def sigmoide_numpy(x):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;return 1.0 \/ (1.0 + np.exp(-x))<\/p>\n<p>Cette expression compacte repose sur le concept de fonction universelle (<em>ufunc<\/em>) propre \u00e0 NumPy. L&rsquo;op\u00e9rateur unaire <code>-x<\/code> applique d&rsquo;abord la n\u00e9gation \u00e0 l&rsquo;ensemble des \u00e9l\u00e9ments du tableau sans g\u00e9n\u00e9rer de boucle Python explicite. La fonction <code>np.exp<\/code> \u00e9value ensuite l&rsquo;exponentielle sur chaque bloc de m\u00e9moire via des routines vectorielles optimis\u00e9es, puis les op\u00e9rateurs arithm\u00e9tiques <code>+<\/code> et <code>\/<\/code> proc\u00e8dent \u00e0 l&rsquo;addition scalaire et \u00e0 l&rsquo;inversion globale par diffusion (broadcasting).<\/p>\n<p>Cette approche s&rsquo;adapte universellement \u00e0 tout type de donn\u00e9es h\u00e9berg\u00e9 au sein d&rsquo;un <code>ndarray<\/code>, qu&rsquo;il s&rsquo;agisse de flottants en simple pr\u00e9cision (<code>float32<\/code>) couramment employ\u00e9s pour all\u00e9ger la charge des calculs graphiques, ou de flottants standard en double pr\u00e9cision (<code>float64<\/code>).<\/p>\n<h3>6.2 Exploitation du m\u00e9canisme de diffusion (broadcasting)<\/h3>\n<p>La combinaison de la formulation vectoris\u00e9e de NumPy avec les r\u00e8gles formelles de <a rel=\"noopener noreferrer\" href=\"https:\/\/numpy.org\/doc\/stable\/user\/basics.broadcasting.html\">diffusion (broadcasting)<\/a> permet de r\u00e9aliser des calculs complexes entre des tenseurs de rangs diff\u00e9rents, \u00e9liminant totalement le besoin de r\u00e9pliquer manuellement des donn\u00e9es en m\u00e9moire.<\/p>\n<p>Consid\u00e9rons le cas typique d&rsquo;une projection lin\u00e9aire de caract\u00e9ristiques au sein d&rsquo;un mod\u00e8le lin\u00e9aire g\u00e9n\u00e9ralis\u00e9, o\u00f9 une matrice de donn\u00e9es <span class=\"arabpsy-math-inline\" data-latex=\"X\">$X$<\/span> de dimensions <span class=\"arabpsy-math-inline\" data-latex=\"(N, D)\">$(N, D)$<\/span> doit \u00eatre combin\u00e9e avec un vecteur de poids synaptiques <span class=\"arabpsy-math-inline\" data-latex=\"W\">$W$<\/span> de dimension <span class=\"arabpsy-math-inline\" data-latex=\"(D,)\">$(D,)$<\/span> et un biais scalaire d&rsquo;ajustement <span class=\"arabpsy-math-inline\" data-latex=\"b\">$b$<\/span> :<\/p>\n<p>N = 1000<br \/>D = 10<\/p>\n<p>X = np.random.randn(N, D)<br \/>W = np.random.randn(D)<br \/>b = 0.35<\/p>\n<p># Calcul du potentiel d&rsquo;activation combin\u00e9 z (dimension N,)<br \/>z = np.dot(X, W) + b<\/p>\n<p># \u00c9valuation vectoris\u00e9e de la probabilit\u00e9 a posteriori<br \/>activations = sigmoide_numpy(z)<\/p>\n<p>Dans ce sc\u00e9nario, le produit matriciel <code>np.dot(X, W)<\/code> engendre un vecteur interm\u00e9diaire de longueur <span class=\"arabpsy-math-inline\" data-latex=\"N\">$N$<\/span>. L&rsquo;addition du scalaire <span class=\"arabpsy-math-inline\" data-latex=\"b\">$b$<\/span> s&rsquo;effectue par diffusion le long de la premi\u00e8re dimension sans aucune allocation m\u00e9moire superflue. La fonction <code>sigmoide_numpy<\/code> traite imm\u00e9diatement le vecteur r\u00e9sultant <span class=\"arabpsy-math-inline\" data-latex=\"z\">$z$<\/span>. Cette symbiose entre la diffusion dimensionnelle et les boucles compil\u00e9es C sous-jacentes garantit une \u00e9criture concise et des performances d&rsquo;ex\u00e9cution optimales.<\/p>\n<h3>6.3 Profilage comparatif : NumPy natif contre SciPy expit<\/h3>\n<p>Il est l\u00e9gitime d&rsquo;\u00e9valuer le diff\u00e9rentiel d&rsquo;efficacit\u00e9 op\u00e9rationnelle existant entre la formulation vectoris\u00e9e NumPy \u00e9l\u00e9mentaire <code>1 \/ (1 + np.exp(-x))<\/code> et l&rsquo;op\u00e9rateur sp\u00e9cialis\u00e9 <code>scipy.special.expit<\/code>. Pour mener cette analyse empirique, concevons un protocole de test \u00e9valuant le temps d&rsquo;ex\u00e9cution et l&rsquo;allocation de m\u00e9moire tampon sur un vecteur dense comprenant <span class=\"arabpsy-math-inline\" data-latex=\"10,000,000\">$10,000,000$<\/span> d&rsquo;\u00e9l\u00e9ments en double pr\u00e9cision :<\/p>\n<p>import time<br \/>import numpy as np<br \/>from scipy.special import expit<\/p>\n<p>vecteur_test = np.linspace(-10.0, 10.0, 10_000_000)<\/p>\n<p># Mesure de l&rsquo;impl\u00e9mentation NumPy standard<br \/>t0 = time.perf_counter()<br \/>res_numpy = 1.0 \/ (1.0 + np.exp(-vecteur_test))<br \/>duree_numpy = time.perf_counter() &#8211; t0<\/p>\n<p># Mesure de l&rsquo;impl\u00e9mentation SciPy expit<br \/>t1 = time.perf_counter()<br \/>res_scipy = expit(vecteur_test)<br \/>duree_scipy = time.perf_counter() &#8211; t1<\/p>\n<p>print(f\u00a0\u00bbNumPy natif : {duree_numpy:.4f} secondes\u00a0\u00bb)<br \/>print(f\u00a0\u00bbSciPy expit : {duree_scipy:.4f} secondes\u00a0\u00bb)<\/p>\n<p>L&rsquo;interpr\u00e9tation des r\u00e9sultats met en lumi\u00e8re des \u00e9l\u00e9ments fondamentaux d&rsquo;ing\u00e9nierie logicielle :<\/p>\n<ul>\n<li><strong>Performances temporelles :<\/strong> <code>scipy.special.expit<\/code> surpasse g\u00e9n\u00e9ralement l&rsquo;expression NumPy \u00e9l\u00e9mentaire d&rsquo;un facteur pouvant atteindre 1,5 \u00e0 2. Ce gain d\u00e9coule du fait que la formule NumPy encha\u00eene trois op\u00e9rations s\u00e9quentielles distinctes (n\u00e9gation du vecteur, calcul exponentiel, puis addition et division), n\u00e9cessitant de multiples lectures et \u00e9critures en m\u00e9moire vive. \u00c0 l&rsquo;inverse, l&rsquo;impl\u00e9mentation C de <code>expit<\/code> calcule l&rsquo;ensemble de l&rsquo;expression en une seule passe (<em>kernel fusion<\/em>), maximisant la localit\u00e9 des registres du processeur.<\/li>\n<li><strong>Empreinte m\u00e9moire :<\/strong> L&rsquo;expression NumPy na\u00efve alloue des tableaux temporaires pour stocker les r\u00e9sultats interm\u00e9diaires de <code>-x<\/code> et de <code>1 + exp(-x)<\/code>, augmentant temporairement la pression sur la m\u00e9moire virtuelle du syst\u00e8me, tandis que <code>expit<\/code> alloue directement le tableau de destination final.<\/li>\n<\/ul>\n<h2>7. Stabilit\u00e9 num\u00e9rique et pr\u00e9vention des d\u00e9passements de capacit\u00e9<\/h2>\n<h3>7.1 M\u00e9canisme du d\u00e9passement de capacit\u00e9 (Overflow) en virgule flottante<\/h3>\n<p>Bien que l&rsquo;expression vectoris\u00e9e <code>1.0 \/ (1.0 + np.exp(-x))<\/code> offre d&rsquo;excellentes performances d&rsquo;ex\u00e9cution sur des donn\u00e9es contr\u00f4l\u00e9es, elle dissimule une faille num\u00e9rique structurelle majeure. Lorsque le vecteur d&rsquo;entr\u00e9e comporte des valeurs r\u00e9elles fortement n\u00e9gatives (par exemple des scores logits non normalis\u00e9s g\u00e9n\u00e9r\u00e9s au cours des premi\u00e8res it\u00e9rations de l&rsquo;entra\u00eenement d&rsquo;un mod\u00e8le non stabilis\u00e9), le terme <span class=\"arabpsy-math-inline\" data-latex=\"-x\">$-x$<\/span> devient strictement positif et prend une amplitude consid\u00e9rable.<\/p>\n<p>D\u00e8s lors que <span class=\"arabpsy-math-inline\" data-latex=\"-x &gt; 709{,}78\">$-x &gt; 709{,}78$<\/span>, la tentative d&rsquo;\u00e9valuation de <code>np.exp(-x)<\/code> surpasse la plus grande valeur finie repr\u00e9sentable en double pr\u00e9cision sous la norme IEEE 754 (<span class=\"arabpsy-math-inline\" data-latex=\"1{,}79769 \\times 10^{308}\">$1{,}79769 \\times 10^{308}$<\/span>). NumPy signale alors imm\u00e9diatement cette anomalie via un message d&rsquo;alerte lors de l&rsquo;ex\u00e9cution :<\/p>\n<p>RuntimeWarning: overflow encountered in exp<\/p>\n<p>Sur le plan binaire, la valeur interm\u00e9diaire de l&rsquo;exponentielle est alors convertie en l&rsquo;entit\u00e9 sp\u00e9ciale <code>inf<\/code> (infini positif). Par ricochet arithm\u00e9tique, l&rsquo;op\u00e9ration subs\u00e9quente \u00e9value <span class=\"arabpsy-math-inline\" data-latex=\"1{,}0 \/ (1{,}0 + \\infty)\">$1{,}0 \/ (1{,}0 + \\infty)$<\/span>, ce qui retourne math\u00e9matiquement <span class=\"arabpsy-math-inline\" data-latex=\"0{,}0\">$0{,}0$<\/span>. Bien que la r\u00e9ponse finale semble co\u00efncider avec l&rsquo;asymptote th\u00e9orique, cette instabilit\u00e9 interm\u00e9diaire engendre des d\u00e9gradations critiques :<\/p>\n<ul>\n<li>Ralentissement brutal de l&rsquo;ex\u00e9cution processeur lors de la prise en charge des interruptions mat\u00e9rielles de virgule flottante.<\/li>\n<li>Impossibilit\u00e9 de propager correctement les gradients analytiques lors de l&rsquo;apprentissage diff\u00e9rentiel, l&rsquo;\u00e9valuation du gradient conduisant directement \u00e0 des ind\u00e9terminations math\u00e9matiques fatales de type <code>nan<\/code> (<span class=\"arabpsy-math-inline\" data-latex=\"\\infty \\times 0\">$\\infty \\times 0$<\/span>).<\/li>\n<\/ul>\n<h3>7.2 Algorithme num\u00e9riquement stable par partitionnement conditionnel<\/h3>\n<p>Pour immuniser d\u00e9finitivement le code contre tout ph\u00e9nom\u00e8ne de saturation ou de d\u00e9bordement arithm\u00e9tique sans d\u00e9pendre de biblioth\u00e8ques compil\u00e9es tierces, il est n\u00e9cessaire de concevoir une formulation alg\u00e9brique partitionn\u00e9e. L&rsquo;astuce computationnelle repose sur une r\u00e9\u00e9criture factoris\u00e9e de la fraction logistique selon le signe de la variable d&rsquo;entr\u00e9e :<\/p>\n<ul>\n<li>Pour les r\u00e9els positifs ou nuls (<span class=\"arabpsy-math-inline\" data-latex=\"x ge 0\">$x ge 0$<\/span>) : Le terme <span class=\"arabpsy-math-inline\" data-latex=\"-x\">$-x$<\/span> est n\u00e9gatif ou nul. Par cons\u00e9quent, l&rsquo;\u00e9valuation de <span class=\"arabpsy-math-inline\" data-latex=\"e^{-x}\">$e^{-x}$<\/span> est strictement comprise dans l&rsquo;intervalle <span class=\"arabpsy-math-inline\" data-latex=\"]0, 1]\">$]0, 1]$<\/span>. Il n&rsquo;existe aucun risque de d\u00e9passement de capacit\u00e9 sup\u00e9rieur. La formulation classique est donc parfaitement stable :<br \/>\n    <span class=\"arabpsy-math-display\" data-latex=\"F(x) = \\frac{1}{1 + e^{-x}}\">$$F(x) = \\frac{1}{1 + e^{-x}}$$<\/span><\/li>\n<li>Pour les r\u00e9els strictement n\u00e9gatifs (<span class=\"arabpsy-math-inline\" data-latex=\"x &lt; 0\">$x &lt; 0$<\/span>) : Afin d&#039;\u00e9viter l&#039;\u00e9valuation de <span class=\"arabpsy-math-inline\" data-latex=\"e^{-x}\">$e^{-x}$<\/span> avec une valeur positive \u00e9lev\u00e9e, nous multiplions le num\u00e9rateur et le d\u00e9nominateur de la fraction par <span class=\"arabpsy-math-inline\" data-latex=\"e^{x}\">$e^{x}$<\/span>. L&#039;expression devient :<br \/>\n    <span class=\"arabpsy-math-display\" data-latex=\"F(x) = \\frac{e^x}{1 + e^x}\">$$F(x) = \\frac{e^x}{1 + e^x}$$<\/span><br \/>\n    Dans cette configuration, puisque <span class=\"arabpsy-math-inline\" data-latex=\"x &lt; 0\">$x &lt; 0$<\/span>, le terme exponentiel \u00e9valu\u00e9 est <span class=\"arabpsy-math-inline\" data-latex=\"e^x\">$e^x$<\/span>, dont la valeur demeure rigoureusement contenue dans l&#039;intervalle <span class=\"arabpsy-math-inline\" data-latex=\"]0, 1[\">$]0, 1[$<\/span>. Tout risque de d\u00e9passement de capacit\u00e9 est donc arithm\u00e9tiquement an\u00e9anti.<\/li>\n<\/ul>\n<p>Cette strat\u00e9gie de partitionnement conditionnel s&rsquo;impl\u00e9mente \u00e9l\u00e9gamment en NumPy au moyen de la primitive vectoris\u00e9e <code>np.where<\/code>, garantissant une robustesse num\u00e9rique sans faille :<\/p>\n<p>def sigmoide_robuste(x):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;x_arr = np.asarray(x, dtype=np.float64)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;return np.where(<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x_arr &gt;= 0,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.0 \/ (1.0 + np.exp(-x_arr)),<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;np.exp(x_arr) \/ (1.0 + np.exp(x_arr))<br \/>&nbsp;&nbsp;&nbsp;&nbsp;)<\/p>\n<h3>7.3 Validation exp\u00e9rimentale sur des plages extr\u00eames<\/h3>\n<p>Afin d&rsquo;\u00e9prouver la robustesse de notre impl\u00e9mentation conditionnelle par rapport \u00e0 la m\u00e9thode na\u00efve, soumettons les deux algorithmes \u00e0 un banc d&rsquo;essai extr\u00eame comprenant des valeurs largement situ\u00e9es hors des limites arithm\u00e9tiques conventionnelles :<\/p>\n<p>valeurs_critiques = np.array([-2000.0, -1000.0, -750.0, 0.0, 750.0, 1000.0, 2000.0])<\/p>\n<p>print(\u00ab\u00a0&#8212; Test avec la sigmo\u00efde na\u00efve &#8212;\u00ab\u00a0)<br \/>res_naif = sigmoide_numpy(valeurs_critiques)<br \/>print(res_naif)<\/p>\n<p>print(\u00ab\u00a0n&#8212; Test avec la sigmo\u00efde robuste &#8212;\u00ab\u00a0)<br \/>res_robuste = sigmoide_robuste(valeurs_critiques)<br \/>print(res_robuste)<\/p>\n<p>print(\u00ab\u00a0n&#8212; Test avec scipy.special.expit &#8212;\u00ab\u00a0)<br \/>res_expit = expit(valeurs_critiques)<br \/>print(res_expit)<\/p>\n<p>Les observations exp\u00e9rimentales confirment nos pr\u00e9dictions th\u00e9oriques :<\/p>\n<ul>\n<li>L&rsquo;impl\u00e9mentation na\u00efve d\u00e9clenche des avertissements <code>RuntimeWarning: overflow encountered in exp<\/code> pour les entr\u00e9es n\u00e9gatives extr\u00eames (<span class=\"arabpsy-math-inline\" data-latex=\"-2000\">$-2000$<\/span>, <span class=\"arabpsy-math-inline\" data-latex=\"-1000\">$-1000$<\/span>, <span class=\"arabpsy-math-inline\" data-latex=\"-750\">$-750$<\/span>).<\/li>\n<li>La routine <code>sigmoide_robuste<\/code> s&rsquo;ex\u00e9cute dans un silence parfait, sans la moindre notification d&rsquo;erreur syst\u00e8me, restituant fid\u00e8lement <span class=\"arabpsy-math-inline\" data-latex=\"0{,}0\">$0{,}0$<\/span> pour les saturations n\u00e9gatives et <span class=\"arabpsy-math-inline\" data-latex=\"1{,}0\">$1{,}0$<\/span> pour les saturations positives.<\/li>\n<li>La fonction <code>scipy.special.expit<\/code> produit rigoureusement les m\u00eames valeurs finies et stables que notre routine conditionnelle, d\u00e9montrant qu&rsquo;elle incorpore une logique analogue directement compil\u00e9e en C sous le capot.<\/li>\n<\/ul>\n<h2>8. Calcul de la d\u00e9riv\u00e9e de la fonction sigmo\u00efde en Python<\/h2>\n<h3>8.1 Formulation diff\u00e9rentielle et simplification alg\u00e9brique<\/h3>\n<p>L&rsquo;optimisation des mod\u00e8les param\u00e9triques fond\u00e9s sur la fonction sigmo\u00efde \u2014 tels que les r\u00e9seaux de neurones ou la r\u00e9gression logistique \u2014 repose quasi exclusivement sur les m\u00e9thodes de descente de gradient. Il est donc fondamental d&rsquo;analyser les propri\u00e9t\u00e9s diff\u00e9rentielles de cette courbe. Calculons la d\u00e9riv\u00e9e premi\u00e8re de la fonction <span class=\"arabpsy-math-inline\" data-latex=\"F(x) = (1 + e^{-x})^{-1}\">$F(x) = (1 + e^{-x})^{-1}$<\/span> par rapport \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"x\">$x$<\/span> en appliquant la r\u00e8gle de d\u00e9rivation en cha\u00eene :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"F&#039;(x) = \\frac{d}{dx}\\left[(1 + e^{-x})^{-1}\\right] = -(1 + e^{-x})^{-2} \\cdot \\frac{d}{dx}(1 + e^{-x}) = -(1 + e^{-x})^{-2} \\cdot (-e^{-x})\">$$F'(x) = \\frac{d}{dx}\\left[(1 + e^{-x})^{-1}\\right] = -(1 + e^{-x})^{-2} \\cdot \\frac{d}{dx}(1 + e^{-x}) = -(1 + e^{-x})^{-2} \\cdot (-e^{-x})$$<\/span><\/p>\n<p>En simplifiant les signes n\u00e9gatifs et en r\u00e9organisant les termes au sein du quotient, nous obtenons une d\u00e9composition d&rsquo;une grande \u00e9l\u00e9gance math\u00e9matique :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"F&#039;(x) = \\frac{e^{-x}}{(1 + e^{-x})^2} = \\frac{1}{1 + e^{-x}} \\cdot \\frac{e^{-x}}{1 + e^{-x}} = \\frac{1}{1 + e^{-x}} \\cdot \\left(\\frac{1 + e^{-x} - 1}{1 + e^{-x}}\\right) = F(x) \\cdot (1 - F(x))\">$$F'(x) = \\frac{e^{-x}}{(1 + e^{-x})^2} = \\frac{1}{1 + e^{-x}} \\cdot \\frac{e^{-x}}{1 + e^{-x}} = \\frac{1}{1 + e^{-x}} \\cdot \\left(\\frac{1 + e^{-x} &#8211; 1}{1 + e^{-x}}\\right) = F(x) \\cdot (1 &#8211; F(x))$$<\/span><\/p>\n<p>Cette propri\u00e9t\u00e9 constitue un atout computationnel capital : la d\u00e9riv\u00e9e de la fonction sigmo\u00efde peut \u00eatre calcul\u00e9e sans invoquer de nouvelles fonctions transcendantes, simplement en effectuant une soustraction unitaire et une multiplication scalaire \u00e0 partir de la valeur de la fonction elle-m\u00eame. La valeur maximale de cette d\u00e9riv\u00e9e est atteinte au centre de sym\u00e9trie <span class=\"arabpsy-math-inline\" data-latex=\"x = 0\">$x = 0$<\/span>, o\u00f9 <span class=\"arabpsy-math-inline\" data-latex=\"F(0) = 0{,}5\">$F(0) = 0{,}5$<\/span>, produisant une pente maximale <span class=\"arabpsy-math-inline\" data-latex=\"F&#039;(0) = 0{,}5 \\times (1 - 0{,}5) = 0{,}25\">$F'(0) = 0{,}5 \\times (1 &#8211; 0{,}5) = 0{,}25$<\/span>.<\/p>\n<h3>8.2 Impl\u00e9mentation d&rsquo;une fonction diff\u00e9rentielle sous Python<\/h3>\n<p>En exploitant l&rsquo;identit\u00e9 <span class=\"arabpsy-math-inline\" data-latex=\"F&#039;(x) = F(x)(1 - F(x))\">$F'(x) = F(x)(1 &#8211; F(x))$<\/span>, nous pouvons structurer un algorithme Python hautement efficient retournant de concert l&rsquo;activation sigmo\u00efdale et son gradient associ\u00e9, \u00e9liminant tout calcul redondant lors de la phase de r\u00e9tropropagation (<em>backpropagation<\/em>) :<\/p>\n<p>from scipy.special import expit<\/p>\n<p>def sigmoide_et_derivee(x):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;\u00ab\u00a0\u00a0\u00bb\u00a0\u00bb<br \/>&nbsp;&nbsp;&nbsp;&nbsp;Calcule simultan\u00e9ment la valeur de la sigmo\u00efde et de sa d\u00e9riv\u00e9e premi\u00e8re.<br \/>&nbsp;&nbsp;&nbsp;&nbsp;\u00ab\u00a0\u00a0\u00bb\u00a0\u00bb<br \/>&nbsp;&nbsp;&nbsp;&nbsp;s = expit(x)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;ds = s * (1.0 &#8211; s)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;return s, ds<\/p>\n<p>V\u00e9rifions num\u00e9riquement la validit\u00e9 de cette relation pour notre point scalaire d&rsquo;\u00e9valuation <span class=\"arabpsy-math-inline\" data-latex=\"x = 2{,}5\">$x = 2{,}5$<\/span> :<\/p>\n<p>activation, gradient = sigmoide_et_derivee(2.5)<br \/>print(f\u00a0\u00bbActivation F(2.5) : {activation:.8f}\u00a0\u00bb)<br \/>print(f\u00a0\u00bbGradient F'(2.5)  : {gradient:.8f}\u00a0\u00bb)<\/p>\n<p>Le calcul manuel confirme la pr\u00e9cision de l&rsquo;ex\u00e9cution : l&rsquo;activation valant approximativement <span class=\"arabpsy-math-inline\" data-latex=\"0{,}92414182\">$0{,}92414182$<\/span>, le gradient s&rsquo;\u00e9value \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"0{,}92414182 \\times (1 - 0{,}92414182) = 0{,}92414182 \\times 0{,}07585818 \\approx 0{,}07011984\">$0{,}92414182 \\times (1 &#8211; 0{,}92414182) = 0{,}92414182 \\times 0{,}07585818 \\approx 0{,}07011984$<\/span>. Cette op\u00e9ration \u00e9l\u00e9mentaire s&rsquo;ex\u00e9cute en une fraction infime de microseconde sur des tableaux de plusieurs millions de composantes.<\/p>\n<h3>8.3 Pertinence pour l&rsquo;optimisation et les gradients descendants<\/h3>\n<p>La formulation diff\u00e9rentielle <span class=\"arabpsy-math-inline\" data-latex=\"F&#039;(x) = F(x)(1 - F(x))\">$F'(x) = F(x)(1 &#8211; F(x))$<\/span> met en lumi\u00e8re un ph\u00e9nom\u00e8ne pathologique bien connu des concepteurs d&rsquo;architectures d&rsquo;apprentissage profond : le probl\u00e8me de la <a rel=\"noopener noreferrer\" href=\"https:\/\/en.wikipedia.org\/wiki\/Vanishing_gradient_problem\">disparition ou de l&rsquo;\u00e9vanescence du gradient<\/a> (<em>vanishing gradient problem<\/em>). Lorsque la valeur absolue de l&rsquo;entr\u00e9e <span class=\"arabpsy-math-inline\" data-latex=\"|x|\">$|x|$<\/span> devient importante (par exemple <span class=\"arabpsy-math-inline\" data-latex=\"|x| &gt; 5\">$|x| &gt; 5$<\/span>), la fonction <span class=\"arabpsy-math-inline\" data-latex=\"F(x)\">$F(x)$<\/span> s&rsquo;approche asymptotiquement de <span class=\"arabpsy-math-inline\" data-latex=\"1{,}0\">$1{,}0$<\/span> ou de <span class=\"arabpsy-math-inline\" data-latex=\"0{,}0\">$0{,}0$<\/span>. Dans les deux cas de figure, le produit <span class=\"arabpsy-math-inline\" data-latex=\"F(x)(1 - F(x))\">$F(x)(1 &#8211; F(x))$<\/span> tend rapidement vers z\u00e9ro.<\/p>\n<p>Lors de l&rsquo;entra\u00eenement d&rsquo;un r\u00e9seau de neurones multicouche via l&rsquo;algorithme de descente de gradient stochastique (SGD), le gradient de la fonction de perte par rapport aux poids des premi\u00e8res couches est calcul\u00e9 par une multiplication en cha\u00eene de d\u00e9riv\u00e9es partielles locales :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\frac{\\partial \\mathcal{L}}{\\partial w^{(1)}} = \\frac{\\partial \\mathcal{L}}{\\partial a^{(L)}} \\prod_{l=1}^{L} \\frac{\\partial a^{(l)}}{\\partial z^{(l)}} \\cdot \\frac{\\partial z^{(l)}}{\\partial w^{(1)}}\">$$\\frac{\\partial \\mathcal{L}}{\\partial w^{(1)}} = \\frac{\\partial \\mathcal{L}}{\\partial a^{(L)}} \\prod_{l=1}^{L} \\frac{\\partial a^{(l)}}{\\partial z^{(l)}} \\cdot \\frac{\\partial z^{(l)}}{\\partial w^{(1)}}$$<\/span><\/p>\n<p>Chaque facteur local \u00e9tant major\u00e9 par <span class=\"arabpsy-math-inline\" data-latex=\"0{,}25\">$0{,}25$<\/span>, la multiplication successive de ces termes d\u00e9cote exponentiellement le signal de r\u00e9tropropagation : pour un r\u00e9seau de 5 couches satur\u00e9es, le gradient subit une att\u00e9nuation th\u00e9orique sup\u00e9rieure \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"0{,}25^5 \\approx 0{,}000976\">$0{,}25^5 \\approx 0{,}000976$<\/span>. Les couches initiales du r\u00e9seau cessent alors d&rsquo;apprendre. Cette limitation a conduit l&rsquo;industrie \u00e0 substituer la sigmo\u00efde par des unit\u00e9s lin\u00e9aires rectifi\u00e9es (<a rel=\"noopener noreferrer\" href=\"https:\/\/en.wikipedia.org\/wiki\/Rectifier_(neural_networks)\">ReLU<\/a>, GELU) au sein des couches cach\u00e9es, tout en cantonnant l&rsquo;usage de la sigmo\u00efde aux couches terminales assurant la pr\u00e9diction de probabilit\u00e9s binaires.<\/p>\n<h2>9. Visualisation graphique de la courbe sigmo\u00efde avec Matplotlib<\/h2>\n<h3>9.1 G\u00e9n\u00e9ration d&rsquo;un trac\u00e9 graphique acad\u00e9mique complet<\/h3>\n<p>Une compr\u00e9hension exhaustive d&rsquo;une fonction math\u00e9matique passe par une restitution visuelle rigoureuse de ses caract\u00e9ristiques topologiques. \u00c0 l&rsquo;aide de la biblioth\u00e8que <a rel=\"noopener noreferrer\" href=\"https:\/\/matplotlib.org\/\">Matplotlib<\/a>, nous pouvons concevoir un graphique de qualit\u00e9 acad\u00e9mique illustrant le comportement continu de la fonction sigmo\u00efde sur un intervalle repr\u00e9sentatif <span class=\"arabpsy-math-inline\" data-latex=\"[-10, 10]\">$[-10, 10]$<\/span>.<\/p>\n<p>Le protocole de g\u00e9n\u00e9ration graphique se d\u00e9ploie selon les \u00e9tapes suivantes :<\/p>\n<p>import numpy as np<br \/>import matplotlib.pyplot as plt<br \/>from scipy.special import expit<\/p>\n<p># Discr\u00e9tisation fine du domaine d&rsquo;\u00e9tude<br \/>x = np.linspace(-10.0, 10.0, 1000)<br \/>y = expit(x)<\/p>\n<p># Initialisation de la figure et des axes cart\u00e9siens<br \/>plt.figure(figsize=(10, 6), dpi=300)<br \/>plt.plot(x, y, label=r&rsquo;<span class=\"arabpsy-math-inline\" data-latex=\"\\sigma(x) = \\frac{1}{1 + e^{-x}}\">$\\sigma(x) = \\frac{1}{1 + e^{-x}}$<\/span>&lsquo;, color=&rsquo;#1f77b4&rsquo;, linewidth=2.5)<\/p>\n<p># Tra\u00e7age des asymptotes horizontales th\u00e9oriques<br \/>plt.axhline(1.0, color=&rsquo;#d62728&prime;, linestyle=&rsquo;&#8211;&lsquo;, linewidth=1.2, label=&rsquo;Asymptote sup\u00e9rieure (y = 1.0)&rsquo;)<br \/>plt.axhline(0.0, color=&rsquo;#2ca02c&rsquo;, linestyle=&rsquo;&#8211;&lsquo;, linewidth=1.2, label=&rsquo;Asymptote inf\u00e9rieure (y = 0.0)&rsquo;)<br \/>plt.axhline(0.5, color=&rsquo;gray&rsquo;, linestyle=&rsquo;:&rsquo;, linewidth=1.0, alpha=0.7)<\/p>\n<p># Mise en valeur du point d&rsquo;inflexion central<br \/>plt.scatter([0.0], [0.5], color=&rsquo;#000000&prime;, zorder=5)<br \/>plt.annotate(&lsquo;Point d&rsquo;inflexion (0, 0.5)&rsquo;, xy=(0.0, 0.5), xytext=(1.5, 0.4),<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arrowprops=dict(arrowstyle=&rsquo;-&gt;&rsquo;, lw=1.2, color=&rsquo;black&rsquo;), fontsize=11)<\/p>\n<p># Configuration des m\u00e9tadonn\u00e9es du graphique<br \/>plt.title(&lsquo;Allure analytique et comportement asymptotique de la fonction sigmo\u00efde&rsquo;, fontsize=14, pad=15)<br \/>plt.xlabel(&lsquo;Variable ind\u00e9pendante (x)&rsquo;, fontsize=12)<br \/>plt.ylabel(&lsquo;Amplitude normalis\u00e9e (y)&rsquo;, fontsize=12)<br \/>plt.xlim(-10, 10)<br \/>plt.ylim(-0.05, 1.05)<br \/>plt.grid(True, linestyle=&rsquo;&#8211;&lsquo;, alpha=0.5)<br \/>plt.legend(loc=&rsquo;center right&rsquo;, fontsize=11)<br \/>plt.tight_layout()<br \/>plt.show()<\/p>\n<p>Ce script produit une figure vectorielle d&rsquo;une clart\u00e9 optimale, mettant en exergue la transition sigmo\u00efdale fluide, le positionnement exact des limites asymptotiques et le centre de sym\u00e9trie ponctuelle.<\/p>\n<h3>9.2 Illustration de la modulation des param\u00e8tres de pente et de centrage<\/h3>\n<p>Dans la mod\u00e9lisation de ph\u00e9nom\u00e8nes physiques ou psychom\u00e9triques r\u00e9els, la fonction logistique appara\u00eet fr\u00e9quemment sous sa forme param\u00e9trique g\u00e9n\u00e9ralis\u00e9e \u00e0 deux degr\u00e9s de libert\u00e9 :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"F(x; k, x_0) = \\frac{1}{1 + e^{-k(x - x_0)}}\">$$F(x; k, x_0) = \\frac{1}{1 + e^{-k(x &#8211; x_0)}}$$<\/span><\/p>\n<p>Cette formulation introduit deux hyperparam\u00e8tres critiques qui modifient profond\u00e9ment la r\u00e9ponse de la courbe :<\/p>\n<ul>\n<li><strong>Le param\u00e8tre de pente ou de rigidit\u00e9 (<span class=\"arabpsy-math-inline\" data-latex=\"k\">$k$<\/span>) :<\/strong> Il module la raideur de la transition. Pour de faibles valeurs (<span class=\"arabpsy-math-inline\" data-latex=\"k = 0{,}5\">$k = 0{,}5$<\/span>), la transition s&rsquo;\u00e9tale sur une plage \u00e9largie de l&rsquo;axe r\u00e9el. Lorsque <span class=\"arabpsy-math-inline\" data-latex=\"k\">$k$<\/span> cro\u00eet (<span class=\"arabpsy-math-inline\" data-latex=\"k = 2{,}0\">$k = 2{,}0$<\/span> ou <span class=\"arabpsy-math-inline\" data-latex=\"k = 5{,}0\">$k = 5{,}0$<\/span>), la pente au centre s&rsquo;accentue drastiquement. \u00c0 la limite o\u00f9 <span class=\"arabpsy-math-inline\" data-latex=\"k to \\infty\">$k to \\infty$<\/span>, la sigmo\u00efde converge structurellement vers la fonction de saut discontinu d&rsquo;Heaviside (ou fonction \u00e9chelon). Inversement, un param\u00e8tre <span class=\"arabpsy-math-inline\" data-latex=\"k\">$k$<\/span> n\u00e9gatif inverse le sens de variation, transformant la fonction en courbe strictement d\u00e9croissante.<\/li>\n<li><strong>Le param\u00e8tre de centrage ou seuil d&rsquo;inflexion (<span class=\"arabpsy-math-inline\" data-latex=\"x_0\">$x_0$<\/span>) :<\/strong> Il induit une translation horizontale rigide de la courbe le long de l&rsquo;axe des abscisses. L&rsquo;ordonn\u00e9e charni\u00e8re <span class=\"arabpsy-math-inline\" data-latex=\"F(x) = 0{,}5\">$F(x) = 0{,}5$<\/span> n&rsquo;est plus atteinte en z\u00e9ro, mais exactement au point <span class=\"arabpsy-math-inline\" data-latex=\"x = x_0\">$x = x_0$<\/span>.<\/li>\n<\/ul>\n<p>Cette flexibilit\u00e9 g\u00e9om\u00e9trique permet d&rsquo;ajuster pr\u00e9cis\u00e9ment la sigmo\u00efde \u00e0 des profils de donn\u00e9es empiriques vari\u00e9s via des m\u00e9thodes de r\u00e9gression non lin\u00e9aire telles que l&rsquo;algorithme de Levenberg-Marquardt impl\u00e9ment\u00e9 dans <code>scipy.optimize.curve_fit<\/code>.<\/p>\n<h3>9.3 Repr\u00e9sentation conjointe de la fonction et de son gradient<\/h3>\n<p>Pour illustrer de mani\u00e8re tangible l&rsquo;interd\u00e9pendance entre la courbe logistique et sa d\u00e9riv\u00e9e premi\u00e8re, il est instructif de superposer les deux fonctions sur un m\u00eame rep\u00e8re cart\u00e9sien partag\u00e9. Ce proc\u00e9d\u00e9 met en \u00e9vidence comment la dynamique d&rsquo;aplatissement de la sigmo\u00efde co\u00efncide rigoureusement avec la d\u00e9croissance du gradient :<\/p>\n<p>x = np.linspace(-8.0, 8.0, 500)<br \/>sig, d_sig = sigmoide_et_derivee(x)<\/p>\n<p>fig, ax1 = plt.subplots(figsize=(10, 6), dpi=300)<\/p>\n<p># Trac\u00e9 de la sigmo\u00efde sur l&rsquo;axe principal gauche<br \/>color = &lsquo;#1f77b4&rsquo;<br \/>ax1.set_xlabel(&lsquo;Score d&rsquo;entr\u00e9e (x)&rsquo;, fontsize=12)<br \/>ax1.set_ylabel(&lsquo;Fonction sigmo\u00efde F(x)&rsquo;, color=color, fontsize=12)<br \/>ax1.plot(x, sig, color=color, linewidth=2.5, label=&rsquo;Sigmo\u00efde F(x)&rsquo;)<br \/>ax1.tick_params(axis=&rsquo;y&rsquo;, labelcolor=color)<br \/>ax1.set_ylim(-0.02, 1.02)<\/p>\n<p># Instanciation d&rsquo;un second axe partag\u00e9 pour la d\u00e9riv\u00e9e<br \/>ax2 = ax1.twinx()<br \/>color = &lsquo;#ff7f0e&rsquo;<br \/>ax2.set_ylabel(&lsquo;D\u00e9riv\u00e9e F'(x)&rsquo;, color=color, fontsize=12)<br \/>ax2.plot(x, d_sig, color=color, linewidth=2.5, linestyle=&rsquo;-.&rsquo;, label=&rsquo;Gradient F'(x)&rsquo;)<br \/>ax2.tick_params(axis=&rsquo;y&rsquo;, labelcolor=color)<br \/>ax2.set_ylim(0.0, 0.30)<\/p>\n<p>plt.title(&lsquo;Superposition conjointe de la sigmo\u00efde et de sa fonction diff\u00e9rentielle&rsquo;, fontsize=14, pad=15)<br \/>ax1.grid(True, linestyle=&rsquo;&#8211;&lsquo;, alpha=0.4)<br \/>fig.tight_layout()<br \/>plt.show()<\/p>\n<p>Cette visualisation confirme visuellement que la d\u00e9riv\u00e9e adopte une g\u00e9om\u00e9trie en cloche unimodale parfaitement sym\u00e9trique. On constate distinctement que d\u00e8s lors que la sigmo\u00efde s&rsquo;\u00e9tablit sur ses plateaux horizontaux (<span class=\"arabpsy-math-inline\" data-latex=\"F(x) &gt; 0{,}98\">$F(x) &gt; 0{,}98$<\/span> ou <span class=\"arabpsy-math-inline\" data-latex=\"F(x) &lt; 0{,}02\">$F(x) &lt; 0{,}02$<\/span>), le gradient <span class=\"arabpsy-math-inline\" data-latex=\"F&#039;(x)\">$F&#039;(x)$<\/span> chute en de\u00e7\u00e0 du seuil critique de <span class=\"arabpsy-math-inline\" data-latex=\"0{,}02\">$0{,}02$<\/span>, concr\u00e9tisant graphiquement le risque d&#039;\u00e9vanescence du signal d&#039;apprentissage lors de l&#039;optimisation par r\u00e9tropropagation.<\/p>\n<h2>10. Application pratique : R\u00e9gression logistique et classification binaire<\/h2>\n<h3>10.1 Transformation des combinaisons lin\u00e9aires en pr\u00e9dictions probabilistes<\/h3>\n<p>La classification binaire constitue sans conteste l&rsquo;application industrielle et statistique la plus r\u00e9pandue de la fonction sigmo\u00efde. Dans un cadre de mod\u00e9lisation discriminante supervis\u00e9e, nous cherchons \u00e0 pr\u00e9dire une variable cible binaire <span class=\"arabpsy-math-inline\" data-latex=\"Y in {0, 1}\">$Y in {0, 1}$<\/span> conditionnellement \u00e0 un vecteur de variables explicatives <span class=\"arabpsy-math-inline\" data-latex=\"X in \\mathbb{R}^D\">$X in \\mathbb{R}^D$<\/span>.<\/p>\n<p>Le mod\u00e8le calcule initialement une combinaison lin\u00e9aire pond\u00e9r\u00e9e des attributs, augment\u00e9e d&rsquo;un terme d&rsquo;interception (biais), formant le score continu non born\u00e9 <span class=\"arabpsy-math-inline\" data-latex=\"z\">$z$<\/span> :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"z = \\mathbf{w}^T \\mathbf{x} + b = \\sum_{j=1}^D w_j x_j + b\">$$z = \\mathbf{w}^T \\mathbf{x} + b = \\sum_{j=1}^D w_j x_j + b$$<\/span><\/p>\n<p>Ce score scalaire <span class=\"arabpsy-math-inline\" data-latex=\"z\">$z$<\/span> \u2014 d\u00e9sign\u00e9 sous le terme de <em>logit<\/em> ou de log-odds (logarithme du rapport de cotes) \u2014 s&rsquo;\u00e9tend sur l&rsquo;int\u00e9gralit\u00e9 de la droite r\u00e9elle <span class=\"arabpsy-math-inline\" data-latex=\"]-\\infty, +\\infty[\">$]-\\infty, +\\infty[$<\/span>. Il ne peut en l&rsquo;\u00e9tat faire office de probabilit\u00e9 valide. C&rsquo;est pr\u00e9cis\u00e9ment ici qu&rsquo;intervient la fonction sigmo\u00efde : en agissant comme une fonction de lien canonique inverse (<em>inverse link function<\/em>), elle projette le logit non contraint dans l&rsquo;espace formel des lois de Bernoulli conditionnelles :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"P(Y = 1 mid \\mathbf{x}) = \\sigma(z) = \\frac{1}{1 + e^{-(\\mathbf{w}^T \\mathbf{x} + b)}}\">$$P(Y = 1 mid \\mathbf{x}) = \\sigma(z) = \\frac{1}{1 + e^{-(\\mathbf{w}^T \\mathbf{x} + b)}}$$<\/span><\/p>\n<p>La r\u00e8gle d&rsquo;affectation d\u00e9cisionnelle finale proc\u00e8de g\u00e9n\u00e9ralement par seuillage de cette probabilit\u00e9 a posteriori au niveau conventionnel de coupure <span class=\"arabpsy-math-inline\" data-latex=\"\\tau = 0{,}5\">$\\tau = 0{,}5$<\/span>. Si <span class=\"arabpsy-math-inline\" data-latex=\"\\sigma(z) ge 0{,}5\">$\\sigma(z) ge 0{,}5$<\/span> (ce qui \u00e9quivaut rigoureusement \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"z ge 0\">$z ge 0$<\/span>), l&rsquo;observation est affect\u00e9e \u00e0 la classe positive ($1$) ; dans le cas contraire, elle est assign\u00e9e \u00e0 la classe n\u00e9gative ($0$).<\/p>\n<h3>10.2 Exemple pratique : classification pas \u00e0 pas en Python<\/h3>\n<p>Concevons un script complet illustrant pas \u00e0 pas le fonctionnement interne d&rsquo;un classifieur binaire vectoris\u00e9 sans recourir \u00e0 des abstractions logicielles de haut niveau (telles que <code>scikit-learn<\/code>), en mobilisant directement <code>scipy.special.expit<\/code> pour l&rsquo;\u00e9valuation d\u00e9cisionnelle :<\/p>\n<p>import numpy as np<br \/>from scipy.special import expit<\/p>\n<p># Initialisation d&rsquo;un jeu de donn\u00e9es synth\u00e9tique reproductible<br \/>np.random.seed(42)<br \/>N_echantillons = 6<\/p>\n<p># Matrice de caract\u00e9ristiques (N x 2) et \u00e9tiquettes r\u00e9elles de classe<br \/>X = np.array([<br \/>&nbsp;&nbsp;&nbsp;&nbsp;[0.5, 1.2],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;[2.3, 3.1],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;[-1.2, -0.8],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;[-0.5, -2.1],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;[1.8, 0.9],<br \/>&nbsp;&nbsp;&nbsp;&nbsp;[-2.0, -1.5]<br \/>])<br \/>y_reel = np.array([1, 1, 0, 0, 1, 0])<\/p>\n<p># Param\u00e8tres pr\u00e9-calibr\u00e9s du mod\u00e8le lin\u00e9aire (poids et biais)<br \/>poids_w = np.array([0.85, 1.15])<br \/>biais_b = -0.25<\/p>\n<p># \u00c9tape 1 : Calcul vectoris\u00e9 du potentiel lin\u00e9aire z<br \/>logits_z = np.dot(X, poids_w) + biais_b<\/p>\n<p># \u00c9tape 2 : Projection probabiliste via expit<br \/>probabilites = expit(logits_z)<\/p>\n<p># \u00c9tape 3 : Application du seuil d\u00e9cisionnel (0.5)<br \/>predictions_classe = (probabilites &gt;= 0.5).astype(int)<\/p>\n<p># \u00c9tape 4 : Calcul de la perte d&rsquo;entropie crois\u00e9e binaire (log-loss)<br \/>epsilon = 1e-15  # Protection contre les singularit\u00e9s logarithmiques log(0)<br \/>prob_tronquees = np.clip(probabilites, epsilon, 1.0 &#8211; epsilon)<br \/>perte_entropie_croisee = -np.mean(y_reel * np.log(prob_tronquees) + (1 &#8211; y_reel) * np.log(1.0 &#8211; prob_tronquees))<\/p>\n<p># Affichage des m\u00e9triques et diagnostics d\u00e9cisionnels<br \/>print(\u00ab\u00a0Logits calcul\u00e9s (z)       :\u00a0\u00bb, np.round(logits_z, 3))<br \/>print(\u00ab\u00a0Probabilit\u00e9s estim\u00e9es P(Y=1) :\u00a0\u00bb, np.round(probabilites, 4))<br \/>print(\u00ab\u00a0Pr\u00e9dictions de classe      :\u00a0\u00bb, predictions_classe)<br \/>print(\u00ab\u00a0Classes r\u00e9elles            :\u00a0\u00bb, y_reel)<br \/>print(f\u00a0\u00bbPerte Log-Loss moyenne     : {perte_entropie_croisee:.4f}\u00a0\u00bb)<\/p>\n<p>L&rsquo;analyse de l&rsquo;ex\u00e9cution confirme la parfaite ad\u00e9quation op\u00e9rationnelle du pipeline : les observations poss\u00e9dant des valeurs d&rsquo;attributs \u00e9lev\u00e9es produisent des logits fortement positifs (<span class=\"arabpsy-math-inline\" data-latex=\"z &gt; 0\">$z &gt; 0$<\/span>), convertis par <code>expit<\/code> en probabilit\u00e9s sup\u00e9rieures \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"0{,}5\">$0{,}5$<\/span>, induisant des pr\u00e9dictions parfaitement conformes \u00e0 la v\u00e9rit\u00e9 terrain.<\/p>\n<h3>10.3 Interpr\u00e9tation dans le cadre de mod\u00e8les de d\u00e9cision comportementale<\/h3>\n<p>Au-del\u00e0 de la simple assignation automatis\u00e9e de labels, l&rsquo;application de la fonction sigmo\u00efde permet une interpr\u00e9tation analytique fine dans le contexte de la mod\u00e9lisation \u00e9conom\u00e9trique et des th\u00e9ories du choix comportemental. En reformulant la probabilit\u00e9 logistique sous l&rsquo;angle du ratio des probabilit\u00e9s compl\u00e9mentaires, nous acc\u00e9dons directement au concept de rapport de cotes (<em>odds ratio<\/em>) :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\frac{P(Y=1 mid \\mathbf{x})}{1 - P(Y=1 mid \\mathbf{x})} = e^{\\mathbf{w}^T \\mathbf{x} + b} = e^b \\cdot \\prod_{j=1}^D e^{w_j x_j}\">$$\\frac{P(Y=1 mid \\mathbf{x})}{1 &#8211; P(Y=1 mid \\mathbf{x})} = e^{\\mathbf{w}^T \\mathbf{x} + b} = e^b \\cdot \\prod_{j=1}^D e^{w_j x_j}$$<\/span><\/p>\n<p>Dans cette formulation multiplicative, chaque coefficient de r\u00e9gression pond\u00e9r\u00e9 <span class=\"arabpsy-math-inline\" data-latex=\"w_j\">$w_j$<\/span> poss\u00e8de une signification op\u00e9rationnelle limpide : le terme <span class=\"arabpsy-math-inline\" data-latex=\"\\exp(w_j)\">$\\exp(w_j)$<\/span> repr\u00e9sente le facteur multiplicatif appliqu\u00e9 aux chances relatives de survenue de l&rsquo;\u00e9v\u00e9nement d&rsquo;int\u00e9r\u00eat pour chaque accroissement unitaire de la variable explicative correspondante <span class=\"arabpsy-math-inline\" data-latex=\"x_j\">$x_j$<\/span>, toutes choses \u00e9gales par ailleurs.<\/p>\n<p>Dans les sciences cognitives et la psychophysique exp\u00e9rimentale, cette mod\u00e9lisation sous-tend les paradigmes de d\u00e9cision probabiliste discrets, tels que l&rsquo;axiome de choix de Luce ou le mod\u00e8le de Bradley-Terry r\u00e9gissant les comparaisons par paires. Elle offre la possibilit\u00e9 de sonder la sensibilit\u00e9 discriminante d&rsquo;un agent rationnel confront\u00e9 \u00e0 des stimuli bruit\u00e9s et d&rsquo;\u00e9valuer la calibration pr\u00e9dictive des mod\u00e8les cognitifs via le calcul du <a rel=\"noopener noreferrer\" href=\"https:\/\/en.wikipedia.org\/wiki\/Brier_score\">score de Brier<\/a> et la construction de diagrammes de fiabilit\u00e9.<\/p>\n<h2>11. Calcul de la fonction sigmo\u00efde dans les cadriciels d&rsquo;apprentissage profond<\/h2>\n<h3>11.1 Impl\u00e9mentation sous PyTorch avec calcul sur acc\u00e9l\u00e9rateur GPU<\/h3>\n<p>D\u00e8s lors que l&rsquo;on aborde l&rsquo;entra\u00eenement de mod\u00e8les neuronaux massifs sur des t\u00e9raoctets de donn\u00e9es, les biblioth\u00e8ques g\u00e9n\u00e9ralistes CPU comme NumPy ou SciPy c\u00e8dent le pas aux cadriciels d&rsquo;apprentissage profond d\u00e9di\u00e9s, au premier rang desquels figure <a rel=\"noopener noreferrer\" href=\"https:\/\/pytorch.org\/\">PyTorch<\/a>. Au sein de cet \u00e9cosyst\u00e8me, la sigmo\u00efde n&rsquo;est plus simplement une fonction d&rsquo;\u00e9valuation num\u00e9rique passive, mais un op\u00e9rateur diff\u00e9rentiable int\u00e9gr\u00e9 au graphe dynamique d&rsquo;autodiff\u00e9renciation (<a rel=\"noopener noreferrer\" href=\"https:\/\/pytorch.org\/tutorials\/beginner\/blitz\/autograd_tutorial.html\">Autograd<\/a>).<\/p>\n<p>L&rsquo;op\u00e9rateur <code>torch.sigmoid<\/code> s&rsquo;applique uniform\u00e9ment sur des structures tensorielles et prend en charge le d\u00e9port instantan\u00e9 des calculs vers les c\u0153urs de calcul matriciel des processeurs graphiques (GPU NVIDIA via CUDA ou acc\u00e9l\u00e9rateurs Apple Metal) :<\/p>\n<p>import torch<\/p>\n<p># Allocation d&rsquo;un tenseur sur le processeur h\u00f4te (CPU)<br \/>tenseur_cpu = torch.tensor([-3.0, 0.0, 3.0], dtype=torch.float32, requires_grad=True)<\/p>\n<p># \u00c9valuation de la fonction d&rsquo;activation vectoris\u00e9e<br \/>activations = torch.sigmoid(tenseur_cpu)<br \/>print(\u00ab\u00a0Sortie de torch.sigmoid :\u00a0\u00bb, activations)<\/p>\n<p># D\u00e9monstration du m\u00e9canisme d&rsquo;autodiff\u00e9renciation automatique<br \/>perte_scalaire = activations.sum()<br \/>perte_scalaire.backward()<br \/>print(\u00ab\u00a0Gradients calcul\u00e9s automatiquement via Autograd :\u00a0\u00bb, tenseur_cpu.grad)<\/p>\n<p># Bascule transparente vers l&rsquo;acc\u00e9l\u00e9rateur GPU (si disponible mat\u00e9riellement)<br \/>if torch.cuda.is_available():<br \/>&nbsp;&nbsp;&nbsp;&nbsp;tenseur_gpu = tenseur_cpu.to(&lsquo;cuda&rsquo;)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;activations_gpu = torch.sigmoid(tenseur_gpu)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;print(\u00ab\u00a0Calcul ex\u00e9cut\u00e9 sur les c\u0153urs CUDA :\u00a0\u00bb, activations_gpu)<\/p>\n<p>L&rsquo;avantage cardinal r\u00e9side dans la pr\u00e9servation automatique de l&rsquo;historique des op\u00e9rations au travers de l&rsquo;attribut <code>grad_fn=&lt;SigmoidBackward0&gt;<\/code>, d\u00e9chargeant int\u00e9gralement l&rsquo;ing\u00e9nieur de la d\u00e9rivation manuelle lors de la r\u00e9tropropagation.<\/p>\n<h3>11.2 Impl\u00e9mentation sous TensorFlow et Keras<\/h3>\n<p>De fa\u00e7on sym\u00e9trique, l&rsquo;\u00e9cosyst\u00e8me <a rel=\"noopener noreferrer\" href=\"https:\/\/www.tensorflow.org\/\">TensorFlow<\/a> et sa composante d&rsquo;ing\u00e9nierie de haut niveau <a rel=\"noopener noreferrer\" href=\"https:\/\/keras.io\/\">Keras<\/a> int\u00e8grent nativement des primitives sigmo\u00efdales optimis\u00e9es via <code>tf.math.sigmoid<\/code> et <code>tf.keras.activations.sigmoid<\/code>.<\/p>\n<p>Ces routines sont optimis\u00e9es pour \u00eatre compil\u00e9es sous forme de graphes computationnels statiques optimis\u00e9s par le compilateur lin\u00e9aire acc\u00e9l\u00e9r\u00e9 <a rel=\"noopener noreferrer\" href=\"https:\/\/www.tensorflow.org\/xla\">XLA (Accelerated Linear Algebra)<\/a> :<\/p>\n<p>import tensorflow as tf<\/p>\n<p># D\u00e9finition d&rsquo;un tenseur constant<br \/>x_tf = tf.constant([[-2.0, 1.5], [0.0, 4.0]], dtype=tf.float32)<\/p>\n<p># Calcul math\u00e9matique direct<br \/>sortie_tf = tf.math.sigmoid(x_tf)<br \/>print(\u00ab\u00a0R\u00e9sultat TensorFlow :\u00a0\u00bb, sortie_tf)<\/p>\n<p># D\u00e9ploiement typique au sein d&rsquo;une couche d&rsquo;activation finale Keras<br \/>couche_dense_sortie = tf.keras.layers.Dense(<br \/>&nbsp;&nbsp;&nbsp;&nbsp;units=1,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;activation=&rsquo;sigmoid&rsquo;,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;kernel_initializer=&rsquo;glorot_uniform&rsquo;<br \/>)<\/p>\n<p># Compilation d\u00e9clarative d&rsquo;une fonction acc\u00e9l\u00e9r\u00e9e par compilation XLA<br \/>@tf.function(jit_compile=True)<br \/>def sigmoide_xla(tenseur):<br \/>&nbsp;&nbsp;&nbsp;&nbsp;return tf.math.sigmoid(tenseur)<\/p>\n<p>Lors de l&rsquo;utilisation de <code>jit_compile=True<\/code>, le compilateur XLA fusionne l&rsquo;op\u00e9ration sigmo\u00efde avec les op\u00e9rations matricielles adjacentes au niveau de la micro-architecture, supprimant totalement les goulots d&rsquo;\u00e9tranglement li\u00e9s aux transferts de bus m\u00e9moire.<\/p>\n<h3>11.3 Comparaison fonctionnelle : biblioth\u00e8ques g\u00e9n\u00e9ralistes vs cadriciels IA<\/h3>\n<p>Pour l&rsquo;architecte logiciel, le choix entre l&rsquo;\u00e9cosyst\u00e8me g\u00e9n\u00e9raliste (SciPy\/NumPy) et les cadriciels d&rsquo;apprentissage profond (PyTorch\/TensorFlow) repose sur des crit\u00e8res d&rsquo;arbitrage fonctionnels bien \u00e9tablis :<\/p>\n<ul>\n<li><strong>SciPy et NumPy :<\/strong> Recommand\u00e9s pour le prototypage algorithmique, l&rsquo;analyse exploratoire des donn\u00e9es, les statistiques descriptives ou la recherche acad\u00e9mique sur petits volumes. Leurs d\u00e9pendances logicielles sont l\u00e9g\u00e8res (quelques dizaines de m\u00e9gaoctets) et ne n\u00e9cessitent aucune configuration complexe de pilotes mat\u00e9riels.<\/li>\n<li><strong>PyTorch et TensorFlow :<\/strong> Indispensables d\u00e8s lors que le calcul implique l&rsquo;optimisation de r\u00e9seaux profonds, la d\u00e9rivation automatique de cha\u00eenes diff\u00e9rentielles complexes ou l&rsquo;ex\u00e9cution massivement parall\u00e8le sur clusters GPU\/TPU. En contrepartie, ces environnements imposent une empreinte m\u00e9moire et disque tr\u00e8s lourde (souvent sup\u00e9rieure \u00e0 2 ou 3 gigaoctets d&rsquo;artefacts binaires) et introduisent une latence d&rsquo;initialisation non n\u00e9gligeable lors du d\u00e9marrage des contextes d&rsquo;ex\u00e9cution mat\u00e9riels.<\/li>\n<\/ul>\n<h2>12. Synth\u00e8se m\u00e9thodologique, benchmarks et bonnes pratiques de codage<\/h2>\n<h3>12.1 Matrice d\u00e9cisionnelle pour le choix de l&rsquo;impl\u00e9mentation<\/h3>\n<p>Face \u00e0 la diversit\u00e9 des approches pr\u00e9sent\u00e9es tout au long de cette \u00e9tude, le tableau synoptique suivant r\u00e9sume les caract\u00e9ristiques fondamentales et guide le choix d&rsquo;ing\u00e9nierie selon le contexte op\u00e9rationnel cibl\u00e9 :<\/p>\n<ul>\n<li><strong>Approche <code>math.exp<\/code> (Biblioth\u00e8que standard) :<\/strong> Adapt\u00e9e exclusivement aux scripts sans d\u00e9pendances externes et aux calculs scalaires isol\u00e9s sur valeurs strictement born\u00e9es (<span class=\"arabpsy-math-inline\" data-latex=\"|x| &lt; 700\">$|x| &lt; 700$<\/span>). Inappropri\u00e9e pour le calcul vectoriel en raison de l&#039;absence de vectorisation et du risque d&#039;<code>OverflowError<\/code>.<\/li>\n<li><strong>Approche <code>scipy.special.expit<\/code> :<\/strong> Standard de r\u00e9f\u00e9rence absolu pour le calcul scientifique et l&rsquo;analyse de donn\u00e9es tabulaires sur CPU. Assure une robustesse num\u00e9rique totale, une \u00e9criture vectoris\u00e9e C native et un temps de traitement minimal sans surcharge cognitive de conception.<\/li>\n<li><strong>Approche <code>numpy<\/code> personnalis\u00e9e (avec partitionnement conditionnel) :<\/strong> Recommand\u00e9e lorsque la biblioth\u00e8que SciPy ne peut \u00eatre d\u00e9ploy\u00e9e au sein de l&rsquo;environnement de production (contraintes d&rsquo;espace embarqu\u00e9, images conteneurs ultra-l\u00e9g\u00e8res), tout en garantissant une immunit\u00e9 totale face aux saturations d&rsquo;exposant.<\/li>\n<li><strong>Approche <code>torch.sigmoid<\/code> \/ <code>tf.math.sigmoid<\/code> :<\/strong> Choix imp\u00e9ratif pour l&rsquo;ing\u00e9nierie des r\u00e9seaux de neurones, la r\u00e9tropropagation des gradients et le traitement matriciel haute performance sur acc\u00e9l\u00e9rateurs graphiques.<\/li>\n<\/ul>\n<h3>12.2 R\u00e8gles d&rsquo;or pour un code robuste en production<\/h3>\n<p>Pour p\u00e9renniser le d\u00e9ploiement d&rsquo;algorithmes reposant sur le calcul de la fonction sigmo\u00efde dans des syst\u00e8mes critiques en production, il convient d&rsquo;adh\u00e9rer scrupuleusement aux trois imp\u00e9ratifs d&rsquo;ing\u00e9nierie suivants :<\/p>\n<ul>\n<li><strong>Normalisation syst\u00e9matique des flux entrants :<\/strong> Ne transmettez jamais de grandeurs physiques non mises \u00e0 l&rsquo;\u00e9chelle directement \u00e0 une fonction sigmo\u00efde. Appliquez toujours une standardisation z-score (<span class=\"arabpsy-math-inline\" data-latex=\"z = (x - \\mu) \/ \\sigma\">$z = (x &#8211; \\mu) \/ \\sigma$<\/span>) ou une mise \u00e0 l&rsquo;\u00e9chelle min-max pr\u00e9alable afin d&rsquo;\u00e9viter que les activations ne d\u00e9rivent instantan\u00e9ment vers les zones de saturation asymptotique o\u00f9 les gradients s&rsquo;\u00e9vanouissent.<\/li>\n<li><strong>Typage strict des donn\u00e9es :<\/strong> Sp\u00e9cifiez explicitement les annotations de types via les modules <code>typing<\/code> et <code>numpy.typing<\/code> pour pr\u00e9venir l&rsquo;injection accidentelle d&rsquo;arguments textuels ou d&rsquo;objets complexes susceptibles de briser les cha\u00eenes d&rsquo;ex\u00e9cution compil\u00e9es C :<br \/>\n    <br \/><code>def calculer_activations(donnees: np.ndarray) -&gt; np.ndarray:<\/code><\/li>\n<li><strong>Int\u00e9gration de tests unitaires aux bornes :<\/strong> Mettez en place dans votre suite logicielle (ex. via <code>pytest<\/code>) des tests de r\u00e9sistance injectant d\u00e9lib\u00e9r\u00e9ment des valeurs extr\u00eames (<span class=\"arabpsy-math-inline\" data-latex=\"-10^9\">$-10^9$<\/span>, <span class=\"arabpsy-math-inline\" data-latex=\"+10^9\">$+10^9$<\/span>, infinis, z\u00e9ros) afin de garantir qu&rsquo;aucune mise \u00e0 jour ult\u00e9rieure de l&rsquo;environnement ne r\u00e9introduise de d\u00e9passements de capacit\u00e9.<\/li>\n<\/ul>\n<h3>12.3 Erreurs courantes et strat\u00e9gies d&rsquo;att\u00e9nuation<\/h3>\n<p>L&rsquo;exp\u00e9rience montre que certaines erreurs r\u00e9currentes p\u00e9nalisent l&rsquo;efficacit\u00e9 des d\u00e9veloppements logiciels. La premi\u00e8re m\u00e9prise fr\u00e9quente consiste \u00e0 confondre la fonction sigmo\u00efde logistique avec la tangente hyperbolique. Bien que toutes deux exhibent une morphologie en esse, <span class=\"arabpsy-math-inline\" data-latex=\"tanh(x)\">$tanh(x)$<\/span> produit des sorties centr\u00e9es sur l&rsquo;intervalle <span class=\"arabpsy-math-inline\" data-latex=\"]-1, 1[\">$]-1, 1[$<\/span>, alors que la sigmo\u00efde produit des sorties strictement positives <span class=\"arabpsy-math-inline\" data-latex=\"]0, 1[\">$]0, 1[$<\/span>. Intervertir ces deux fonctions dans une architecture de classification probabiliste g\u00e9n\u00e8re des pr\u00e9dictions arithm\u00e9tiquement incoh\u00e9rentes.<\/p>\n<p>Une seconde erreur fr\u00e9quente r\u00e9side dans l&rsquo;omission involontaire du signe de n\u00e9gation dans l&rsquo;exposant : \u00e9crire <code>1 \/ (1 + exp(x))<\/code> au lieu de <code>1 \/ (1 + exp(-x))<\/code> a pour cons\u00e9quence d&rsquo;inverser int\u00e9gralement la dynamique de classement, assignant les plus fortes probabilit\u00e9s aux scores d&rsquo;activation les plus faibles.<\/p>\n<p>Enfin, l&rsquo;\u00e9cueil le plus dommageable concerne le calcul disjoint de l&rsquo;entropie crois\u00e9e : \u00e9valuer manuellement <code>log(expit(x))<\/code> sur des valeurs fortement n\u00e9gatives engendre une ind\u00e9termination num\u00e9rique due \u00e0 l&rsquo;\u00e9valuation de <span class=\"arabpsy-math-inline\" data-latex=\"ln(0)\">$ln(0)$<\/span>. Il convient de toujours lui pr\u00e9f\u00e9rer les fonctions de perte num\u00e9riquement int\u00e9gr\u00e9es (telles que <code>scipy.special.log_expit<\/code> ou <code>torch.nn.BCEWithLogitsLoss<\/code>), qui stabilisent le produit analytique au moyen de formulations logarithmiques unifi\u00e9es sans aucune perte d&rsquo;information sous la virgule.<\/p>\n<h2>R\u00e9f\u00e9rences<\/h2>\n<ul>\n<li>Cox, D. R. (1958). The regression analysis of binary sequences. <em>Journal of the Royal Statistical Society: Series B (Methodological)<\/em>, 20(2), 215-232. <a rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.1111\/j.2517-6161.1958.tb00292.x\">https:\/\/doi.org\/10.1111\/j.2517-6161.1958.tb00292.x<\/a><\/li>\n<li>Goodfellow, I., Bengio, Y., &amp; Courville, A. (2016). <em>Deep Learning<\/em>. MIT Press. <a rel=\"noopener noreferrer\" href=\"https:\/\/www.deeplearningbook.org\/\">https:\/\/www.deeplearningbook.org\/<\/a><\/li>\n<li>Harris, C. R., Millman, K. J., van der Walt, S. J., Gommers, R., Virtanen, P., Cournapeau, D., &#8230; &amp; Oliphant, T. E. (2020). Array programming with NumPy. <em>Nature<\/em>, 585(7825), 357-362. <a rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.1038\/s41586-020-2649-2\">https:\/\/doi.org\/10.1038\/s41586-020-2649-2<\/a><\/li>\n<li>IEEE Computer Society. (2019). <em>IEEE Standard for Floating-Point Arithmetic<\/em> (IEEE Std 754-2019). IEEE. <a rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.1109\/IEEESTD.2019.8766229\">https:\/\/doi.org\/10.1109\/IEEESTD.2019.8766229<\/a><\/li>\n<li>Nelder, J. A., &amp; Wedderburn, R. W. (1972). Generalized linear models. <em>Journal of the Royal Statistical Society: Series A (General)<\/em>, 135(3), 370-384. <a rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.2307\/2344614\">https:\/\/doi.org\/10.2307\/2344614<\/a><\/li>\n<li>Paszke, A., Gross, S., Massa, F., Lerer, A., Bradbury, J., Chanan, G., &#8230; &amp; Chintala, S. (2019). PyTorch: An imperative style, high-performance deep learning library. <em>Advances in Neural Information Processing Systems<\/em>, 32, 8026-8037. <a rel=\"noopener noreferrer\" href=\"https:\/\/proceedings.neurips.cc\/paper\/2019\/hash\/bdbca288fee7f92f2bfa9f7012727740-Abstract.html\">https:\/\/proceedings.neurips.cc\/paper\/2019\/hash\/bdbca288fee7f92f2bfa9f7012727740-Abstract.html<\/a><\/li>\n<li>Verhulst, P. F. (1838). Notice sur la loi que la population poursuit dans son accroissement. <em>Correspondance Math\u00e9matique et Physique<\/em>, 10, 113-121.<\/li>\n<li>Virtanen, P., Gommers, R., Oliphant, T. E., Haberland, M., Reddy, T., Cournapeau, D., &#8230; &amp; SciPy 1.0 Contributors. (2020). SciPy 1.0: Fundamental algorithms for scientific computing in Python. <em>Nature Methods<\/em>, 17(3), 261-272. <a rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.1038\/s41592-019-0686-2\">https:\/\/doi.org\/10.1038\/s41592-019-0686-2<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>D\u00e9couvrez comment calculer la fonction sigmo\u00efde en Python avec SciPy, NumPy et la biblioth\u00e8que standard au travers d&rsquo;exemples math\u00e9matiques d\u00e9taill\u00e9s.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","categories":[4882,2465,359],"tags":[9975,2960,2468,2560,9976],"class_list":["post-9130","psych_stat","type-psych_stat","status-publish","hentry","category-calcul-scientifique","category-programmation-python","category-statistiques-appliquees","tag-fonction-sigmoide","tag-numpy","tag-python","tag-regression-logistique","tag-scipy-expit"],"_links":{"self":[{"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/psych_stat\/9130","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/psych_stat"}],"about":[{"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/types\/psych_stat"}],"author":[{"embeddable":true,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=9130"}],"version-history":[{"count":1,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/psych_stat\/9130\/revisions"}],"predecessor-version":[{"id":9132,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/psych_stat\/9130\/revisions\/9132"}],"wp:attachment":[{"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=9130"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=9130"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=9130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}