除夕夜的后厨,剁菜声咔咔作响,炖锅咕嘟冒泡,电视里放着春晚,老板还在催单。阿善一边切葱,一边听见头顶收音机里那句“明天多云转晴”——人脑天生就会在嘈杂中锁定目标声音,这就是著名的“鸡尾酒会效应”。可当他事后拿着录音软件,想把收音机那句预报从后厨混音里“抽”出来时,软件只能摊手:所有声音叠成一条波形,谁是谁,早已分不清。 这就是语音分离要解决的问题:从一段“声音大乱炖”里,把每位说话人单独捞出来。好消息是,现代AI已经找到了一整套“捞菜”的厨具——先用语谱图把声音摆上“切菜盘”,再用掩蔽这把“漏勺”按比例放行每个时频格子;捞出来的菜标签对不上,就用排列不变训练多试几种贴法;而Conv-TasNet、DPRNN、SepFormer这些深度学习模型,则像是越来越聪明的厨师,有的直接捞生鲜,有的切段后两头对照,有的让每块食材互相“对眼神”。读完这篇,你不仅能听懂这些名词,还能亲手写一段代码,做一次简单的“声音分拣”。

岗位关联

掌握语音分离,等于掌握了会议记录、助听器、播客修音这些工具的“内核引擎”;无论做模型训练还是工程落地,这都是语音增强方向最能体现价值的一环。

目录
  1. 可视化演示
  2. 鸡尾酒会问题
  3. 时频分析
  4. 掩蔽与映射
  5. 排列不变训练
  6. Conv-TasNet
  7. DPRNN
  8. SepFormer
  9. 评估与部署
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示神经网络前向传播、损失计算、反向传播梯度回传、参数更新的完整流程,支持步进查看每个阶段的激活值与梯度变化。

本节配有交互动效(进入视口后自动加载,约 3KB)。

前向传播 输入数据逐层加权求和并经过激活函数 每层节点的激活值由上一层决定 a_l = σ(W_l · a_{l-1} + b_l) 前向传播将输入变换为输出预测

鸡尾酒会问题

年夜饭后厨是声音的武林大会:剁菜声咔咔、炖锅咕嘟、电视里的春晚、老板催菜,人人都在喊。阿善却能一边切葱,一边听清头顶收音机里那句“明天多云转晴”。耳朵替他从一片嘈杂里锁定目标,这就是心理学家说的“鸡尾酒会效应”。可当他事后想把收音机那句预报从后厨录音里单独剪出来,软件只能给他一整段糊在一起的声波。机器没有人的“选择性听觉”。

语音分离要做的,就是把这段“声音大乱炖”还原成几道“干净食材”:输入一段音频,输出若干条音频,每条对应一个说话人。这恰好是鸡尾酒会问题在工程上的形态。1953年,Cherry首次记录了这一现象,此后几十年它都是信号处理与AI领域最硬的骨头之一。它难在哪?第一,混合后的信息高度纠缠,单条波形看不出谁是谁;第二,真实环境还叠加噪声和混响,更难下手。

按通道数分,有单通道和多通道分离。多通道能用空间位置帮忙,而单通道只有一个话筒,只能“按声音本身的规律”硬拆,难度更集中在算法本身。按说话人数是否已知,又分固定人数的有监督分离和开放人数的说话人日志。我们这篇聚焦最常见也最能讲清原理的设定:单通道、说话人数量已知(通常2-3人)的语音分离。它既是语音增强的特例——增强想保目标压噪声,分离想同时保留所有人——又是许多下游应用的第一公里。

回到后厨:阿善明白了,饭要做得好,先得承认“乱炖”是现实。而接下来要学的这批“厨具”——语谱图、掩蔽、PIT、各种深度网络——都是为了让“捞食材”这件事越来越精准。

x(t)=∑i=1Nsi(t)+n(t)\displaystyle x(t) = \sum_{i=1}^{N} s_i(t) + n(t)
这是最简混合模型:麦克风收到的信号,等于所有说话人信号的直接叠加,再加上环境噪声。
  1. 混合信号 x(t)麦克风在时刻 t 录到的总声压,是所有声音相加的结果。
    x(t)\displaystyle x(t)
  2. 求和符号把 N 个说话人的干净语音逐点相加,这是无混响、无非线性失真的理想化前提。
    ∑i=1Nsi(t)\displaystyle \sum_{i=1}^{N} s_i(t)
  3. 噪声项 n(t)剁菜声、空调底噪等无关声音;在标准基准实验中常令 n=0,集中考察“人与人”的分离。
    n(t)\displaystyle n(t)
  4. 分离目标只给 x,要估计出每个 s_i——也就是从乱炖里把每道食材原样端出来。

