当前位置:首页 > 工业控制 > 电路设计项目集锦
[导读]我一直对谷歌助手在我们说“好,谷歌”或“嘿,Siri”时立即开始录音的机制感到着迷。这种启发促使我探索如何将唤醒词检测技术应用于嵌入式设备。在这个项目中,我也意识到在树莓派等小型板载计算机(SBC)上运行时需要进行必要的优化。我完整记录了构建唤醒词识别模型的整个过程,并利用该模型在检测到唤醒词时实现图像采集以及在OLED显示屏上显示时间的功能。

我一直对谷歌助手在我们说“好,谷歌”或“嘿,Siri”时立即开始录音的机制感到着迷。这种启发促使我探索如何将唤醒词检测技术应用于嵌入式设备。在这个项目中,我也意识到在树莓派等小型板载(SBC)上运行时需要进行必要的优化。我完整记录了构建唤醒词识别模型的整个过程,并利用该模型在检测到唤醒词时实现图像采集以及在OLED显示屏上显示时间的功能。

1. 硬件设置:将INMP441麦克风连接到树莓派

我使用了INMP441 MEMS麦克风在树莓派5上进行音频采集和语音识别。连接过程相当简单,只需利用树莓派的标准SPI引脚即可。以下是接线细节:

1. VDD(INMP441)→ 3.3V(RPI)

2. GND(INMP441) --> GND(rpi)

3. SCK(INMP441) --> PCM_CLK(rpi)

4. WS(INMP441) --> PCM_FS(rpi)

5. SD(INMP441) --> PCM_DIN(rpi)

6. (可选)L/R(INMP441) --> 左声道连接GND,右声道连接VDD。

虽然我最初使用一对INMP441麦克风进行立体声音频采集,但注意到左声道存在轻微噪声,即使更换了跳线和软件线缆后也未能消除。因此,我决定仅使用右声道进行音频采集和推理。

2. 数据采集

由于我正在构建一个唤醒词检测系统,因此我的模型必须仅识别我指定的唤醒词,并忽略所有其他词语或背景噪音,本质上相当于一个“一与多”的分类器。为实现这一目标,我录制了多个唤醒词样本,以及一些随机词语的样本。

本项目所选的唤醒词是“raspi”,这很合适,因为我的设备使用的是树莓派(Raspberry Pi),而且音频信号中幅度的变化有助于分类器更准确地识别唤醒词。音频采集可通过连接至树莓派的INMP441进行,也可通过电脑内置麦克风完成。

以下是一个Python脚本,用于实现音频采集过程,每次捕获2秒的音频样本并存储到相应目录中:

对于上述脚本,我选择了16 kHz的采样率,以优化在树莓派上的运行效果。标准采样率44.1 kHz在笔记本电脑或PC上运行时也完全可行,但在树莓派上响应速度通常会稍慢。

我收集了大约100个唤醒词“raspi”的样本,以及约200个其他随机词语的样本,其中包括45个空背景音频样本。此外,我还录制了一些连续语音样本,例如自己阅读书籍的声音,以确保模型不会在连续语音中误判唤醒词。

唤醒词样本和非唤醒词样本分别存储在两个独立文件夹中,以便在预处理阶段方便地进行区分。

可选(适用于树莓派):您也可以使用树莓派上的arecord命令来获取测试样本。以下是一个采集单个2秒样本的示例命令。

说明:

-D plughw:2:指定硬件设备编号为2。使用“arecord -l”检查您的硬件设备的设备编号。

-c1:将通道数设置为1,便于唤醒词模型处理。

-r 16000:将采样率设置为16,000 Hz。

-f S32_LE:将格式设置为32位小端序。

-t wav:指定文件类型为WAV。

-d 2:录音持续2秒。

-V stereo:在录音期间启用立体声音量指示器。

-v:启用详细模式,提供有关录音过程的详细信息。

file_name.wav:用于保存录音的文件名。

3. 数据划分:训练、验证和测试

