푸리에 변환(The Fourier Transform)

모든 신호(signal)는 사인파(sine wave)의 합입니다. 푸리에 변환(Fourier transform)은 어떤 사인파가 들어 있는지 알려줍니다.

유형: Build 언어: Python 선수 지식: Phase 1, Lesson 01-04, 19(복소수, complex numbers) 예상 시간: 약 90분

학습 목표

  • 이산 푸리에 변환(Discrete Fourier Transform; DFT)을 직접 처음부터 구현하고, O(N log N) 쿨리-튜키 FFT(Cooley-Tukey FFT)와 비교해 검증합니다.
  • 주파수 계수(frequency coefficient)를 해석해 신호에서 진폭(amplitude), 위상(phase), 파워 스펙트럼(power spectrum)을 추출합니다.
  • 컨볼루션 정리(Convolution theorem)를 적용해 FFT 곱셈으로 컨볼루션(convolution)을 수행합니다.
  • 푸리에 주파수 분해(Fourier frequency decomposition)를 트랜스포머(Transformer) 위치 인코딩(positional encoding)과 합성곱 신경망(CNN)의 컨볼루션 계층(convolution layer)에 연결합니다.

문제

오디오 녹음(audio recording)은 시간에 따른 압력 측정값의 연속된 수열입니다. 주가(stock price)는 날짜별 값의 수열이고, 이미지는 공간 위의 픽셀 강도(pixel intensity) 격자입니다. 이들은 모두 시간 영역(time domain) 또는 공간 영역(space domain)의 데이터입니다. 어떤 색인을 따라 값이 변하는 모습을 봅니다.

하지만 많은 패턴은 시간 영역에서는 보이지 않습니다. 이 오디오 신호는 순음(pure tone)일까요, 화음(chord)일까요? 주가에는 주간 주기가 있을까요? 이미지에는 반복되는 질감이 있을까요? 이런 질문은 모두 주파수 성분(frequency content)에 대한 질문이고, 시간 영역은 그것을 가려 버립니다.

푸리에 변환은 데이터를 시간 영역에서 주파수 영역(frequency domain)으로 변환합니다. 신호를 서로 다른 주파수의 사인파로 분해합니다. 각 사인파는 진폭(얼마나 강한지)과 위상(어디에서 시작하는지)을 가지며, 푸리에 변환은 이 둘을 모두 알려줍니다.

기계 학습(ML)에서 이것이 중요한 이유는 주파수 영역 사고(frequency-domain thinking)가 곳곳에 등장하기 때문입니다. 합성곱 신경망(Convolutional Neural Network; CNN)은 컨볼루션을 수행하며, 컨볼루션은 주파수 영역에서의 곱셈에 해당합니다. 트랜스포머의 위치 인코딩은 위치를 표현하기 위해 주파수 분해를 사용합니다. 음성 인식(speech recognition)이나 음악 생성(music generation) 같은 오디오 모델은 소리의 주파수 표현인 스펙트로그램(spectrogram) 위에서 작동합니다. 시계열 모델은 주기적 패턴을 찾습니다. 푸리에 변환을 이해하면 이 모든 것을 다룰 어휘를 얻게 됩니다.

사전 테스트

2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요

1.푸리에 변환(Fourier transform)은 신호(signal)에 무엇을 하나요?

2.직접 계산하는 DFT와 비교할 때 빠른 푸리에 변환(Fast Fourier Transform; FFT)의 시간 복잡도(time complexity)는 어떻게 되나요?

0/2 답변 완료

개념

DFT 정의(DFT Definition)

N개의 샘플(sample) x[0], x[1], ..., x[N-1]이 주어지면, 이산 푸리에 변환(Discrete Fourier Transform; DFT)은 N개의 주파수 계수(frequency coefficient) X[0], X[1], ..., X[N-1]을 만듭니다.

X[k] = sum_{n=0}^{N-1} x[n] * e^(-2*pi*i*k*n/N)

