Salta ai contenuti

Fourier: vedere frequenze invece di tempo

Qualunque segnale, sotto ipotesi ragionevoli, è una somma di sinusoidi pure; cambiare la lente dal tempo alla frequenza rende facili problemi altrimenti difficili, e la stessa idea ricompare come front-end dei modelli audio, come positional encoding dei transformer e come trucco per insegnare alle reti i dettagli fini.

C’è un fatto che, la prima volta che lo si incontra, sembra troppo bello per essere vero: prendi una qualsiasi forma d’onda complicata — il suono di una voce, il tracciato di una latenza, l’increspatura di un’immagine — e la puoi scrivere esattamente come una somma di onde semplici, le sinusoidi, ciascuna con la sua frequenza, la sua altezza e il suo sfasamento. Niente vincoli artificiosi: vale per quasi ogni segnale che incontrerai. La forma d’onda mescolata che vedi è in realtà una ricetta di ingredienti elementari, e Fourier è lo strumento che legge quella ricetta.

Questo non è erudizione matematica. È il motivo per cui un problema può essere atrocemente difficile guardato da un lato e quasi banale guardato dall’altro. Filtrare un segnale nel tempo richiede una convoluzione — far scorrere un kernel e sommare prodotti, un conto pesante. Lo stesso filtraggio, guardato in frequenza, diventa una moltiplicazione punto per punto: scegli quanto tenere di ogni frequenza e moltiplichi. Lo stesso identico risultato, due livelli di fatica opposti. Imparare a saltare dal dominio del tempo a quello della frequenza, e a scegliere quale dei due rende il problema facile, è una delle abilità più riutilizzabili di tutta l’ingegneria dei segnali.

E c’è la ragione per cui questa idea vale per chi lavora con l’AI, e non è marginale. Lo spettrogramma — una rappresentazione costruita con Fourier — è ciò che entra in quasi ogni modello di speech, Whisper compreso: il modello non vede la forma d’onda grezza, vede frequenze nel tempo. Il positional encoding dei transformer è costruito con sinusoidi a frequenze diverse, un uso dichiarato di basi di Fourier. Le Fourier features sono il trucco che permette a una rete di imparare i dettagli ad alta frequenza che altrimenti le sfuggirebbero. Capire Fourier toglie il mistero da tutti e tre questi pezzi in un colpo solo.

Nel 1807 un matematico francese di nome Joseph Fourier (1768-1830, fisico e matematico, fra l’altro prefetto napoleonico e studioso d’Egitto) presenta all’Académie des Sciences di Parigi una memoria su un problema di fisica concreto: come si propaga il calore dentro un corpo solido. Per risolvere l’equazione che governa quel fenomeno — l’equazione del calore, un’equazione differenziale — Fourier introduce un’idea che ai suoi contemporanei suona quasi assurda: qualunque funzione, anche una con spigoli netti, si può scrivere come somma di seni e coseni, funzioni perfettamente lisce.

Perché proprio seni e coseni, e non altre funzioni? La ragione, per Fourier, era fisica prima che estetica. Le sinusoidi sono le “forme proprie” del problema del calore: una distribuzione di temperatura a forma di sinusoide si raffredda mantenendo la sua forma, limitandosi a diminuire d’ampiezza nel tempo, e ogni sinusoide lo fa a una velocità che dipende dalla sua frequenza. Scomporre la temperatura iniziale in sinusoidi significava quindi spezzare un problema difficile in tanti problemi facili e indipendenti, ciascuno risolubile da solo. È lo stesso vantaggio che ritroveremo in tutta la Parte: in frequenza, componenti che nel tempo si intrecciano diventano indipendenti.

L’idea incontra resistenza, e da uno dei più grandi matematici dell’epoca. Joseph-Louis Lagrange (1736-1813, matematico italo-francese, fra i padri della meccanica analitica) si oppone con fermezza: come può una somma di curve lisce riprodurre una funzione con un salto verticale, come l’onda quadra che alterna bruscamente tra due valori? Pierre-Simon Laplace (1749-1827) e Gaspard Monge sono più favorevoli, ma l’obiezione di Lagrange — e la critica generale di mancanza di rigore, perché le questioni di convergenza non erano ancora state chiarite — ritarda la pubblicazione. La versione premiata del 1811 resta criticata. Solo nel 1822 Fourier pubblica il libro che consolida la teoria, Théorie analytique de la chaleur (Teoria analitica del calore).

Il finale della storia è istruttivo: Fourier aveva ragione, ma la giustificazione rigorosa della sua intuizione arriva dopo, con Peter Gustav Lejeune Dirichlet (1805-1859, matematico tedesco, che nel 1829 stabilisce le prime condizioni sotto cui la serie converge davvero) e poi Riemann e Lebesgue.

È un caso da manuale di intuizione corretta che precede di decenni il formalismo che la mette in sicurezza — e di come anche un grande come Lagrange possa sbagliare a fiutare un’idea giusta. Vale la pena tenerlo a mente: l’obiezione di Lagrange non era stupida (la convergenza ai punti di salto è davvero delicata, come vedremo con il fenomeno di Gibbs), era solo eccessiva.

C’è una seconda data che conta quanto il 1822, ed è recente. Per usare Fourier su un computer si calcola la sua versione discreta, la DFT (la incontreremo fra poco), e il conto diretto costa moltissimo: cresce con il quadrato del numero di campioni. Nel 1965 James Cooley (matematico all’IBM Watson Research Center) e John Tukey (statistico) pubblicano “An Algorithm for the Machine Calculation of Complex Fourier Series” (Mathematics of Computation, vol. 19, pp. 297-301), introducendo la Fast Fourier Transform (FFT): un algoritmo divide-et-impera che abbatte il costo da proporzionale a N2N^2 a proporzionale a NlogNN \log N.

L’aneddoto è che la motivazione venne da un’esigenza geopolitica: Richard Garwin, fisico all’IBM, voleva un modo rapido di analizzare i dati sismici per rilevare test nucleari sovietici nel contesto dei negoziati sul disarmo. La FFT è regolarmente citata fra gli algoritmi più importanti del Novecento, ed è ciò che ha trasformato Fourier da bella teoria a strumento praticabile in tempo reale.

C’è una nota a margine che fa sorridere gli storici della matematica: l’idea di base della FFT era già stata scoperta da Carl Friedrich Gauss (1777-1855, matematico tedesco) intorno al 1805, mentre cercava di interpolare le orbite di asteroidi — prima ancora che Fourier pubblicasse la sua teoria. Ma il lavoro di Gauss restò in un quaderno non pubblicato, scritto in un latino oscuro, e l’algoritmo dovette essere riscoperto un secolo e mezzo dopo per avere impatto. La storia della scienza è piena di idee giuste arrivate troppo presto per essere usate.

L’algoritmo di Cooley-Tukey è, in spirito, parente stretto del divide-et-impera che vedremo negli algoritmi (la stessa idea di Monte Carlo Tree Search e della programmazione dinamica: spezzare un problema in sotto-problemi più piccoli, risolverli e ricombinare).

Nella mappa di questa Parte, il capitolo siede dopo i filtri e la convoluzione, che hanno enunciato e usato il teorema di convoluzione “in attesa di Fourier”, e prima degli spettrogrammi, che costruiscono sopra la trasformata a finestra che introdurremo qui. Logicamente i tre si sostengono a vicenda: i filtri si capiscono in frequenza, e la frequenza è l’oggetto di questo capitolo.

La trasformata di Fourier si lascia afferrare da tre angoli diversi, e tenerli tutti e tre evita di ridurla a una formula. Il primo è una metafora fisica — il prisma. Il secondo è strutturale — due viste dello stesso oggetto. Il terzo è operativo e fa da ponte verso il machine learning — una misura di somiglianza.

