Skip to content

Commit

Permalink
fix: remove typos and release printable copy
Browse files Browse the repository at this point in the history
  • Loading branch information
LemuelPuglisi committed Jan 25, 2021
1 parent 62375ef commit b4c7ee2
Show file tree
Hide file tree
Showing 9 changed files with 27 additions and 25 deletions.
26 changes: 14 additions & 12 deletions 10_Reti_neurali.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Una rete neurale in cui ogni nodo di un certo layer riceve tutti gli output del

### 1.3 Explanable AI

La rete neurale si presenta come un modello *black-box*: un osservatore esterno vede l'output prodotto dal modello a partire da un input, ma il modello non è in grado di *giustificare* il risultato ottenuto, ovvero non è in grado di spiegare il procedimento logico per cui si arriva a produrre quel risultato. Il termine *Explnable AI* indica una serie di tecniche a supporto di modelli di intelligenza artificiale per far sì che un risultato prodotto da tali modelli possa essere compreso da un essere umano. Tali tecniche sono molto importanti in ambito medico, nella guida autonoma, nella computer vision, etc.
La rete neurale si presenta come un modello *black-box*: un osservatore esterno vede l'output prodotto dal modello a partire da un input, ma il modello non è in grado di *giustificare* il risultato ottenuto, ovvero non è in grado di spiegare il procedimento logico per cui si arriva a produrre quel risultato. Il termine *Explanable AI* indica una serie di tecniche a supporto di modelli di intelligenza artificiale per far sì che un risultato prodotto da tali modelli possa essere compreso da un essere umano. Tali tecniche sono molto importanti in ambito medico, nella guida autonoma, nella computer vision, etc.

<div style="page-break-after: always;"></div>

Expand All @@ -73,7 +73,7 @@ La costruzione di una rete neurale è fondamentale per ottenere un modello di ma
* Quanti hidden layer definire?
* Quanti nodi deve contenere ciascun layer?
* Come connettere i nodi di layer consecutivi?
* Quale funzione di attivazione scegliere per ogni nodo di ogni layer?
* Quale funzione di attivazione scegliere per ogni layer?

Una volta definita la struttura, il modello deve essere addestrato su un training set al fine di trovare i valori ottimali dei pesi degli input ricevuti da ogni nodo della rete neurale in ogni layer. Per fare ciò occorre definire una funzione di costo *globale* $F$, detta ***funzione loss***, e trovare i pesi che la minimizzino. Le due ulteriori domande da porsi sono:

Expand Down Expand Up @@ -182,7 +182,7 @@ A differenza delle funzioni sigmoidee, la funzione softmax non opera sulla singo
$$
\mu(x_i) = \frac {exp(x_i)} {\sum_{j=1}^n exp(x_j)}
$$
La funzione ha valori in $[0, 1]$ come la funzione logistica. La somma dei valori calcolati su ogni componente del vettore è 1, dunque $\mu(\bar x)$ è una distribuzione di probabilità. Grazie all'esponenziale, le componenti del vettore con valori più alti ricevono valori molto più alti rispetto alle altre. In particolare se c'è una componente con un valore significativamente più alto rispetto a tutti gli altri, a questo componenti corrisponderà un valore vicino ad 1, mentre alle restanti un valore prossimo allo 0. La softmax ha problemi di saturazione, che possono essere aggirati utilizzando come funzione costo l'*entropia incrociata*.
La funzione ha valori in $[0, 1]$ come la funzione logistica. La somma dei valori calcolati su ogni componente del vettore è 1, dunque $\mu(\bar x)$ è una distribuzione di probabilità. Grazie all'esponenziale, le componenti del vettore con valori più alti ricevono valori molto più alti rispetto alle altre. In particolare se c'è una componente con un valore significativamente più alto rispetto a tutti gli altri, a questa componente corrisponderà un valore vicino ad 1, mentre alle restanti un valore prossimo allo 0. La softmax ha problemi di saturazione, che possono essere aggirati utilizzando come funzione costo l'*entropia incrociata*.

