|
发表于 2007-3-29
|
|阅读模式
简单的音频识别% A! T& G1 n: w$ f
0 {% s3 A1 e, ~( P1 E( f2 w5 d7 e# [: Y( A3 ]
今天的文章将向您展示如何构建可以识别 10 个不同字词的基本语音识别网络。需要注意的是,真正的语音和音频识别系统要复杂得多,但就像用于识别图像的 MNIST,这个基本语音识别网络能够帮助您基本了解所涉及的技术。学完本教程后,您将获得一个模型,该模型会尝试将时长为 1 秒的音频片段归类为无声、未知字词、“yes”、“no”、“up”、“down”、“left”、“right”、“on”、“off”、“stop” 或 “go”。您还可以在 Android 应用中运行该模型。
4 M5 a! A/ ~. q1 F% I, V
$ \3 X$ p# _6 t( @3 ~( }
. N1 Q6 H- E, E/ M准备
/ w# ^ r( T' T1 E E您应确保安装了 TensorFlow;此外,由于脚本会下载超过 1GB 的训练数据,因此您需要确保计算机拥有稳定的互联网连接和足够的可用空间。训练过程可能需要几个小时,因此请确保您的计算机可以完成这么长时间的训练操作。
( W5 A3 R2 M) |7 |% Q4 q: f
+ v* _4 `" y3 L) z6 p
% @$ e9 @* Z( ^) z2 ~4 w* ^训练
9 I( T7 w4 F1 ?1 v- Y: h2 ~5 z) H要开始训练过程,请转到 TensorFlow 源代码树,然后运行以下脚本:7 J, R t7 N. g' [
python tensorflow/examples/speech_commands/train.py6 s9 U/ q# j* s$ `$ E5 e: C# ~$ A
: q) i+ I/ X: l该脚本会先下载语音指令数据集,其中包含超过 105000 个 WAVE 音频文件,音频内容是有人说出 30 个不同的字词。这些数据由 Google 收集,并依据 CC BY 许可发布,您可以提交 5 分钟自己的录音来帮助改进该数据。归档数据超过 2GB,因此这部分过程可能需要一段时间,但您应该可以看到进度日志;下载完成后,您无需再次执行此步骤。如需详细了解该数据集,请参阅 https://arxiv.org/abs/1804.03209. x# Z1 ]7 P1 K$ O: j3 {
' d8 w( W8 H7 X' c4 p$ x
下载完成后,您将看到如下日志信息:9 D4 m/ g. C' O+ c) E
I0730 16:53:44.766740 55030 train.py:176] Training from step: 1! z6 ?3 b3 p9 y J3 W7 q
I0730 16:53:47.289078 55030 train.py:217] Step #1: rate 0.001000, accuracy 7.0%, cross entropy 2.6115710 y. a: r7 f+ T2 h
5 S: y5 m; P! {, x. k8 e/ a7 W这表明初始化过程已经完成,训练循环已经开始。您将看到该日志输出每个训练步的信息。下面详细说明了该日志信息的含义:
0 }1 }0 p1 R6 ]3 C1 `
0 @+ g! o5 S( A, mStep #1 表明正在进行训练循环的第一步。在此示例中总共有 18000 个训练步,您可以查看步编号来了解还有多少步即可完成。
1 }% E/ z& l- f; g4 ^. ~$ N, |8 F( k. r
rate 0.001000 是控制网络权重更新速度的学习速率。在训练的早期阶段,它是一个相对较大的数字 (0.001),但在训练周期的后期会减少到原来的十分之一,即 0.0001。" Q2 g& B8 d4 i! T& c* B
1 v8 ~) L, n* k' h6 V! K0 Y
accuracy 7.0% 表示模型在本训练步中预测正确的类别数量。该值通常会有较大的波动,但应该会随着训练的进行总体有所提高。该模型会输出一个数字数组,每个标签对应一个数字,每个数字都表示输入可能归入该类别的预测概率。可通过选择得分最高的条目来挑选预测标签。得分始终介于 0 到 1 之间,值越高表示结果的置信度越高。* Q9 c1 a; R6 U+ C" V0 `+ H
4 h3 E8 P: X# n$ r. b7 e
cross entropy 2.611571 是用于指导训练过程的损失函数的结果。它是一个得分,通过将当前训练运行的得分向量与正确标签进行比较计算而出,该得分应在训练期间呈下滑趋势。5 |3 P- x+ _& T/ p+ a# o2 W
5 g& X& B" k1 G6 W& Z; a8 t
经过 100 步之后,您应看到如下所示的行:
; @" Y0 R# r$ E6 QI0730 16:54:41.813438 55030 train.py:252] Saving to "/tmp/speech_commands_train/conv.ckpt-100"
7 g8 i6 i' T4 @
+ N3 X6 G* v6 m此行会将当前的训练权重保存到检查点文件中。如果训练脚本中断了,您可以查找上次保存的检查点,然后将 --start_checkpoint=/tmp/speech_commands_train/conv.ckpt-100 用作命令行参数重启该脚本,以便从该点开始。
, ?6 l/ E5 ^2 R5 k. `" }: @4 u% M
_ l: W+ M U+ {4 P
/ d: @6 N- @0 H S混淆矩阵
1 @: t. q6 K( |经过 400 步之后,您会看到以下日志信息:
7 O' {7 |0 R2 }( b) F; DI0730 16:57:38.073667 55030 train.py:243] Confusion Matrix:2 M* _$ Q! Q; U0 y
[[258 0 0 0 0 0 0 0 0 0 0 0]. e% a) n8 u; `1 b8 @1 N4 ?
[ 7 6 26 94 7 49 1 15 40 2 0 11]4 t5 \( x5 {" I* l
[ 10 1 107 80 13 22 0 13 10 1 0 4]
/ e5 D0 B% P1 f! A* g [ 1 3 16 163 6 48 0 5 10 1 0 17]
; q. J9 A) I+ y4 { [ 15 1 17 114 55 13 0 9 22 5 0 9]* V* z* B# W c3 |" z
[ 1 1 6 97 3 87 1 12 46 0 0 10]
% u2 c; ], H9 [, ?" x [ 8 6 86 84 13 24 1 9 9 1 0 6]! C J2 [) \2 _6 b
[ 9 3 32 112 9 26 1 36 19 0 0 9]
( M3 O+ p$ m: e* P [ 8 2 12 94 9 52 0 6 72 0 0 2]
: D" u: M' P6 G# T6 M [ 16 1 39 74 29 42 0 6 37 9 0 3]
+ e+ P( V+ g' e5 X, }( e& \: @/ w1 d [ 15 6 17 71 50 37 0 6 32 2 1 9]
6 n% L+ ?- p( w8 Q, f [ 11 1 6 151 5 42 0 8 16 0 0 20]]
, F9 ?$ [' t0 ~/ [; k7 m+ t( V" y+ B* K) |
第一部分是混淆矩阵。要理解它的具体含义,您首先需要了解所用的标签。在本示例中,所用的标签是 “silence”、“unknown”、“yes”、“no”、“up”、“down”、“left”、“right”、“on”、“off”、“stop” 和 “go”。每列代表一组被模型预测为每个标签的样本,因此第一列代表预测为无声的所有音频片段,第二列代表预测为未知字词的所有音频片段,第三列代表预测为 “yes” 的所有音频片段,依此类推。
' G; j; U3 W# j, j' L3 C
: ]9 r7 I! u) o每行表示音频片段实际归入的标签。第一行是归入无声的所有音频片段,第二行是归入未知字词的所有音频片段,第三行是归入 “yes” 的所有音频片段,依此类推。
& {3 S/ S5 g% E8 a2 y+ U
7 e9 p; t6 ?4 e* G* B此矩阵比单个准确率得分更加有用,因为它可以很好地总结网络出现的错误。在此示例中,您可以发现,除了第一个数值以外,第一行中的所有条目均为 0。因为第一行表示所有实际无声的音频片段,这意味着所有音频片段都未被错误地标记为字词,因此我们未得出任何有关无声的假负例。这表示网络已经可以很好地区分无声和字词。
- a! z$ x( A% |" q
$ m3 `: V* z1 U" l$ p& a如果我们往下看,就会发现第一列有大量非零值。该列表示预测为无声的所有音频片段,因此第一个单元格外的正数是错误的预测。这表示一些实际是语音字词的音频片段被预测为无声,因此我们得出了很多假正例。4 D1 n4 m: C8 {2 S2 s; d o& B( w' x
}7 Q; y& f, \# e. v) V完美的模型会生成混淆矩阵,除了穿过中心的对角线上的条目以外,所有其他条目都为 0。发现偏离这个模式的地方有助于您了解模型最容易在哪些方面混淆;确定问题所在后,您就可以通过添加更多数据或清理类别来解决这些问题。. {5 ^. J5 P% j4 q5 G
& @! X% L% w3 z }( e- _& K. x `4 g" `
验证
6 r0 y) ^8 m, ]/ d在混淆矩阵之后,您应看到如下所示的行:% w" m5 h8 u$ R3 O' ^' a
I0730 16:57:38.073777 55030 train.py:245] Step 400: Validation accuracy = 26.3% (N=3093)
4 W: B: ~! M1 O- X6 W, n2 S ]: G! G+ h0 U* f X, x) {
最好将数据集分成三个类别。最大的子集(本示例中为约 80% 的数据)用于训练网络,较小的子集(本示例中为约 10% 的数据,称为 “验证” 集)预留下来以评估训练期间的准确率,另一个子集(剩下的 10%,称为 “测试” 集)用来评估训练完成后的准确率。
3 ], e1 g0 \& z) w5 v& p! T& B$ Z
0 ~6 O( z! Y% P; L2 j5 W之所以采用这种拆分方法,是因为始终存在这样一种风险:网络在训练期间开始记忆输入。通过将验证集分离开来,可以确保模型能够处理它之前从未见过的数据。测试集是一种额外的保护措施,可以确保您不仅以适合训练集和验证集的方式调整模型,而且使模型能够泛化到范围更广的输入。2 e' b6 f% u& e) c* n1 Z, m' r
8 d. y" ^7 N* Z: U( Y: z" u. r
训练脚本会自动将数据集分为这三个类别,上面的日志行会显示在验证集上运行时模型的准确率。理想情况下,该准确率应该相当接近训练准确率。如果训练准确率有所提高但验证准确率没有,则表明存在过拟合,模型只学习了有关训练音频片段的信息,而没有学习能泛化的更广泛模式。
1 }" |* D$ L, ~$ Y6 Y' I2 Y' x( L$ F' \ P* k* S- y+ I% C+ K0 V
" J( |+ a5 Y$ O+ \' [Tensorboard
, l% O# q/ P1 i使用 Tensorboard 可以很好地观察训练进度。默认情况下,脚本会将事件保存到 /tmp/retrain_logs,您可以通过运行以下命令加载这些事件:
: g$ |5 M @! M0 U, z' Ptensorboard --logdir /tmp/retrain_logs
- y" f. \+ e7 M; A5 Q0 T4 I9 H* P
然后,在浏览器中转到 http://localhost:6006,您将看到显示模型进度的图表。
8 W' y" [# S' e
6 |8 b, G& H2 Y! r
|
|