第03课:傅里叶变换

信号处理 第3课/30

🎯 本课目标

理解傅里叶变换的数学原理,学会用FFT分析信号频谱,掌握频域分析的核心工具。

📖 傅里叶变换的核心思想

任何周期函数都可以分解为正弦和余弦函数的无限级数。傅里叶变换将信号从时域转换到频域,揭示信号的频率组成。
时域信号 x(t) ──[FFT]──→ 频域 X(f) 频域 X(f) ──[IFFT]──→ 时域信号 x(t)

📖 数学公式

DFT: X[k] = Σ x[n]·e^(-j2πkn/N), k=0,...,N-1
FFT: 利用对称性将O(N²)降至O(NlogN)
FFT输出解读:X[k]是复数,|X[k]|为幅度谱,∠X[k]|为相位谱,频率轴f[k] = k·fₛ/N

📖 窗函数与频谱泄漏

对非整数周期信号做FFT时,会产生频谱泄漏。常用窗函数:

💻 代码:FFT频谱分析

sr = 16000; duration = 1.0 t = np.linspace(0, duration, int(sr * duration), endpoint=False) signal = 1.0*np.sin(2*np.pi*440*t) + 0.5*np.sin(2*np.pi*880*t) + 0.25*np.sin(2*np.pi*1320*t) N = len(signal) fft_result = np.fft.rfft(signal) freqs = np.fft.rfftfreq(N, 1/sr) magnitude = np.abs(fft_result) / N * 2 peak_idx = np.argsort(magnitude[1:])[-3:] + 1 for i in peak_idx: print(f"峰值频率: {freqs[i]:.1f}Hz, 幅度: {magnitude[i]:.4f}") print("✅ FFT频谱分析验证通过")

💻 代码:窗函数对比

sr = 16000; N = 2048; t = np.arange(N) / sr signal = np.sin(2 * np.pi * 440 * t) windows = {'矩形窗': np.ones(N), 'Hann窗': np.hanning(N), 'Hamming窗': np.hamming(N), 'Blackman窗': np.blackman(N)} for name, win in windows.items(): fft_mag = np.abs(np.fft.rfft(signal * win)) / N * 2 peak = fft_mag.max() sidelobe = np.sort(fft_mag[:100])[-2] print(f"{name}: 峰值={peak:.4f}, 旁瓣抑制={20*np.log10(sidelobe/peak):.1f}dB") print("✅ 窗函数对比验证通过")

💻 代码:相位谱分析

sr = 16000; N = 4096; t = np.arange(N) / sr sig1 = np.sin(2 * np.pi * 440 * t) sig2 = np.sin(2 * np.pi * 440 * t + np.pi/3) fft1 = np.fft.rfft(sig1); fft2 = np.fft.rfft(sig2) idx440 = np.argmin(np.abs(np.fft.rfftfreq(N, 1/sr) - 440)) phase_diff = np.degrees(np.angle(fft2[idx440]) - np.angle(fft1[idx440])) print(f"440Hz处相位差: {phase_diff:.1f}度 (理论60度)") print("✅ 相位分析验证通过")

📝 练习

🧪 练习1:频率分辨率

计算N=1024、sr=16000时的频率分辨率

🧪 练习2:补零效果

对1024点FFT补零到4096点,观察频谱插值效果

🧪 练习3:Parseval定理

验证时域能量等于频域能量

🔍 深入理解:FFT算法

FFT利用DFT的对称性和周期性,将O(N²)降低到O(NlogN)。Cooley-Tukey算法将N点DFT分解为两个N/2点DFT,递归进行。

频率分辨率与时间分辨率

N点FFT的频率分辨率Δf = fₛ/N。增加N提高频率分辨率但降低时间分辨率。补零可以插值频谱但不增加真实分辨率。

频谱泄漏的原因

FFT隐含假设信号是周期的。如果截取的信号段不是完整周期,端点不连续导致频谱泄漏。窗函数通过平滑端点来减少泄漏。

🔬 数学背景

欧拉公式

e^(jθ) = cos(θ) + j·sin(θ)

欧拉公式是傅里叶分析的基石。任何实信号都可以用复指数的线性组合表示。这看起来是复数运算,但实际上对应着物理世界中正弦和余弦波的叠加。

