TensorFlow Lite for Microcontrollers 및 SparkFun Edge를 사용한 AI 음성 인식

1. 소개

빌드할 항목

이 Codelab에서는 TensorFlow Lite For Microcontrollers를 사용하여 SparkFun Edge 개발 보드에서 딥 러닝 모델을 실행하는 방법을 알아봅니다. 보드의 내장 음성 감지 모델을 사용합니다. 이 모델은 컨볼루션 신경망을 사용하여 보드의 두 마이크를 통해 말하는 '예'와 '아니요'라는 단어를 감지합니다.

bf256d403a1821af.gif

마이크로컨트롤러의 머신러닝

머신러닝을 사용하면 Google 어시스턴트와 같이 사용자의 삶을 더 편리하게 만들어 주는 지능형 도구를 만들 수 있습니다. 하지만 이러한 환경에는 강력한 클라우드 서버나 데스크톱을 포함할 수 있는 많은 컴퓨팅 또는 리소스가 필요한 경우가 많습니다. 하지만 이제 마이크로컨트롤러와 같은 작고 전력 소비가 적은 하드웨어에서 머신러닝 추론을 실행할 수 있습니다.

마이크로 컨트롤러는 매우 일반적이고 저렴하며 에너지를 거의 필요로 하지 않고 매우 안정적입니다. 가전제품, 자동차, 장난감 등 다양한 가정용 기기에 사용됩니다. 실제로 매년 약 300억 개의 마이크로컨트롤러 기반 기기가 생산됩니다.

1360b61fbfa33657.jpeg

머신러닝을 소형 마이크로 컨트롤러에 적용하면 값비싼 하드웨어나 안정적인 인터넷 연결에 의존하지 않고도 일상생활에서 사용하는 수십억 개의 기기의 지능을 향상할 수 있습니다. 일상 업무에 적응할 수 있는 스마트 가전, 문제와 일반 작업의 차이를 파악하는 지능형 산업 센서, 어린이가 신나고 재미있게 배우도록 돕는 마술 장난감을 상상해 보세요.

TensorFlow Lite For Microcontrollers (소프트웨어)

358ffdb9eb758b90.png

TensorFlow는 모델을 학습하고 실행하기 위한 Google의 오픈소스 머신러닝 프레임워크입니다. TensorFlow Lite는 소프트웨어 프레임워크이자 TensorFlow의 최적화된 버전으로, 휴대기기와 같이 작고 상대적으로 전력이 낮은 기기에서 TensorFlow 모델을 실행하는 데 타겟팅됩니다.

TensorFlow Lite For Microcontrollers는 마이크로컨트롤러와 같은 소형 저전력 하드웨어에서 TensorFlow 모델을 실행하도록 설계된 최적화된 버전의 TensorFlow인 소프트웨어 프레임워크입니다. 이 라이브러리는 이러한 삽입된 환경에 필요한 제약 조건을 준수합니다.즉, 바이너리 크기가 작고 운영체제 지원, 표준 C 또는 C++ 라이브러리, 동적 메모리 할당 등이 필요하지 않습니다.

SparkFun Edge (하드웨어)

SparkFun Edge는 마이크로컨트롤러 기반 플랫폼으로, 단일 회로 기판에 있는 작은 컴퓨터입니다. 다른 기기에 디지털 신호를 보내고 받을 수 있는 프로세서, 메모리, I/O 하드웨어가 있습니다. 좋아하는 Google 색상으로 된 소프트웨어 제어 가능 LED가 4개 있습니다.

aa4493835a2338c6.png

컴퓨터와 달리 마이크로컨트롤러는 운영체제를 실행하지 않습니다. 대신 작성한 프로그램이 하드웨어에서 직접 실행됩니다. 컴퓨터에서 코드를 작성하고 프로그래머라는 기기를 통해 마이크로컨트롤러에 다운로드합니다.

마이크로컨트롤러는 강력한 컴퓨터가 아닙니다. 프로세서가 작고 메모리가 많지 않습니다. 하지만 최대한 간단하게 설계되었기 때문에 마이크로컨트롤러는 에너지를 아주 적게 사용할 수 있습니다. 프로그램의 기능에 따라 SparkFun Edge는 단일 코인 셀 배터리로 몇 주 동안 실행할 수 있습니다.