for k = 0, 1, ..., N-1

X[k]는 복소수(complex number)입니다. 크기(magnitude) |X[k]|는 주파수 k의 진폭을 알려주고, 위상 angle(X[k])는 그 주파수의 위상 오프셋(phase offset)을 알려줍니다.

핵심 통찰은 e^(-2*pi*i*k*n/N)이 주파수 k의 회전 페이저(rotating phasor)라는 점입니다. DFT는 신호와 N개의 같은 간격의 주파수 사이의 상관(correlation)을 계산합니다. 신호가 주파수 k에서 에너지(energy)를 가지고 있으면 상관 값이 크고, 그렇지 않으면 거의 0이 됩니다.

각 계수(coefficient)의 의미

X[0]: 직류 성분(DC component). 모든 샘플의 합입니다. 평균에 비례하며, 신호의 상수 항, 즉 주파수가 0인 오프셋(zero-frequency offset)을 나타냅니다.

X[0] = sum_{n=0}^{N-1} x[n] * e^0 = sum of all samples

1 <= k <= N/2 구간의 X[k]: 양의 주파수(positive frequency). X[k]는 N개 샘플당 k 주기(cycle)의 주파수를 나타냅니다. k가 클수록 주파수가 높고 진동(oscillation)이 빠릅니다.

X[N/2]: 나이퀴스트 주파수(Nyquist frequency). N개 샘플로 표현할 수 있는 가장 높은 주파수입니다. 이보다 높은 주파수는 에일리어싱(aliasing)을 일으킵니다. 높은 주파수가 낮은 주파수처럼 보이는 현상입니다.

N/2 < k < N 구간의 X[k]: 음의 주파수(negative frequency). 실숫값 신호(real-valued signal)에서는 X[N-k] = conj(X[k])가 성립합니다. 음의 주파수는 양의 주파수의 거울상(mirror image)이므로, 유용한 정보는 보통 처음 N/2 + 1개 계수에 들어 있습니다.

역 DFT(Inverse DFT)

역 DFT는 주파수 계수에서 원래 신호를 다시 만들어 냅니다(reconstruct).

x[n] = (1/N) * sum_{k=0}^{N-1} X[k] * e^(2*pi*i*k*n/N)

for n = 0, 1, ..., N-1

순방향(forward) DFT와 다른 점은 지수(exponent)의 부호가 양수이고, 1/N이라는 정규화 계수(normalization factor)가 붙는다는 것입니다.

역 DFT는 완전 복원(perfect reconstruction)이라 정보가 손실되지 않습니다. 시간 영역에서 주파수 영역으로 갔다가 되돌아와도 오차가 생기지 않습니다. DFT는 일종의 기저 변환(change of basis)이며, 같은 정보를 다른 좌표계로 다시 표현하는 작업이라고 볼 수 있습니다.

FFT: 빠르게 만들기

위 정의를 그대로 사용해 DFT를 계산하면 시간 복잡도가 O(N^2)입니다. N개의 출력 계수마다 N개의 입력 샘플을 모두 더해야 하기 때문입니다. N = 1,000,000이면 약 10^12번의 연산이 필요합니다.

빠른 푸리에 변환(Fast Fourier Transform; FFT)은 같은 결과를 O(N log N)에 계산합니다. N = 1,000,000이면 1조 번 연산 대신 약 2천만 번의 연산이면 됩니다. 이것이 주파수 분석을 실제로 쓸 수 있게 만들어 줍니다.

가장 흔히 쓰는 FFT인 쿨리-튜키 알고리즘(Cooley-Tukey algorithm)은 분할 정복(divide and conquer) 방식으로 동작합니다.

  1. 신호를 짝수 인덱스(even-indexed)와 홀수 인덱스(odd-indexed) 샘플로 나눕니다.
  2. 각 절반의 DFT를 재귀적으로 계산합니다.
  3. 두 절반 크기 DFT를 트위들 인자(twiddle factor) e^(-2*pi*i*k/N)로 결합합니다.