在总共获取的300个样本中,采用80/20的比例将数据划分为训练集和测试集。其中20%的训练数据用作验证集,以评估验证损失,从而避免模型过拟合或欠拟合。

4. 预处理

为了对.wav音频文件进行预处理并提取MFCC(梅尔频率倒谱系数),我选择使用Python库Librosa。

提取13个特征已被证明是唤醒词检测模型的最佳选择。我还尝试调整快速傅里叶变换(FFT)的数量和窗口大小,以实现最佳性能,因为这些参数在实时推理过程中必须保持一致。将n_fft设置为1024,hop_length设置为512,可确保树莓派的平滑过渡和快速响应。最初将n_fft设为2048,在我的电脑上推理效果良好,但在树莓派上则效果较差。

以下是一个从单个输入样本中提取13个特征的代码片段:

下方显示的MFCC频谱图展示了唤醒词和非唤醒词特征在时间上的倒谱系数变化。观察频谱图可以发现,当时间超过1秒时,两个特征都出现了明显的变化。在唤醒词样本中,0.5到1秒之间的时间段内,系数存在显著差异,这可能正是我发出唤醒词的时刻。

5. 模型训练:

由于输入数据是时间序列,因此检测“raspi”一词需要理解音素出现的顺序。因此,使用循环神经网络(RNN)来处理此类序列数据是合理的。

在预处理阶段我们提取了13个MFCC特征,训练阶段让模型学习这些特征的序列,并据此进行自我训练。

以下是用于唤醒词检测的RNN模型。该模型结构较为简单,包含64层隐藏层和1层RNN,符合我们的需求。

我也接触过长短期记忆(LSTM)模型,但为了简化,我决定继续使用RNN模型。

模型共训练100个epoch,学习率为1%。以下是初始和最终的损失结果。增加epoch数似乎能降低训练损失,但模型出现了过拟合现象,即当说话者说出其他随机词语时,仍会误识别为唤醒词。

6. 模型测试

在训练模型100个周期后,我获得了整体准确率91.6%。通过增加训练周期可以进一步提升测试准确率,但会导致模型过拟合,从而在实时推理时检测效果可能存在问题。经过调整训练周期和学习率后,这是我获得的最佳结果。

7. 实时推理流程如下:

i. 获取当前时刻的音频帧。

ii. 将该音频帧与之前若干时间步长内捕获的帧一起添加到缓冲区中。

iii. 对大小为2秒×16千赫的缓冲区进行处理,计算并取其MFCC(梅尔频率倒谱系数)的平均值。

iv. 将特征加载至预训练模型,并使用Sigmoid函数计算预测概率。

v. 重复步骤(i)中的相同过程,缓冲区持续追加并计算,实现类似滑动窗口的机制。

以下代码片段用于对intdata中的音频帧进行处理。

当检测到唤醒词时,实时准确率显著提升。

在无背景噪音的情况下,唤醒词的预测通常为20%;一旦检测到唤醒词,预测率通常超过70%。当用户靠近麦克风或大声说话时,预测概率还会进一步上升,甚至超过80%。有时,当用户仅说出一个词(如“hello”)时,预测率可达45%。基于这些参数,我将唤醒词检测的阈值设定为65%,以确保检测结果为真。

8. 应用1:时间显示

我实现唤醒词模型的一个应用是使用OLED显示屏进行简单的时间显示,当用户说出唤醒词时,系统会显示指定时间段内的当前时间。

8.1. 设置OLED显示屏

我使用了一个128x64像素的SSD1306 OLED显示屏,通过I2C接口与树莓派连接。该OLED通过以下方式连接到Raspberry Pi 5的标准I2C引脚:

SDA(SSD1306)→ GPIO2(树莓派)

SCL(SSD1306)→ GPIO3(树莓派)

VCC(SSD1306)→ 3.3V(树莓派)

GND(SSD1306)→ GND(树莓派)

用于I2C扫描,请使用以下命令:

如需安装必要模块并设置SSD1306在树莓派上,请按照本文中的步骤操作。

本文编译自hackster.io

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