时频分析

乱炖怎么捞?光用筷子在汤里瞎搅没用,得先把汤端到“切菜盘”上分格看。语音分析里这个“切菜盘”叫语谱图:横轴是时间,纵轴是频率,每个小格子的颜色深浅表示那一刻那个频率有多响。阿善第一次看到语谱图时愣住了——原来“剁菜声”和“收音机”在图上根本不在一处:剁菜像竖直亮条,收音机播音则有连续的横纹。分格看清了,才能谈得上“分开”。

怎么把一段波形变成语谱图?靠短时傅里叶变换。波形本身只是一条随时间起伏的曲线,看不出“哪个频率什么时候出现”。STFT 的做法是:用一个滑动的小窗,比如 30 毫秒,把信号切成一小段一小段,对每一段做傅里叶变换,得到这一小段时间内的频率构成。窗一格格滑过去,就拼出一张二维画面。画面上的每一小格,叫一个时频单元。

有了切菜盘,工作的单位就从“整条波形”变成了“一个个小格子”。掩蔽和映射这两大流派,本质都是在回答同一个问题:这些格子,到底归谁?

X(t,f)=∑nx(n) w(n−t) e−j2πfn\displaystyle X(t,f) = \sum_{n} x(n)\, w(n - t)\, e^{-j 2\pi f n}
STFT 的每个值代表“在 t 附近、频率 f 上的成分有多大”,把所有格子拼起来就是语谱图。实际使用中,人们通常只看幅度谱 |X(t,f)|,相位则常常“借用”混合信号的相位来合成波形——因为人耳对相位不那么敏感,这个近似在工程上屡试不爽。
  1. x(n)原始的离散语音波形,是“一锅乱炖”本身。
    x(n)\displaystyle x(n)
  2. w(n-t)以 t 为中心的时间窗,比如汉宁窗,它决定切段时每段的长度与平滑程度。
    w(n−t)\displaystyle w(n - t)
  3. 复指数项傅里叶变换的“频率探测器”,把窗内信号分解成不同频率成分。
    e−j2πfn\displaystyle e^{-j 2\pi f n}
  4. 求和对所有采样点加总,得到 t 时刻、频率 f 上的复数值,取模就是语谱图上的颜色。

掩蔽与映射

有了切菜盘,怎么捞?第一种办法像漏勺:对每个格子乘一个 0 到 1 之间的权重。属于收音机的格子乘 1 留下,属于剁菜声的格子乘 0 滤掉,拿不准的格子乘 0.5。这种“给每个格子打分放行”的操作,就是掩蔽。漏勺全留全滤叫理想二值掩蔽(IBM),按比例放行叫理想比值掩蔽(IRM)——现实中 IRM 更常用,因为硬切边缘会让人耳听到一种恼人的“音乐噪声”。

第二种办法像“照着吃过的味道想象原食材”:不直接对混合信号做乘法,而是让网络端到端地回归出目标说话人的幅度谱,这叫映射。你可以这样理解:掩蔽是“在混合里选”,映射是“直接预测目标”。两者并不互斥,很多现代模型一锅烩:先预测掩蔽,再用掩蔽乘混合,等效于一个软性的“预测+选择”。

漏勺网眼该多密、该用什么材质,成了这几年深度学习竞赛的核心。从 IBM 到 IRM,从手工规则到让网络自己学掩蔽,捞法越来越聪明,但“按格放行”的底层直觉始终没变。

