数字信号$x[n]$表示模拟声波在离散时间点上的振幅,得到一系列数字。这称为时域表示。它直接回答了“信号在特定时刻的振幅是多少?”这个问题。尽管这一视图必不可少,但它在语音识别方面存在明显局限。时域视图当我们绘制数字音频信号的振幅随时间(或采样点数)变化的图时,会得到一个波形。这种可视化方法有助于观察整体特征,如响度(对应较高的振幅)和静音时刻(振幅接近零)。我们来看一个简单的波形。下方的图表显示了信号在几分之一秒内的振幅。{"layout": {"title": "时域表示:波形", "xaxis": {"title": "时间 (秒)"}, "yaxis": {"title": "振幅"}, "template": "plotly_white", "width": 700, "height": 400}, "data": [{"x": [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49], "y": [0.0, 0.59, 0.95, 0.95, 0.59, 0.0, -0.59, -0.95, -0.95, -0.59, -0.0, 0.59, 0.95, 0.95, 0.59, 0.0, -0.59, -0.95, -0.95, -0.59, -0.0, 0.31, 0.59, 0.81, 0.95, 1.0, 0.95, 0.81, 0.59, 0.31, 0.0, -0.31, -0.59, -0.81, -0.95, -1.0, -0.95, -0.81, -0.59, -0.31, -0.0, 0.31, 0.59, 0.81, 0.95, 1.0, 0.95, 0.81, 0.59, 0.31], "type": "scatter", "mode": "lines", "line": {"color": "#4263eb"}}]}一个显示信号振幅随时间变化的波形图。你可以分辨出响亮和安静的部分,但要区分语音的实际内容,比如“s”音和“sh”音之间的差异,几乎不可能。这些不同的声音是由它们的频率成分决定的,而不仅仅是整体振幅。为了让机器学习模型学习语音的基本组成,它需要更丰富的数据表示。频域视图频域提供了一个不同的视角。我们不再绘制振幅与时间的关系图,而是绘制信号强度(或能量)与频率的关系图。这种视图回答了“信号中存在哪些频率以及它们有多突出?”这个问题。为了从时域转换到频域,我们使用一种数学方法,称为傅里叶变换。对于数字信号,我们使用其对应的离散傅里叶变换(DFT),它通常通过一种高效算法——**快速傅里叶变换(FFT)**来计算。傅里叶变换将信号分解为一组不同频率的正弦波和余弦波,这些波加在一起可以重建原始信号。FFT的输出为我们提供了每个频率分量的两个重要信息:它的幅度(该频率存在多少)和它的相位(波的偏移)。对于语音分析,我们主要关注幅度。如果我们取一个由两个纯正弦波组成的信号,一个在200赫兹,另一个在500赫兹,它的频谱将如下图所示:{"layout": {"title": "频域表示:频谱", "xaxis": {"title": "频率 (赫兹)"}, "yaxis": {"title": "幅度"}, "template": "plotly_white", "width": 700, "height": 400}, "data": [{"x": [100, 200, 300, 400, 500, 600], "y": [0, 1, 0, 0, 0.75, 0], "type": "bar", "marker": {"color": ["#adb5bd", "#f76707", "#adb5bd", "#adb5bd", "#f76707", "#adb5bd"]}}]}显示在200赫兹和500赫兹处有两个明显峰值的频谱图。这提供了更多的信息。我们可以清楚地看到构成信号的各个频率,这些在时域波形中是不可见的。非平稳信号的难题这里有一个问题。语音是一种非平稳信号,这意味着它的统计特性,特别是其频率成分,会随时间变化。当你发出“语音”(speech)这个词时,“s”音的频率与“ee”音的频率差异很大。如果我们对“语音”(speech)这个词的整个音频片段应用一次FFT,我们将得到一个单一的频谱,它平均了“s”、“p”和“ee”音的频率。我们将知道这个词整体上存在哪些频率,但会丢失所有关于它们何时出现的信息。这种时间信息对于区分“cats”和“stack”来说非常重要。时频结合:短时傅里叶变换解决方法是对信号进行小的、易于处理的分段分析,在这些分段中我们可以假定信号是平稳的(其属性变化不大)。这就是**短时傅里叶变换(STFT)**的作用。STFT的工作方式如下:分帧: 将长音频信号切割成短的、通常重叠的帧。典型的帧大小为20-30毫秒,这足以捕捉单个语音事件。加窗: 每个帧乘以一个窗函数(如汉宁窗或汉明窗)。这会将帧开头和结尾的信号逐渐减小到零,从而减少因突然截断信号而可能产生的频谱失真。应用FFT: 对每个加窗的帧计算快速傅里叶变换,以获取其频谱。结果是一系列频谱,每帧一个。通过将这些频谱并排排列,我们创建了一种表示,它显示了信号的频率内容如何随时间变化。这个过程是创建语谱图的依据,我们将在下一节讨论。digraph G { graph [bgcolor="transparent", fontname="sans-serif"]; node [shape=box, style="filled", fontname="sans-serif", fillcolor="#e9ecef", color="#495057"]; edge [fontname="sans-serif"]; rankdir=TB; subgraph cluster_0 { style=invis; A [label="完整音频信号\nx[n]", fillcolor="#a5d8ff"]; } subgraph cluster_1 { style=invis; B [label="分帧", shape=invhouse, fillcolor="#bac8ff"]; } subgraph cluster_2 { style=invis; label="信号被分割成短帧"; node [shape=record, fillcolor="#d0bfff"]; C [label="<f0> 帧 1 | <f1> 帧 2 | <f2> 帧 3 | <f3> ..."]; } subgraph cluster_3 { style=invis; D [label="每帧加窗与FFT", shape=invhouse, fillcolor="#bac8ff"]; } subgraph cluster_4 { style=invis; label="每帧获得其频谱"; node [shape=record, fillcolor="#d0bfff"]; E [label="<f0> 频谱 1 | <f1> 频谱 2 | <f2> 频谱 3 | <f3> ..."]; } F [label="时频表示\n(语谱图)", fillcolor="#96f2d7"]; A -> B; B -> C; C -> D; D -> E; E -> F; }对音频信号应用短时傅里叶变换(STFT)的过程。这种时频分析对现代ASR很重要。它将一维、模糊的波形转换为一个内容丰富的二维图像,清晰地分离出模型需要学习的声音模式。通过理解时域的“何时”和频域的“何种内容”,我们为语音识别模型获取有效特征创造了条件。