Punta un raggio di luce bianca contro un prisma di vetro e ne esce un arcobaleno. Il prisma non ha aggiunto niente: la luce bianca era già la somma di tutte quelle frequenze (i colori), solo mescolate in modo da apparire bianche. Il prisma le separa, e tu vedi finalmente di cosa era fatta quella luce.

La trasformata di Fourier è il prisma dei segnali. Prendi una forma d’onda qualunque — apparentemente un’unica cosa che varia nel tempo — e la trasformata la scompone nelle sue frequenze pure, le sinusoidi che la compongono. L’uscita di questo prisma matematico si chiama spettro: per ogni frequenza, dice quanta energia il segnale contiene a quella frequenza. Lo spettro è l’arcobaleno del segnale.

Va detto con chiarezza di che tipo di legame si tratta: questa è un’analogia didattica, non un’identità fisica. Il prisma è un pezzo di vetro che separa i colori per dispersione (la luce di frequenza diversa si piega di un angolo diverso); la trasformata di Fourier è un calcolo. La somiglianza è reale e profonda — entrambi decompongono in frequenze — ma il prisma non “esegue Fourier”, e Fourier non è fatto di vetro. Tieni la metafora come gancio per l’intuizione, non come affermazione sul mondo.

Il segnale è un solo oggetto, ma lo puoi descrivere in due lingue diverse. La prima è il dominio del tempo: l’ampiezza istante per istante, la forma d’onda che vedresti su un oscilloscopio. La seconda è il dominio della frequenza: quanta energia c’è a ciascuna frequenza, lo spettro che vedresti su un analizzatore di spettro.

Il punto cruciale: nessuna delle due viste è più “vera” dell’altra. Sono la stessa identica informazione, ricodificata. La trasformata di Fourier è la lente che ti porta dalla vista temporale a quella in frequenza; la trasformata inversa ti riporta indietro, e — sotto ipotesi ragionevoli sul segnale — non perdi nulla nel viaggio di andata e ritorno.

È come avere lo stesso brano musicale scritto in due notazioni: lo spartito (quali note, cioè quali frequenze) e la registrazione audio (la pressione dell’aria istante per istante, cioè il tempo). Stesso brano, due rappresentazioni, ciascuna comoda per cose diverse. Lo spartito è imbattibile per sapere quali note ci sono; la registrazione è imbattibile per sapere a che secondo entra il pianoforte. Cambiare notazione non cambia la musica.

Questa è la mossa concettuale che rende Fourier potente. Alcune domande sono difficili in una vista e facili nell’altra. “Quanto pesa la componente lenta di questo segnale rispetto a quella rapida?” è quasi illeggibile nel tempo e ovvia in frequenza. “A che istante preciso arriva questo impulso?” è ovvia nel tempo e diluita in frequenza. Saper scegliere la vista giusta è metà del lavoro.

Terzo angolo: misurare quanto il segnale somiglia a ogni sinusoide

Sezione intitolata “Terzo angolo: misurare quanto il segnale somiglia a ogni sinusoide”

Il terzo angolo è operativo e fa da ponte diretto verso le reti neurali. Come fa la trasformata, concretamente, a sapere “quanta” di una certa frequenza c’è nel segnale? Non per magia: lo misura per correlazione. Confronta il segnale con una sinusoide pura di quella frequenza e calcola quanto si somigliano.

Quel “quanto si somigliano” è, tecnicamente, un prodotto scalare — la stessa operazione di proiezione e somiglianza della Parte IV. Moltiplichi il segnale per la sinusoide punto per punto e sommi. Se il segnale contiene quella frequenza, i due “vanno a tempo” e la somma è grande; se non la contiene, le parti positive e negative si cancellano e la somma è circa zero. La trasformata fa questo confronto per ogni frequenza possibile, e il risultato è lo spettro.

Letta così, la trasformata di Fourier è esattamente lo stesso meccanismo del matched filter incontrato nel capitolo sui filtri — “quanto il segnale somiglia localmente a questo pattern” — solo che qui i pattern sono le sinusoidi a tutte le frequenze.

C’è una struttura matematica precisa sotto questa lettura. Le sinusoidi formano una base dello spazio dei segnali: un insieme di “direzioni” ortogonali fra cui si può scomporre qualunque segnale, senza ambiguità e senza ridondanza. La trasformata calcola le coordinate del segnale lungo quelle direzioni. È la stessa logica con cui un vettore nello spazio si scompone lungo gli assi xx, yy, zz proiettandolo su ciascuno: solo che gli assi, qui, sono le frequenze, e sono infiniti. Lo spettro è semplicemente l’elenco di quelle coordinate.

I tre angoli sono lo stesso oggetto da tre lati. Il prisma dà l’immagine fisica, le due viste danno la struttura logica, la correlazione dà il meccanismo di calcolo e il ponte verso il ML. Tienili tutti e tre: ciascuno torna utile in un punto diverso del capitolo.

C’è una sola idea — decomporre in sinusoidi — e quattro varianti formali, a seconda che il segnale sia periodico o no, continuo o campionato. Vale la pena tenerle distinte, perché confonderle è una delle fonti di errore più comuni.

Serie di Fourier — segnali periodici e continui. Un segnale che si ripete con periodo TT (un’onda che torna identica ogni TT secondi) si scrive come somma di sinusoidi le cui frequenze sono multipli interi della frequenza fondamentale 1/T1/T. Questi multipli si chiamano armoniche: la fondamentale, poi il doppio, il triplo, e così via. In forma compatta:

x(t)=n=cnei2πnt/Tx(t) = \sum_{n=-\infty}^{\infty} c_n\, e^{\,i\, 2\pi n t / T}

In parole povere: il segnale periodico è una somma di mattoni, e ogni mattone è una sinusoide a una frequenza multipla della fondamentale, pesata da un coefficiente cnc_n. Lo spettro di un segnale periodico è quindi un insieme di righe discrete: c’è energia solo alle armoniche, niente in mezzo.

Trasformata di Fourier — segnali aperiodici e continui. E se il segnale non si ripete? Immagina di far crescere il periodo TT all’infinito: le armoniche, che distavano 1/T1/T l’una dall’altra, si infittiscono finché lo spettro a righe diventa una curva continua. La somma diventa un integrale:

X(f)=x(t)ei2πftdtX(f) = \int_{-\infty}^{\infty} x(t)\, e^{-i\, 2\pi f t}\, dt

Per ogni frequenza ff, l’integrale è esattamente la correlazione del terzo angolo: il segnale x(t)x(t) moltiplicato per l’esponenziale complesso (che racchiude seno e coseno a frequenza ff) e sommato su tutto il tempo. Il risultato X(f)X(f) dice quanto di quella frequenza c’è nel segnale.

DFT — segnali discreti e finiti. Nei computer non abbiamo funzioni continue: abbiamo NN campioni, i numeri usciti dal campionamento. Né possiamo integrare su tutto il tempo, perché il segnale che teniamo in memoria è finito. La DFT (Discrete Fourier Transform) è la versione fatta apposta per questo caso: prende quegli NN campioni e restituisce NN coefficienti complessi:

X[k]=n=0N1x[n]ei2πkn/NX[k] = \sum_{n=0}^{N-1} x[n]\, e^{-i\, 2\pi k n / N}

Leggiamola: per ottenere il coefficiente X[k]X[k] della kk-esima frequenza, scorri tutti gli NN campioni x[n]x[n], moltiplica ciascuno per l’esponenziale complesso valutato in kn/Nkn/N, e sommi. È la correlazione, di nuovo, ma su un numero finito di campioni e per un numero finito di frequenze. Il costo di calcolare tutti gli NN coefficienti in modo diretto è dell’ordine di N2N^2: NN coefficienti, ognuno una somma di NN termini.

FFT — non una trasformata, un algoritmo. Qui sta l’equivoco più frequente, da disinnescare subito: la FFT non è una trasformata diversa dalla DFT. È un algoritmo per calcolare la stessa, identica DFT in modo molto più rapido.