IRMi(t,f)=∣Si(t,f)∣2∑j=1N∣Sj(t,f)∣2\displaystyle \mathrm{IRM}_i(t,f) = \frac{|S_i(t,f)|^2}{\sum_{j=1}^{N} |S_j(t,f)|^2}
IRM 计算第 i 个说话人在某个时频格子上的能量占比,值越大,说明这个格子主要由他贡献。
  1. 分子第 i 个说话人在该时频格子的能量,来自他干净语音的幅度谱平方。
    ∣Si(t,f)∣2\displaystyle |S_i(t,f)|^2
  2. 分母所有说话人在同一格子的能量总和,代表这个格子“总共有多响”。
    ∑j=1N∣Sj(t,f)∣2\displaystyle \sum_{j=1}^{N} |S_j(t,f)|^2
  3. 比值能量占比,范围在 0 到 1 之间——这就是“漏勺网眼”的疏密程度。
    ∣Si∣2∑j∣Sj∣2\displaystyle \frac{|S_i|^2}{\sum_j |S_j|^2}
  4. 分离合成估算出 IRM 后,把它乘到混合信号的复频谱对应格子上,再逆变换回波形,就得到第 i 路分离结果。

排列不变训练

阿善用漏勺捞出了两盘东西,却愣住了:哪盘是收音机,哪盘是剁菜?这个“对不上号”的问题,就是语音分离里臭名昭著的置换歧义——模型输出 N 个估计,但这 N 个输出和 N 个真实标签谁对应谁,训练时没人告诉它。

早期方法尝试固定顺序:强制要求“第一个输出永远对应说话人 1”。结果模型训练剧烈震荡:因为两个说话人的身份、内容、音色都在变,硬性对齐等于让模型猜一个不存在的规则。2017 年,Yu 等人提出排列不变训练(PIT):干脆不固定顺序,把所有对应关系都试一遍,选损失最小的那种分配作为本次训练的“标准答案”,反向传播也只作用于这一种最优排列。

这个“多贴几次标签,选最像的”的做法,让训练过程一下稳定下来,几乎成了后世深度语音分离模型的标配。它像后厨的传菜规则:不强行规定谁端哪道菜,但每次必须保证“菜和菜单对得上”。

LPIT=min⁡p∈P1N∑i=1Nℓ(s^p(i),  si)\displaystyle \mathcal{L}_{PIT} = \min_{p \in \mathbb{P}} \frac{1}{N} \sum_{i=1}^{N} \ell\big(\hat{s}_{p(i)},\; s_i\big)
PIT 的损失函数:穷举 N! 种排列,取平均损失最小的一组作为当前 batch 的标签分配。
  1. 输出与标签\hat{s}_{p(i)} 是模型第 p(i) 个输出,s_i 是第 i 个真实说话人。
    s^p(i),  si\displaystyle \hat{s}_{p(i)},\; s_i
  2. 排列集合\mathbb{P} 包含 N 个输出的全部排列;N=2 只有 2 种,N=3 有 6 种,穷举成本可接受。
    p∈P\displaystyle p \in \mathbb{P}
  3. 求平均损失对某一排列下 N 对“输出-标签”的损失取平均,常用负 SI-SNR 或 L1 距离。
    1N∑i=1Nℓ(⋅)\displaystyle \frac{1}{N} \sum_{i=1}^{N} \ell(\cdot)
  4. 取最小值遍历所有排列,只保留损失最小的那一组用于反向传播——每个 batch 的最优排列都可以不同,这就是“动态标签”。

Conv-TasNet

阿善发现老办法有个别扭之处:先算 STFT 再算掩蔽,窗该多宽?固定窗的“切菜盘”是为了人眼设计的,不是为机器设计的。2019 年的 Conv-TasNet 决定不玩这套——直接在时域“捞生鲜”,一步到位:把波形直接送进网络,输出也是波形,中间的编码器、分离器、解码器全部可学习。

Conv-TasNet 的结构是“编码器-分离器-解码器”:编码器用一维卷积把原始波形变成一组特征,相当于机器自己学了一个更合适的“切菜盘”;分离器利用时间卷积网络估计掩蔽;解码器用转置卷积把特征还原成波形。因为全程可微,它可以直接优化语音分离最相关的指标——尺度不变信噪比(SI-SNR),彻底绕开“幅度掩蔽+借用混合相位”带来的近似失真。

Conv-TasNet 用深度可分离卷积替代标准卷积,参数量少、感受野却很大,在 WSJ0-2mix 基准上首次稳定地把 SI-SNR 提升到 10dB 以上,成为时域方法的开山之作。就像阿善丢掉了笨重的案板直接上手处理“生鲜食材”,步骤少了,鲜味也更足。