학습할 내용

  • 컴퓨터에서 SparkFun Edge용 샘플 프로그램을 컴파일합니다.
  • 기기에 프로그램 배포
  • 프로그램을 변경하고 다시 배포하기

필요한 항목

다음 하드웨어가 필요합니다.

다음 소프트웨어가 필요합니다.

  • Git (명령줄에서 git을 실행하여 설치되어 있는지 확인)
  • Python 3 (명령줄에서 python3 또는 python --version을 실행하여 설치되어 있는지 확인)
  • Python 3용 Pip ( 유용한 StackOverflow 답변)
  • 4.2.1 이상 (명령줄에서 make --version를 실행하여 설치되었는지 확인)
  • SparkFun Serial Basic 드라이버

2. 하드웨어 설정

SparkFun Edge 마이크로컨트롤러에는 음성 모델을 실행할 수 있는 사전 설치된 바이너리가 함께 제공됩니다. 자체 버전으로 덮어쓰기 전에 먼저 이 모델을 실행해 보겠습니다.

다음과 같은 방법으로 보드에 전원을 공급합니다.

  1. 보드 뒷면의 배터리 커넥터에 코인 셀 배터리를 삽입합니다 (배터리의 '+' 측면이 위를 향함). 보드에 배터리가 이미 삽입되어 있는 경우 플라스틱 탭을 당겨 빼고 배터리를 밀어 완전히 삽입합니다.

25a6cc6b208e8a4e.png

  1. 코인 배터리가 없는 경우 SparkFun USB-C Serial Basic 프로그래머 기기를 사용하여 보드에 전원을 공급할 수 있습니다. 이 기기를 보드에 연결하려면 다음 단계를 따르세요.
  • SparkFun Edge 측면에 있는 6핀 헤더를 찾습니다.
  • 각 기기의 'BLK' 및 'GRN' 라벨이 지정된 핀이 올바르게 정렬되도록 SparkFun USB-C Serial Basic을 이러한 핀에 연결합니다.
  • SparkFun USB-C Serial Basic과 컴퓨터 사이에 USB-C 케이블을 연결합니다.

b140822f0019f92a.png

배터리를 삽입하거나 USB 프로그래머를 연결하여 보드에 전원을 공급하면 보드가 절전 모드에서 해제되고 마이크로 듣기 시작합니다. 파란색 표시등이 깜박이기 시작합니다.

보드의 머신러닝 모델은 '예'와 '아니요'라는 단어를 인식하고 음성의 유무를 감지하도록 학습됩니다. 색상 LED를 켜서 결과를 전달합니다. 다음 표에는 각 LED 색상의 의미가 나와 있습니다.

감지 결과

LED 색상

'예'

노란색

'아니요'

빨간색

알 수 없는 음성

초록색

음성이 감지되지 않음

LED가 켜져 있지 않음

지금 확인해 보세요

보드를 입에 대고 '예'라고 몇 번 말합니다. 노란색 LED가 깜박입니다. '예'라고 말해도 아무 반응이 없으면 다음을 시도해 보세요.

  • 입에서 약 25cm 떨어진 곳에 보드를 잡습니다.
  • 과도한 배경 소음 방지
  • '예'를 여러 번 연속으로 반복합니다('예 예 예'라고 말해 보세요).

3. 소프트웨어 설정

이제 마이크로컨트롤러에 음성 모델을 직접 다운로드하고 설치하고 실행합니다. 이를 위해 먼저 이 프로그램의 소스 코드와 빌드하는 데 필요한 종속 항목을 다운로드합니다. 이 프로그램은 C++로 작성되었으며, 보드에 다운로드하기 전에 바이너리로 컴파일해야 합니다. 바이너리는 SparkFun Edge 하드웨어에서 직접 실행할 수 있는 형식으로 프로그램을 포함하는 파일입니다.

다음 안내는 Linux 또는 MacOS용으로 작성되었습니다.

