撕天
发表于 2006-10-16 02:47:00
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?快速注册
x
简单的音频识别
# L5 W6 b, S G4 P3 @( x- O
6 t0 n8 ]1 [+ t0 [1 y$ G e0 ]
4 a& ^' f3 O$ R' G今天的文章将向您展示如何构建可以识别 10 个不同字词的基本语音识别网络。需要注意的是,真正的语音和音频识别系统要复杂得多,但就像用于识别图像的 MNIST,这个基本语音识别网络能够帮助您基本了解所涉及的技术。学完本教程后,您将获得一个模型,该模型会尝试将时长为 1 秒的音频片段归类为无声、未知字词、“yes”、“no”、“up”、“down”、“left”、“right”、“on”、“off”、“stop” 或 “go”。您还可以在 Android 应用中运行该模型。" {+ C# N5 A* Y2 w9 X2 m" K9 t7 R a
; r/ q, u, H3 i/ r
2 s K i1 }6 l' x( g) h准备2 s+ l) f3 {) M0 E( a
您应确保安装了 TensorFlow;此外,由于脚本会下载超过 1GB 的训练数据,因此您需要确保计算机拥有稳定的互联网连接和足够的可用空间。训练过程可能需要几个小时,因此请确保您的计算机可以完成这么长时间的训练操作。
4 L# g4 M3 E' x# b
1 P) U, O/ U2 K
2 A/ W, _$ y" ]5 c, q, y训练# @; A1 Z1 e5 t- \1 s- S
要开始训练过程,请转到 TensorFlow 源代码树,然后运行以下脚本:
" o" ]) J7 w' u0 O8 [# {python tensorflow/examples/speech_commands/train.py
7 n" O! {# `" W" I7 x+ f |, q! ]0 u! [' {9 p
该脚本会先下载语音指令数据集,其中包含超过 105000 个 WAVE 音频文件,音频内容是有人说出 30 个不同的字词。这些数据由 Google 收集,并依据 CC BY 许可发布,您可以提交 5 分钟自己的录音来帮助改进该数据。归档数据超过 2GB,因此这部分过程可能需要一段时间,但您应该可以看到进度日志;下载完成后,您无需再次执行此步骤。如需详细了解该数据集,请参阅 https://arxiv.org/abs/1804.03209* {, J% a% K T
2 N1 W9 D$ A) X1 `) m. B
下载完成后,您将看到如下日志信息:
. o3 ?# n4 j( QI0730 16:53:44.766740 55030 train.py:176] Training from step: 1, N; U& g" |4 R5 A. c2 \" v
I0730 16:53:47.289078 55030 train.py:217] Step #1: rate 0.001000, accuracy 7.0%, cross entropy 2.611571
7 q3 D% L/ O: i! M3 `
. u4 i# X+ Q S8 Z; q& G这表明初始化过程已经完成,训练循环已经开始。您将看到该日志输出每个训练步的信息。下面详细说明了该日志信息的含义:
8 L/ ^$ [; a" e2 A H' r3 @( c: U1 B# l- p' r
Step #1 表明正在进行训练循环的第一步。在此示例中总共有 18000 个训练步,您可以查看步编号来了解还有多少步即可完成。2 B! r* }3 t* A2 i
2 _) X, i4 g) }0 ~# B' nrate 0.001000 是控制网络权重更新速度的学习速率。在训练的早期阶段,它是一个相对较大的数字 (0.001),但在训练周期的后期会减少到原来的十分之一,即 0.0001。3 d( Y! T v9 m* V4 X8 T/ p' H
$ I( z# p# a1 {
accuracy 7.0% 表示模型在本训练步中预测正确的类别数量。该值通常会有较大的波动,但应该会随着训练的进行总体有所提高。该模型会输出一个数字数组,每个标签对应一个数字,每个数字都表示输入可能归入该类别的预测概率。可通过选择得分最高的条目来挑选预测标签。得分始终介于 0 到 1 之间,值越高表示结果的置信度越高。
- ?8 L' z6 M9 b5 ?8 z! J8 V: E$ \0 C' |8 F% ^3 T5 i
cross entropy 2.611571 是用于指导训练过程的损失函数的结果。它是一个得分,通过将当前训练运行的得分向量与正确标签进行比较计算而出,该得分应在训练期间呈下滑趋势。
# j% f+ G( c& N4 G, L6 ^: s1 B; P S) b5 s" O* e/ v8 S8 B
经过 100 步之后,您应看到如下所示的行:
6 ]% S8 h& S" DI0730 16:54:41.813438 55030 train.py:252] Saving to "/tmp/speech_commands_train/conv.ckpt-100"' a5 S$ ^; f8 d4 s. s; S) t0 d
% l% ^1 `4 H% b1 p5 M* ]# u
此行会将当前的训练权重保存到检查点文件中。如果训练脚本中断了,您可以查找上次保存的检查点,然后将 --start_checkpoint=/tmp/speech_commands_train/conv.ckpt-100 用作命令行参数重启该脚本,以便从该点开始。" F0 w* o( o% D! }
* D, S" t# O+ K8 i; j- }: `8 i
& M$ C+ `. J4 P! z- ~3 ~% \# j) w混淆矩阵
3 F$ m1 u: |* B N: v* b1 w经过 400 步之后,您会看到以下日志信息:7 p# F" m6 ]8 W3 B
I0730 16:57:38.073667 55030 train.py:243] Confusion Matrix: J- B3 D! y! x0 E! l3 h( r* _
[[258 0 0 0 0 0 0 0 0 0 0 0]
M# g; h# Q1 w Q I [ 7 6 26 94 7 49 1 15 40 2 0 11]+ z0 S6 ^0 E }
[ 10 1 107 80 13 22 0 13 10 1 0 4]- v" u2 s& u- a
[ 1 3 16 163 6 48 0 5 10 1 0 17]8 `5 L- ?1 h5 X
[ 15 1 17 114 55 13 0 9 22 5 0 9]0 N5 f; l& a [# z \# j& z& T
[ 1 1 6 97 3 87 1 12 46 0 0 10]3 i* U/ l0 ?2 v: B8 B
[ 8 6 86 84 13 24 1 9 9 1 0 6]
1 c, g' Y0 E x4 f' Z [ 9 3 32 112 9 26 1 36 19 0 0 9]0 L! I9 c m8 C5 z
[ 8 2 12 94 9 52 0 6 72 0 0 2] k; I* J) D9 V
[ 16 1 39 74 29 42 0 6 37 9 0 3]
! W: [) `& C+ l/ H: K [ 15 6 17 71 50 37 0 6 32 2 1 9]
0 e9 L, C; y, E: f0 p" u [ 11 1 6 151 5 42 0 8 16 0 0 20]]/ ?) O7 w$ f& M+ S
' q& X5 b' }2 ]5 s第一部分是混淆矩阵。要理解它的具体含义,您首先需要了解所用的标签。在本示例中,所用的标签是 “silence”、“unknown”、“yes”、“no”、“up”、“down”、“left”、“right”、“on”、“off”、“stop” 和 “go”。每列代表一组被模型预测为每个标签的样本,因此第一列代表预测为无声的所有音频片段,第二列代表预测为未知字词的所有音频片段,第三列代表预测为 “yes” 的所有音频片段,依此类推。# o/ }. T' V7 F5 x2 H0 x
# r9 `) O& H! Z+ {
每行表示音频片段实际归入的标签。第一行是归入无声的所有音频片段,第二行是归入未知字词的所有音频片段,第三行是归入 “yes” 的所有音频片段,依此类推。! o' K E# e* V8 u1 R
8 F8 m# b3 g: k+ y/ R: M
此矩阵比单个准确率得分更加有用,因为它可以很好地总结网络出现的错误。在此示例中,您可以发现,除了第一个数值以外,第一行中的所有条目均为 0。因为第一行表示所有实际无声的音频片段,这意味着所有音频片段都未被错误地标记为字词,因此我们未得出任何有关无声的假负例。这表示网络已经可以很好地区分无声和字词。
6 ^# o& u( q+ B$ ~+ v
' P1 \9 ?2 h i4 S' @) t如果我们往下看,就会发现第一列有大量非零值。该列表示预测为无声的所有音频片段,因此第一个单元格外的正数是错误的预测。这表示一些实际是语音字词的音频片段被预测为无声,因此我们得出了很多假正例。! Y; c! f3 h6 x0 k# n+ K( @9 V
* i3 q' R' W6 Y+ L% z0 I$ E) F
完美的模型会生成混淆矩阵,除了穿过中心的对角线上的条目以外,所有其他条目都为 0。发现偏离这个模式的地方有助于您了解模型最容易在哪些方面混淆;确定问题所在后,您就可以通过添加更多数据或清理类别来解决这些问题。: M& O' x# f% T2 Z
4 i7 e, ?# K, w" J0 R9 q
6 b9 N+ W) U0 p* w) M
验证
( f! D! C( Z6 |$ [) D在混淆矩阵之后,您应看到如下所示的行:
8 v d8 U' V( e2 E( JI0730 16:57:38.073777 55030 train.py:245] Step 400: Validation accuracy = 26.3% (N=3093). [! Z9 d( r7 ^% ~1 z
5 \! `( Q6 v5 E2 f0 \8 P0 c' s1 j最好将数据集分成三个类别。最大的子集(本示例中为约 80% 的数据)用于训练网络,较小的子集(本示例中为约 10% 的数据,称为 “验证” 集)预留下来以评估训练期间的准确率,另一个子集(剩下的 10%,称为 “测试” 集)用来评估训练完成后的准确率。
5 f$ h: H9 R, _! Y/ w; V# [/ S. P3 j4 J( y" Z( {: B! ~
之所以采用这种拆分方法,是因为始终存在这样一种风险:网络在训练期间开始记忆输入。通过将验证集分离开来,可以确保模型能够处理它之前从未见过的数据。测试集是一种额外的保护措施,可以确保您不仅以适合训练集和验证集的方式调整模型,而且使模型能够泛化到范围更广的输入。; u6 @. }0 {9 a! L$ z
: a. p- u: Q) W3 C( V5 h
训练脚本会自动将数据集分为这三个类别,上面的日志行会显示在验证集上运行时模型的准确率。理想情况下,该准确率应该相当接近训练准确率。如果训练准确率有所提高但验证准确率没有,则表明存在过拟合,模型只学习了有关训练音频片段的信息,而没有学习能泛化的更广泛模式。
) W2 M# } n: Z+ ~/ {2 Z
" }# G( f$ w& y& p) Q: b# W3 F& Y. l
Tensorboard# t: N% M5 K# W0 w2 X9 Y3 P7 ?+ Z
使用 Tensorboard 可以很好地观察训练进度。默认情况下,脚本会将事件保存到 /tmp/retrain_logs,您可以通过运行以下命令加载这些事件:$ s x( H3 p$ T |- v8 ~9 f
tensorboard --logdir /tmp/retrain_logs
6 {, n1 ~7 `; l# c' V) M2 m2 a2 C1 @
然后,在浏览器中转到 http://localhost:6006,您将看到显示模型进度的图表。8 v; D2 W* r0 X. Q' Z" n
* p' u6 m) T2 }1 Q
|
|
|
|
|