講座の本文は現在、中国語版のみです。各講のタイトルと導入文、メニューやボタンは日本語で表示しています。

第 05 講全 23 講約 13 分

録音から何を計算してプログラムに渡すべきか?——音声特徴量の 5 つの軸

前の講までで、30 秒の音楽は 60 万個あまりの数字の列になりました(1 秒に 2 万 2 千回あまり、それを 30 秒分)。この数字の列をそのまま分類プログラムに渡してもうまくいきません。長すぎるし、細かすぎるし、1 つの数だけでは何もわからないからです。そこでまず、いくつかの要約を計算します。この要約を音声特徴量と呼びます。「どの音声特徴量を使えばいいか」と検索すると長い用語リストが出てきますが、それぞれの名前が答えている問いは同じではありません。この講ではリストを暗記するのではなく、分類の地図を示します。どんな音声特徴量も、5 つの軸で位置を決められます。抽象度、時間の範囲、音楽のどの性質か、信号の領域、そしてどんな方法で計算するか。

导读: 到上一课为止,一段 30 秒的音乐已经变成了一串六十多万个数字(每秒记两万两千多次,记了三十秒)。直接把这串数字丢给分类程序不行——太长、太细、而且单独一个数说明不了任何事。所以要先算出一些摘要,这些摘要就叫音频特征。搜「该用什么音频特征」会搜到一份长长的名词清单,可这些名字回答的不是同一种问题。这一课不背清单,而是给出一张分类地图:任何一个音频特征,都可以用五个维度定位——抽象层级、时间范围、音乐属性、信号域、用什么方法算出来。

第 5 课属于第 1 组「认识声音与数字录音」,本组共 5 课

为什么需要音频特征

需要音频特征,有三个直接理由:

  • 特征是对声音的一种描述。 那六十多万个数(每一个都是某一瞬间量到的一个值)本身不构成描述,它只是记录。
  • 不同的特征抓住声音的不同侧面。 有的抓强弱,有的抓高低,有的抓变化快慢。没有哪一个能抓住全部。
  • 要造出能听懂声音的系统,就得先有这些描述。 分类、识别、检索,全都建在特征之上。

关键在第二条:不同特征抓的侧面不同。 所以「哪个特征最好」这个问法本身不成立——就像问「体温计和 CT 哪个更好」。它们回答的不是同一个问题。

一个特征,可以用五个维度定位

音频特征的五个分类维度

图 1:这不是五选一,是五个各自独立的问题。任何一个特征名字,都能在这五条上各找到一个位置。

这里说的维度,就是「可以分别去问的一个问题」。五个维度互相独立:换一个答案,不影响另外四个。

维度这个词的意思它问的是
抽象层级「离原始数字有几层」这个描述是直接算出来的,还是要先学
时间范围「一次看多长」一次概括 50 毫秒,还是几秒,还是整段
音乐属性「描述音乐的哪一面」是快慢,是听着像什么乐器,还是别的
信号域「从哪个角度看」看随时间的起伏,还是看有哪些高低成分
算法来源「谁算出来的」人按公式算,还是让程序从数据里学

后面三个名字(抽象层级、信号域这类)现在不用懂,下面五节各讲一个。

维度一:抽象层级

抽象层级问的是:这个描述离原始测量有多远。

  • 低层:直接从那串数字算出来,中间不需要先训练任何东西。这一小段有多响、那条曲线穿过中线多少次。含义稳定,换个项目也是同一个意思。
  • 中层:由低层的结果组织起来。音高(第 02 课讲过,就是「这个音有多高」)随时间怎么走、节拍落在哪里、成分分布是什么形状。
  • 高层:需要从数据里学出来。说话人是谁、什么音乐风格、什么情绪。它的含义离不开训练它的那批数据。

所以呢? 越抽象的目标,越不能直接去清单里找一个名字。「判断这台机器是不是要坏了」是高层,没有任何函数能直接算它;得先拆成低层的可测证据:是不是出现了以前没有的固定高低的尖声?是不是出现了有规律的撞击?背景的沙沙声是不是变大了? 这三条才是能直接算的。

维度二:时间范围

时间范围问的是:一次概括多长的声音。 它可以分成三档:

档多长能看见什么
瞬时约 50 毫秒局部质地:这一小段是元音还是摩擦音
片段级几秒一个完整事件:一次敲击、一个词、一小节
全局整段录音只剩总体统计:「平均而言这段偏尖锐」