Il denominatore della funzione softmax coinvolge una somma di esponenziazioni. Quando i valori $x_i$ variano in un range molto ampio, le loro esponenziazioni $exp(x_i)$ finiscono per variare in un range esponenzialmente più ampio, che coinvolge valori molto piccoli e molto grandi. Sommare valori molto piccoli e molto grandi può portare a problemi di accuratezza nel calcolo svolto da una macchina.

Expand Down Expand Up @@ -221,7 +221,7 @@ x \text { if } x \ge 0 \\
\alpha [\exp(x) - 1] \text { if } x < 0
\end{cases}
$$
Dove $\alpha \ge 0$ p un *iper-parametro* tenuto fisso durante il learning dei pesi. Il processo di learning viene ripetuto con diversi valori di $\alpha$ per trovare il valore che permette di ottenere performance migliori.
Dove $\alpha \ge 0$ è un *iper-parametro* tenuto fisso durante il learning dei pesi. Il processo di learning viene ripetuto con diversi valori di $\alpha$ per trovare il valore che permette di ottenere performance migliori.

<div style="page-break-after: always;"></div>

Expand All @@ -245,7 +245,7 @@ $$
e la ***Huber loss***:
$$
L_{\delta}(\hat y, y) = \begin {cases}
(\hat y - y)^2 \text { if } |\hat y_i - y_i| \le \delta \\
(\hat y - y)^2 \text { if } |\hat y - y| \le \delta \\
2 \delta \times (|\bar y - y| - \frac 1 2 \delta) \text{ otherwise}
\end {cases}
$$
Expand All @@ -271,7 +271,7 @@ La radice quadrata del MSE è definita ***Root Mean Square Error*** (RMSE). Nell



#### 3.1.2 Regresson loss con vettori
#### 3.1.2 Regression loss con vettori

Nel caso in cui l'output è un vettore di valori $\bar {\hat y} = (\hat y_1 , ..., \hat y_n)$ anziché uno scalare, si sostituisce nel calcolo della squared loss, della Huber loss e del MSE la norma della differenza tra i vettori reale e predetto al posto della differenza tra i valori scalari.
$$
Expand Down Expand Up @@ -313,7 +313,7 @@ $$

#### 3.2.3 Divergenza di Kullback-Leibler

In generale sappiamo che $C(\bar p || \bar q) > H(\bar p)$ poiché $\bar q$ è sub-ottimale, mentre $\bar p$ è ottimale. La differenza tra $C(\bar p || \bar q)$ e $H(\bar p)$, chiamata Divergenza di *Kullback-Leiber* (*KL*), misura il numero medio di bit in più che occorrono per ogni simbolo:
In generale sappiamo che $C(\bar p || \bar q) > H(\bar p)$ poiché $\bar q$ è sub-ottimale, mentre $\bar p$ è ottimale. La differenza tra $C(\bar p || \bar q)$ e $H(\bar p)$, chiamata Divergenza di *Kullback-Leibler* (*KL*), misura il numero medio di bit in più che occorrono per ogni simbolo:
$$
KL(\bar p || \bar q) = C(\bar p || \bar q) - H(\bar p)
= \sum_{i=1}^n p_i \log_2 \frac {p_i}{q_i}
Expand Down Expand Up @@ -392,7 +392,7 @@ Similmente, per ogni matrice $X$, abbiamo che $\nabla_{X} ||X||_F^{2} = 2X$.

### 4.2 Matrice jacobiana

Sia $\bar{x} = (x_1, ..., x_n)$ un vettore di $n$ valori reali. Sia $f:\R^n \to \R^m$ ed $\bar y = f(\bar{x})$. La matrice jacobiana di $\bar{y}$ rispetto ad $\bar{x}$ è la matrice formata dalle derivate parziali prima di ciascuna componente di $\bar{y}$ rispetto a ciascuna componente di $\bar{x}$:
Sia $\bar{x} = (x_1, ..., x_n)$ un vettore di $n$ valori reali. Sia $f:\R^n \to \R^m$ ed $\bar y = f(\bar{x})$. La matrice jacobiana di $\bar{y}$ rispetto ad $\bar{x}$ è la matrice formata dalle derivate parziali prime di ciascuna componente di $\bar{y}$ rispetto a ciascuna componente di $\bar{x}$:
$$
Jf(\bar{x}) = J(\bar{y}) =
\begin{bmatrix}
Expand Down Expand Up @@ -449,7 +449,7 @@ Il metodo *stochastic gradient descent* è una variante della discesa del gradie

