esp-sr/docs/zh_CN/speech_command_recognition/README.rst

227 lines
7.8 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

命令词
======
:link_to_translation:`en:[English]`
MultiNet 命令词识别模型
----------------------------
MultiNet 是为了在 {IDF_TARGET_NAME} 系列上离线实现多命令词识别而设计的轻量化模型,目前支持 200 个以内的自定义命令词识别。
.. list::
:esp32s3: - 支持中文和英文命令词识别
:esp32: - 支持中文命令词识别
- 支持用户自定义命令词
- 支持运行过程中 增加/删除/修改 命令词语
- 最多支持 200 个命令词
- 支持单次识别和连续识别两种模式
- 轻量化,低资源消耗
- 低延时,延时 500 ms内
:esp32s3: - 支持在线中英文模型切换
- 模型单独分区,支持用户应用 OTA
MultiNet 输入为经过前端语音算法AFE处理过的音频格式为 16 KHz16 bit单声道。通过对音频进行识别则可以对应到相应的汉字或单词。
请参考 :doc:`Models Benchmark <../benchmark/README>` 去查看当前不同芯片支持的模型。
用户选择不同的模型的方法请参考 :doc:`模型加载 <../flash_model/README>`
.. note::
其中以 ``Q8`` 结尾的模型代表模型的 8 bit 版本,表明该模型更加轻量化。
命令词识别原理
-----------------
命令词识别原理如下图所示:
.. figure:: ../../_static/multinet_workflow.png
:alt: speech_command-recognition-system
speech_command-recognition-system
.. _command-requirements:
命令词格式要求
----------------
不同版本的MultiNet命令词格式不同。命令词需要满足特定的格式具体如下
MultiNet5和MultiNet6使用汉语拼音作为基本识别单元并且每个字的拼音拼写间隔一个空格。比如“打开空调”应该写成 “da kai kong tiao”请使用以下工具将汉字转为拼音 :project_file:`tool/multinet_pinyin.py`
自定义要求
~~~~~~~~~~~
在设计命令词时有如下要求和建议:
.. list::
- 中文推荐长度一般为 4-6 个汉字,过短导致误识别率高,过长不方便用户记忆
:esp32s3: - 英文推荐长度一般为 4-6 个单词
- 不支持中英文混合
- 不能含有阿拉伯数字和特殊字符
- 应避免使用常用语
- 命令词中每个汉字/单词的发音相差越大越好
自定义方法
~~~~~~~~~~~
MultiNet 支持多种且灵活的命令词设置方式,可通过在线或离线方法设置命令词,还允许随时动态增加/删除/修改命令词
.. only:: latex
.. figure:: ../../_static/QR_multinet_g2p.png
:alt: menuconfig_add_speech_commands
离线设置命令词
^^^^^^^^^^^^^^^
MultiNet6 离线设置命令词的方法:
- 中文通过修改 :project_file:`model/multinet_model/fst/commands_cn.txt`
格式如下第一个数字代表command id, 后面为指令的中文拼音,两者由空格隔开,拼音间也由空格隔开
::
# command_id command_sentence
1 da kai kong tiao
2 guan bi kong tiao
MultiNet5 离线设置命令词的方法:
- 通过 ``menuconfig``
1. ``idf.py menuconfig`` > ``ESP Speech Recognition`` > ``Add Chinese speech commands/Add English speech commands``,添加命令词。具体也可参考 ESP-Skainet 中的 example。
.. figure:: ../../_static/menuconfig_add_speech_commands.png
:alt: menuconfig_add_speech_commands
menuconfig_add_speech_commands
注意,单个 Command ID 可以支持多个短语,比如“打开空调”和“开空调”表示的意义相同,则可以将其写在同一个 Command ID 对应的词条中,用英文字符“,”隔开相邻词条(“,”前后无需空格)。
2. 在代码里调用以下 API
::
/**
* @brief Update the speech commands of MultiNet by menuconfig
*
* @param multinet The multinet handle
*
* @param model_data The model object to query
*
* @param langugae The language of MultiNet
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Fail
*/
esp_err_t esp_mn_commands_update_from_sdkconfig(esp_mn_iface_t *multinet, const model_iface_data_t *model_data);
- 通过修改代码
该方法中,用户直接在代码中编写命令词,并传给 MultiNet。在实际产品开发和使用中用户可以通过网络/UART/SPI 等多种接口,传递所需的命令词并随时更换命令词。具体 API 说明请参考 :project_file:`src/esp_mn_speech_commands.c` 和 ESP-Skainet 中的 example。
MultiNet 的使用
----------------
MultiNet 命令词识别建议和 ESP-SR 中的 AFE 声学算法模块一起运行,具体请参考 :doc:`AFE 介绍及使用 <../audio_front_end/README>` )。
当用户配置完成 AFE 后,请按照以下步骤配置和运行 MultiNet。
MultiNet 初始化
~~~~~~~~~~~~~~~
- 模型加载与初始化,请参考 :doc:`模型加载 <../flash_model/README>`
- 设置命令词,请参考 :ref:`command-requirements`
MultiNet 运行
~~~~~~~~~~~~~
当用户开启 AFE 且使能 WakeNet 后,则可以运行 MultiNet。但需要注意以下几点要求
* 传入帧长和 AFE fetch 帧长长度相等
* 支持音频格式为 16 KHz16 bit单通道。AFE fetch 拿到的数据也为这个格式
- 确定需要传入 MultiNet 的帧长
::
int mu_chunksize = multinet->get_samp_chunksize(model_data);
``mu_chunksize`` 是需要传入 MultiNet 的每帧音频的 ``short`` 型点数,这个大小和 AFE 中 fetch 的每帧数据点数完全一致。
- MultiNet 识别
我们将 AFE 实时 ``fetch`` 到的数据送入以下 API
::
esp_mn_state_t mn_state = multinet->detect(model_data, buff);
``buff`` 的长度为 ``mu_chunksize * sizeof(int16_t)``
MultiNet 识别结果
~~~~~~~~~~~~~~~~~
命令词识别必须和唤醒搭配使用,当唤醒后可以运行命令词的检测。
命令词模型在运行时,会实时返回当前帧的识别状态 ``mn_state`` ,目前分为以下几种识别状态:
- ESP_MN_STATE_DETECTING
该状态表示目前正在识别中,还未识别到目标命令词。
- ESP_MN_STATE_DETECTED
该状态表示目前识别到了目标命令词,此时用户可以调用 ``get_results`` 接口获取识别结果。
::
esp_mn_results_t *mn_result = multinet->get_results(model_data);
识别结果的信息存储在 ``get_result`` API 的返回值中,返回值的数据类型如下:
::
typedef struct{
esp_mn_state_t state;
int num; // The number of phrase in list, num<=5. When num=0, no phrase is recognized.
int phrase_id[ESP_MN_RESULT_MAX_NUM]; // The list of phrase id.
float prob[ESP_MN_RESULT_MAX_NUM]; // The list of probability.
} esp_mn_results_t;
其中,
- ``state`` 为当前识别的状态
- ``num`` 表示识别到的词条数目, ``num`` <= 5即最多返回 5 个候选结果
- ``phrase_id`` 表示识别到的词条对应的 Phrase ID
- ``prob`` 表示识别到的词条识别概率,从大到到小依次排列
用户可以使用 ``phrase_id[0]````prob[0]`` 拿到概率最高的识别结果。
- ESP_MN_STATE_TIMEOUT
该状态表示长时间未检测到命令词,自动退出。等待下次唤醒。
单次识别模式和连续识别模式:
当命令词识别返回状态为 ``ESP_MN_STATE_DETECTED`` 时退出命令词识别,则为单次识别模式;
当命令词识别返回状态为 ``ESP_MN_STATE_TIMEOUT`` 时退出命令词识别,则为连续识别模式;
资源消耗
--------
有关本模型的资源消耗情况,请见 :doc:`资源消耗 <../benchmark/README>`
其他配置和使用
--------------
阈值设置
~~~~~~~~
该功能仍在开发中。