TensorFlow 저장소 다운로드

코드는 GitHub의 TensorFlow 저장소에서 다음 위치에 제공됩니다.

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/micro

컴퓨터에서 터미널을 열고 일반적으로 코딩 프로젝트를 저장하는 디렉터리로 변경한 후 아래와 같이 TensorFlow 저장소를 다운로드하고 생성된 디렉터리로 이동합니다.

cd ~  # change into your home (or any other) directory
git clone --depth 1 https://github.com/tensorflow/tensorflow.git
cd tensorflow

Python 종속 항목 다운로드

Python 3를 사용하여 바이너리를 준비하고 기기에 플래시합니다. Python 스크립트는 특정 라이브러리를 사용할 수 있어야 합니다. 다음 명령어를 실행하여 이러한 종속 항목을 설치합니다.

pip3 install pycrypto pyserial --user

4. 바이너리 빌드 및 준비

바이너리를 빌드하고 기기에 다운로드할 수 있도록 준비하는 명령어를 실행합니다.

바이너리 빌드

필요한 종속 항목을 모두 다운로드하고 바이너리를 만들려면 다음 명령어를 실행합니다.

make -f tensorflow/lite/micro/tools/make/Makefile TARGET=sparkfun_edge micro_speech_bin

빌드가 성공적으로 작동하면 출력의 마지막 줄이 다음과 같이 표시됩니다.

arm-none-eabi-objcopy tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin -O binary

바이너리가 성공적으로 생성되었는지 확인하려면 다음 명령어를 실행합니다.

test -f \
tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin && \
 echo "Binary was successfully created" || echo "Binary is missing"

콘솔에 Binary was successfully created가 출력됩니다. Binary is missing가 표시되면 디버깅이 필요한 빌드 프로세스에 문제가 있는 것입니다.

바이너리 준비

바이너리는 암호화 키로 서명되어야 기기에 배포될 수 있습니다. 이제 SparkFun Edge에 다운로드할 수 있도록 바이너리에 서명하는 명령어를 실행합니다.

다음 명령어를 입력하여 개발에 사용할 수 있는 더미 암호화 키를 설정합니다.

cp tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info0.py tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/keys_info.py

이제 다음 명령어를 실행하여 서명된 바이너리를 만듭니다.

python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_image_blob.py \
--bin tensorflow/lite/micro/tools/make/gen/sparkfun_edge_cortex-m4/bin/micro_speech.bin \
--load-address 0xC000 \
--magic-num 0xCB \
-o main_nonsecure_ota \
--version 0x0

그러면 main_nonsecure_ota.bin 파일이 생성됩니다. 이제 다음 단계에서 사용할 부트로더 스크립트로 기기를 플래시하는 데 사용할 수 있는 최종 버전의 파일을 만들기 위해 다른 명령어를 실행합니다.

python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/create_cust_wireupdate_blob.py \
--load-address 0x20000 \
--bin main_nonsecure_ota.bin \
-i 6 \
-o main_nonsecure_wire \
--options 0x1

이제 명령어를 실행한 디렉터리에 main_nonsecure_wire.bin라는 파일이 있어야 합니다. 이 파일은 기기에 플래시할 파일입니다.

5. 바이너리 플래시 준비

플래싱이란 무엇인가요?

SparkFun Edge는 현재 실행 중인 프로그램을 512KB의 플래시 메모리에 저장합니다. 보드에서 새 프로그램을 실행하려면 보드에 전송해야 합니다. 그러면 플래시 메모리에 저장되어 이전에 저장된 프로그램을 덮어씁니다.

이 프로세스를 '플래시'라고 하며, 이를 사용하여 프로그램을 보드로 전송합니다.

프로그래머를 보드에 연결합니다.

보드에 새 프로그램을 다운로드하려면 SparkFun USB-C Serial Basic 직렬 프로그래머를 사용합니다. 이 기기를 사용하면 컴퓨터가 USB를 통해 마이크로컨트롤러와 통신할 수 있습니다.