L’idea di Cooley e Tukey è divide-et-impera: la DFT di NN campioni si spezza nella DFT dei campioni di indice pari più quella dei campioni di indice dispari, e si ricombinano i due risultati. Ricorsivamente, ogni livello dimezza il problema, e i livelli sono logN\log N. Il costo crolla da N2N^2 a NlogNN \log N.

Per dare una scala: con N=106N = 10^6 campioni, N2N^2 è mille miliardi di operazioni, mentre NlogNN \log N è circa venti milioni — il fattore che separa “impraticabile” da “in tempo reale”. La distanza fra le due crescite è esattamente il tipo di cosa che la notazione Big-O (Parte IV) serve a misurare, e qui non è teoria: è la differenza fra poter calcolare lo spettro di un brano audio mentre lo ascolti oppure no.

Negli integrali sopra è comparso ei2πfte^{-i\,2\pi f t}, e vale spendere una riga per demistificarlo. La formula di Eulero dice che

eiθ=cosθ+isinθe^{i\theta} = \cos\theta + i\,\sin\theta

In parole povere: un esponenziale complesso è solo un modo compatto di portare insieme un coseno e un seno. Perché servono entrambi? Perché un singolo coseno non basta a catturare una sinusoide qualunque: serve sapere quanto è alta (l’ampiezza) e a che punto del suo ciclo si trova (la fase). Un numero complesso porta esattamente due informazioni — il suo modulo e il suo argomento (l’angolo) — e mappa perfettamente su ampiezza e fase. Non serve saper manipolare numeri complessi per seguire il capitolo: basta tenere a mente che un coefficiente complesso è una coppia “quanto” + “dove nel ciclo”.

C’è una domanda pratica che spesso si trascura e poi morde: la DFT restituisce NN coefficienti indicizzati da k=0,1,,N1k = 0, 1, \dots, N-1, ma quel kk è un indice astratto, non una frequenza in Hertz. A che frequenza fisica corrisponde il bin kk? La risposta dipende da quanto velocemente hai campionato. Se la frequenza di campionamento è fsf_s (campioni al secondo) e hai NN campioni, il bin kk corrisponde alla frequenza

fk=kfsNf_k = k \cdot \frac{f_s}{N}

In parole povere: i bin sono spaziati uniformemente di fs/Nf_s/N Hz l’uno dall’altro. Il bin 00 è la frequenza zero (la componente continua, la media del segnale); l’ultimo bin utile sta vicino a fs/2f_s/2, la frequenza di Nyquist incontrata nel capitolo sul campionamento.

Due conseguenze pratiche. Primo, la risoluzione in frequenza è fs/Nf_s/N: per distinguere frequenze più vicine fra loro devi acquisire più campioni (un NN più grande), che a parità di fsf_s significa una finestra temporale più lunga — di nuovo il principio di indeterminazione, da un’altra porta. Secondo, per un segnale reale (numeri veri, non complessi) lo spettro è simmetrico: la seconda metà dei bin è il riflesso della prima, e per questo le librerie offrono una variante “reale” (rfft) che restituisce solo i N/2+1N/2 + 1 bin indipendenti, risparmiando metà del lavoro e metà della confusione.

Vale la pena ancorare l’intuizione di “alta” e “bassa” frequenza, perché tornerà di continuo nel ponte verso l’AI. Una frequenza bassa è una variazione lenta: l’andamento di fondo, ciò che cambia gradualmente lungo tutto il segnale. In un’immagine, le basse frequenze sono le grandi zone di colore uniforme e le transizioni morbide. In una serie temporale, sono il trend di fondo.

Una frequenza alta è una variazione rapida: i dettagli fini, i bordi netti, i cambiamenti bruschi da un campione al successivo. In un’immagine, le alte frequenze sono i contorni, la grana, le texture. In audio, sono gli acuti e i transienti percussivi.

Questa lettura collega Fourier a due fatti che incontreremo. I filtri passa-basso del capitolo precedente tengono le basse frequenze e buttano le alte: ecco perché sfocano (cancellano i dettagli fini). E lo spectral bias delle reti neurali — il fatto che imparino prima le basse frequenze — significa, in questa lingua, che una rete coglie subito l’andamento grossolano di una funzione e fatica sui dettagli fini, esattamente come un’immagine che si mette a fuoco partendo dalle forme grandi.

Ogni coefficiente X[k]X[k] è dunque un numero complesso, e porta due cose. Il suo modulo X[k]|X[k]| è lo spettro di ampiezza: quanta energia c’è a quella frequenza. È quello che si vede quasi sempre disegnato, l’altezza delle barre nello spettro. Il suo argomento (l’angolo) è lo spettro di fase: a che punto del ciclo parte quella sinusoide, che equivale a uno spostamento temporale.

Un errore diffusissimo è trattare la fase come un dettaglio trascurabile e guardare solo l’ampiezza. La fase porta invece moltissima struttura. Un esperimento classico lo mostra in modo netto: prendi due immagini, calcola la trasformata di ciascuna, poi ricombina l’ampiezza della prima con la fase della seconda e antitrasforma. L’immagine che esce assomiglia alla seconda, non alla prima: è la fase a portare la disposizione spaziale, i contorni, la “forma” delle cose. L’ampiezza dice quanto di ogni frequenza c’è; la fase dice come quelle frequenze sono allineate fra loro, ed è lì che vive gran parte dell’informazione.

Il teorema di convoluzione, finalmente giustificato

Sezione intitolata “Il teorema di convoluzione, finalmente giustificato”

Nel capitolo sui filtri abbiamo enunciato e usato un fatto, promettendo che la sua giustificazione sarebbe vissuta qui:

xh        XHx * h \;\;\longleftrightarrow\;\; X \cdot H

La convoluzione nel tempo corrisponde alla moltiplicazione in frequenza. Se XX e HH sono le trasformate di xx e hh, allora la trasformata della convoluzione xhx * h è semplicemente il prodotto XHX \cdot H, frequenza per frequenza. E vale anche il duale: moltiplicare nel tempo corrisponde a convolvere in frequenza.

L’intuizione del perché è alla portata, e poggia sul terzo angolo. Una convoluzione è una somma di copie scalate e traslate di un segnale. La trasformata di una versione traslata di un segnale è la trasformata originale moltiplicata per un fattore di fase (uno sfasamento dipendente dalla frequenza). Quando sommi tutte le copie traslate e trasformi, quei fattori di fase si combinano in modo da dare esattamente il prodotto XHX \cdot H. La traslazione nel tempo, che nel dominio del tempo costringe a “far scorrere e sommare”, in frequenza diventa una pura moltiplicazione. La dimostrazione completa è un conto di un paio di righe; qui basta tenere l’intuizione e la conclusione.

C’è anche un modo intuitivo di vederlo dal lato del filtro. Un filtro lascia passare certe frequenze e ne attenua altre: la sua risposta in frequenza H(f)H(f) è proprio il “guadagno” che applica a ciascuna frequenza. Filtrare un segnale, allora, significa moltiplicare la quantità di ogni frequenza presente nel segnale (X(f)X(f)) per il guadagno del filtro a quella frequenza (H(f)H(f)). È letteralmente una moltiplicazione frequenza per frequenza. La convoluzione nel tempo è solo lo stesso effetto descritto nell’altra lingua, dove appare molto più laboriosa. Il teorema dice che le due descrizioni coincidono.

Questo è un teorema — una relazione formalmente provabile, valida sotto ipotesi precise sull’esistenza delle trasformate — non un’analogia né una regola empirica.

È anche la ragione tecnica per cui filtrare in frequenza è facile: scegli la forma di H(f)H(f) (quanto tenere di ogni frequenza) e moltiplichi, invece di progettare un kernel nel tempo e farlo scorrere. Ed è perché la FFT rese il filtraggio praticabile: invece di una convoluzione che costa NMN \cdot M, fai la FFT del segnale, moltiplichi per HH, e antitrasformi, il tutto in NlogNN \log N. Per kernel lunghi è un risparmio enorme, ed è oggi il modo standard di applicare filtri lunghi a segnali lunghi.