s^i=Decoder(Maski⊙Encoder(x))\displaystyle \hat{s}_i = \mathrm{Decoder}\big( \mathrm{Mask}_i \odot \mathrm{Encoder}(x) \big)
整个流程可以浓缩成一句话:波形先编码成特征,在特征上乘一个掩蔽,再解码回波形。
  1. Encoder(x)一维卷积把原始波形映射成特征序列,等效于可学习版的“时频变换”。
    Encoder(x)\displaystyle \mathrm{Encoder}(x)
  2. Mask_i网络预测的第 i 路比值掩蔽,取值在 0 到 1 之间,决定每个特征位置“放行多少”。
    Maski\displaystyle \mathrm{Mask}_i
  3. 逐元素相乘 ⊙把掩蔽应用到特征上,筛选出属于第 i 个说话人的部分。
    Maski⊙Encoder(x)\displaystyle \mathrm{Mask}_i \odot \mathrm{Encoder}(x)
  4. Decoder转置卷积把筛选后的特征重建为第 i 路的时域波形,输出最终分离结果。

DPRNN

Conv-TasNet 虽好,但卷积的感受野终究有限,像捞长长的粉条:一截一截地捞,容易捞断、捞漏。语音是长程依赖很强的信号,前一句的气息可能影响后面半句的音色。怎么处理“超长粉条”?DPRNN 的答案是:先把粉条切段,再两头照顾。

DPRNN 也就是双路径循环网络:先把特征序列分割成 S 个重叠的块,每块长度 L;然后用两个循环神经网络交替处理——块内 RNN 把每一块内部的时序关系理顺,块间 RNN 在“块与块”之间来回对照,捕捉跨块的长程依赖。两个方向交替数轮,局部和全局的信息就都吃透了,这也是“双路径”这个名字的由来。

靠这个朴素又有效的“先切段、再交叉对照”,DPRNN 用较轻的参数量在多数基准上反超 Conv-TasNet。阿善学到这里直拍大腿:这和“把葱姜蒜分格腌好,再回锅翻炒”是一个道理。

Z=IntraRNN(V),U=InterRNN(Z)\displaystyle Z = \mathrm{IntraRNN}(V), \qquad U = \mathrm{InterRNN}(Z)
一次双路径处理 = 先做块内建模,再做块间建模;实际模型中会把这两步交替重复多次。
  1. V分块后的三维特征张量,维度为“通道数 × 块数 × 块内长度”,即切好的“粉条段”。
    V\displaystyle V
  2. IntraRNN(V)沿块内方向做双向 LSTM,理顺每一段粉条内部的时间顺序,这是局部建模。
    IntraRNN(V)\displaystyle \mathrm{IntraRNN}(V)
  3. InterRNN(Z)沿块间方向再做双向 LSTM,让不同块之间交换信息,这是全局建模。
    InterRNN(Z)\displaystyle \mathrm{InterRNN}(Z)
  4. 交替重复把“局部→全局”的组合循环 R 次,让信息在块内与块间充分流动。

SepFormer

DPRNN 用的是双向 LSTM,但 RNN 有个老毛病:信息要一个时间步一个时间步地“接力”,遇到隔得很远的依赖,传得慢还容易在路上衰减。阿善想:要是能让每个格子和所有格子同时“对上眼神”,是不是更好?SepFormer 正是这么做的。

SepFormer 的核心是 Transformer 的自注意力机制:给定特征序列的 Q、K、V,先算每个位置和所有位置的相关性得分,再按得分加权融合信息。每一层编码器都能一次性看到全局,而且可以并行计算——这正是 RNN 做不到的。SepFormer 依然沿用 DPRNN 的双路径框架,只是把“块内/块间循环”换成了“块内/块间 Transformer”,在多数基准上效果全面超过 DPRNN。

好处当然不是免费的:注意力矩阵是序列长度的平方复杂度,越长越费算。SepFormer 之所以先分块再做注意力,很大程度就是为了控制这个二次复杂度。阿善总结:这招像把所有食材摊在案板上,每块都和其他每一块“对眼神”,分得准,但眼睛确实有点忙。