이 기기를 보드에 연결하려면 다음 단계를 따르세요.

  1. SparkFun Edge 측면에 있는 6핀 헤더를 찾습니다.
  2. 각 기기의 'BLK' 및 'GRN' 라벨이 지정된 핀이 올바르게 정렬되도록 SparkFun USB-C Serial Basic을 이러한 핀에 연결합니다.

b140822f0019f92a.png

프로그래머를 컴퓨터에 연결

USB를 통해 보드를 컴퓨터에 연결합니다. 보드를 프로그래밍하려면 컴퓨터에서 기기에 부여한 이름을 알아야 합니다. 가장 좋은 방법은 연결 전후에 컴퓨터의 모든 기기를 나열하고 어떤 기기가 새로 추가되었는지 확인하는 것입니다.

USB를 통해 기기를 연결하기 전에 다음 명령어를 실행합니다.

If you are using Linux: ls /dev/tty*
If you are using MacOS: ls /dev/cu*

다음과 같은 연결된 기기 목록이 출력됩니다.

/dev/cu.Bluetooth-Incoming-Port
/dev/cu.MALS
/dev/cu.SOC

이제 프로그래머를 컴퓨터의 USB 포트에 연결합니다. 다음 명령어를 다시 입력합니다.

If you are using Linux: ls /dev/tty*
If you are using MacOS: ls /dev/cu*

아래 예와 같이 출력에 항목이 추가됩니다. 새 항목의 이름이 다를 수 있습니다. 이 새 항목은 기기의 이름입니다.

/dev/cu.Bluetooth-Incoming-Port
/dev/cu.MALS
/dev/cu.SOC
/dev/cu.wchusbserial-1450

먼저 기기 이름을 식별하는 환경 변수를 만듭니다.

export DEVICENAME=put your device name here

다음으로 데이터를 기기로 전송할 속도인 보드율을 지정하는 환경 변수를 만듭니다.

export BAUD_RATE=921600

6. 바이너리 플래시

스크립트를 실행하여 보드 플래시

보드를 플래시하려면 새 바이너리를 수신할 수 있도록 준비하는 특수한 '부트로더' 상태로 전환해야 합니다. 그런 다음 스크립트를 실행하여 바이너리를 보드로 전송합니다.

보드의 다음 버튼을 살펴보겠습니다.

64c620570b9d2f83.png

다음 단계에 따라 보드를 재설정하고 플래시합니다.

  1. 보드가 프로그래머에 연결되어 있고 전체 설정이 USB를 통해 컴퓨터에 연결되어 있는지 확인합니다.
  2. 보드에서 14로 표시된 버튼을 누른 상태로 시작합니다. 6단계까지 계속 누르고 있습니다.
  3. 14 표시된 버튼을 계속 누른 상태에서 보드를 부트로더 상태로 재설정하려면 RST 표시된 버튼을 클릭하여 보드를 재설정합니다.
  4. 14 표시된 버튼을 계속 누른 상태에서 다음 명령어를 터미널에 붙여넣고 Enter 키를 눌러 실행합니다. 편의를 위해 버튼을 누르기 전에 이 명령어를 터미널에 붙여넣어도 되지만 이 단계에 도달할 때까지 Enter 키를 누르지 마세요.
python3 tensorflow/lite/micro/tools/make/downloads/AmbiqSuite-Rel2.2.0/tools/apollo3_scripts/uart_wired_update.py -b ${BAUD_RATE} ${DEVICENAME} -r 1 -f main_nonsecure_wire.bin -i 6
  1. 14 표시가 있는 버튼을 계속 누르고 있으면 화면에 다음과 같은 내용이 표시됩니다.
Connecting with Corvette over serial port /dev/cu.usbserial-1440...
Sending Hello.
Received response for Hello
Received Status
length =  0x58
version =  0x3
Max Storage =  0x4ffa0
Status =  0x2
State =  0x7
AMInfo =
0x1
0xff2da3ff
0x55fff
0x1
0x49f40003
0xffffffff
[...lots more 0xffffffff...]
Sending OTA Descriptor =  0xfe000
Sending Update Command.
number of updates needed =  1
Sending block of size  0x158b0  from  0x0  to  0x158b0
Sending Data Packet of length  8180
Sending Data Packet of length  8180
[...lots more Sending Data Packet of length  8180...]
  1. Sending Data Packet of length 8180이 표시되면 보드에 14로 표시된 버튼을 누르는 것을 중지합니다 (계속 눌러도 괜찮음). 프로그램은 터미널에 계속해서 줄을 출력합니다. 결과는 다음과 같습니다.
