Funpack第二季第1期 Syntiant TinyML Board实现语音指令识别
Syntiant TinyML Board Funpack第二季第1期 机器学习 语音识别
标签
嵌入式系统
测试
aramy
更新2022-07-04
1324

硬件介绍
funpack 第二季第1期活动,推出了Syntiant TinyML Board 机器学习的板子。这个开发板非常小巧,板的尺寸为 24 毫米 x 28 毫米,是一个小型的独立系统,通过微型 USB 连接通过 Edge Impulse 轻松下载经过训练的模型,而无需任何专用硬件。板子自身配备超低功耗 Syntiant  NDP101神经决策处理器,可以使语音和传感器应用程序分别在 140 和 100 微瓦以下运行。FtF53e47PKN-vZxe7gmL3KsTPKmX

任务:
本期选择任务1:用自带的麦克风,搭建机器学习模型,使板卡上的LED灯根据中文语音指令(不少于三个指令)呈现出不同效果,如开灯、关灯、闪烁、SOS、呼吸等.

这里我的目标是做一个用语音控制的玩具车。通过语音下达命令控制小车的移动。命令关键字有:向前进、向后退、向左转、向右转。在设计中允许命令字变形。比如:“向前走“、“前进”、”前进四”。 这些都能够作为小车前进的命令字。使用led灯来展示对应的命令字。FlrYRIlnQFKJ2rLgcj_2JI4wMENI

 

实现过程
1、准备工作。先给开发板烧写官方的固件。访问这个页面:https://docs.edgeimpulse.com/docs/development-platforms/officially-supported-mcu-targets/syntiant-tinyml-board 从这个页面中下载Audio firmware固件。电脑上需要安装Arduino CLI。我这里使用的是ArduinoCLI 0.19.2。刷好固件后,Syntiant的板子接在电脑上,就能被识别成一个麦克风,用这个麦克风来收集语音数据。

2、数据收集。在网站https://studio.edgeimpulse.com 提供了完整的机器学习解决方案。登录这个网站,注册自己的用户,然后开始创建自己的工程。FnXOF0Dr4Jdei4oopAIAPgJvsHSA然后在Data acquistition中收集数据。我这里使用了四个标签:forward、back、left、right。每个标签,长度设置为1秒,采样率1600Hz。收集的训练样本是越多越好,最好有不同人的声音,每个标签对应的不同的命令字都要有足够多的样本。我这里一共采集了160个样本。FsY_V95E4vLAmdhzrEzjpzfqNjev

 

3、训练模型。使用收集来的语音数据,使用神经网络进行训练。网站提供了多种模型供选择,但是不太明白模型的本质,直接使用了例程中使用的NN神经网络来作为训练模型。 这里网站带来的便利性就体现出来了,不用自己手工去写复杂的神经网络,可以使用已经造好的车轮。降低了学习成本。FnWlZ_w-RVTWIZjfInjgOc-eQkYv选择好模型,就是配置模型参数了。选择impulse design下的Syntiant就可以选择配置参数。这里使用滑动窗口的方式截取声音的每个小片,将声音做了FFT变换,提取声音的频域信息,最终将声音转换成信息矩阵。可以配置转换参数,这里也是使用例程中的参数。这个网站的可视化做的很好,可以看见每一个样本的波形和fft信息。FgH2ynJxVQk8o-gSgFpntZz0WzXt

配置好参数后,就是训练了,训练还是挺快的,几分钟就能完成训练了。但是看训练结果并不太理想。尤其是向右转正确识别率才66.7%。分析原因,应该和样本数量过少有关。如果想提高识别成功率,训练样本数量真的不能太少了,否则训练后的效果不佳。如果能够有合适的样本库就好了,收集训练样本实在是累而且无聊。Fqp3DOcTmXskuhnPhIoTYMSEVp4L

4 模型部署。训练完模型后,就可以部署到开发板上了。网页上提供了3个方法。最简单就是选择页面中的“build firmware”直接生成开发板的固件。生成固件后,能够下载到一个压缩包,解压后直接运行包内的批处理文件,就可以把固件烧写到开发板上。可以使用串口观察识别情况。FhytmpVR7aQfH1zEpIMMq_ULe3tF

我这里选择的是生成syntiant NDP101 library,选择这里就能生成arduino可以使用的库文件。生成后,打卡压缩包,有个model-parameters的文件夹,在这个文件夹下有三个头文件,就是训练好了的模型文件。使用https://github.com/edgeimpulse/firmware-syntiant-tinyml这个工程作为基础,将src下model-parameters里的模型文件替换成自己的模型文件,然后修改model_variables.h这个文件(需要注释掉一个包含头文件的语句和一个函数)。接下来就可以使用arduino编译烧写了。