Attention(Q,K,V)=softmax ⁣(QK⊤dk)V\displaystyle \mathrm{Attention}(Q,K,V) = \mathrm{softmax}\!\left( \frac{QK^{\top}}{\sqrt{d_k}} \right) V
自注意力的关键:Q 和 K 的相似度决定“该关注谁”,归一化后加权求和 V,使每个位置都拿到全局信息。
  1. QK^T查询与键做内积,得到“每个位置与其他所有位置”的相似度得分矩阵。
    QK⊤\displaystyle QK^{\top}
  2. 缩放因子除以 \sqrt{d_k} 防止 softmax 输入过大导致梯度消失,让注意力分布更温和。
    1dk\displaystyle \frac{1}{\sqrt{d_k}}
  3. softmax 归一化把每行得分变成 0 到 1 且和为 1 的注意力权重,相当于“每块食材看其他食材的眼神有多重”。
    softmax(⋅)\displaystyle \mathrm{softmax}(\cdot)
  4. 乘 V 加权求和按权重融合所有位置的值,输出每个位置融合了全局信息的新表示。

评估与部署

捞出一盘“收音机”,怎么知道捞得干不干净?靠“试菜”:工程师用各种定量指标来打分。最常用的是 SI-SDR(尺度不变信噪比):它先把估计信号做一次整体缩放,尽量对齐真实信号,再算“信号能量 / 误差能量”的比值并取分贝,这样评估时不会因为音量大小不同而误判——你大声说和悄悄说,分数不该差太多。

除 SI-SDR 外,STOI 衡量“人耳能不能听懂”,PESQ 衡量“听感是否自然”,它们更贴近真实使用感受,常与 SI-SDR 搭配使用。工程上,模型推理延迟必须压到几十毫秒级才能支撑实时通话,剪枝、蒸馏、量化是常见手段。阿善的“声音大乱炖”之旅到此闭环:从切盘到漏勺,从贴标签到端到端网络,最后用 SI-SDR 给每款厨具打分——评估指标就是他的“试菜勺”,让他知道哪一招真正好用。

SI-SDR(s,s^)=10log⁡10∥αs∥2∥s^−αs∥2,α=s^⊤s∥s∥2\displaystyle \mathrm{SI\text{-}SDR}(s, \hat{s}) = 10 \log_{10} \frac{\| \alpha s \|^2}{\| \hat{s} - \alpha s \|^2}, \qquad \alpha = \frac{\hat{s}^{\top} s}{\| s \|^2}
SI-SDR 先通过最小二乘找到最优缩放系数 α,把真实信号调到与估计信号同一音量后,再计算信噪比。分数越高,说明分离结果与真实声源越接近。
  1. 最优缩放 α用内积除以能量求得,让“缩放后的真值”在最小二乘意义下最接近估计信号。
    α=s^⊤s∥s∥2\displaystyle \alpha = \frac{\hat{s}^{\top} s}{\| s \|^2}
  2. 分子缩放后真实信号的能量,代表“该有的信号”有多强。
    ∥αs∥2\displaystyle \| \alpha s \|^2
  3. 分母估计信号与缩放真值之间的误差能量,代表“残留了多少不该有的东西”。
    ∥s^−αs∥2\displaystyle \| \hat{s} - \alpha s \|^2
  4. 取对数乘 10把比值转换成分贝单位,便于跨实验比较,数值越大越好。

AI 应用场景

会议记录:先把“抢麦”拆成单人轨

阶段:语音前端处理

解决的问题:多人线上会议同时发言、频繁抢麦时,ASR 转写引擎分不清谁是谁,字稿乱成一锅粥。传统方案只能靠声纹预注册或麦克风阵列定位,临时参会者一旦抢话就出错。用语音分离模型先把每位发言人的声音拆成独立音轨,再分别送转写,说话人标签和字准率同步提升。

具体案例:某团队在视频会议产品中部署了轻量版 SepFormer:开启“发言分离”后,系统输出每人一条音频流,转写时自动配上说话人姓名。上线三个月后,会议纪要的说话人错误率下降约 40%,用户满意度显著提升。

助听器:地铁里听清孙女说话

阶段:实时边缘推理