[...lots more Sending Data Packet of length  8180...]
Sending Data Packet of length  8180
Sending Data Packet of length  6440
Sending Reset Command.
Done.

Done가 표시되면 성공적으로 깜박인 것입니다. 프로그램 출력이 오류로 끝나면 Sending Reset Command가 출력되었는지 확인합니다. 이 경우 오류가 발생했지만 플래시가 성공했을 수 있습니다.

Linux 머신에서는 NoResponse Error가 발생할 수 있습니다. 이는 ch34x 직렬 드라이버가 기존 직렬 드라이버와 함께 설치되었기 때문이며, 다음과 같이 해결할 수 있습니다.

1단계: 올바른 버전의 ch34x 라이브러리를 다시 설치합니다. 설치하는 동안 기기가 컴퓨터에서 분리되어 있는지 확인합니다.

git clone https://github.com/juliagoda/CH341SER.git
cd CH341SER/
make
sudo insmod ch34x.ko
sudo rmmod ch341

2단계: 보드 USB를 연결하고 다음을 실행합니다.

dmesg | grep "ch34x"

다음과 같은 메시지가 나타납니다.

[ 1299.444724]  ch34x_attach+0x1af/0x280 [ch34x]
[ 1299.445386] usb 2-13.1: ch34x converter now attached to ttyUSB0

사용된 드라이버가 'ch34x'가 아닌 경우(예: ch341) 다음을 실행하여 다른 드라이버를 사용 중지해 보세요.

rmmod <non-ch34x driver name>

기기를 분리했다가 다시 연결하고 사용 중인 드라이버가 'ch34x'인지 확인합니다.

7. 데모

프로그램 사용해 보기

보드가 성공적으로 플래시되면

RST를 눌러 보드를 다시 시작하고 프로그램을 시작합니다. 파란색 LED가 깜박이기 시작하면 플래시가 성공한 것입니다. 문제가 해결되지 않으면 아래의 '문제가 해결되지 않으면 어떻게 해야 하나요?' 섹션으로 스크롤하세요.

bf256d403a1821af.gif

보드의 머신러닝 모델은 '예'와 '아니요'라는 단어를 인식하고 음성의 유무를 감지하도록 학습됩니다. 색상 LED를 켜서 결과를 전달합니다. 다음 표에는 각 LED 색상의 의미가 나와 있습니다.

감지 결과

LED 색상

'예'

노란색

'아니요'

빨간색

알 수 없는 음성

초록색

음성이 감지되지 않음

LED가 켜져 있지 않음

지금 확인해 보세요

보드를 입에 대고 '예'라고 몇 번 말합니다. 노란색 LED가 깜박입니다. '예'라고 말해도 아무 반응이 없으면 다음을 시도해 보세요.

  • 입에서 약 25cm 떨어진 곳에 보드를 잡습니다.
  • 과도한 배경 소음 방지
  • '예'를 여러 번 연속으로 반복합니다('예 예 예'라고 말해 보세요).

그래도 문제가 해결되지 않으면 어떻게 하나요?

다음은 몇 가지 가능한 문제와 디버깅 방법입니다.

문제: 플래시 후 LED가 켜지지 않습니다.

해결 방법: RST 버튼을 누르거나 프로그래머에서 보드를 분리했다가 다시 연결해 보세요. 이러한 방법으로 문제가 해결되지 않으면 보드를 다시 플래시해 보세요.

문제: 파란색 LED가 켜지지만 매우 어둡습니다.

해결 방법: 배터리가 부족하므로 배터리를 교체합니다. 또는 프로그래머와 케이블을 사용하여 컴퓨터로 보드에 전원을 공급할 수 있습니다.

8. 디버그 출력 읽기 (선택사항)