#### 4.3.5 Calcolo del gradiente

Una volta calcolata la funzione loss su un vettore di input, occorre calcolare il gradiente della funzione loss rispetto ai pesi della rete in quel determinato momento. Un algoritmo efficiente per il calcolo del gradiente è l'algoritmo di ***backpropagation***, che sfrutta il concetto di *grafo computazionale*.
Una volta calcolata la funzione loss su un vettore di output, occorre calcolare il gradiente della funzione loss rispetto ai pesi della rete in quel determinato momento. Un algoritmo efficiente per il calcolo del gradiente è l'algoritmo di ***backpropagation***, che sfrutta il concetto di *grafo computazionale*.



Expand Down Expand Up @@ -483,7 +483,7 @@ Dove la norma di Frobenius (o norma matriciale) è semplicemente la norma $L_2$
$$
J = L + s
$$
Ci riferiremo a $J$ con il nome di *objective function*. o *funzione loss regolarizzata*
Ci riferiremo a $J$ con il nome di *objective function* o *funzione loss regolarizzata*

<div style="page-break-after: always;"></div>

Expand All @@ -507,7 +507,9 @@ $$
$$
Nel caso più generale di funzioni multivariate, supponiamo che la funzione differenziabile $y$ abbia $u_1, \dots, u_m$ variabili, e che ogni funzione differenziabile $u_i$ abbia $x_1, ..., x_n$ variabili. La regola della catena enuncia che per calcolare la derivata parziale di $y$ rispetto ad $x_i$ è sufficiente calcolare:
$$
\frac{dy}{dx_i} = \frac{dy}{du_1}\frac{du_1}{dx_1} + \dots + \frac{dy}{du_n}\frac{du_m}{dx_1}
\frac{dy}{dx_i} = \frac{dy}{du_1}\frac{du_1}{dx_1} +
\frac{dy}{du_2}\frac{du_2}{dx_1} +
\dots + \frac{dy}{du_m}\frac{du_m}{dx_1}
$$
per $i = 1, 2, \dots, n$.

Expand Down Expand Up @@ -614,7 +616,7 @@ $$

### 4.9 Dropout

Nei capitoli precedenti si è vista la tecnica di bootstrapping utilizzata nella classificazione. Analogamente, viene utilizzata una tecnica che prende il nome di *dropout* nelle reti neurali. Lo scopo è quello di creare un consenso sui valori ottimali dei pesi, considerando il risultato ottenuto da diverse sottoreti neurali. Ad ogni epoca si seleziona in maniera random una frazione dei nod della rete, chiamata ***dropout rate***, e si rimuovono. Sulla rete neurale ridotta si effettua una iterazione del metodo di discesa del gradiente. Dal momento in cui la rete neurale completa contiene più nodi rispetto a quella utilizzata durante il training, alla fine del processo di allenamento i pesi ottenuti vengono ri-scalati, ovvero moltiplicati per il dropout rate.
Nei capitoli precedenti si è vista la tecnica di bootstrapping utilizzata nella classificazione. Analogamente, viene utilizzata una tecnica che prende il nome di *dropout* nelle reti neurali. Lo scopo è quello di creare un consenso sui valori ottimali dei pesi, considerando il risultato ottenuto da diverse sottoreti neurali. Ad ogni epoca si seleziona in maniera random una frazione dei nodi della rete, chiamata ***dropout rate***, e si rimuovono. Sulla rete neurale ridotta si effettua una iterazione del metodo di discesa del gradiente. Dal momento in cui la rete neurale completa contiene più nodi rispetto a quella utilizzata durante il training, alla fine del processo di allenamento i pesi ottenuti vengono ri-scalati, ovvero moltiplicati per il dropout rate.



Expand Down
2 changes: 1 addition & 1 deletion 6_Graph_matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ Per costruire tale sequenza si procede ad iterazioni:
* Al tempo 1 viene inserito in $U_1$ il nodo con il grado massimo.
* Al generico tempo $i$ viene inserito il nodo $u_i$ con il più alto numero di vicini in $U_{i-1}$.