X[k] = E[k] + e^(-2*pi*i*k/N) * O[k]          for k = 0, ..., N/2 - 1
X[k + N/2] = E[k] - e^(-2*pi*i*k/N) * O[k]    for k = 0, ..., N/2 - 1

where E = DFT of even-indexed samples
      O = DFT of odd-indexed samples

대칭성 덕분에 재귀 단계마다 O(N) 만큼의 작업만 필요하고, 단계는 log2(N)개이므로 전체 복잡도는 O(N log N)이 됩니다.

graph TD
    subgraph "8-point FFT (Cooley-Tukey)"
        X["x[0..7]<br/>8 samples"] -->|"split even/odd"| E["Even: x[0,2,4,6]"]
        X -->|"split even/odd"| O["Odd: x[1,3,5,7]"]
        E -->|"4-pt FFT"| EK["E[0..3]"]
        O -->|"4-pt FFT"| OK["O[0..3]"]
        EK -->|"combine with twiddle factors"| XK["X[0..7]"]
        OK -->|"combine with twiddle factors"| XK
    end
    subgraph "Complexity"
        C1["DFT: O(N^2) = 64 multiplications"]
        C2["FFT: O(N log N) = 24 multiplications"]
    end

FFT는 신호 길이가 2의 거듭제곱(power of 2)일 때 가장 자연스럽습니다. 실제로는 신호를 다음 2의 거듭제곱까지 0으로 채우는(zero-pad) 경우가 많습니다.

스펙트럼 분석(Spectral Analysis)

파워 스펙트럼(power spectrum)은 |X[k]|^2, 즉 각 주파수 계수의 크기 제곱입니다. 각 주파수에 에너지가 얼마나 있는지 보여 줍니다.

위상 스펙트럼(phase spectrum)은 angle(X[k]), 즉 각 주파수의 위상 오프셋입니다. 대부분의 분석 작업에서는 파워 스펙트럼을 중요하게 보고 위상은 무시하는 경우가 많습니다.

Power at frequency k:  P[k] = |X[k]|^2 = X[k].real^2 + X[k].imag^2
Phase at frequency k:  phi[k] = atan2(X[k].imag, X[k].real)

주파수 해상도(Frequency Resolution)

DFT의 주파수 해상도는 샘플 수 N과 표본화율(sampling rate) fs에 따라 달라집니다.

Frequency of bin k:      f_k = k * fs / N
Frequency resolution:    delta_f = fs / N
Maximum frequency:       f_max = fs / 2  (Nyquist)

서로 가까운 두 주파수를 구분하려면 더 많은 샘플이 필요합니다. 또한 높은 주파수를 잡아내려면 더 높은 표본화율이 필요합니다.

컨볼루션 정리(Convolution Theorem)

이것은 신호 처리(signal processing)에서 가장 중요한 결과 중 하나이며, 합성곱 신경망(CNN)과도 직접 관련됩니다.

시간 영역에서의 컨볼루션은 주파수 영역에서의 원소별 곱셈(pointwise multiplication)과 같습니다.

x * h = IFFT(FFT(x) . FFT(h))

where * is convolution and . is element-wise multiplication

이것이 중요한 이유는 다음과 같습니다.

  • 길이 N과 M인 두 신호의 직접 컨볼루션은 O(N*M) 연산이 필요합니다.
  • FFT 기반 컨볼루션은 O(N log N)에 가능합니다. 두 신호를 변환하고, 곱한 다음, 다시 역변환합니다.
  • 커널(kernel)이 클수록 FFT 컨볼루션이 훨씬 빠릅니다.
  • 수용 영역(receptive field)이 큰 컨볼루션 계층에서도 같은 아이디어가 사용됩니다.

주의할 점이 있습니다. DFT가 계산하는 컨볼루션은 순환 컨볼루션(circular convolution)이라 신호가 끝과 처음으로 이어집니다. 끝점이 이어지지 않는 선형 컨볼루션(linear convolution)을 얻으려면 계산 전에 두 신호를 길이 N + M - 1까지 0으로 채워야 합니다.