解决的问题:助听器用户最大的抱怨是“背景一吵,人就听不清”。传统降噪会把目标人声一并压掉,越降越闷。语音分离模型实时把“当前对话者”从环境声中捞出来,保留自然音色。

具体案例:某助听器芯片厂商把 Conv-TasNet 剪枝量化后烧进 DSP,端到端延迟约 15ms,功耗只增加了 8%;在地铁、餐厅等强噪声场景下,用户报告“能听清孙女说话了”。

播客后期:重叠采访音节不再白剪

阶段:离线后期制作

解决的问题:访谈录音里主持人和嘉宾频繁抢话,重叠段落到剪辑师手里最难办——硬剪会切断语义,留着又听不清。语音分离模型把重叠片段拆成两条干净音轨,各自降噪、对齐时间轴后再混回,剪辑自由度大增。

具体案例:某播客工坊用开源 DPRNN 模型批量处理了 200 期访谈:先把重叠段自动检测出来,再分轨、重混、做响度平衡,后期时长缩短近 30%,口误替换也从“整段重录”变成了“单轨补录”。

Python 演示

python40 行
"""演示语音分离核心思想: 理想比值掩蔽(IRM) + SI-SDR 评估"""import numpy as npfrom scipy.signal import stft, istft  def make_sources(duration=3.0, sr=8000):    """构造两个'说话人': 不同基频的合成语音段"""    t = np.linspace(0, duration, int(sr * duration), endpoint=False)    s1 = 0.6 * np.sin(2 * np.pi * 220 * t) + 0.3 * np.sin(2 * np.pi * 330 * t + 1.0)    s2 = 0.5 * np.sin(2 * np.pi * 148 * t) + 0.4 * np.sin(2 * np.pi * 397 * t + 3.0)    return s1, s2  def irm_separate(mix, ref1, ref2, nperseg=512, noverlap=256):    """用理想比值掩蔽把第一个说话人从混合信号中捞出来"""    _, _, mix_stft = stft(mix, nperseg=nperseg, noverlap=noverlap)    _, _, s1_stft = stft(ref1, nperseg=nperseg, noverlap=noverlap)    _, _, s2_stft = stft(ref2, nperseg=nperseg, noverlap=noverlap)    irm = np.abs(s1_stft) ** 2 / (np.abs(s1_stft) ** 2 + np.abs(s2_stft) ** 2 + 1e-8)    sep_stft = mix_stft * irm    _, sep = istft(sep_stft, nperseg=nperseg, noverlap=noverlap)    return sep, irm  def si_sdr(ref, est, eps=1e-8):    """尺度不变信噪比: 先对齐音量再算信噪比"""    ref = ref[: len(est)]    alpha = np.dot(est, ref) / (np.dot(ref, ref) + eps)    energy = np.sum((alpha * ref) ** 2)    error = np.sum((est - alpha * ref) ** 2)    return 10 * np.log10(energy / (error + eps) + eps)  if __name__ == "__main__":    speaker_a, speaker_b = make_sources()    mix = speaker_a + speaker_b    sep_a, mask = irm_separate(mix, speaker_a, speaker_b)    print("掩蔽矩阵形状", mask.shape)    print("混合信号 SI-SDR: %.2f dB" % si_sdr(speaker_a, mix))    print("分离信号 SI-SDR: %.2f dB" % si_sdr(speaker_a, sep_a))
目的:用两段不同基频的正弦信号模拟两个说话人,把它们叠加成“声音大乱炖”,再用理想比值掩蔽把第一个说话人捞出来,最后用 SI-SDR 给分离效果打分。
  1. s1 = 0.6 * np.sin(2 * np.pi * 220 * t) + ...用两个正弦叠加模拟一个说话人的复杂音色
  2. irm = np.abs(s1_stft) ** 2 / (np.abs(s1_stft) ** 2 + ...)按能量占比计算掩蔽,对应文中的 IRM 公式
  3. sep_stft = mix_stft * irm把掩蔽乘到混合频谱上,这就是“漏勺按格放行”
  4. alpha = np.dot(est, ref) / (np.dot(ref, ref) + eps)计算最优缩放系数,让估计对齐真实信号后再打分
  5. return 10 * np.log10(energy / (error + eps) + eps)返回 SI-SDR 分贝值,数值越大分离质量越好

常见误区