Quindi nodi con alto grado e che hanno un elevato numero di connessioni con nodi *già presenti* nell'ordinamento vengono inseriti prima nella sequenza ordinata. In generale, ad ogni iterazioni si calcola un punteggio $S$ per ogni nodo.
Quindi nodi con alto grado e che hanno un elevato numero di connessioni con nodi *già presenti* nell'ordinamento vengono inseriti prima nella sequenza ordinata. In generale, ad ogni iterazione si calcola un punteggio $S$ per ogni nodo.

Sia $O^{m-1} = (u_1, ..., u_{m-1})$ la sequenza ordinata parziale. Il punteggio di un nodo candidato $v$ è definito sulla base di 3 insiemi:

Expand Down
4 changes: 2 additions & 2 deletions 7_Graph_Mining.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Vediamo un esempio con soglia $\sigma = 3$:

![image-20201221092846424](./_media/8._Graph_Mining__1.png)

Piuttosto che fare riferimento al *supporto*, che è un conteggio relativo, spesso si utilizza la *frequenza*, che è invece un conteggio relativo. La frequenza di un sottografo $S$ in un database $D$ è il rapporto tra il supporto ed il numero di grafi nel database. La soglia minima $\sigma$ in questo caso sarà espressa come una percentuale. Un sottografo è frequente se è presente in almeno $\sigma$% grafi del database.
Piuttosto che fare riferimento al *supporto*, che è un conteggio assoluto, spesso si utilizza la *frequenza*, che è invece un conteggio relativo. La frequenza di un sottografo $S$ in un database $D$ è il rapporto tra il supporto ed il numero di grafi nel database. La soglia minima $\sigma$ in questo caso sarà espressa come una percentuale. Un sottografo è frequente se è presente in almeno $\sigma$% grafi del database.



Expand Down Expand Up @@ -61,7 +61,7 @@ Quando al generico passo $k$ si verifica che l'insieme di sottografi frequenti c

L'approccio descritto in precedenza è basato su una strategia in ampiezza, ovvero BFS (Breadth-first Search): prima di generare i sottografi candidati con $k+1$ nodi, si calcolano tutti i sottografi frequenti con $k$ nodi.

Esiste anche un approccio alternativo che utilizza la strategia DFS (Depth-first search): si calcola il supporto di un sottografo candidato con $k-nodi$ e, se è frequente, si estende. Quindi si controlla il supporto del sottografo esteso e così via. L'approccio DFS richiede meno memoria, ma risulta meno efficace nel pruning.
Esiste anche un approccio alternativo che utilizza la strategia DFS (Depth-first search): si calcola il supporto di un sottografo candidato con $k- 1$ nodi e, se è frequente, si estende. Quindi si controlla il supporto del sottografo esteso e così via. L'approccio DFS richiede meno memoria, ma risulta meno efficace nel pruning.

<img src="./_media/8._Graph_Mining__3.png" alt="image-20201221110044089" style="margin:20px" />

Expand Down
20 changes: 10 additions & 10 deletions 8_Catene_di_Markov_HMM.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ Sia $A$ la **distribuzione di probabilità** iniziale. Ogni qual volta effettuia

Sia $M = (Q,I,A)$ una catena di Markov del primo ordine, irriducibile e aperiodica con *k* stati. Si dimostra che:
$$
\lim_{x\to\infty} P(\pi_n = j | \pi_i = i) = \lim_{x\to\infty} A_{i,j}^n = \sigma
\lim_{n\to\infty} P(\pi_n = j | \pi_i = i) = \lim_{n\to\infty} A_{i,j}^n = \sigma
$$
Tale proprietà vale per tutti gli $j$, dunque si ottiene un vettore di valori $\bar{\sigma} = (\sigma_1, ...,\sigma_k)$. Se $\bar{\sigma}$ contiene valori non nulli, allora $\bar{\sigma}$ è detta **distribuzione stazionaria**. Se tutti i valori di $\bar{\sigma}$ sono non nulli allora $\bar{\sigma}$ è l'unica distribuzione stazionaria.