C’è un limite che non si può aggirare, e merita di essere capito perché è facile prenderlo per un difetto tecnologico mentre è matematica pura. Non puoi avere risoluzione perfetta sia nel tempo sia nella frequenza contemporaneamente. Il prodotto delle due risoluzioni è limitato dal basso:

ΔtΔf    costante\Delta t \cdot \Delta f \;\geq\; \text{costante}

In parole povere: più stringi la localizzazione di un segnale nel tempo, più il suo spettro si allarga, e viceversa. Gli estremi lo rendono evidente. Un tono puro — una sinusoide che dura per sempre — ha uno spettro a riga singola, perfettamente preciso in frequenza, ma è totalmente delocalizzato nel tempo (è ovunque, non “a un certo istante”). All’opposto, un click istantaneo — un singolo colpo secco — è perfettamente localizzato nel tempo ma ha uno spettro larghissimo, contiene tutte le frequenze. Non c’è verso di avere entrambe le precisioni insieme.

Questo è lo stesso principio di indeterminazione che in fisica porta il nome di Heisenberg; in questo contesto si chiama principio di Heisenberg-Gabor (da Dennis Gabor, fisico ungherese-britannico, premio Nobel per l’olografia, che lo formalizzò per i segnali). La finestra che raggiunge il limite con uguaglianza — la migliore risoluzione congiunta possibile — è la gaussiana. Non è un teorema della fisica prestato ai segnali: è una proprietà matematica della coppia di trasformate, vale per qualunque segnale.

Quando le frequenze cambiano: la STFT e lo spettrogramma

Sezione intitolata “Quando le frequenze cambiano: la STFT e lo spettrogramma”

La trasformata di Fourier ha un limite pratico vistoso: assume che il segnale sia “sempre uguale a se stesso” su tutto il dominio. Ti dice quali frequenze ci sono, ma non quando. Per una sinusoide eterna va bene; per il parlato — dove le frequenze cambiano di continuo, vocale dopo vocale — è inutile sapere che “nel brano c’è un po’ di tutto” senza sapere a che istante.

La risposta è la Short-Time Fourier Transform (STFT, trasformata di Fourier a finestra). L’idea è semplice: invece di trasformare tutto il segnale in un colpo, lo spezzi in finestre brevi e sovrapposte, fai la FFT di ciascuna finestra, e impili i risultati uno accanto all’altro. L’assunzione di stazionarietà non viene eliminata, viene ridimensionata: si chiede che il segnale sia “abbastanza costante” solo dentro ogni breve finestra, non su tutto il brano.

Ottieni una matrice: un asse è il tempo (quale finestra), l’altro è la frequenza, e il valore in ogni cella è l’ampiezza di quella frequenza in quella finestra. Visualizzata come immagine — tempo in orizzontale, frequenza in verticale, intensità in colore — questa matrice si chiama spettrogramma.

Il principio di indeterminazione ricompare qui in forma operativa, come scelta della lunghezza della finestra. Una finestra lunga abbraccia molto tempo e dà ottima risoluzione in frequenza (distingue frequenze vicine) ma cattiva nel tempo (non sai con precisione quando una frequenza è comparsa). Una finestra corta dà ottima risoluzione temporale ma frequenze sfocate. Non puoi vincere su entrambi i fronti: la scelta della finestra è il modo in cui spendi il budget fissato dall’indeterminazione. Lo spettrogramma è il fondamento del capitolo successivo (spettrogrammi, in preparazione, questa Parte) e, come vedremo, il front-end di quasi ogni modello speech.

Spectral leakage: perché lo spettro a volte è “sporco”

Sezione intitolata “Spectral leakage: perché lo spettro a volte è “sporco””

C’è un’insidia che colpisce chiunque calcoli una DFT su dati reali, e conviene anticiparla qui perché spiega molti spettri dall’aspetto strano. La DFT assume implicitamente che il blocco di NN campioni che le dai si ripeta periodicamente all’infinito: di fatto, lo tratta come un periodo di un segnale periodico.

Se il segnale completa un numero intero di cicli dentro il blocco, l’assunzione regge e ottieni picchi netti. Ma se non lo fa — e nei dati reali quasi mai lo fa — alla giunzione fra la fine del blocco e l’inizio della sua copia c’è una discontinuità fittizia, un salto che il segnale vero non aveva.

Quella discontinuità ha le sue frequenze, e la sua energia si “spande” sui bin vicini al picco vero. Il risultato è lo spectral leakage: invece di una riga netta, vedi un picco allargato con code che si estendono ai lati, e rischi di scambiare quelle code per frequenze che nel segnale non c’erano.

La cura è la finestratura (windowing): prima della FFT, moltiplichi il blocco per una funzione che va dolcemente a zero ai bordi — la finestra di Hann o di Hamming sono le più comuni. Azzerando i bordi, elimini la discontinuità alla giunzione e il leakage cala drasticamente. Il prezzo è un lieve allargamento di tutti i picchi (perché smorzare i bordi accorcia di fatto la parte utile del segnale), ma è un ottimo affare rispetto alle code del leakage. È la stessa finestra che la STFT applica a ogni segmento, ed è il motivo per cui gli spettrogrammi seri non usano mai blocchi “tagliati netti”.

Numeri minuscoli tolgono ogni mistero. Prendi quattro soli campioni, alternati: x=[1,  0,  1,  0]x = [\,1,\; 0,\; -1,\; 0\,]. È un segnale che sale e scende una volta nei quattro istanti — intuitivamente, “una oscillazione completa ogni quattro campioni”. Calcoliamo la DFT applicando la formula X[k]=n=03x[n]ei2πkn/4X[k] = \sum_{n=0}^{3} x[n]\, e^{-i\,2\pi k n / 4}. Conviene notare che, con N=4N = 4, l’esponenziale assume solo i valori 11, i-i, 1-1, ii a seconda dell’angolo, perché ruota a passi di un quarto di giro.

Il bin k=0k = 0 è la somma semplice dei campioni (l’esponenziale vale 11 per ogni nn): X[0]=1+01+0=0X[0] = 1 + 0 - 1 + 0 = 0. Significa che il segnale ha media zero, nessuna componente continua. Per k=1k = 1 la formula pesa i campioni con 1,i,1,i1, -i, -1, i:

X[1]=11+0(i)+(1)(1)+0i=1+1=2X[1] = 1\cdot 1 + 0\cdot(-i) + (-1)\cdot(-1) + 0\cdot i = 1 + 1 = 2

Per k=2k = 2 i pesi sono 1,1,1,11, -1, 1, -1, e si ottiene X[2]=1010=0X[2] = 1 - 0 - 1 - 0 = 0. Per k=3k = 3, per simmetria del segnale reale, si ottiene di nuovo X[3]=2X[3] = 2. Lo spettro è dunque [0,  2,  0,  2][\,0,\; 2,\; 0,\; 2\,]: tutta l’energia sta nel bin 11 (e nel suo riflesso, il bin 33). E ha senso — il segnale compie esattamente un’oscillazione nei quattro campioni, quindi vive interamente alla frequenza “una oscillazione per blocco”, che è proprio il bin 11. La DFT ha letto la frequenza corretta da quattro numeri, senza che dovessimo sapere in anticipo cosa cercare.

Esempio 2 — numerico: due sinusoidi che si sommano

Sezione intitolata “Esempio 2 — numerico: due sinusoidi che si sommano”

Prendi un segnale fatto di due sole frequenze: una sinusoide a 1 Hz di ampiezza 1, sommata a una a 3 Hz di ampiezza 0.5.

