Sampling

Campionamento dei dati
Di solito la distribuzione delle probabilità normalizzata viene campionata usando torch.multinomial.

torch.multinomial(input, num_samples, replacement=False, *, generator=None, out=None)

Multinomial funziona in questo modo:
ritorna un tensore dove ogni riga contiene num_samples indici interi, campionati a partire dalla distribuzione di probabilità in input, locata alla corrispondente riga del tensore.

es.:

g = torch.Generator().manual_seed(2147483647)

# immaginiamo di avere una distribuzione di probabità del tipo
p = torch.tensor([0.6064, 0.3033, 0.0903])

# tale distribuzione ci dice che:
# il valore 0 ha probabilità 0.60
# il valore 1 ha probabilità 0.30
# il valore 2 ha probabilità 0.09

t = torch.multinomial(p, num_samples=10, replacement=True, generator=g)
# t = tensor([1, 1, 2, 0, 0, 2, 1, 1, 0, 0])

# Avremo un tensore che contiene un'array con i valori 0,1,2
# distribuiti secondo le probabilità dettate da p, quindi '0' comparirà il 60% delle volte,
# '1' il 30% e così via.

Considerando la mappatura itos dell'alfabeto, e avendo una distribuzione di probabilità dei 27 caratteri dell'alfabeto, possiamo campionarne 1 valore:

itos = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i', 10: 'j', 11: 'k', 12: 'l', 13: 'm', 14: 'n', 15: 'o', 16: 'p', 17: 'q', 18: 'r', 19: 's', 20: 't', 21: 'u', 22: 'v', 23: 'w', 24: 'x', 25: 'y', 26: 'z', 0: '.'}

p = torch.randn(27) # 27 numeri random tra 0. e 1.
# p = torch.tensor tensor([ 1.5555, -0.3182, -0.6450, -0.6836, -2.0897,  0.9151,  0.2523, -1.1074,
# -0.6000, -0.5682,  1.0553,  0.3278, -0.2156,  1.6075,  0.9092, -1.0640,
# 1.0440,  2.1065,  0.4608, -1.4605,  2.5640, -1.0001,  0.1883,  0.0841,
# -0.3244,  0.9603, -1.9544])

# assicuriamoci che i valori siano tutti positivi
p = p.exp()

# e che la distribuzione sia normalizzata
p = p / p.sum()

# p = tensor([0.0123, 0.0208, 0.0279, 0.1123, 0.0113, 0.0551, 0.0053, 0.0669, 0.1635,
#        0.0381, 0.0490, 0.0233, 0.0108, 0.0280, 0.0281, 0.0268, 0.0763, 0.0824,
#        0.0495, 0.0071, 0.0272, 0.0044, 0.0183, 0.0187, 0.0103, 0.0089, 0.0174])

# p.shape = torch.Size([27])

d = torch.multinomial(p, num_samples=1, replacement=True, generator=g)

# d = tensor([3]) che corrisponde a 
itos[d.item()]  # 'c'