Expand Down Expand Up @@ -224,7 +224,7 @@ P(\pi_1) \times
\prod_{i=1}^{n-1} P(\pi_{i+1}|\pi_i) \times P(x_1, ..., x_n | \pi_1, ..., \pi_n) = P(\pi_1) \times
\prod_{i=1}^{n-1} P(\pi_{i+1}|\pi_i) \times \prod_{i=1}^n P(x_i|\pi_i)
$$
Ma $P(\pi_{i+1}|\pi_i)$ corrisponde alla elemento $a_{\pi_i, \pi_{i+1}}$ della matrice di transizione e $P(x_i,\pi_i)$ corrisponde all'elemento $e_{\pi_i, x_i}$ della matrice di emissione, per cui riscriviamo l'espressione finale come segue:
Ma $P(\pi_{i+1}|\pi_i)$ corrisponde alla elemento $a_{\pi_i, \pi_{i+1}}$ della matrice di transizione e $P(x_i\mid\pi_i)$ corrisponde all'elemento $e_{\pi_i, x_i}$ della matrice di emissione, per cui riscriviamo l'espressione finale come segue:
$$
P(x_1, ..., x_n, \pi_1, ..., \pi_n) = P(\pi_1) \times \prod_{i=1}^{n-1} a_{\pi_i, \pi_{i+1}} \times \prod_{i=1}^n e_{\pi_i, x_i}
$$
Expand Down Expand Up @@ -293,7 +293,7 @@ for t = 1 in len(X):
for j = 1 to k:
sum = 0
# calcolo la probabilità di passare
# dallo uno qualsiasi tra gli stati
# da uno qualsiasi tra gli stati
# precedenti i a j
for i = 1 in k:
sum = sum + f[t,i] * A[i,j]
Expand Down Expand Up @@ -333,7 +333,7 @@ $$

#### 2.4.1 Algoritmo di Viterbi

L'algoritmo di Viterbi ha una struttura simile a quella dell'algoritmo forward. Tuttavia, anziché sommare il contributi provenienti da ogni singolo stato visitato al passo precedente, seleziona di volta in volta il contributo migliore, ovvero quello con il valore massimo. Ciò equivale nel lattice a tracciare un cammino di stati di lunghezza *n* che massimizzi la probabilità di ottenere la sequenza $X$:
L'algoritmo di Viterbi ha una struttura simile a quella dell'algoritmo forward. Tuttavia, anziché sommare i contributi provenienti da ogni singolo stato visitato al passo precedente, seleziona di volta in volta il contributo migliore, ovvero quello con il valore massimo. Ciò equivale nel lattice a tracciare un cammino di stati di lunghezza *n* che massimizzi la probabilità di ottenere la sequenza $X$:

<img src="./_media/9._Catene_di_Markov,_HMM__8.png" alt="image-20201123111918963" style="zoom:80%;" />

Expand Down Expand Up @@ -421,15 +421,15 @@ Mediante la struttura dati $phi$ si tiene traccia, ad ogni istante di tempo $t$,

### 2.5 Posterior Decoding