x(t)=1sin(2π1t)+0.5sin(2π3t)x(t) = 1 \cdot \sin(2\pi \cdot 1 \cdot t) + 0.5 \cdot \sin(2\pi \cdot 3 \cdot t)

Nel dominio del tempo, questo è una curva increspata: l’onda lenta a 1 Hz fa da andamento di fondo, e sopra ci galleggia un’increspatura più rapida a 3 Hz. A occhio, sulla forma d’onda, è difficile dire con precisione “quante frequenze ci sono e quali”. Nel dominio della frequenza, invece, lo spettro di ampiezza è di una semplicità totale: due barre, una alta 1 alla frequenza 1 Hz, una alta 0.5 alla frequenza 3 Hz, e zero ovunque altro. La trasformata ha letto la ricetta: due ingredienti, in quelle proporzioni. La trasformata inversa, da quelle due barre, ricostruisce esattamente la forma d’onda di partenza.

Esempio 3 — in codice: leggere e ricostruire uno spettro

Sezione intitolata “Esempio 3 — in codice: leggere e ricostruire uno spettro”
import numpy as np
fs = 100 # frequenza di campionamento: 100 campioni/secondo
t = np.arange(0, 1, 1 / fs) # 1 secondo, 100 campioni
x = np.sin(2 * np.pi * 1 * t) + 0.5 * np.sin(2 * np.pi * 3 * t)
# DFT calcolata via FFT (costo N log N, non N^2)
X = np.fft.rfft(x) # spettro (solo frequenze non negative)
freqs = np.fft.rfftfreq(len(x), 1 / fs)
ampiezze = np.abs(X) / len(x) * 2 # normalizzazione per leggere le ampiezze
picchi = freqs[ampiezze > 0.1]
print(picchi) # [1. 3.] -> trova le due frequenze
# antitrasformata: dallo spettro torno al tempo, senza perdere nulla
x_ricostruito = np.fft.irfft(X, n=len(x))
print(np.allclose(x, x_ricostruito)) # True

Tre cose da portare via. np.fft.rfft calcola la DFT di un segnale reale con l’algoritmo FFT, quindi in tempo NlogNN \log N. Lo spettro di ampiezza ha i picchi esattamente alle due frequenze del segnale, 11 e 33 Hz: la decomposizione si legge a occhio. E irfft riporta dallo spettro al tempo ricostruendo il segnale identico — la prova operativa che tempo e frequenza sono due viste della stessa informazione.

Esempio 4 — in codice: il teorema di convoluzione, verificato

Sezione intitolata “Esempio 4 — in codice: il teorema di convoluzione, verificato”

Il teorema di convoluzione si può toccare con mano: convolvere nel tempo deve dare lo stesso risultato che moltiplicare in frequenza. Verifichiamolo su due segnaletti corti.

import numpy as np
x = np.array([1.0, 2.0, 3.0, 0.0])
h = np.array([0.0, 1.0, 0.5, 0.0])
# Via 1: convoluzione diretta nel tempo (circolare, su N punti)
diretta = np.real(np.fft.ifft(np.fft.fft(x) * np.fft.fft(h)))
# Via 2: prodotto in frequenza, poi antitrasformata
X, H = np.fft.fft(x), np.fft.fft(h)
via_frequenza = np.real(np.fft.ifft(X * H))
print(np.allclose(diretta, via_frequenza)) # True

Le due strade danno lo stesso vettore, a meno di errori di arrotondamento. La prima fa il conto nel tempo; la seconda porta entrambi i segnali in frequenza con due FFT, li moltiplica punto per punto (un’operazione lineare, NN moltiplicazioni) e torna indietro con un’antitrasformata. Per segnali e kernel lunghi la seconda via è drasticamente più veloce, perché ogni FFT costa NlogNN \log N invece dei circa N2N^2 della convoluzione diretta. È il teorema di convoluzione che smette di essere una formula e diventa una scelta implementativa con un costo misurabile. (Nota tecnica: la FFT calcola la convoluzione circolare, che assume i segnali periodici; per la convoluzione lineare ordinaria si imbottiscono di zeri prima di trasformare.)

Esempio 5 — scenario reale: il ronzio di rete a 50 Hz

Sezione intitolata “Esempio 5 — scenario reale: il ronzio di rete a 50 Hz”

Hai registrato dell’audio, o un tracciato di elettrocardiogramma, e c’è un fastidioso ronzio di sottofondo: l’interferenza della rete elettrica, che in Europa oscilla a 50 Hz (60 Hz in Nord America). Nel dominio del tempo il ronzio è mescolato a tutto il resto e non sai come toglierlo senza rovinare il segnale utile.

In frequenza, invece, il problema si risolve quasi da solo. Calcoli lo spettro e vedi un picco netto e isolato esattamente a 50 Hz: il ronzio è lì, separato da tutto il resto. A quel punto azzeri (o attenui) il coefficiente di quella frequenza e antitrasformi. Il ronzio sparisce, il resto del segnale resta intatto. Questo è esattamente il filtro notch incontrato nel capitolo sui filtri: “togliere una banda stretta e lasciare passare tutto il resto”. Lì lo abbiamo descritto come un kernel di convoluzione nel tempo; qui si vede perché funziona e quanto è banale in frequenza — è togliere una barra dallo spettro. Stessa operazione, descrizione molto più semplice grazie al cambio di vista.

Esempio 6 — l’onda quadra: la somma che scandalizzò Lagrange

Sezione intitolata “Esempio 6 — l’onda quadra: la somma che scandalizzò Lagrange”

L’onda quadra è il segnale che salta bruscamente fra due valori, +1+1 e 1-1, e ci resta a tratti costanti. È proprio il tipo di funzione con spigoli che a Lagrange sembrava impossibile costruire con curve lisce. Eppure la sua serie di Fourier esiste, ed è elegante: una somma di sole armoniche dispari, con ampiezze che decrescono come 1/n1/n.

x(t)=4π(sin(ωt)+13sin(3ωt)+15sin(5ωt)+)x(t) = \frac{4}{\pi}\left(\sin(\omega t) + \frac{1}{3}\sin(3\omega t) + \frac{1}{5}\sin(5\omega t) + \cdots\right)

Sommando solo il primo termine ottieni una sinusoide che ricorda vagamente l’onda quadra. Aggiungendo la terza armonica, poi la quinta, la settima, la curva si fa sempre più squadrata: i tratti piatti si appiattiscono, i fronti si fanno ripidi. Con infinite armoniche, l’uguaglianza è esatta. C’è un dettaglio affascinante: vicino ai salti rimane un piccolo overshoot, un sussulto che non scompare aggiungendo armoniche, solo si stringe. Si chiama fenomeno di Gibbs, ed è il modo in cui la matematica “paga” lo spigolo netto con un’oscillazione residua ai bordi — proprio nel punto che dava da pensare a Lagrange.

Esempio 7 — di sistema: lo spettrogramma di una voce

Sezione intitolata “Esempio 7 — di sistema: lo spettrogramma di una voce”

Registra qualcuno che pronuncia “ciao”. Nel tempo è una forma d’onda che non dice quasi nulla a occhio nudo. Calcola la STFT — finestre brevi, una FFT ciascuna — e disegna lo spettrogramma: ora vedi la struttura. Le vocali appaiono come bande orizzontali a frequenze ben definite (le formanti, i picchi di risonanza del tratto vocale), che si spostano nel tempo mentre la bocca cambia forma. Le consonanti come la “c” appaiono come schizzi verticali ad ampia banda (rumore breve, tutte le frequenze insieme). Lo spettrogramma rende visibile la struttura tempo-frequenza del parlato che la forma d’onda nascondeva — ed è esattamente in questa forma che il parlato entra in un modello di speech, come vedremo fra poco.

Front-end di audio e speech. Quasi nessun modello che lavora sul suono riceve la forma d’onda grezza. Riceve uno spettrogramma, o una sua variante (mel-spectrogram, MFCC) che ricalibra le frequenze sulla scala con cui l’orecchio umano le percepisce — più risoluzione sui bassi, dove l’orecchio è più sensibile, meno sugli acuti.