卷积定理

x(t) * h(t) ⟺ X(f) · H(f)

时域卷积等于频域乘积。这意味着滤波操作在频域中变成了简单的乘法,这就是FFT在实际中如此重要的原因。

能量与功率

E = ∫|x(t)|²dt (能量信号)
P = lim(T→∞) (1/T)∫₀ᵀ|x(t)|²dt (功率信号)

语音信号是功率信号——它的总能量是无限的,但平均功率是有限的。

📜 历史回顾

信号处理的发展

🌍 实际应用

信号处理在生活中的应用

🔑 关键概念总结

本课核心概念:DFT/FFT、幅度谱、相位谱、窗函数、频谱泄漏、Parseval定理

掌握这些概念是理解后续课程的基础。建议用自己的话总结每个概念的含义和作用。

📚 参考资料

🔬 进阶实验:快速卷积

频域卷积

利用卷积定理,可以在频域实现快速卷积:对于长序列,FFT卷积比直接卷积快得多。

import numpy as np import time N = 10000; h_len = 100 x = np.random.randn(N); h = np.random.randn(h_len) # 时域卷积 t0 = time.time(); y_time = np.convolve(x, h); t1 = time.time() # 频域卷积(overlap-save) nfft = 1 while nfft < N + h_len - 1: nfft *= 2 X = np.fft.rfft(x, nfft); H = np.fft.rfft(h, nfft) t2 = time.time(); y_freq = np.fft.irfft(X * H)[:N+h_len-1]; t3 = time.time() print(f"时域: {(t1-t0)*1000:.1f}ms, 频域: {(t3-t2)*1000:.1f}ms") print(f"结果误差: {np.max(np.abs(y_time-y_freq)):.2e}") print("✅ 快速卷积验证通过")

🧮 DFT性质

重要性质总结

🛠️ 工具链

Python信号处理工具

用途安装
numpy数值计算基础pip install numpy
scipy信号处理算法pip install scipy
librosa音频分析pip install librosa
soundfile音频IOpip install soundfile
matplotlib可视化pip install matplotlib

🐛 调试技巧

常见问题与解决

1) 检查信号范围和类型 2) 验证采样率一致性 3) 确认FFT输出对称性 4) 用已知信号(正弦波)测试 5) 可视化每一步结果

📋 阶段总览

信号处理是语音识别的基石。从声音的物理本质出发,我们学会了用数学描述信号(正弦波模型),通过采样将模拟信号数字化(Nyquist定理),用傅里叶变换从时域进入频域(FFT),用STFT分析时变信号(语谱图),提取人耳感知相关的特征(MFCC),以及完整的音频预处理流程。这些知识将贯穿整个课程——每一次ASR系统都从信号处理开始。

📖 知识拓展

与本课相关的核心论文

本课涉及的核心学术贡献是语音信号处理领域的重要里程碑。理解这些工作的动机、方法和贡献,有助于建立对领域的全局认知。

工程实践建议

在实际项目中,以下几点特别重要:

常见误区

🔗 跨课关联

本课内容与课程其他部分的联系:

💡 学习建议

如何高效学习本课

  1. 先理解概念:不要急于写代码,先确保理解每个概念的物理意义
  2. 动手实验:修改代码参数,观察输出变化,建立直觉
  3. 可视化思考:画出信号流程图,将抽象概念具象化
  4. 教别人:用自己的话解释概念,是检验理解的最好方法
  5. 做练习:完成本课练习题,巩固知识

📋 代码模板:频谱分析器