注意最上面那一档是 50 毫秒,不是一个数。上一课说过,录音就是每隔极短一瞬量一次得到的一串数,每一次测量叫一个采样点。单独一个采样点几乎没有信息——「第 8137 个数是 0.03」,这句话什么也说明不了。要有一小段,才谈得上「质地」。

不同时间范围能看见的东西不同

图 2:四条色条的长度差就是覆盖范围的差。最上面那条几乎看不见——一个采样点确实什么也说明不了。

维度三:音乐属性

这一维在做音乐任务时才用得上。它问的是:这个特征描述的是音乐的哪个方面。 常见内容可以分成四类:

  • 节拍(beat):什么时候有一下,快慢如何。
  • 音色(timbre):听起来像什么乐器。第 03 课把它拆成了三样:声音怎么起怎么落、一个音里那些整数倍成分各有多强、以及它自己抖不抖。
  • 音高(pitch):这个音有多高。只有一段图案在反复重复的声音才谈得上音高,第 02 课讲过。
  • 和声(harmony):同时响的几个音之间是什么关系。
音乐属性的四个方面:节拍、音色、音高、和声

图 3:四个方面互相独立。同一段音乐,换个乐器演奏,音色变了而节拍、音高、和声都没变。

所以呢? 这一维直接决定你该往哪儿找特征。课程的三分类任务里,古典和摇滚差在节拍(密度和规整程度)和音色(失真吉他 vs 钢琴)上,而不是差在音高上——所以后面要算的特征,得往节拍和音色这两个方向找。

维度四:信号域

信号域问的是:从哪个角度观察这段声音。 这一维最重要,因为整个课程的后半段就是按它组织的。

下面会一口气冒出十来个名字。现在一个都不用懂——只要知道它们分别属于哪一档,以及各自在第几课展开。

① 时域——看数值随时间怎么起伏。这一档的三个代表:

  • 振幅包络:每一小段里最高的那个数有多大
  • 均方根:每一小段整体上有多强
  • 过零率:每一小段里,曲线穿过中线多少次

主场是第 07—09 课,那三课会从头算一遍。

② 频域——看声音由哪些高低成分组成,不管它们什么时候出现。

  • 三个代表:频带能量比、频谱质心、频谱通量。「频谱」指的是「这段声音由哪些高低成分组成」的那张分布
  • 主场是第 21—23 课

③ 时频表示——同时看「有哪些成分」和「它们什么时候出现」。这一档的东西都是二维的图:一个方向是时间,另一个方向是高低成分。

  • 声谱图:最基本的那一张,第 16 课细讲
  • 梅尔频谱:把纵轴按人耳的习惯重新分格之后的版本,第 17 课细讲
  • 常数 Q 变换:把纵轴按音乐的音高关系分格的版本

主场是第 15—18 课。

时域、频域和时频表示三种观察角度

图 4:素材是一段从低到高的音阶。右图里一级级往上的亮块就是一个个音,还能看到每个音上方那几条更淡的横线——这是左右两张图都给不了的信息。

再说一遍:这些名字现在只要知道分属哪一档就够了,具体怎么算,各自那一课会从头讲。

维度五:用什么方法算出来

最后一维问的是:这个特征是人按公式算的,还是程序从数据里学的。

所谓深度学习,指的是让一个多层的程序自己从大量数据里摸索出该看什么,人不指定;传统机器学习则是人先算好一组数字,再让算法从这些数字里学规则。

传统机器学习深度学习
特征从哪来人手工设计,按公式算程序自己从数据里学
输入是什么一组算好的数(AE、RMS、ZCR、频谱质心……)接近原始的表示(比如声谱图)
需要多少数据较少较多
能不能解释高,每一维都说得清低,需要额外手段分析
换个项目定义稳定,直接能用依赖训练数据的分布
主要风险规则不适合任务,漏掉关键线索数据覆盖不足,学到无关差异
人按公式算和程序从数据里学,两种来源可以组合

图 5:两张卡片之间是箭头,不是分隔线。下面那条橙色的才是实际做法:前面按公式算好,后面交给程序去学。

常见错误:把这一维当成二选一。 很多实用系统的做法是:前面用一个稳定、便宜、可解释的规则算好中间表示(比如梅尔频谱),后面交给模型去学。既省数据,又保留灵活性。

