Softmax et temperature

Softmax et temperature#

Cette explication est inspirée du tutoriel ici

Pour visualiser la fonction et comprendre le concept de temperature cf ici

Pour mieux comprendre le sens de cette fonction, cf. aussi cette vidéo

Qu’est-ce que la fonction softmax?

C’est une fonction d’activation qui permet de transformer les outputs d’un réseau de neurones en probabilités. Les outputs sont des chiffres arbitraires qui vont de -∞ à ∞. Il faut les normaliser pour faire en sorte de les transformer en une série de valeurs dont la somme est égale à 1.

Pour ce faire on utilise la fonction exponentielle

\[ {\displaystyle \forall x\quad \exp(x)=\mathrm {e} ^{x}}. \]

Et on normalise les valeurs en les divisant par leur somme.

Voici un exemple:

import numpy as np
logits = np.array([0,-1,1])

Ici j’ai trois valeurs. Évidemment le plus probable sera le plus élévé (1) et le moins probable le moins élévé (-1). Je peux le contater comme suit:

np.argmax(logits)
2

La fonction argmax me dit quel est l’argument (dans la liste [1,-10,23]) qui a la valeur la plus élévée. C’est le 2 (à savoir le 3ème).

Je peux aussi utiliser la fonction argsort pour avoir le classement des trois:

np.argsort(logits)
array([1, 0, 2])

Voici l’ordre: le moins probable est le deuxième, ensuite le premier et le plus probable est le troisième.

Mais de cette manière je ne connais pas leur probabilité relative, je ne connais pas la distribution de la probabilité.

Je peux alors utiliser la focntion exponentielle pour normaliser la liste d’outputs:

exp_logits = np.exp(logits)
exp_logits
array([1.        , 0.36787944, 2.71828183])

ensuite aditionner les trois:

sum_e_l = np.sum(exp_logits)
sum_e_l
4.086161269630487

et ensuite diviser chaque output de la fonction exponentielle par la somme totale. De cette manière j’aurai trois valeurs dont la somme est égale à 1.:

exp_logits/sum_e_l
array([0.24472847, 0.09003057, 0.66524096])

J’aurais donc obtenu que la probabilité du premier output est du 24,4%, celle du deuxième de 0,9% et celle du troisième de 66%.

Définissons maintenant une fonction qui fait tout cela:

def softmax(array):
    logits = np.array(array)
    probability = np.exp(logits)/sum(np.exp(logits))
    return probability
softmax([1,2,3])
array([0.09003057, 0.24472847, 0.66524096])

Le problème de cette approche est qu’elle est très déterministe. Si les valeurs sont un peu plus lointaine, la probabilité du plus élévé sera presque égale à 100%:

softmax([-20,0,45])
array([5.90009054e-29, 2.86251858e-20, 1.00000000e+00])

Vous voyez? Pour corriger ce biais on peut multiplier les valeurs initiales de façon plus ou moins arbitraire pour faire en sorte de les rapprocher artificiellement. C’est ce qu’on appelle “temperature”. Le plus élévée sera la temperature, le plus on rapprochera les valeurs et le moins la prédiction sera déterministe (et donc les probabilités seront plus proches).

Nous allons rédéfinir notre fonction softmax sur cette base:

def softmax_tm(array,temperature):
    logits = np.array(array)
    probability = np.exp(logits/temperature)/sum(np.exp(logits/temperature))
    return probability
softmax_tm([-20,0,45],100)
array([0.24172435, 0.29524279, 0.46303286])