|
发表于 2007-3-29
|
|阅读模式
简单的音频识别* W3 I1 ], P8 f6 r& h
) ^" e! ^" H% m3 i; b6 U
- a( D9 O5 D+ T6 i4 G. H& |( n" X今天的文章将向您展示如何构建可以识别 10 个不同字词的基本语音识别网络。需要注意的是,真正的语音和音频识别系统要复杂得多,但就像用于识别图像的 MNIST,这个基本语音识别网络能够帮助您基本了解所涉及的技术。学完本教程后,您将获得一个模型,该模型会尝试将时长为 1 秒的音频片段归类为无声、未知字词、“yes”、“no”、“up”、“down”、“left”、“right”、“on”、“off”、“stop” 或 “go”。您还可以在 Android 应用中运行该模型。) z: @; A6 v5 D8 @4 Y/ T
, x% o; {2 [# t) ~' O
I5 d6 h" Y4 K; J准备 e% I6 O y4 p o
您应确保安装了 TensorFlow;此外,由于脚本会下载超过 1GB 的训练数据,因此您需要确保计算机拥有稳定的互联网连接和足够的可用空间。训练过程可能需要几个小时,因此请确保您的计算机可以完成这么长时间的训练操作。
7 }: y9 p& m6 q: k7 H6 V
& T$ z1 L7 i; I- {* F0 ` E1 G3 S) \
训练
" n5 g; T/ z" K8 Y1 x7 R) W要开始训练过程,请转到 TensorFlow 源代码树,然后运行以下脚本:: X P/ ]% E% T- |2 L Q% u; V
python tensorflow/examples/speech_commands/train.py
1 M) o0 \7 t5 E
2 R6 c, T4 G- i1 I+ X; R该脚本会先下载语音指令数据集,其中包含超过 105000 个 WAVE 音频文件,音频内容是有人说出 30 个不同的字词。这些数据由 Google 收集,并依据 CC BY 许可发布,您可以提交 5 分钟自己的录音来帮助改进该数据。归档数据超过 2GB,因此这部分过程可能需要一段时间,但您应该可以看到进度日志;下载完成后,您无需再次执行此步骤。如需详细了解该数据集,请参阅 https://arxiv.org/abs/1804.03209
4 N1 J8 C1 ]% {2 }5 R
; I1 s3 s6 e7 y6 g4 [% m下载完成后,您将看到如下日志信息:2 J2 l: G7 U0 i/ v
I0730 16:53:44.766740 55030 train.py:176] Training from step: 1" w- \+ |7 ^2 ] q: ?6 b- K4 `
I0730 16:53:47.289078 55030 train.py:217] Step #1: rate 0.001000, accuracy 7.0%, cross entropy 2.611571
+ Z U, { ]3 l" F8 Z* n+ U# f
' N1 i! M* d( |( _* T这表明初始化过程已经完成,训练循环已经开始。您将看到该日志输出每个训练步的信息。下面详细说明了该日志信息的含义:
( @) z- \; i7 p0 B6 T: e
# T8 [% x2 S( R7 pStep #1 表明正在进行训练循环的第一步。在此示例中总共有 18000 个训练步,您可以查看步编号来了解还有多少步即可完成。
$ r; K8 o, f% r" k: ~
1 E8 t/ m. u- Y3 f% P9 ]$ Q$ T' Srate 0.001000 是控制网络权重更新速度的学习速率。在训练的早期阶段,它是一个相对较大的数字 (0.001),但在训练周期的后期会减少到原来的十分之一,即 0.0001。" B' Z" e. }( f( C! |
" {1 C& ^7 P3 ^
accuracy 7.0% 表示模型在本训练步中预测正确的类别数量。该值通常会有较大的波动,但应该会随着训练的进行总体有所提高。该模型会输出一个数字数组,每个标签对应一个数字,每个数字都表示输入可能归入该类别的预测概率。可通过选择得分最高的条目来挑选预测标签。得分始终介于 0 到 1 之间,值越高表示结果的置信度越高。
8 j4 h, O! M+ b' f3 P- `' F; b5 }4 V) F% W+ S" w" `0 q/ r9 t- w
cross entropy 2.611571 是用于指导训练过程的损失函数的结果。它是一个得分,通过将当前训练运行的得分向量与正确标签进行比较计算而出,该得分应在训练期间呈下滑趋势。
, y' p6 X$ O$ G7 O& q) \: k
0 R) n7 v. m& R) V经过 100 步之后,您应看到如下所示的行:
, S* G% ^. |- ^I0730 16:54:41.813438 55030 train.py:252] Saving to "/tmp/speech_commands_train/conv.ckpt-100"
( G. c0 k5 a- _- E7 e
! X, ]! K' E, ?! }/ Z0 O: Z此行会将当前的训练权重保存到检查点文件中。如果训练脚本中断了,您可以查找上次保存的检查点,然后将 --start_checkpoint=/tmp/speech_commands_train/conv.ckpt-100 用作命令行参数重启该脚本,以便从该点开始。
. B$ S+ f1 `+ p4 v6 Y
+ D. S, X) n. ?2 k$ \) d0 x9 y b, u* V+ p
混淆矩阵4 Q1 H8 \& v. z& G# c- y c7 S6 K
经过 400 步之后,您会看到以下日志信息:9 m+ H4 X7 b, p6 F3 N
I0730 16:57:38.073667 55030 train.py:243] Confusion Matrix:/ `& p/ u- c8 f; D8 E4 m q6 c. S
[[258 0 0 0 0 0 0 0 0 0 0 0]' F# n5 }- B! L9 u* G
[ 7 6 26 94 7 49 1 15 40 2 0 11]- A, B( O! w# K7 |# j4 p
[ 10 1 107 80 13 22 0 13 10 1 0 4]
+ T9 i* |: W7 n [ 1 3 16 163 6 48 0 5 10 1 0 17]
+ R) r$ m7 w, C9 B [ 15 1 17 114 55 13 0 9 22 5 0 9]0 ~' S" U* ^5 A; }: ?# {! ^
[ 1 1 6 97 3 87 1 12 46 0 0 10]! I% t0 p7 `" s( e. T
[ 8 6 86 84 13 24 1 9 9 1 0 6]7 h+ `- {( X& M+ G
[ 9 3 32 112 9 26 1 36 19 0 0 9]2 y1 _& x/ |+ P
[ 8 2 12 94 9 52 0 6 72 0 0 2]! N m6 v5 L* x& Q0 p, h7 R
[ 16 1 39 74 29 42 0 6 37 9 0 3]
; n) g' z9 f0 Q0 w* B [ 15 6 17 71 50 37 0 6 32 2 1 9]- V, m+ @* g* L8 d/ O3 n& e P
[ 11 1 6 151 5 42 0 8 16 0 0 20]]. q5 f3 f3 y( k4 r$ P0 T
6 D" `5 n& [& E" U% ^
第一部分是混淆矩阵。要理解它的具体含义,您首先需要了解所用的标签。在本示例中,所用的标签是 “silence”、“unknown”、“yes”、“no”、“up”、“down”、“left”、“right”、“on”、“off”、“stop” 和 “go”。每列代表一组被模型预测为每个标签的样本,因此第一列代表预测为无声的所有音频片段,第二列代表预测为未知字词的所有音频片段,第三列代表预测为 “yes” 的所有音频片段,依此类推。
- {% I8 Y1 C; p8 { I4 K) o- i c* {( g! g
每行表示音频片段实际归入的标签。第一行是归入无声的所有音频片段,第二行是归入未知字词的所有音频片段,第三行是归入 “yes” 的所有音频片段,依此类推。* H: p; d/ [1 c8 n
_0 C$ L0 S4 q* A
此矩阵比单个准确率得分更加有用,因为它可以很好地总结网络出现的错误。在此示例中,您可以发现,除了第一个数值以外,第一行中的所有条目均为 0。因为第一行表示所有实际无声的音频片段,这意味着所有音频片段都未被错误地标记为字词,因此我们未得出任何有关无声的假负例。这表示网络已经可以很好地区分无声和字词。
! ^& e. \& H" A5 s# Z/ j5 p! O; R9 Z( F8 i
如果我们往下看,就会发现第一列有大量非零值。该列表示预测为无声的所有音频片段,因此第一个单元格外的正数是错误的预测。这表示一些实际是语音字词的音频片段被预测为无声,因此我们得出了很多假正例。1 B$ U& l- z. W. W" f5 O
$ ?" M- o! ^" Q5 z: L7 D完美的模型会生成混淆矩阵,除了穿过中心的对角线上的条目以外,所有其他条目都为 0。发现偏离这个模式的地方有助于您了解模型最容易在哪些方面混淆;确定问题所在后,您就可以通过添加更多数据或清理类别来解决这些问题。
$ n! X2 \. {/ p4 r: Q2 l- f$ s1 B0 g$ m- J
' W; a; @2 P$ a; U3 R0 W7 j验证
/ t9 a3 |- L) e9 w2 w在混淆矩阵之后,您应看到如下所示的行:/ M: M( |3 G. ~! B" n
I0730 16:57:38.073777 55030 train.py:245] Step 400: Validation accuracy = 26.3% (N=3093)
4 k/ T7 P( C7 ^+ A1 E$ a9 U. ^/ k6 o( r# [( d
最好将数据集分成三个类别。最大的子集(本示例中为约 80% 的数据)用于训练网络,较小的子集(本示例中为约 10% 的数据,称为 “验证” 集)预留下来以评估训练期间的准确率,另一个子集(剩下的 10%,称为 “测试” 集)用来评估训练完成后的准确率。2 H' A; _3 s! V) V/ ?
) A. \6 |* c/ n; V3 o1 z之所以采用这种拆分方法,是因为始终存在这样一种风险:网络在训练期间开始记忆输入。通过将验证集分离开来,可以确保模型能够处理它之前从未见过的数据。测试集是一种额外的保护措施,可以确保您不仅以适合训练集和验证集的方式调整模型,而且使模型能够泛化到范围更广的输入。0 `- U6 F4 r9 L% p
# @+ ?6 Y9 r$ G% G. ?$ V
训练脚本会自动将数据集分为这三个类别,上面的日志行会显示在验证集上运行时模型的准确率。理想情况下,该准确率应该相当接近训练准确率。如果训练准确率有所提高但验证准确率没有,则表明存在过拟合,模型只学习了有关训练音频片段的信息,而没有学习能泛化的更广泛模式。3 a/ ]- D" @7 u
* c7 E+ ^9 q3 I) \) C, r. [+ A) f; r6 W! _. e# h
Tensorboard
4 H! c ~7 M @7 }6 r" R使用 Tensorboard 可以很好地观察训练进度。默认情况下,脚本会将事件保存到 /tmp/retrain_logs,您可以通过运行以下命令加载这些事件:% o* S) n) O3 n# K) o% P3 E8 S& l: t
tensorboard --logdir /tmp/retrain_logs
# f& f" t$ A9 y. K% T* d
; r% p% Q i1 {- p0 u; H6 U然后,在浏览器中转到 http://localhost:6006,您将看到显示模型进度的图表。
0 T; c3 a" \3 |6 z! B
6 d5 N$ z. F) A! X: w
|
|