Capire la STFT spiega le scelte di questo front-end — lunghezza della finestra, passo (hop) fra finestre, numero di bande di frequenza — e i loro trade-off, che ricadono direttamente sulla qualità di ciò che il modello vede. Una finestra troppo corta sfoca le frequenze e confonde le vocali; un hop troppo grande perde i transienti rapidi delle consonanti.

Filtraggio efficiente. Per applicare un filtro lungo a un segnale lungo, il modo standard è passare per la frequenza: FFT del segnale, moltiplicazione per la risposta in frequenza del filtro, antitrasformata. Il teorema di convoluzione garantisce che il risultato è identico alla convoluzione nel tempo, ma il costo scende da NMN \cdot M a NlogNN \log N. È il motivo per cui i riverberi, gli equalizzatori e i filtri delle librerie di elaborazione audio sono veloci.

Analisi di serie temporali. Trovare periodicità nascoste — una stagionalità giornaliera nel traffico, un ciclo settimanale nelle metriche — è un problema di frequenza. Lo spettro (in questo contesto, il periodogramma) mostra i picchi alle frequenze dei cicli ricorrenti. È il ponte verso time-series-base (in preparazione, questa Parte).

Debug di rumore e interferenze. Un disturbo periodico — un ronzio, un’interferenza elettromagnetica, un artefatto di campionamento — si manifesta come picco netto nello spettro, anche quando nel tempo è invisibile perché annegato nel segnale. Lo spettro è spesso il primo posto dove guardare quando “c’è qualcosa che non va e non so cosa”.

Compressione. JPEG comprime le immagini con la DCT (Discrete Cosine Transform, una cugina stretta della DFT che usa solo coseni), perché in frequenza l’energia di un’immagine naturale si concentra in pochi coefficienti a bassa frequenza, e quelli ad alta frequenza si possono scartare con poca perdita visibile. MP3 e AAC fanno l’analogo sull’audio, lavorando in frequenza e buttando via ciò che l’orecchio non sente. È un cenno, ma mostra che “lavorare in frequenza per scartare il superfluo” è un pattern ricorrente.

Trattare l’audio come un’immagine. Una conseguenza dello spettrogramma è strategica per chi costruisce modelli: una volta che il suono è diventato una matrice tempo-frequenza, è di fatto un’immagine, e tutto l’armamentario della computer vision (strati convoluzionali, encoder pensati per immagini) si può riusare quasi pari pari. È esattamente la scelta di Whisper, il cui encoder tratta lo spettrogramma 80×300080 \times 3000 come tratterebbe un’immagine. La trasformazione di Fourier non è solo pre-processing: è il ponte che porta un problema audio dentro l’ecosistema, molto più maturo, dei modelli per immagini.

Il ponte verso l’AI: spettrogrammi, posizioni e dettagli fini

Sezione intitolata “Il ponte verso l’AI: spettrogrammi, posizioni e dettagli fini”

Qui Fourier smette di essere uno strumento da corso di elaborazione dei segnali e diventa un mattone di alcune delle architetture più usate nel deep learning. I legami sono di classi diverse — alcuni sono usi espliciti e dichiarati di basi o trasformate di Fourier, uno è un risultato empirico-teorico — e li marchiamo uno per uno, perché confonderli porta a intuizioni che si rompono.

Il legame più diretto è un’identità d’uso. Whisper, il modello di riconoscimento vocale di OpenAI (2022, descritto in “Robust Speech Recognition via Large-Scale Weak Supervision”), non riceve la forma d’onda grezza. La converte in un log-mel spectrogram: 80 bande di frequenza sulla scala mel, finestre da 25 ms con un passo di 10 ms, e per uno spezzone da 30 secondi una matrice di forma 80×300080 \times 3000 (80 frequenze per 3000 istanti). L’encoder di Whisper la tratta sostanzialmente come un’immagine — primi strati convoluzionali compresi.

Non è una scelta isolata di Whisper: dai vecchi sistemi a modelli di Markov nascosti (HMM-GMM) fino ai modelli end-to-end moderni, l’input dello speech è quasi sempre uno spettrogramma o features da esso derivate (come gli MFCC, una compressione dello spettro mel).

La classe del legame è precisa: è la STFT di questo capitolo, usata come front-end. Non è un’analogia — è proprio la trasformata a finestra che produce ciò che il modello vede. Capire la STFT significa capire letteralmente l’input di un modello speech, e capire i suoi parametri (lunghezza finestra, hop, numero di bande mel) significa capire le leve che governano cosa il modello può e non può distinguere.

Il positional encoding sinusoidale dei transformer

Sezione intitolata “Il positional encoding sinusoidale dei transformer”

Il secondo legame è un uso esplicito di basi di Fourier, dichiarato dagli autori. Nei transformer — l’architettura introdotta in “Attention Is All You Need” (Vaswani et al., NeurIPS 2017), che processa una sequenza guardando tutti i token in parallelo invece che uno alla volta — c’è un problema: l’attention, di per sé, non sa in che ordine stanno i token. Bisogna iniettare l’informazione di posizione, e il modo originale lo fa con le sinusoidi.

La posizione di ogni token viene codificata con un vettore di seni e coseni a frequenze diverse:

PE(pos,2i)=sin ⁣(pos100002i/d),PE(pos,2i+1)=cos ⁣(pos100002i/d)PE(\text{pos}, 2i) = \sin\!\left(\frac{\text{pos}}{10000^{\,2i/d}}\right), \qquad PE(\text{pos}, 2i+1) = \cos\!\left(\frac{\text{pos}}{10000^{\,2i/d}}\right)

Ogni dimensione ii del vettore oscilla a una velocità diversa: le lunghezze d’onda formano una progressione geometrica da 2π2\pi fino a 100002π10000 \cdot 2\pi. Le dimensioni a frequenza alta cambiano rapidamente fra posizioni vicine (distinguono token adiacenti), quelle a frequenza bassa cambiano lentamente (codificano la posizione su lunga scala).

È, di fatto, un orologio multidimensionale: come le lancette dei secondi, dei minuti e delle ore identificano insieme un istante preciso senza ambiguità, le sinusoidi a frequenze diverse identificano insieme una posizione precisa nella sequenza. Una sola lancetta non basterebbe (dopo un giro si ripete); più lancette a velocità diverse, sì. Gli autori scelgono questa codifica anche perché ha una proprietà comoda: la rappresentazione di una posizione spostata di kk passi è una funzione lineare della posizione originale, il che aiuta il modello a ragionare per posizioni relative.

La classe va marcata con cura: questo è uso diretto di basi di Fourier, non un’analogia. Gli autori scelgono deliberatamente le sinusoidi a frequenze diverse — le stesse di questo capitolo — come base per rappresentare la posizione. Anche RoPE, l’erede che ha finito per dominare nei modelli recenti, è costruito su rotazioni sinusoidali con lo stesso spirito. Il legame con il transformer (transformer-2017, in preparazione, Parte I) e con i capitoli dedicati al positional encoding (positional-assoluta, rope, in preparazione, Parte XXI) è questo: chi ha disegnato il primo positional encoding ha preso in prestito esplicitamente l’idea di Fourier.

Il terzo legame è un altro uso esplicito, e risolve un problema concreto. Quando vuoi che una rete neurale impari una funzione di coordinate — per esempio, dato un punto (x,y)(x, y) di un’immagine, il suo colore; o dato un punto (x,y,z)(x, y, z) di una scena 3D, ciò che si vede da lì — un MLP che riceve le coordinate grezze fatica a riprodurre i dettagli ad alta frequenza: i bordi netti, le texture fini. Il risultato esce sfocato.