graph LR
    subgraph "Time Domain"
        TA["Signal x[n]"] -->|"convolve (slow: O(NM))"| TC["Output y[n]"]
        TB["Filter h[n]"] -->|"convolve"| TC
    end
    subgraph "Frequency Domain"
        FA["FFT(x)"] -->|"multiply (fast: O(N))"| FC["FFT(x) * FFT(h)"]
        FB["FFT(h)"] -->|"multiply"| FC
        FC -->|"IFFT"| FD["y[n]"]
    end
    TA -.->|"FFT"| FA
    TB -.->|"FFT"| FB
    FD -.->|"same result"| TC

윈도잉(Windowing)

DFT는 신호가 주기적이라고 가정합니다. 즉 N개의 샘플을 무한히 반복되는 신호의 한 주기로 취급합니다. 신호가 같은 값으로 시작하고 끝나지 않으면 경계에서 불연속(discontinuity)이 생기고, 이것이 본래 신호에 없던 가짜 고주파 성분으로 나타납니다. 이를 스펙트럼 누설(spectral leakage)이라고 합니다.

윈도잉은 DFT를 계산하기 전에 신호 양 끝을 0으로 점점 줄여(tapering) 누설을 줄여 줍니다.

자주 쓰는 창 함수(window):

창 함수모양주엽 폭(main lobe width)부엽 수준(side lobe level)사용 사례
직사각(Rectangular)평평함(창 없음)가장 좁음가장 높음(-13 dB)신호가 N개 샘플 안에서 정확히 주기적일 때
한(Hann)들린 코사인(raised cosine)보통낮음(-31 dB)범용 스펙트럼 분석
해밍(Hamming)변형 코사인보통더 낮음(-42 dB)오디오 처리, 음성 분석
블랙맨(Blackman)3중 코사인넓음매우 낮음(-58 dB)부엽 억제가 중요한 경우
Hann window:    w[n] = 0.5 * (1 - cos(2*pi*n / (N-1)))
Hamming window: w[n] = 0.54 - 0.46 * cos(2*pi*n / (N-1))

DFT 전에 신호에 창 함수를 원소별로 곱합니다. 즉 X = DFT(x * w)입니다.

DFT 성질(DFT Properties)