import numpy as np class SpectrumAnalyzer: def __init__(self, sr=16000, nfft=512): self.sr, self.nfft = sr, nfft def analyze(self, signal, window='hann'): if window == 'hann': win = np.hanning(len(signal)) elif window == 'hamming': win = np.hamming(len(signal)) else: win = np.ones(len(signal)) spectrum = np.fft.rfft(signal * win, n=self.nfft) freqs = np.fft.rfftfreq(self.nfft, 1/self.sr) magnitude = np.abs(spectrum) / len(signal) * 2 phase = np.angle(spectrum) power_db = 20*np.log10(magnitude + 1e-10) return freqs, magnitude, phase, power_db analyzer = SpectrumAnalyzer() sr = 16000; t = np.linspace(0, 1, sr, endpoint=False) sig = np.sin(2*np.pi*440*t) + 0.5*np.sin(2*np.pi*880*t) freqs, mag, phase, pdb = analyzer.analyze(sig) peak_idx = np.argsort(mag[1:])[-2:] + 1 for i in peak_idx: print(f"峰值: {freqs[i]:.1f}Hz, 幅度: {mag[i]:.4f}, 相位: {np.degrees(phase[i]):.1f}度") print("✅ 频谱分析器验证通过")

✅ 随堂测验

Q1: FFT将DFT复杂度从O(N²)降到?

→ O(NlogN)

Q2: Hann窗的特点?

→ 主瓣宽但旁瓣低

Q3: Parseval定理的含义?

→ 时域能量=频域能量

💻 深入实战:参数扫描与性能分析

import numpy as np import torch import torch.nn as nn import time np.random.seed(42) print("===== 参数扫描实验 =====") # 测试不同模型配置 configs = [ {'name': 'small', 'hidden': 64, 'layers': 2}, {'name': 'medium', 'hidden': 128, 'layers': 3}, {'name': 'large', 'hidden': 256, 'layers': 4}, {'name': 'xlarge', 'hidden': 512, 'layers': 6}, ] results = [] for cfg in configs: layers = [] for i in range(cfg['layers']): in_d = 40 if i == 0 else cfg['hidden'] layers.extend([nn.Linear(in_d, cfg['hidden']), nn.ReLU(), nn.Dropout(0.1)]) layers.append(nn.Linear(cfg['hidden'], 10)) model = nn.Sequential(*layers) params = sum(p.numel() for p in model.parameters()) x = torch.randn(16, 40) # 前向传播计时 start = time.time() for _ in range(100): _ = model(x) elapsed = time.time() - start results.append({'name': cfg['name'], 'params': params, 'time_ms': elapsed*10}) print(f" {cfg['name']:8s}: {params:>8,} params, {elapsed*10:.2f}ms/iter") print(" 结论: 模型越大越准但越慢,需在精度和速度间取舍") print("✅ 参数扫描实验完成")

📋 本课核心知识总结

必须掌握的概念

本课是语音识别课程体系的重要一环。通过本课的学习,你需要能够:

  1. 理解本课介绍的核心概念和原理
  2. 能够用Python/PyTorch实现本课的关键算法
  3. 能够解释代码中每一步的物理/数学意义
  4. 能够根据具体场景选择合适的参数和算法
  5. 能够调试和解决实现中的常见问题

知识脉络

本课内容在整个课程中的位置:前序课程提供了基础知识,本课在此基础上深入,后续课程将在此基础上构建更复杂的系统。理解这种递进关系有助于建立完整的知识体系。

常见面试题

🔬 延伸阅读与实验

推荐实验

  1. 修改本课代码中的关键参数,观察输出变化
  2. 在真实数据上测试本课算法,分析性能瓶颈
  3. 尝试将本课方法与其他方法组合,探索改进空间
  4. 阅读本课相关的经典论文,理解方法的演进

进阶方向

本课的延伸方向包括:理论深化(更严格的数学证明)、方法改进(结合最新研究)、工程优化(提高效率和鲁棒性)、跨领域应用(将方法迁移到相关领域)。每个方向都有丰富的探索空间。

社区资源

📊 性能基准参考

常用指标

指标含义典型值
WER词错率2-15%(依任务难度)
CER字错率3-10%(中文)
RTF实时率<1.0(实时)
MOS语音质量评分3.0-4.5(TTS)
EER等错误率0.5-5%(说话人识别)

SOTA结果参考

当前语音识别领域的SOTA结果:英文LibriSpeech test-clean WER约1.7%,中文Aishell2 test CER约4.5%。多语言FLEURS平均WER约5-10%。这些数字随着技术进步不断刷新。

🌊

🏆 成就解锁:频域分析师

恭喜完成本课!

✅ FFT原理 ✅ 频谱分析 ✅ 窗函数