Il **posterior decoding** è un particolare problema di decoding. Avendo osservato una intera sequenza di simboli $X$, si vuole calcolare (a posteriori) lo stato $s$ più probabile all'istante $t$, ovvero lo stato $s$ tale che;
Il **posterior decoding** è un particolare problema di decoding. Avendo osservato una intera sequenza di simboli $X$, si vuole calcolare (a posteriori) lo stato $s$ più probabile all'istante $t$, ovvero lo stato $s$ tale che
$$
P(\pi_t = s|X) = arg \max_{i =1,...,k} P(\pi_t = i | X)
$$
Ma osserviamo che:
$$
P(\pi_t = i| X) = \frac{P(\pi_t = i, X)}{P(X)}
$$
Il problema di massimizzazione è analogo se anziché il rapporto consideriamo solo la probabilità congiunta al numeratore, che tral'altro possiamo esplicitare:
Il problema di massimizzazione è analogo se anziché il rapporto consideriamo solo la probabilità congiunta al numeratore, che tra l'altro possiamo esplicitare:
$$
P(\pi_t = i, X) = P(x_1, ..., x_n, \pi_1, ..., \pi_t=i, ..., \pi_n)
$$
Expand Down Expand Up @@ -459,7 +459,7 @@ Possiamo scomporre l'espressione:
$$
\sum_{j=1}^k P(x_{t+1}, ..., x_n, \pi_{t+1} = j, ..., \pi_n|\pi_t=i)
$$
Essendo che ad ogni iterazione della sommatoria lo stato $\pi_{t+1}$ è fissato a $j$, possiamo rimuovere dalla probabilità l'emissione dell'elemento $x_{t+1}$ (che sarà banalmente emessa dallo stato $j$) e la transizione dallo stato $i$ allo stato $j$ e moltiplicarli singolarmente:
Essendo che ad ogni iterazione della sommatoria lo stato $\pi_{t+1}$ è fissato a $j$, possiamo rimuovere dalla probabilità l'emissione dell'elemento $x_{t+1}$ (che sarà banalmente emesso dallo stato $j$) e la transizione dallo stato $i$ allo stato $j$ e moltiplicarli singolarmente:
$$
\sum_{j=1}^k P(\pi_{t+2}, ..., \pi_n, x_{t+2}, ..., x_n|\pi_t=i) \times a_{i,j} \times e_{j,x_{t+1}}
$$
Expand Down Expand Up @@ -504,7 +504,7 @@ def backward_probability(X, Q, Sigma):
symbol_emitted = X[t+1]
probabilty_to_add = B[t+1] * A[i,j] * E[j, symbol_emitted]
probability = probability + probability_to_add
# aggiorniamo il valore della backword probability
# aggiorniamo il valore della backward probability
# per lo stato i-esimo esaminato al tempo t
B[t,i] = probability

Expand Down Expand Up @@ -539,7 +539,7 @@ a_{s,t} = \frac{A_{s,t}}{\sum_{i=1}^k A_{s,i}}
$$

$$
e_{s,b} = \frac{E_{s,b}}{\sum_{j=1}^m A_{s,j}}
e_{s,b} = \frac{E_{s,b}}{\sum_{j=1}^m E_{s,j}}
$$

Tuttavia, pochi dati in input possono essere insufficienti per una stima corretta. Quindi è possibile ricadere nel problema dell'**overfitting**.
Expand Down Expand Up @@ -572,7 +572,7 @@ Data la sequenza di simboli $X$, tale espressione esprime la probabilità a post

![image-20201123172009711](./_media/9._Catene_di_Markov,_HMM__9.png)

Possiamo calcolare la probabilità che si arrivi allo stato $\pi_t = i$ attraverso un percorso $\pi_1, ..., \pi_{t-1}$ qualsiasi attraverso la **probabilità forward**, mentre calcoliamo la probabilità di arrivare al tempo $t+1$ tale che $\pi_{t+1} = j$ provenendo, al tempo $n$, da uno qualunque dei $k$ stati attraverso la **probabilità backward**. È necessario considerare anche la transizione centra da $i$ a $j$ e l'emissione del simbolo $x_{t+1}$.
Possiamo calcolare la probabilità che si arrivi allo stato $\pi_t = i$ attraverso un percorso $\pi_1, ..., \pi_{t-1}$ qualsiasi attraverso la **probabilità forward**, mentre calcoliamo la probabilità di arrivare al tempo $t+1$ tale che $\pi_{t+1} = j$ provenendo, al tempo $n$, da uno qualunque dei $k$ stati attraverso la **probabilità backward**. È necessario considerare anche la transizione da $i$ a $j$ e l'emissione del simbolo $x_{t+1}$.
$$
f_t(i) \times a_{i,j} \times e_{j, x_{t+1}} \times b_{t+1}(j)
$$
Expand Down
Binary file removed _releases/dive_into_data_mining_11_01_2021.pdf
Binary file not shown.
Binary file removed _releases/dive_into_data_mining_12_01_2021.pdf
Binary file not shown.
Binary file removed _releases/dive_into_data_mining_13_01_2021.pdf
Binary file not shown.
Binary file removed _releases/dive_into_data_mining_14_01_2021.pdf
Binary file not shown.
Binary file not shown.

0 comments on commit b4c7ee2

Please sign in to comment.