误区很多初学者以为掩蔽就是把不想要的频率直接设成 0,像一把摧毁性的橡皮擦,把“剁菜声”从录音里擦掉。

正解掩蔽是“按比例放行”,IRM 输出连续的 0~1 权重,不是非黑即白。硬切边界会让人耳听到一种恼人的“音乐噪声”,这也是为什么实际系统中二值掩蔽逐渐让位于比值掩蔽。就像用筛子把沙子滤走,而不是泼掉整锅汤——留多留少,讲究的是分寸。

为何常见:“分离”的直觉容易让人联想到“切割”,而“噪声=删掉”的降噪经验也会强化这种误解。

误区有人认为排列不变训练就是“把训练数据随机打乱顺序,让模型学会顺序无关”。

正解PIT 并不打乱输入,而是在每次前向传播后,对“当前输出与真实标签”枚举所有排列,选损失最小的排列来反向传播。模型对输入顺序依然敏感,只是训练目标对“输出-标签”的匹配方式鲁棒;而且每个 batch 的最佳排列都会重新选择,这正是它名字里“排列不变”的真正含义。

为何常见:“排列不变”字面上容易被理解成“对输入重排”,而它实际关心的是“输出如何对标签排列”。

误区看到“时域端到端”的宣传,有人以为 Conv-TasNet 彻底抛弃了频域,完全不关心频率。

正解它不手工计算 STFT,但编码器中的一维卷积经过学习后,等效于一个“可学习的时频变换”,解码器则是它的逆变换。它并没有抛弃频率信息,而是让网络自己决定怎么切、切几块,因此比固定窗长的 STFT 更灵活,也避免了相位近似带来的失真。

为何常见:“端到端”的宣传常伴随“摆脱手工特征”的表述,容易让人把“不手工做”误读成“完全不存在”。

误区听到“双路径”就以为是两个循环神经网络简单叠在一起,加深层数就能提升效果。

正解DPRNN 的精髓是“分块 + 块内/块间交替”:先把长序列切成重叠块,Intra-RNN 沿块内时间建模局部,Inter-RNN 沿块索引建模全局,两个方向交替 R 轮才算一次完整处理。简单堆两个 RNN 无法获得跨块的全局依赖,正是“分块”与“交替”这两个设计共同起作用。

为何常见:“双路径”三个字太容易让人只注意到“两个网络”,而忽略了“分块”和“交替循环”才是它的核心创新。

面试题

Q1. 鸡尾酒会问题要解决的核心挑战是什么?

单选题 · easy

  • A.把嘈杂环境中的噪音完全消除掉
  • B.从多人说话混音中分离出每个说话人声音← 正确答案
  • C.提高麦克风对远距离声源的拾音灵敏度
  • D.把不同语言实时翻译成同一种语言

答案:B。鸡尾酒会问题的本质是“多人声音叠加后,单独提取每个目标声源”,选项 B 正中定义。A 只涉及单源去噪,C 是麦克风拾音问题,D 是翻译任务,都与“多说话人分离”无关。

Q2. 语谱图的两个坐标轴分别是什么?

单选题 · easy

  • A.横轴频率,纵轴时长
  • B.横轴时间,纵轴频率← 正确答案
  • C.横轴幅度,纵轴时间
  • D.横轴相位,纵轴时间

答案:B。语谱图横轴是时间、纵轴是频率,格子的颜色深浅表示该时频点能量大小。A 把横纵轴写反了,C 和 D 的“幅度/相位”并不是坐标轴,而是图中颜色的含义。

Q3. 理想比值掩蔽(IRM)对每个时频格子的取值范围是?

单选题 · mid

  • A.只有 0 或 1 两个离散值
  • B.0 到 1 之间的连续数值← 正确答案
  • C.任意实数范围取值
  • D.-1 到 1 之间的连续值

答案:B。IRM 定义为“某个说话人的能量 / 所有说话人总能量”,能量非负且占比必然不超过 1,所以取值是 [0,1] 的连续值。0/1 离散是二值掩蔽(IBM)的特征;C、D 的取值范围都与能量占比矛盾。

Q4. 掩蔽和映射两种分离思路的根本区别是什么?

