푸리에 변환(Fourier transform, FT)
2025. 6. 2. 16:07ㆍ연구하기, 지식
서론
- 딥러닝을 공부하다보면 데이터 전처리에서 심심치 않게 등장하는 것이 바로 '푸리에 변환' 이다. 우리는 그것을 이해하기 보다는 그저 특징 추출을 위한 하나의 장치로 넘어가곤 한다. numpy.fft 하면 끝나는데 알 필요가 있을까? 물론 알 필요 없다. 하지만 궁금한건 못 참는다. 바로 알아보겠다.
시간과 주파수
- 우리는 흔히 오디오 데이터나 시계열 데이터들에 푸리에 변환을 자주 적용한다. 이 둘은 시간에 따른 데이터의 흐름과 변화를 나타내는 '시간 도메인' 으로 표현된다. 시간 도메인은 흐름을 알기는 쉽지만 특징을 잡기가 어렵다.
- 이런 시간 도메인들에서 특징을 찾기 위해 조제프 푸리에 선생님이 고안 해내신 것이 푸리에 변환이다. 시간 도메인을 주파수 도메인으로 바꿔 특징을 찾기 쉽게 해준다. 주파수 도메인을 사용하면 특정 주파수 대역을 필터링 하거나 고르는게 용이해져 딥러닝 모델 학습 시 매우 용이하다. 또한 인간에게도 더욱이 직관적이다. 소리를 눈으로 이해할 수 있다.
https://www.projectrhea.org/rhea/index.php/Fourier_analysis_in_Music
Fourier analysis in Music - Rhea
www.projectrhea.org
- 위 연구 자료에서 보면 악기의 소리를 푸리에 변환 했다. 변환 결과 악기별 특징을 확실히 알 수 있다. 만약 시간 도메인으로 확인 했으면 시간에 따른 소리의 크기(진폭) 만 보였을 것이므로 어떤 악기인지 구분할 수 없었을 것이다. 하지만 푸리에 변환을 하면 눈으로 소리를 들을 수 있다! 색깔에서의 RGB 같은 것이다. 미술을 좋아하는 사람이면 RGB 값만 보고 색상을 알 수 있듯이 푸리에 변환도 마찬가이다.
변환 원리
- 사실 그 원리를 자세히 설명하자면 너무너무 어렵다. 얼마나 어려운지 체험하고 싶으시면 아래 링크를 타들어가길 바란다. 하지만 간단히 설명하면 그다지 어렵지 않다.
https://ko.wikipedia.org/wiki/%ED%91%B8%EB%A6%AC%EC%97%90_%EB%B3%80%ED%99%98
푸리에 변환 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 푸리에 변환(Fourier transform, FT)은 시간이나 공간에 대한 함수를 시간 또는 공간 주파수 성분으로 분해하는 변환을 말한다. 푸리에 변환은 이 변환으로 나타난 주
ko.wikipedia.org
- 간단한 원리는 복잡한 신호를 사인파(코사인파, 정현파) 로 나타내는 것이다. 사인파는 매우 규칙적이고 순수한 음이다. 미적분도 쉽다. 따라서 여러 개의 서로 다른 주파수, 진폭, 위상을 가진 사인파와 코사인파들의 합으로 복잡한(주기적이지 않은) 신호를 나타낼 수 있다. 우선 주파수에 따른 사인파, 코사인파를 그려 보겠다. 해당 코드에는 코랩 matplotlib에서 폰트 적용하는 법까지 있다.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
# 코랩 폰트 적용
font_path = '/content/malgun.ttf'
fontprop = fm.FontProperties(fname=font_path)
plt.rc('font', family=fontprop.get_name())
plt.rcParams['axes.unicode_minus'] = False
# 시간축
t = np.linspace(0, 1, 1000)
# 사인파들 (주파수: 2, 5, 10Hz)
sine_waves = [
(np.sin(2 * np.pi * 2 * t), '2Hz 사인파', 'blue', '-'),
(np.sin(2 * np.pi * 5 * t), '5Hz 사인파', 'orange', '-'),
(np.sin(2 * np.pi * 10 * t), '10Hz 사인파', 'green', '-')
]
# 코사인파들 (주파수: 3, 6, 9Hz)
cosine_waves = [
(np.cos(2 * np.pi * 3 * t), '3Hz 코사인파', 'red', '-'),
(np.cos(2 * np.pi * 6 * t), '6Hz 코사인파', 'purple', '-'),
(np.cos(2 * np.pi * 9 * t), '9Hz 코사인파', 'brown', '-')
]
# 사인파 시각화
plt.figure(figsize=(12, 4))
for wave, label, color, style in sine_waves:
plt.plot(t, wave, label=label, color=color, linestyle=style)
plt.title('다양한 사인파', fontproperties=fontprop)
plt.xlabel('시간 (s)', fontproperties=fontprop)
plt.ylabel('진폭', fontproperties=fontprop)
plt.legend(prop=fontprop)
plt.grid(True)
plt.tight_layout()
plt.show()
# 코사인파 시각화
plt.figure(figsize=(12, 4))
for wave, label, color, style in cosine_waves:
plt.plot(t, wave, label=label, color=color, linestyle=style)
plt.title('다양한 코사인파', fontproperties=fontprop)
plt.xlabel('시간 (s)', fontproperties=fontprop)
plt.ylabel('진폭', fontproperties=fontprop)
plt.legend(prop=fontprop)
plt.grid(True)
plt.tight_layout()
plt.show()
- 이 사인파, 코사인파의 진폭과 주파수의 약간의 가중치를 부여해 조합하면 다음과 같은 복잡한 형태를 띄게 된다.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
font_path = '/content/malgun.ttf'
fontprop = fm.FontProperties(fname=font_path)
plt.rc('font', family=fontprop.get_name())
plt.rcParams['axes.unicode_minus'] = False
# 시간축
t = np.linspace(0, 1, 1000)
# 주파수 리스트 및 사인/코사인 성분의 가중치
frequencies = [2, 3, 5, 6, 9, 10]
sin_weights = {
2: 1.0,
5: 0.5,
10: 0.3
}
cos_weights = {
3: 0.8,
6: 0.6,
9: 0.4
}
# 신호 초기화
composite_signal = np.zeros_like(t)
# 사인파 가중합
for f, w in sin_weights.items():
composite_signal += w * np.sin(2 * np.pi * f * t)
# 코사인파 가중합
for f, w in cos_weights.items():
composite_signal += w * np.cos(2 * np.pi * f * t)
# 결과 시각화
plt.figure(figsize=(14, 5))
plt.plot(t, composite_signal, color='black', label='복합 신호 (합성파)')
plt.title('사인파와 코사인파의 복합 신호', fontproperties=fontprop)
plt.xlabel('시간 (s)', fontproperties=fontprop)
plt.ylabel('진폭', fontproperties=fontprop)
plt.legend(prop=fontprop)
plt.grid(True)
plt.tight_layout()
plt.show()
- 이렇듯 둘의 조합만으로 복잡한 형상을 만들 수 있다. 따라서 사인파, 코사인파만 있으면 복잡한 신호들을 처리할 수 있을 것이다.
728x90
'연구하기, 지식' 카테고리의 다른 글
Gemma3 - 무료 멀티모달 LLM 모델 사용하기 (3) | 2025.06.29 |
---|---|
JIT 컴파일과 데코레이터 (2) | 2025.06.09 |
NeMo Speaker Recognition(SR) 성능 올리기 (6) | 2025.05.25 |
파이썬에서 오디오 파일 다루기(pydub, soundfile) (0) | 2025.05.25 |
API 통신과 소켓 통신 (4) | 2025.05.18 |