Il lavoro di Matthew Tancik e colleghi (UC Berkeley e Google), “Fourier Features Let Networks Learn High Frequency Functions in Low Dimensional Domains” (NeurIPS 2020), mostra la cura. Prima di dare le coordinate alla rete, le si mappa attraverso un banco di sinusoidi a frequenze diverse:

γ(v)=[cos(2πBv),  sin(2πBv)]\gamma(v) = \big[\cos(2\pi B v),\; \sin(2\pi B v)\big]

dove BB è una matrice di frequenze. Questa mappa di Fourier trasforma le coordinate in un vettore di componenti sinusoidali a varie frequenze, e con quell’input la rete impara i dettagli fini che prima le sfuggivano.

L’idea, riletta alla luce dello spectral bias, è quasi ovvia: se la rete fatica a generare alte frequenze da sola, gliele si fornisce già pronte come ingredienti dell’input, e a lei resta solo da combinarle. È il trucco che sta dietro NeRF (Neural Radiance Fields, le reti che imparano una scena 3D da un insieme di sue fotografie) e in generale dietro i neural fields. La classe è uso esplicito di features di Fourier, sostenuto da un’analisi teorica (via neural tangent kernel) oltre che dall’evidenza empirica.

Lo spectral bias: perché serve il trucco di Tancik

Sezione intitolata “Lo spectral bias: perché serve il trucco di Tancik”

Il quarto legame è un risultato empirico e teorico, ed è il “perché” sotto il punto precedente. Il lavoro di Nasim Rahaman e colleghi (fra cui Yoshua Bengio e Aaron Courville), “On the Spectral Bias of Neural Networks” (ICML 2019), documenta un fatto sistematico: le reti neurali, durante il training, imparano prima le componenti a bassa frequenza di una funzione, e solo più tardi (e con più fatica) quelle ad alta frequenza. La velocità di apprendimento dipende dalla frequenza, e le basse vincono.

Questo spectral bias spiega due cose insieme. Spiega perché le reti tendono a produrre funzioni “lisce” e a generalizzare smussando — un effetto spesso desiderabile, perché impedisce alla rete di inseguire subito il rumore ad alta frequenza nei dati.

E spiega esattamente perché serve il trucco delle Fourier features: se la rete fatica con le alte frequenze, gliele dai già pronte in input, mappando le coordinate attraverso sinusoidi ad alta frequenza. Tancik supera lo spectral bias che Rahaman aveva caratterizzato — i due lavori sono due facce dello stesso problema, uno che lo diagnostica e l’altro che lo cura. La classe va tenuta onesta: lo spectral bias è un risultato empirico con supporto teorico, non un teorema chiuso; ma è robusto e riproducibile attraverso architetture diverse.

Un quinto legame chiude il cerchio con il capitolo precedente, ed è un’identità matematica (il teorema di convoluzione applicato alle reti). Una CNN (Convolutional Neural Network, la rete che fa scorrere kernel appresi su un’immagine) calcola convoluzioni.

Per il teorema di convoluzione, ogni convoluzione nello spazio corrisponde a una moltiplicazione in frequenza. Questo ha due ricadute concrete, una pratica e una interpretativa.

La prima è implementativa: quando i kernel sono grandi, conviene calcolare le convoluzioni via FFT (FFT dell’immagine, moltiplicazione per la trasformata del kernel, antitrasformata), perché NlogNN \log N batte la convoluzione diretta. Diverse librerie lo fanno sotto il cofano per certi formati di kernel, scegliendo automaticamente fra convoluzione diretta e via-frequenza in base alla dimensione.

La seconda è interpretativa, ed è un’analogia con evidenza già incontrata nel capitolo sui filtri: i primi layer di una CNN, dopo il training, apprendono spontaneamente filtri che assomigliano a rilevatori di bordi e a filtri di Gabor (sinusoidi modulate da una gaussiana, cioè passa-banda orientati). In frequenza, sono filtri che selezionano bande e orientazioni specifiche. La rete riscopre dai dati, lasciata libera, gli stessi strumenti che l’ingegneria dei segnali aveva progettato a mano — convergenza osservata, non discendenza progettata. Il legame con cnn-base (Parte XVIII, in preparazione) passa proprio di qui.

Un ultimo legame, da cenno. FNet (Lee-Thorp et al., Google, 2021, “FNet: Mixing Tokens with Fourier Transforms”) fa una mossa radicale: sostituisce il meccanismo di self-attention dell’encoder di un transformer con una semplice trasformata di Fourier discreta in due dimensioni, non parametrizzata — senza pesi da imparare.

L’idea è che la DFT “mescola” l’informazione fra tutti i token globalmente, un po’ come fa l’attention, ma a costo zero di parametri e con un algoritmo (la FFT) velocissimo. Il risultato: il 92-97% dell’accuratezza di BERT sul benchmark GLUE, con un training molto più rapido. È un esempio limite di quanto la pura trasformata di Fourier possa fare lavoro che credevamo richiedesse l’attention — uso diretto della trasformata come operatore di mixing. Non ha soppiantato l’attention, ma chiarisce che parte del suo lavoro è “rimescolamento globale” che una trasformata fissa già sa fare.

La morale per chi costruisce sistemi AI è che Fourier non vive solo nei vecchi corsi di ingegneria. È ciò che produce l’input dei modelli speech, ciò che codifica la posizione nei transformer, ciò che fa imparare i dettagli fini ai neural fields, e — in casi estremi — può perfino rimpiazzare l’attention. Riconoscere le basi di Fourier sotto i loro travestimenti, e sapere ogni volta di che classe è il legame (uso esplicito, identità d’uso, risultato empirico), separa una comprensione meccanica da una superstiziosa.

Le idee di Fourier sono solide, ma le intuizioni scivolano in errori ricorrenti. Vale la pena disinnescarli uno per uno.

La FFT non è una trasformata diversa dalla DFT. È l’errore numero uno. La FFT è un algoritmo per calcolare la DFT, non una trasformata a sé. Il risultato è identico, bit per bit (a meno di errori di arrotondamento); cambia solo il costo, da N2N^2 a NlogNN \log N. Dire “ho usato la FFT invece della DFT” è come dire “ho usato il merge sort invece dell’ordinamento”: stai confondendo l’algoritmo con il problema che risolve.

La fase non è un dettaglio. Si disegna quasi sempre solo lo spettro di ampiezza, e si finisce per credere che la fase sia trascurabile. È falso: la fase porta gran parte della struttura, in particolare la disposizione spaziale e i contorni. L’esperimento di scambiare ampiezza e fase fra due immagini lo dimostra — l’immagine ricostruita segue la fase. Buttare via la fase, o trattarla con noncuranza, distrugge informazione che spesso è proprio quella che ti interessa.

Fourier “puro” assume stazionarietà. La trasformata di Fourier classica ti dice quali frequenze ci sono nel segnale, mediate su tutto il dominio, ma non quando compaiono. Per un segnale che cambia nel tempo — parlato, musica, qualunque cosa non stazionaria — la FT pura è quasi inutile da sola: ti dice che “nel brano c’è un La e un Mi” senza dirti che il La è all’inizio e il Mi alla fine. Per sapere quando serve la STFT/spettrogramma. Confondere i due strumenti porta ad aspettarsi dalla FT informazioni che, per costruzione, non può dare.

Il principio di indeterminazione non è un limite tecnologico. Nessun algoritmo migliore, nessuna finestra più furba, nessun hardware più potente ti darà risoluzione perfetta in tempo e in frequenza insieme. È matematica intrinseca alla coppia di trasformate: ΔtΔf\Delta t \cdot \Delta f ha un minimo invalicabile. Chi cerca lo spettrogramma “a risoluzione infinita su entrambi gli assi” sta inseguendo qualcosa che non esiste; può solo scegliere come spendere il budget fra tempo e frequenza.