성질시간 영역주파수 영역
선형성(Linearity)ax + byaX + bY
시간 이동(Time shift)x[n - k]X[f] * e^(-2piifk/N)
주파수 이동(Frequency shift)x[n] * e^(2piif0n/N)X[f - f0]
컨볼루션(Convolution)x * hX * H(원소별)
곱셈(Multiplication)x * h(원소별)X * H(순환 컨볼루션, 1/N 스케일)
파스발 정리(Parseval's theorem)sum |x[n]|^2(1/N) * sum |X[k]|^2
켤레 대칭(Conjugate symmetry, 실수 입력)x[n]이 실수X[k] = conj(X[N-k])

파스발 정리(Parseval's theorem)는 두 영역에서 전체 에너지가 같다고 말합니다. 에너지는 변환을 거쳐도 보존됩니다.

위치 인코딩(Positional Encoding)과의 연결

원본 트랜스포머는 사인파 위치 인코딩(sinusoidal positional encoding)을 사용합니다.

PE(pos, 2i)   = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

각 차원 쌍 (2i, 2i+1)은 서로 다른 주파수로 진동합니다. 주파수는 차원 0과 1의 높은 주파수에서 시작해 마지막 차원의 낮은 주파수까지 기하적으로 간격이 나뉘어 있습니다(geometrically spaced). 이 구조는 각 위치에 모든 주파수 대역에 걸친 고유한 패턴을 부여합니다. 푸리에 계수가 신호를 유일하게 식별하는 방식과 비슷합니다.

이 방식이 제공하는 핵심 성질은 다음과 같습니다.

  • 고유성(Uniqueness): 서로 다른 두 위치가 같은 인코딩 값을 갖지 않습니다.
  • 유계 값(Bounded values): sincos는 항상 [-1, 1] 범위 안에 있습니다.
  • 상대 위치(Relative position): 위치 p+k의 인코딩은 위치 p의 인코딩에 대한 선형 함수로 표현할 수 있습니다. 모델은 상대적 위치에 어텐션을 두는 방법을 학습할 수 있습니다.

CNN과의 연결

컨볼루션 계층(convolution layer)은 학습된 필터(커널)를 입력 위로 미끄러뜨리며 적용합니다. 수학적으로 이것은 컨볼루션 연산입니다.

컨볼루션 정리에 따르면 이 연산은 다음과 같이 바꿔 쓸 수 있습니다.

  1. 입력에 FFT를 적용합니다.
  2. 커널에 FFT를 적용합니다.
  3. 주파수 영역에서 원소별로 곱합니다.
  4. 결과에 역 FFT(IFFT)를 적용합니다.

표준 CNN 구현은 직접 컨볼루션(direct convolution)을 사용합니다. 작은 3x3 커널에서는 직접 컨볼루션이 더 빠르기 때문입니다. 하지만 커널이 크거나 전역 컨볼루션(global convolution)을 다룰 때는 FFT 기반 방식이 훨씬 빠릅니다. FNet 같은 일부 아키텍처는 어텐션을 FFT로 완전히 대체해, O(N^2) 대신 O(N log N) 복잡도로도 경쟁력 있는 정확도를 얻습니다.

스펙트로그램(Spectrogram)과 단시간 푸리에 변환(Short-Time Fourier Transform)

단일 FFT는 전체 신호의 주파수 성분을 알려 주지만, 그 주파수가 언제 발생했는지는 알려 주지 못합니다. 시간에 따라 주파수가 증가하는 처프(chirp)와, 모든 주파수가 동시에 존재하는 화음(chord)이 같은 크기 스펙트럼(magnitude spectrum)을 가질 수 있습니다.

단시간 푸리에 변환(Short-Time Fourier Transform; STFT)은 신호의 겹치는 창마다 FFT를 계산해 이 문제를 해결합니다. 그 결과가 스펙트로그램(spectrogram)으로, 한 축은 시간, 다른 축은 주파수인 2차원 표현입니다. 각 점의 강도(intensity)는 해당 시점, 해당 주파수의 에너지를 나타냅니다.

STFT procedure:
1. Choose a window size (e.g., 1024 samples)
2. Choose a hop size (e.g., 256 samples -- 75% overlap)
3. For each window position:
   a. Extract the windowed segment
   b. Apply a Hann/Hamming window
   c. Compute FFT
   d. Store the magnitude spectrum as one column of the spectrogram

스펙트로그램은 오디오 기계 학습 모델의 표준 입력 표현(input representation)입니다. 음성 인식 모델인 Whisper와 DeepSpeech는 멜 스펙트로그램(mel-spectrogram)을 사용합니다. 멜 스펙트로그램은 주파수를 사람의 음높이 지각(human pitch perception)에 더 잘 맞는 멜 척도(mel scale)로 매핑한 스펙트로그램입니다.

에일리어싱(Aliasing)

신호에 fs/2, 즉 나이퀴스트 주파수보다 높은 주파수가 포함되어 있으면, 표본화율 fs로 샘플링할 때 에일리어싱된 복제(aliased copy)가 만들어집니다. 100 Hz로 샘플링한 90 Hz 신호는 10 Hz 신호와 똑같이 보입니다. 샘플만으로는 둘을 구분할 방법이 없습니다.

Example:
  True signal: 90 Hz sine wave
  Sampling rate: 100 Hz
  Apparent frequency: 100 - 90 = 10 Hz

  The samples from the 90 Hz signal at 100 Hz sampling rate
  are identical to the samples from a 10 Hz signal.
  No amount of math can recover the original 90 Hz.

그래서 아날로그-디지털 변환기(analog-to-digital converter)는 샘플링 전에 나이퀴스트보다 높은 주파수를 제거하는 안티 에일리어싱 필터(anti-aliasing filter)를 포함합니다. 기계 학습에서도 적절한 저역 통과 필터(low-pass filter)를 거치지 않고 특징 맵(feature map)을 다운샘플링하면 에일리어싱이 나타납니다. 일부 아키텍처는 안티 에일리어싱 풀링 계층(anti-aliased pooling layer)으로 이를 완화합니다.

제로 패딩(Zero-Padding)은 해상도(Resolution)를 높이지 않는다

흔한 오해가 있습니다. FFT 전에 신호를 0으로 채우면 주파수 해상도가 좋아진다는 생각입니다. 그렇지 않습니다. 제로 패딩은 기존 주파수 구간(frequency bin) 사이를 보간해 스펙트럼을 더 매끄럽게 보이게 할 뿐, 원래 샘플에 들어 있지 않던 주파수 세부 정보를 드러낼 수는 없습니다.

실제 주파수 해상도는 관측 시간(observation time) T = N / fs에만 의존합니다. delta_f만큼 떨어진 두 주파수를 구분하려면 적어도 T = 1 / delta_f초 분량의 데이터가 필요합니다. 아무리 제로 패딩을 해도 이 본질적인 한계는 바뀌지 않습니다.

만들어 보기

단계 1: DFT 직접 구현하기

O(N^2) DFT는 정의에서 곧바로 따라 나옵니다.

import math

class Complex:
    ...

def dft(x):
    N = len(x)
    result = []
    for k in range(N):
        total = Complex(0, 0)
        for n in range(N):
            angle = -2 * math.pi * k * n / N
            w = Complex(math.cos(angle), math.sin(angle))
            xn = x[n] if isinstance(x[n], Complex) else Complex(x[n])
            total = total + xn * w
        result.append(total)
    return result

단계 2: 역 DFT(Inverse DFT)

구조는 같습니다. 지수의 부호만 양수이고, 마지막에 N으로 나눕니다.

def idft(X):
    N = len(X)
    result = []
    for n in range(N):
        total = Complex(0, 0)
        for k in range(N):
            angle = 2 * math.pi * k * n / N
            w = Complex(math.cos(angle), math.sin(angle))
            total = total + X[k] * w
        result.append(Complex(total.real / N, total.imag / N))
    return result

단계 3: FFT(Cooley-Tukey)

재귀형 FFT는 길이가 2의 거듭제곱이어야 합니다. 짝수와 홀수 인덱스로 나누고, 재귀로 계산한 뒤, 트위들 인자로 결합합니다.

def fft(x):
    N = len(x)
    if N <= 1:
        return [x[0] if isinstance(x[0], Complex) else Complex(x[0])]
    if N % 2 != 0:
        return dft(x)

    even = fft([x[i] for i in range(0, N, 2)])
    odd = fft([x[i] for i in range(1, N, 2)])

    result = [Complex(0)] * N
    for k in range(N // 2):
        angle = -2 * math.pi * k / N
        twiddle = Complex(math.cos(angle), math.sin(angle))
        t = twiddle * odd[k]
        result[k] = even[k] + t
        result[k + N // 2] = even[k] - t
    return result

단계 4: 스펙트럼 분석(Spectral Analysis) 보조 함수

def power_spectrum(X):
    return [xk.real ** 2 + xk.imag ** 2 for xk in X]

def convolve_fft(x, h):
    N = len(x) + len(h) - 1
    padded_N = 1
    while padded_N < N:
        padded_N *= 2

    x_padded = x + [0.0] * (padded_N - len(x))
    h_padded = h + [0.0] * (padded_N - len(h))

    X = fft(x_padded)
    H = fft(h_padded)

    Y = [xk * hk for xk, hk in zip(X, H)]

    y = idft(Y)
    return [y[n].real for n in range(N)]

사용하기

실무에서는 최적화된 C 라이브러리 위에서 동작하는 numpy의 FFT를 사용합니다.

import numpy as np

signal = np.sin(2 * np.pi * 5 * np.arange(256) / 256)
spectrum = np.fft.fft(signal)
freqs = np.fft.fftfreq(256, d=1/256)

power = np.abs(spectrum) ** 2

positive_freqs = freqs[:len(freqs)//2]
positive_power = power[:len(power)//2]

윈도잉과 더 정교한 스펙트럼 분석에는 다음을 사용할 수 있습니다.

from scipy.signal import windows, stft

window = windows.hann(256)
windowed = signal * window
spectrum = np.fft.fft(windowed)

컨볼루션에는 다음을 사용할 수 있습니다.

from scipy.signal import fftconvolve

result = fftconvolve(signal, kernel, mode='full')

스펙트로그램에는 다음을 사용할 수 있습니다.

from scipy.signal import stft

frequencies, times, Zxx = stft(signal, fs=sample_rate, nperseg=256)
spectrogram = np.abs(Zxx) ** 2

스펙트로그램 행렬의 형상(shape)은 (n_frequencies, n_time_frames)입니다. 각 열은 하나의 시간 창(time window)에서의 파워 스펙트럼입니다. 이것이 오디오 기계 학습 모델이 입력으로 사용하는 표현입니다.

산출물 만들기

code/fourier.py를 실행해 DFT, FFT, 신호 복원, 컨볼루션 정리, 윈도잉, 위치 인코딩 예제를 확인합니다. 최종 산출물로는 outputs/prompt-spectral-analyzer.md가 검수됩니다.

연습문제

  1. 순음 식별(쉬움). 1초 동안 128 Hz로 표본화한, 1-50 Hz 사이의 미지 주파수를 가진 단일 사인파 신호를 만듭니다. 직접 구현한 DFT로 그 주파수를 찾아내고, 정답이 맞는지 확인합니다. 그다음 표준 편차가 0.5인 가우시안 잡음(Gaussian noise)을 더해 같은 작업을 반복합니다. 잡음은 스펙트럼에 어떤 영향을 주나요?

  2. FFT와 DFT 검증(중간). 길이 64의 무작위 신호를 만듭니다. DFT(O(N^2))와 FFT를 모두 계산하고, 모든 계수가 1e-10 이내에서 일치하는지 확인합니다. 길이 256, 512, 1024, 2048 신호에서 두 함수의 실행 시간을 측정하고, DFT 시간 대 FFT 시간의 비율을 그래프로 그립니다.

  3. 예시로 보는 컨볼루션 정리 증명(중간). 신호 x = [1, 2, 3, 4, 0, 0, 0, 0]과 필터 h = [1, 1, 1, 0, 0, 0, 0, 0]을 만듭니다. 중첩 반복문(nested loop)으로 순환 컨볼루션을 직접 계산합니다. 그다음 FFT, 원소별 곱셈, 역변환으로 다시 계산해, 두 결과가 일치하는지 확인합니다. 마지막으로 적절히 제로 패딩을 해서 선형 컨볼루션을 수행합니다.

  4. 윈도잉 효과(중간). 10 Hz와 12 Hz 두 사인파의 합으로 이루어진 신호를 만듭니다. 두 주파수는 매우 가깝습니다. 1초 동안 128 Hz로 표본화한 뒤, 창을 적용하지 않은 경우, 한(Hann) 창, 해밍(Hamming) 창 각각으로 파워 스펙트럼을 계산합니다. 어떤 창이 두 봉우리를 가장 잘 구분해 주나요? 그 이유는 무엇인가요?

  5. 위치 인코딩 분석(어려움). d_model = 128, max_pos = 512에 대해 사인파 위치 인코딩을 만듭니다. 위치 쌍 (p1, p2)마다 두 인코딩의 내적(dot product)을 계산합니다. 내적이 절대 위치가 아니라 |p1 - p2|에만 의존한다는 점을 보이고, 거리(distance)가 커질수록 내적이 어떻게 변하는지 살펴봅니다.

핵심 용어

용어의미
이산 푸리에 변환(DFT; Discrete Fourier Transform)N개의 시간 영역 샘플을 N개의 주파수 영역 계수로 변환한다. 각 계수는 해당 주파수의 복소 사인파(complex sinusoid)와의 상관 값이다.
빠른 푸리에 변환(FFT; Fast Fourier Transform)DFT를 O(N log N)에 계산하는 알고리즘이다. 쿨리-튜키 알고리즘은 짝수/홀수 인덱스를 재귀적으로 분할한다.
역 DFT(Inverse DFT)주파수 계수에서 시간 영역 신호를 복원한다. DFT와 같은 식이지만 지수의 부호가 반대이고 1/N 스케일링이 붙는다.
주파수 구간(Frequency bin)DFT 출력의 각 인덱스 k이며, 주파수 k*fs/N Hz를 나타내는 이산 슬롯이다.
직류 성분(DC component)X[0], 즉 주파수가 0인 계수이다. 신호의 평균에 비례한다.
나이퀴스트 주파수(Nyquist frequency)fs/2이다. 표본화율 fs로 표현 가능한 최대 주파수이며, 이보다 높은 주파수는 에일리어싱을 일으킨다.
파워 스펙트럼(Power spectrum)`
위상 스펙트럼(Phase spectrum)angle(X[k])이다. 각 주파수 성분의 위상 오프셋이며, 분석에서는 종종 무시된다.
스펙트럼 누설(Spectral leakage)비주기 신호를 주기적이라고 취급할 때 생기는 가짜 주파수 성분이다. 윈도잉으로 줄일 수 있다.
창 함수(Window function)DFT 전에 신호에 적용하는 끝맺음(tapering) 함수이다. Hann, Hamming, Blackman 등이 있다.
트위들 인자(Twiddle factor)FFT의 버터플라이 계산(butterfly computation)에서 부분 DFT를 결합할 때 쓰는 복소 지수 e^(-2*pi*i*k/N)이다.
컨볼루션 정리(Convolution theorem)시간 영역의 컨볼루션이 주파수 영역의 원소별 곱셈과 같다는 정리이다. 신호 처리와 CNN의 핵심이다.
순환 컨볼루션(Circular convolution)신호가 끝에서 처음으로 이어지며 계산되는 컨볼루션이다. DFT가 자연스럽게 계산하는 형태이다.
선형 컨볼루션(Linear convolution)끝이 이어지지 않는 표준 컨볼루션이다. DFT 전에 제로 패딩을 하면 얻을 수 있다.
파스발 정리(Parseval's theorem)푸리에 변환을 거쳐도 전체 에너지가 보존된다는 정리이다. `sum
에일리어싱(Aliasing)표본화율이 부족해 나이퀴스트보다 높은 주파수가 낮은 주파수처럼 보이게 되는 현상이다.

더 읽을거리

실습 코드

이 강의의 실습 코드 1개

fourier
Code

산출물

이 강의에서 생성된 프롬프트, 스킬, 코드 산출물 1개

prompt-spectral-analyzer

Guides analysis of frequency content in signals using Fourier transform techniques

Prompt

확인 문제

3문제 · 모두 맞추면 완료 표시가 가능합니다

1.컨볼루션 정리(Convolution theorem)는 무엇을 말하나요?

2.FFT 전에 제로 패딩(zero-padding)을 해도 실제 주파수 해상도(true frequency resolution)가 증가하지 않는 이유는 무엇인가요?

3.원본 트랜스포머(Transformer)의 사인파 위치 인코딩(sinusoidal positional encoding)에서 차원 쌍(dimension pair)마다 기하적으로 간격이 나뉜 주파수를 배정하는 이유는 무엇인가요?

0/3 답변 완료