三类能听懂声音的系统

把上一维再往外推一层,按「特征从哪儿来」,能听懂声音的系统可以分成三类。

DSP 规则系统、传统机器学习、深度学习三类系统

图 6:从左到右,人写的部分越来越少,程序自己学的部分越来越多;同时需要的数据越来越多,能解释的程度越来越低。

  • DSP / 规则系统:人把判断规则整条写死。不需要训练数据,完全可解释,但换个场景就得重写。
  • 传统机器学习:人做特征工程——手工算出一组数字,再让算法从这些数字里学判断规则。
  • 深度学习:人只给接近原始的输入,特征提取也交给程序自己完成。

这门课的位置在中间那一类:我们手工算特征,把它整理成一张可信的表。表交给哪种算法,不在这 23 课的范围内。

实验:为了长度一致而求平均,代价有多大

五个维度里,时间范围最容易被随手糊弄过去——「为了让每段录音长度一致,整段求个平均吧」。这一步的代价可以直接量出来。

运行 lesson05_feature_choices.py:

原序 [0.1, 0.2, 0.9, 0.4, 0.8, 0.1]
  均值 = 0.4167   标准差 = 0.3236
倒序 [0.1, 0.8, 0.4, 0.9, 0.2, 0.1]
  均值 = 0.4167   标准差 = 0.3236
随机打乱 [0.4, 0.9, 0.1, 0.8, 0.1, 0.2]
  均值 = 0.4167   标准差 = 0.3236

三行一位小数都不差。

所以呢? 这不是巧合:均值和标准差的定义里都是求和,而加法不在乎顺序。推广一下——任何与顺序无关的统计量,都无法还原「峰值出现在第几段」。换成最大值、中位数、分位数,结论一样。

判据因此非常干脆:

  • 任务里出现「什么时候」,就必须保留一段一段的先后顺序。
  • 只判断「整段属于哪一类」,才可以考虑压成统计量。

同一份数据,两种形状:

log_mel   (64, 501)
          64 个频带 × 501 个时间帧
保留时间  (501, 64)
          每个时刻一个 64 维向量
丢掉时间  (128,)
          64 个均值 + 64 个标准差

第二种长度固定,和录音多长无关,适合做第一版对照方案;但「峰出现在第几帧」再也问不出来了。

一个会安静出错的参数。 把梅尔频谱换算成分贝时有个 ref 参数,它决定「以什么为 0 dB」:

        三段音乐的最大值
        ref=1.0    ref=max
古典      12.75       0.00
爵士      19.76       0.00
摇滚      18.40       0.00

ref=np.max 让每段以自身峰值为 0 dB——右边一列三个全是 0.00,三段之间的电平差被抹掉了。左边那一列还留着差别。

所以呢? 如果任务恰好依赖「这台机器比以前更吵了」,用 ref=np.max 就把关键线索删掉了,而且不会报错。这类参数不改变输出的形状,只改变数值——形状对了不代表数值可比,所以它必须和 n_fft、hop_length 一样被记录下来。

把五个维度套到课程项目上

拆成什么  高频占比 / 节奏密度 / 力度起伏
看多长    节奏和力度是随时间的事,
          先留序列,最后一步才聚合
哪个角度  高频占比看成分,节奏看时间,
          力度起伏两边都要
谁来算    只有几十个片段,
          先用规则算出的特征做基线

再加上音乐属性那一维:三种风格差在节拍和音色上,不差在音高上。

答案是五个问题共同决定的,不是从清单上挑一个名词。

这一课得到了什么,下一课接着讲什么

这一课没有教任何一种具体算法,它给的是一张地图:看到一个陌生的特征名字,能在五个维度上把它定位;面对一个新任务,能按五个问题依次推出该算什么。

第 01—05 课到这里结束。回头看这一组走过的路:声音怎么产生(02)→ 怎么被记成数字(04)→ 强弱和音色怎么量(03)→ 该算什么交给程序(05)。

可有一件事还没解决。上面反复说「一小段」「逐帧」「保留时间顺序」,可这些「小段」到底怎么切出来? 下一课就讲这件事:把一整段录音切成许多短小、互相重叠的片段,然后逐段计算。那是第 06—10 课整组的起点。