문제가 발생하여 코드를 자세히 디버그해야 하는 경우 이 섹션을 검토하세요. 코드가 실행될 때 마이크로컨트롤러에서 어떤 일이 발생하는지 이해하려면 보드의 직렬 연결을 통해 디버깅 정보를 출력하면 됩니다. 컴퓨터를 사용하여 보드에 연결하고 보드에서 전송하는 데이터를 표시합니다.

직렬 연결 열기

기본적으로 SparkFun Edge 샘플 코드는 음성 명령어를 신뢰도와 함께 기록합니다. 보드의 출력을 확인하려면 다음 명령어를 실행하면 됩니다.

screen ${DEVICENAME} 115200

처음에는 다음과 같은 출력이 표시될 수 있습니다. (이는 보드가 연결된 후 재설정된 경우에만 표시되며, 그렇지 않으면 디버그 정보가 표시될 수 있습니다.)

Apollo3 Burst Mode is Available

                               Apollo3 operating in Burst Mode (96MHz)

'예' 또는 '아니요'라고 말하여 명령을 내려 보세요. 각 명령어에 대한 디버그 정보가 보드에 출력됩니다.

 Heard yes (202) @65536ms

위 로그에서 yes는 명령어를 나타냅니다. 202은 명령어가 들렸다는 신뢰도 수준을 나타냅니다 (최소값은 200). 마지막으로 65536ms는 마이크로컨트롤러가 마지막으로 재설정된 이후 경과된 시간을 나타냅니다.

디버그 출력을 중지하려면 Ctrl+A를 누른 다음 바로 K 키를 누르고 Y 키를 누릅니다.

디버그 로그 작성

방금 작업한 command_responder.cc 파일에서 이 정보를 로깅하는 코드를 확인할 수 있습니다.

tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc

데이터를 로깅하려면 error_reporter->Report() 메서드를 호출하면 됩니다. 문자열 삽입을 위한 표준 printf 토큰을 지원하며, 이를 사용하여 로그에 중요한 정보를 포함할 수 있습니다.

error_reporter->Report("Heard %s (%d) @%dms", found_command, score, current_time);

이 메서드는 다음 섹션에서 코드에 직접 변경사항을 적용할 때 유용합니다.

9. 코드 확장 (선택사항)

이제 SparkFun Edge를 빌드하고 플래시하는 방법을 알았으므로 코드를 사용해 보고 기기에 배포하여 결과를 확인할 수 있습니다.

코드 읽기

코드를 읽기 시작하기에 좋은 곳은 command_responder.cc. 파일입니다.

tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc

GitHub에서 파일을 확인할 수 있습니다(여기).

이 파일의 메서드인 RespondToCommand는 음성 명령이 감지되면 호출됩니다. 기존 코드는 '예', '아니요' 또는 알 수 없는 명령어가 들렸는지에 따라 다른 LED를 켭니다. 다음 스니펫은 작동 방식을 보여줍니다.

if (found_command[0] == 'y') {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_YELLOW);
}
if (found_command[0] == 'n') {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_RED);
}
if (found_command[0] == 'u') {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_GREEN);
}

found_command 인수에는 감지된 명령어의 이름이 포함되어 있습니다. 첫 번째 문자를 확인하여 이 if 문 집합은 어떤 LED를 켤지 결정합니다.

RespondToCommand 메서드는 다음과 같은 여러 인수로 호출됩니다.