Lo spectral leakage e l’illusione dello spettro pulito. La DFT assume implicitamente che il blocco di NN campioni si ripeta periodicamente. Se il segnale non completa un numero intero di cicli nel blocco, c’è una discontinuità fittizia al bordo, e la sua energia “spande” sui bin vicini: lo spectral leakage.

Il sintomo è uno spettro sporco, con picchi allargati e code, dove ti aspettavi righe nette. La cura è applicare una finestra (Hann, Hamming) che smorza i bordi del blocco prima della FFT, come discusso nella meccanica. Dimenticare la finestra e poi stupirsi dei picchi sbavati è un classico, ed è probabilmente l’errore pratico più comune fra chi calcola spettri per la prima volta.

L’aliasing vive anche in frequenza. Lo spettro di un segnale campionato è periodico: si ripete a multipli della frequenza di campionamento. Le frequenze sopra la soglia di Nyquist (metà della frequenza di campionamento) si “ripiegano” e compaiono come alias a frequenze più basse, indistinguibili da quelle vere. È lo stesso aliasing del capitolo sul campionamento, letto in frequenza: una frequenza sopra Nyquist nello spettro appare specchiata sotto Nyquist. Interpretare uno spettro senza tenere conto di Nyquist porta a “vedere” frequenze che non c’erano.

“Fourier features”, “positional encoding” e “spectral bias” sono tre cose diverse. Sono legate, ma confonderle è facile e dannoso. Il positional encoding rappresenta la posizione di un token con sinusoidi a frequenze diverse (è un input). Le Fourier features rappresentano le coordinate con sinusoidi per battere lo spectral bias (è una trasformazione dell’input). Lo spectral bias è il fenomeno — le reti imparano prima le basse frequenze — che motiva le Fourier features (è una proprietà osservata del training). Tenere distinte le tre evita di attribuire a una ciò che vale per un’altra.

La metafora del prisma non è un’identità. Il prisma è un’analogia didattica, comodissima, ma il prisma è ottica fisica e Fourier è un calcolo. Spingere la metafora fino a dire “il prisma calcola la trasformata di Fourier della luce” è scivolare da analogia a equivalenza senza diritto: la dispersione cromatica e l’integrale di Fourier sono fenomeni diversi che condividono la struttura della decomposizione in frequenze, niente di più.

La normalizzazione e il fattore di scala mordono. Le librerie non concordano su dove mettere il fattore 1/N1/N che compare quando si va avanti e indietro fra tempo e frequenza: alcune lo mettono sulla trasformata diretta, altre sull’inversa, altre lo spalmano come 1/N1/\sqrt{N} su entrambe. Il risultato è che l’ampiezza che leggi nello spettro può essere scalata in modi diversi a seconda dello strumento. Se ti aspetti che un picco corrisponda numericamente all’ampiezza della sinusoide nel tempo e i numeri non tornano, quasi sempre è una convenzione di normalizzazione, non un errore nel segnale. Leggi la documentazione della tua FFT prima di interpretare i numeri assoluti.

Reale dentro, complesso fuori. Un segnale reale produce uno spettro fatto di numeri complessi, e questo confonde chi se lo aspetta reale. Non è un difetto: i numeri complessi servono a portare ampiezza e fase insieme. Lo spettro di un segnale reale ha però una simmetria precisa (la metà superiore è il coniugato riflesso della metà inferiore), quindi i valori indipendenti sono solo N/2+1N/2 + 1. Trattare tutti gli NN bin come informazione distinta, o stupirsi che lo spettro sia complesso, sono entrambi sintomi di non aver capito cosa porta ciascun coefficiente.

L’overlap delle finestre nella STFT non è opzionale. Se nella STFT fai scorrere le finestre senza farle sovrapporre, l’informazione vicino ai bordi di ogni finestra viene smorzata (dalla finestratura) e mai recuperata, perché non c’è una finestra adiacente che la “copra”. Il risultato è uno spettrogramma con artefatti periodici e una ricostruzione che non torna. Per questo la STFT usa quasi sempre un passo (hop) molto più piccolo della lunghezza della finestra — Whisper, per esempio, usa finestre da 25 ms con hop di 10 ms, quindi forte sovrapposizione. Trascurare l’overlap è un errore concreto, non un dettaglio teorico.

  • Segnali continui, discreti, sistemi lineari — introduce i sistemi LTI e la risposta in frequenza; Fourier è la lente che rende quella risposta in frequenza un oggetto calcolabile.
  • Campionamento, aliasing, teorema di Nyquist — lo spettro di un segnale campionato è periodico, e l’aliasing è il ripiegamento delle frequenze sopra Nyquist: Fourier è la vista in cui Nyquist si enuncia naturalmente.
  • Filtri, convoluzione, smoothing, edge detection — il teorema di convoluzione e la descrizione dei filtri come scelta di H(f)H(f), lì enunciati e usati “in attesa di Fourier”, qui trovano la loro giustificazione.
  • spettrogrammi (in preparazione, questa Parte) — la STFT di questo capitolo è il fondamento dello spettrogramma e delle rappresentazioni tempo-frequenza.
  • rumore-snr (in preparazione, questa Parte) — il filtraggio del rumore e la lettura del rapporto segnale-rumore vivono spesso nello spettro.
  • time-series-base (in preparazione, questa Parte) — autocorrelazione, periodogramma e stagionalità sono Fourier applicato alle serie temporali.
  • Prodotto scalare come proiezione e somiglianza (Parte IV) — la trasformata è una correlazione (prodotto scalare) del segnale con le sinusoidi di base: il terzo angolo dell’intuizione nasce da lì.
  • Big-O come lingua franca per parlare di scaling (Parte IV) — O(N2)O(N^2) contro O(NlogN)O(N \log N): la FFT è il caso da manuale del valore di un algoritmo migliore.
  • DP con esempi classici (Parte VIII) — la FFT è divide-et-impera, lo stesso spirito di spezzare un problema in sotto-problemi che governa programmazione dinamica e ricerca ad albero.
  • transformer-2017 (Parte I, in preparazione) e positional-assoluta / rope (Parte XXI, in preparazione) — il positional encoding sinusoidale e RoPE come uso esplicito di basi di Fourier per rappresentare la posizione.
  • cnn-base (Parte XVIII, in preparazione) — la convoluzione di una CNN corrisponde a una moltiplicazione in frequenza (teorema di convoluzione), e i primi layer apprendono filtri tipo Gabor (passa-banda).
  • whisper (Parte XXII, in preparazione) — lo spettrogramma log-mel come input del modello: la STFT di questo capitolo usata come front-end di uno speech model.
  • Ronald N. Bracewell — The Fourier Transform and Its Applications (3rd ed., McGraw-Hill, 2000). Il testo classico: trasformata, teorema di convoluzione, principio di indeterminazione, applicazioni. La fonte di riferimento del campo.
  • Alan V. Oppenheim, Alan S. Willsky — Signals and Systems (2nd ed., Prentice Hall, 1996). Serie e trasformata di Fourier, DFT e risposta in frequenza dei sistemi LTI, in continuità con il riferimento usato nel capitolo sui filtri.
  • James W. Cooley, John W. Tukey — An Algorithm for the Machine Calculation of Complex Fourier Series (Mathematics of Computation, 19:297-301, 1965). Il paper che introduce la FFT e porta la DFT da N2N^2 a NlogNN \log N: la fonte primaria sul costo e sulla genesi storica.
  • Matthew Tancik et al. — Fourier Features Let Networks Learn High Frequency Functions in Low Dimensional Domains (NeurIPS 2020, arXiv:2006.10739). Le Fourier features per le coordinate, il trucco dietro NeRF: la mappa sinusoidale che supera lo spectral bias.
  • Nasim Rahaman et al. — On the Spectral Bias of Neural Networks (ICML 2019, arXiv:1806.08734). Il risultato che le reti imparano prima le basse frequenze: il “perché” sotto le Fourier features.

← Torna all’indice della Parte XII