/* Generated by Edge Impulse
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef _EI_CLASSIFIER_MODEL_VARIABLES_H_
#define _EI_CLASSIFIER_MODEL_VARIABLES_H_

#include <stdint.h>
#include "model_metadata.h"
//#include "edge-impulse-sdk/classifier/ei_model_types.h"

const char* ei_classifier_inferencing_categories[] = { "back", "forward", "left", "right" };

uint8_t ei_dsp_config_14_axes[] = { 0 };
const uint32_t ei_dsp_config_14_axes_size = 1;
ei_dsp_config_audio_syntiant_t ei_dsp_config_14 = {
    1,
    1,
    0.032f,
    0.024f,
    40,
    512,
    0,
    0,
    0.96875f
};
//const ei_model_performance_calibration_t ei_calibration = {
//    1, /* integer version number */
//    (int32_t)(EI_CLASSIFIER_RAW_SAMPLE_COUNT / ((EI_CLASSIFIER_FREQUENCY > 0) ? EI_CLASSIFIER_FREQUENCY : 1)) * 1000, /* Model window */
//    0.8f, /* Default threshold */
//    (int32_t)(EI_CLASSIFIER_RAW_SAMPLE_COUNT / ((EI_CLASSIFIER_FREQUENCY > 0) ? EI_CLASSIFIER_FREQUENCY : 1)) * 500, /* Half of model window */
//    0   /* Don't use flags */
//};
#endif // _EI_CLASSIFIER_MODEL_METADATA_H_

结果展示

当开发板通过板载麦克风收集到语音信息后就会送到NDP101与加载的模型进行运算,然后得出最高概率的标签值返还。在arduino中,通过返还的标签来控制LED灯。

/**
 * @brief      Called when a inference matches 1 of the features
 *
 * @param[in]  event          The event
 * @param[in]  confidence     The confidence
 * @param[in]  anomaly_score  The anomaly score
 */
void on_classification_changed(const char *event, float confidence, float anomaly_score) {
  Serial.print(confidence);
  Serial.print("   ");
  Serial.print(anomaly_score);
  Serial.print("    "); 
  Serial.println(event);
    // here you can write application code, e.g. to toggle LEDs based on keywords
   if (strcmp(event, "forward") == 0) {
       // Toggle LED
       digitalWrite(LED_RED, HIGH);
       digitalWrite(LED_GREEN, LOW);
       digitalWrite(LED_BLUE, LOW);
   }

   if (strcmp(event, "back") == 0) {
       // Toggle LED
       digitalWrite(LED_RED, LOW);
       digitalWrite(LED_GREEN, LOW);
       digitalWrite(LED_BLUE, LOW);
   }

   if (strcmp(event, "left") == 0) {
       // Toggle LED
       digitalWrite(LED_RED, LOW);
       digitalWrite(LED_GREEN, HIGH);
       digitalWrite(LED_BLUE, LOW);
   }

   if (strcmp(event, "right") == 0) {
       // Toggle LED
       digitalWrite(LED_RED, LOW);
       digitalWrite(LED_GREEN,LOW );
       digitalWrite(LED_BLUE, HIGH);
   }
}


向后退向后退


向前进向前进向右转向右转向左转向左转

开发板的使用中遇到的问题。1、语音识别,只要麦克风接收到数据就会做识别,会计算出标签对应的概率,然后返回最大概率的标签。这样会导致没有命令时也会不停地识别出命令字来!2、工程文件中,调用命令字识别函数入口中有命令字识别的概率变量,但是按代码查询,这个概率被赋值为0了,这样就没有办法通过设定阈值来过滤环境噪音了。

/**
 * @brief      Called from the ndp101 read out. Print classification output
 *             and send matched output string to user callback
 *
 * @param[in]  matched_feature
 */
void ei_classification_output(int matched_feature)
{
    if (ei_run_impulse_active()) {

        ei_printf("\nPredictions:\r\n");

        for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
            ei_printf("    %s: \t%d\r\n", ei_classifier_inferencing_categories[ix],
                (matched_feature == ix) ? 1 : 0);
        }

        on_classification_changed(ei_classifier_inferencing_categories[matched_feature], 0, 0);
    }
}

/**

心得体会:突然发现机器学习已经开始渗透到我们的生活中来了。身边越来越多的电器开始开始用机器学习的方式来提供服务。机器学习很有意思,感谢funpack带来的活动,让我通过玩了解到了机器学习。谢谢!

附件下载
firmware-syntiant-tinyml.zip
团队介绍
DIY折腾
团队成员
aramy
单片机业余爱好者,瞎捣鼓小能手。
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号