单选题 · mid

  • A.掩蔽用深度网络而映射完全不用网络
  • B.掩蔽乘混合信号,映射直接回归目标频谱← 正确答案
  • C.映射只适用于说话人数量为二的情况
  • D.掩蔽只能用在时域波形而不能用于频谱

答案:B。掩蔽是在混合频谱上乘一个 0~1 的权重来筛选目标;映射则是让网络直接回归目标说话人的幅度谱。A 说法错误,两种方法都可以用深度网络;C、D 的说法没有依据,映射不限制说话人数,掩蔽也常用于时频特征。

Q5. 当说话人数量为 3 时,PIT 每次前向需要枚举多少种排列?

单选题 · mid

  • A.3 种排列
  • B.6 种排列← 正确答案
  • C.9 种排列
  • D.27 种排列

答案:B。PIT 需要穷举 N 个输出的全部排列,排列数为 N!。3 个说话人时 3! = 6 种,因此选 B。A 是“排列数等于人数”的直觉误区,C、D 都没有对应排列组合的数学含义。

Q6. 关于排列不变训练(PIT),下列说法正确的是?

多选题 · mid

  • A.每次前向都穷举输出与标签的所有排列← 正确答案
  • B.训练时模型固定输出顺序对应固定说话人
  • C.选损失最小的排列用于反向传播← 正确答案
  • D.训练好的模型推理时自带说话人顺序标签

答案:AC。PIT 的核心就是“穷举排列、取最小损失更新”,A 和 C 正确。B 正是 PIT 要抛弃的固定顺序做法;D 错误,PIT 只解决训练阶段的标签分配,推理时输出的顺序仍需借助声纹嵌入或聚类来区分。

Q7. Conv-TasNet 相比传统 STFT+掩蔽方法的主要优势是?

单选题 · hard

  • A.能处理任意数量的说话人
  • B.可学习编码器优化 SI-SNR← 正确答案
  • C.计算复杂度必定更低
  • D.完全不需要任何训练数据

答案:B。Conv-TasNet 用可学习的一维卷积编码器替代固定 STFT,并直接优化 SI-SNR,绕开“幅度掩蔽+借用混合相位”的近似失真,这是它效果好的关键。A 错误:说话人数量靠输出通道设计决定;C 的“必定更低”过于绝对;D 错误,它依然需要大量配对训练数据。

Q8. DPRNN 双路径设计中,块内和块间 RNN 各自解决什么问题?

多选题 · hard

  • A.块内 RNN 建模每个块的局部时序依赖← 正确答案
  • B.块间 RNN 建模跨块的长程全局依赖← 正确答案
  • C.块内 RNN 负责去除环境背景噪声
  • D.块间 RNN 负责压缩中间特征维度

答案:AB。DPRNN 把序列切成重叠块后,Intra-RNN 沿块内方向建模局部时序,Inter-RNN 沿块间方向交换信息、捕捉长程依赖,二者交替循环多轮。C 描述的是降噪任务而非双路径分工,D 的说法与块间建模的语义无关。

Q9. SepFormer 用 Transformer 替换 RNN 后,带来的核心好处是?

单选题 · hard

  • A.支持任意长音频且计算量恒定
  • B.自注意力并行计算且直接建模长依赖← 正确答案
  • C.完全不需要位置编码信息
  • D.参数量一定少于循环网络

答案:B。自注意力一次计算就能让每个位置看到全序列,并且能并行处理,这是相对 RNN 的核心优势。A 错误:注意力复杂度随序列长度平方增长;C 错误:Transformer 仍需要位置编码;D 没有必然性,参数量取决于具体设计。

Q10. 关于 SI-SDR 评估指标,下列说法正确的有?

多选题 · extreme

  • A.先把估计信号整体缩放对齐再算信噪比← 正确答案
  • B.对音量的整体大小变化不敏感← 正确答案
  • C.数值越低代表分离出来的质量越好
  • D.它完全等同于人耳的主观听感

答案:AB。SI-SDR 通过最小二乘求出缩放系数 α,把真实信号对齐到估计信号的音量尺度后再计算信噪比,因此对整体音量不敏感,A、B 正确。C 说反了:SI-SDR 数值越高越好。D 错误:SI-SDR 只是信号层面的相似度,与人耳听感并不完全一致,实际中常搭配 STOI、PESQ 使用。