EfficientWord-Net
基于少样本学习的唤醒词检测
家庭助手需要特殊短语作为唤醒词来激活(例如:"OK Google")。 EfficientWord-Net 是一个基于少样本学习的唤醒词检测引擎,允许开发者免费为他们的程序添加自定义唤醒词。该库完全用 Python 编写,并使用 Google 的 Tflite 实现来实现更快的实时推理。它的灵感来自 FaceNet 的孪生网络架构,当直接从用户收集 3-4 个唤醒词样本时,效果最佳。
EfficientWord-Net 在树莓派上的演示
访问训练文件
数据集
以下是链接:https://drive.google.com/file/d/1f6dp72D9WxErXvaZP6KIBLv4-eKpvLZa/view?usp=sharing, https://drive.google.com/file/d/19QUTiAZvF1pFy5BeaV_rc83MeDu8yojv/view?usp=sharing
访问论文
Python 版本要求
该库适用于以下 Python 版本:
3.6 到 3.9
依赖项安装
在运行库的 pip 安装命令之前,需要手动安装一些依赖项。
- PyAudio (依赖于 PortAudio)
- Tflite (tensorflow 轻量级二进制文件)
- Librosa (某些系统可能无法使用二进制文件) Mac OS M* 和树莓派用户可能需要编译这些依赖项。
tflite 包无法列在 requirements.txt 中,因此当包在系统中初始化时会自动安装。
librosa 包仅在推理时不需要,但当调用 generate_reference 时会自动安装。
包安装
运行以下 pip 命令
pip install EfficientWord-Net
导入运行
import eff_word_net
演示
安装包后,您可以运行库内置的演示脚本(确保您有一个可用的麦克风)。
访问文档:https://ant-brain.github.io/EfficientWord-Net/
运行演示的命令
python -m eff_word_net.engine
生成自定义唤醒词
对于任何新的唤醒词,库需要有关唤醒词的信息,这些信息从名为 {wakeword}_ref.json
的文件中获取。
例如:对于唤醒词 'alexa',库需要名为 alexa_ref.json
的文件
可以通过以下步骤生成这些文件:
需要收集给定唤醒词的 4 到 10 个独特发音。然后将它们放入一个单独的文件夹中,该文件夹不包含其他内容。
或者可以使用以下命令为给定单词生成音频文件,使用 IBM 神经 TTS 演示 API。请不要为了我们过度使用它。
python -m eff_word_net.ibm_generate
最后运行此命令,它会询问输入文件夹的位置(包含音频文件)和输出文件夹(存储 _ref.json 文件的位置)。
python -m eff_word_net.generate_reference
生成的唤醒词的路径名需要传递给 HotwordDetector 检测器实例。
HotwordDetector(
hotword="hello",
model = Resnet_50_Arc_loss(),
reference_file = "/full/path/name/of/hello_ref.json"),
threshold=0.9, #考虑触发所需的最小置信度
relaxation_time = 0.8 #默认值,单位为秒
)
model 变量可以接收 Resnet_50_Arc_loss 或 First_Iteration_Siamese 的实例。
relaxation_time 参数用于确定任意两次触发之间的最小时间,在 relaxation_time 之前的任何潜在触发都将被取消。 检测器采用滑动窗口方法,导致单次唤醒词utterance产生多次触发,可以使用 relaxation_time 参数来控制多次触发,在大多数情况下 0.8 秒(默认值)就足够了。
现成的示例唤醒词
对于一些唤醒词,如 Mycroft、Google、Firefox、Alexa、Mobile、Siri,库中已经预定义了现成的嵌入,可以在库安装目录中找到,其路径可以通过以下变量获取
from eff_word_net import samples_loc
尝试您的第一个单一唤醒词检测脚本
import os
from eff_word_net.streams import SimpleMicStream
from eff_word_net.engine import HotwordDetector
from eff_word_net.audio_processing import Resnet50_Arc_loss
from eff_word_net import samples_loc
base_model = Resnet50_Arc_loss()
mycroft_hw = HotwordDetector(
hotword="mycroft",
model = base_model,
reference_file=os.path.join(samples_loc, "mycroft_ref.json"),
threshold=0.7,
relaxation_time=2
)
mic_stream = SimpleMicStream(
window_length_secs=1.5,
sliding_window_secs=0.75,
)
mic_stream.start_stream()
print("说 Mycroft ")
while True :
frame = mic_stream.getFrame()
result = mycroft_hw.scoreFrame(frame)
if result==None :
#无语音活动
continue
if(result["match"]):
print("唤醒词已说出",result["confidence"])
从音频流中检测多个唤醒词
该库提供了一种计算友好的方式来从给定流中检测多个唤醒词,而不是单独运行每个唤醒词的 scoreFrame()
import os
from eff_word_net.streams import SimpleMicStream
from eff_word_net import samples_loc
print(samples_loc)
base_model = Resnet50_Arc_loss()
mycroft_hw = HotwordDetector(
hotword="mycroft",
model = base_model,
reference_file=os.path.join(samples_loc,"mycroft_ref.json"),
threshold=0.7,
relaxation_time=2
)
alexa_hw = HotwordDetector(
hotword="alexa",
model=base_model,
reference_file=os.path.join(samples_loc,"alexa_ref.json"),
threshold=0.7,
relaxation_time=2,
#verbose=True
)
computer_hw = HotwordDetector(
hotword="computer",
model=base_model,
reference_file=os.path.join(samples_loc,"computer_ref.json"),
threshold=0.7,
relaxation_time=2,
#verbose=True
)
multi_hotword_detector = MultiHotwordDetector(
[mycroft_hw, alexa_hw, computer_hw],
model=base_model,
continuous=True,
)
mic_stream = SimpleMicStream(window_length_secs=1.5, sliding_window_secs=0.75)
mic_stream.start_stream()
print("说 ", " / ".join([x.hotword for x in multi_hotword_detector.detector_collection]))
while True:
frame = mic_stream.getFrame()
result = multi_hotword_detector.findBestMatch(frame)
if None not in result:
print(result[0], f",置信度 {result[1]:0.4f}")
可以从这里访问库的文档:https://ant-brain.github.io/EfficientWord-Net/
## 从0.2.2到v1.0.1的变更说明
### 新增模型Resnet_50_Arc_loss,带来巨大改进!!
使用从MLCommons提取的经过修改的蒸馏数据集从头训练了一个新模型,使用Arcloss函数替代了三元组损失函数。
生成的新模型存储为resnet_50_arcloss。
新模型表现出对背景噪音更好的抗干扰能力,并且需要更少的样本就能达到良好的准确率。
对API流程进行了微小调整,以便于轻松添加新模型。
新模型可以处理1.5秒的固定窗口长度。
仍可通过first_iteration_siamese访问旧模型。
## 从v0.1.1到0.2.2的变更说明
对处理每次语音中多个触发词的复杂逻辑进行了重大改变,使用了更简单的逻辑和更简单的API供程序员使用。
引入了破坏性变更
## 当前模型的局限性
- 仅针对单个词进行训练,因此在使用"嘿xxx"这样的短语时可能会产生奇怪的行为。
- 音频处理窗口限制为1秒。因此对于较长的热词效果不佳。
## 常见问题:
* **热词性能不佳**:如果遇到这样的问题,请随时在[讨论区](https://github.com/Ant-Brain/EfficientWord-Net/discussions/4)中询问。
* **它能在Arduino这样的FPGA上运行吗?**:不能,新模型Resnet_50_Arcloss太大(大约88MB),无法在Arduino上运行。我们很快会添加对模型剪枝版本的支持,使其足够轻量以在微型设备上运行。目前它应该能在树莓派这样的设备上运行。
## 贡献:
* 如果你有让项目变得更好的想法,请随时在[讨论区](https://github.com/Ant-Brain/EfficientWord-Net/discussions/3)中联系我们。
* 当前的[logmelcalc.tflite](/eff_word_net/logmelcalc.tflite)图每次只能将1个音频帧转换为对数梅尔频谱图。如果有TensorFlow专家能在这方面帮助我们,将不胜感激。
## 待办事项:
* 在数据流中添加音频文件处理器。欢迎提交PR。
* 移除librosa依赖,以鼓励直接在边缘设备上生成参考文件。
* 添加更详细的文档,解释滑动窗口概念。
* 添加模型微调支持。
* 添加稀疏和细粒度剪枝支持,生成的模型可用于微调(已在进行中)。
## 支持我们:
与Porcupine相比,我们的热词检测器性能明显较低。我们已经考虑了更好的神经网络架构,希望能超越Porcupine。这是我们的本科项目。因此,你的支持和鼓励将激励我们继续开发这个引擎。如果你喜欢这个项目,请向你的同行推荐,在GitHub上给我们一个🌟,在[medium](https://link.medium.com/yMBmWGM03kb)上给我们一个掌声👏。
更新:你们的星星鼓励我们创建了一个更好的新模型,让我们一起壮大这个社区吧!
## 许可证:[Apache License 2.0](/LICENSE.md)