void RespondToCommand(tflite::ErrorReporter* error_reporter,
    int32_t current_time, const char* found_command,
    uint8_t score, bool is_new_command) {
  • error_reporter는 디버그 정보를 로깅하는 데 사용됩니다 (자세한 내용은 나중에 설명).
  • current_time은 명령어가 감지된 시간을 나타냅니다.
  • found_command는 감지된 명령어를 알려줍니다.
  • score는 명령어를 감지했음을 얼마나 확신하는지 알려줍니다.
  • is_new_command는 명령어를 처음 듣는 것인지 알려줍니다.

score는 명령어가 감지될 확률을 나타내는 0~255 사이의 정수입니다. 샘플 코드에서는 점수가 200보다 큰 경우에만 명령어를 유효한 것으로 간주합니다. 테스트 결과에 따르면 대부분의 유효한 명령은 200~210 범위에 속합니다.

코드 수정

SparkFun Edge 보드에는 LED가 4개 있습니다. 현재는 인식 중임을 나타내기 위해 파란색 LED가 깜박입니다. command_responder.cc 파일에서 이를 확인할 수 있습니다.

static int count = 0;

// Toggle the blue LED every time an inference is performed.
++count;
if (count & 1) {
  am_hal_gpio_output_set(AM_BSP_GPIO_LED_BLUE);
} else {
  am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
}

LED가 4개 있으므로 특정 명령어의 score를 시각적으로 나타내도록 프로그램을 수정해 보겠습니다. 점수가 낮으면 LED가 하나만 켜지고 점수가 높으면 여러 개의 LED가 켜집니다.

프로그램이 실행 중임을 알 수 있도록 파란색 대신 빨간색 LED가 계속 깜박이도록 합니다. 인접한 파란색, 녹색, 노란색 LED는 가장 최근의 score의 강도를 표시하는 데 사용됩니다. 간단하게 하기 위해 '예'라는 단어가 말해진 경우에만 LED가 켜지도록 하겠습니다. 다른 단어가 감지되면 LED가 꺼집니다.

이 변경사항을 적용하려면 command_responder.cc 파일의 모든 코드를 다음 스니펫으로 바꾸세요.

#include "tensorflow/lite/micro/examples/micro_speech/command_responder.h"

#include "am_bsp.h"

// This implementation will light up the LEDs on the board in response to different commands.
void RespondToCommand(tflite::ErrorReporter* error_reporter,
                      int32_t current_time, const char* found_command,
                      uint8_t score, bool is_new_command) {
  static bool is_initialized = false;
  if (!is_initialized) {
    // Setup LEDs as outputs
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_RED, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_BLUE, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_GREEN, g_AM_HAL_GPIO_OUTPUT_12);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_LED_YELLOW, g_AM_HAL_GPIO_OUTPUT_12);
    // Ensure all pins are cleared
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_RED);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_GREEN);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_YELLOW);
    is_initialized = true;
  }
  static int count = 0;

   // Toggle the red LED every time an inference is performed.
   ++count;
   if (count & 1) {
     am_hal_gpio_output_set(AM_BSP_GPIO_LED_RED);
   } else {
     am_hal_gpio_output_clear(AM_BSP_GPIO_LED_RED);
   }

  if (is_new_command) {
    // Clear the last three LEDs
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_BLUE);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_GREEN);
    am_hal_gpio_output_clear(AM_BSP_GPIO_LED_YELLOW);
    error_reporter->Report("Heard %s (%d) @%dms", found_command, score,
                           current_time);
    // Only indicate a 'yes'
    if (found_command[0] == 'y') {
      // Always light the blue LED
      am_hal_gpio_output_set(AM_BSP_GPIO_LED_BLUE);
      // Light the other LEDs depending on score
      if (score >= 205) {
        am_hal_gpio_output_set(AM_BSP_GPIO_LED_GREEN);
      }
      if(score >= 210) {
        am_hal_gpio_output_set(AM_BSP_GPIO_LED_YELLOW);
      }
    }
  }
}

새 명령어가 감지되면 is_new_command가 true가 됩니다. 파란색, 녹색, 노란색 LED를 지운 다음 found_commandscore 값에 따라 다시 켭니다.

재빌드 및 플래시

코드 변경을 완료한 후 바이너리 빌드 및 준비의 모든 단계를 실행하여 테스트합니다.

10. 다음 단계

축하합니다. 마이크로컨트롤러에서 첫 번째 음성 감지기를 빌드했습니다.

TensorFlow Lite for Microcontrollers를 사용한 개발에 관한 간략한 소개가 도움이 되었기를 바랍니다. 마이크로컨트롤러에서의 딥 러닝은 새롭고 흥미로운 아이디어이며, 직접 실험해 보시기 바랍니다.

참조 문서

26699b18f2b199f.png

감사합니다. 즐거운 조립 되세요.