1. Giới thiệu
Sản phẩm bạn sẽ tạo ra
Trong lớp học lập trình này, chúng ta sẽ tìm hiểu cách sử dụng TensorFlow Lite cho vi điều khiển để chạy một mô hình học sâu trên Bảng phát triển SparkFun Edge. Chúng ta sẽ làm việc với mô hình phát hiện lời nói tích hợp của bảng mạch. Mô hình này sử dụng mạng nơ-ron tích chập để phát hiện các từ "có" và "không" được nói qua 2 micrô của bảng mạch.

Công nghệ học máy trên vi điều khiển
Bạn có thể sử dụng công nghệ học máy để tạo ra những công cụ thông minh giúp cuộc sống của người dùng trở nên dễ dàng hơn, chẳng hạn như Trợ lý Google. Nhưng thường thì những trải nghiệm này đòi hỏi nhiều hoạt động tính toán hoặc tài nguyên, chẳng hạn như một máy chủ đám mây mạnh mẽ hoặc máy tính để bàn. Tuy nhiên, giờ đây, bạn có thể chạy suy luận bằng công nghệ học máy trên phần cứng nhỏ, tiêu thụ ít điện năng, chẳng hạn như vi điều khiển.
Vi điều khiển rất phổ biến, rẻ tiền, tiêu thụ rất ít năng lượng và rất đáng tin cậy. Chúng có trong mọi loại thiết bị gia dụng: hãy nghĩ đến các thiết bị, ô tô và đồ chơi. Trên thực tế, mỗi năm có khoảng 30 tỷ thiết bị sử dụng vi điều khiển được sản xuất.

Bằng cách đưa công nghệ học máy vào các vi điều khiển nhỏ, chúng ta có thể tăng cường trí thông minh của hàng tỷ thiết bị mà chúng ta sử dụng trong cuộc sống mà không cần dựa vào phần cứng đắt tiền hoặc kết nối Internet đáng tin cậy. Hãy tưởng tượng những thiết bị gia dụng thông minh có thể thích ứng với quy trình hằng ngày của bạn, các cảm biến công nghiệp thông minh có thể phân biệt giữa vấn đề và hoạt động bình thường, cũng như những món đồ chơi kỳ diệu có thể giúp trẻ em học tập một cách thú vị và hấp dẫn.
TensorFlow Lite cho vi điều khiển (Phần mềm)

TensorFlow là nền tảng học máy nguồn mở của Google để huấn luyện và chạy các mô hình. TensorFlow Lite là một khung phần mềm, một phiên bản được tối ưu hoá của TensorFlow, nhắm đến việc chạy các mô hình TensorFlow trên các thiết bị nhỏ, tương đối có công suất thấp, chẳng hạn như điện thoại di động.
TensorFlow Lite For Microcontrollers là một khung phần mềm, một phiên bản được tối ưu hoá của TensorFlow, nhắm đến việc chạy các mô hình TensorFlow trên phần cứng nhỏ, công suất thấp, chẳng hạn như vi điều khiển. Nó tuân thủ các giới hạn bắt buộc trong những môi trường nhúng này, tức là có kích thước tệp nhị phân nhỏ, không yêu cầu hệ điều hành hỗ trợ, bất kỳ thư viện C hoặc C++ tiêu chuẩn nào hoặc việc phân bổ bộ nhớ động, v.v.
SparkFun Edge (Phần cứng)
SparkFun Edge là một nền tảng dựa trên vi điều khiển: một máy tính nhỏ trên một bảng mạch duy nhất. Thiết bị này có bộ xử lý, bộ nhớ và phần cứng I/O cho phép gửi và nhận tín hiệu kỹ thuật số đến các thiết bị khác. Thiết bị này có 4 đèn LED có thể điều khiển bằng phần mềm, với các màu sắc bạn yêu thích của Google.

Không giống như máy tính, vi điều khiển không chạy hệ điều hành. Thay vào đó, các chương trình bạn viết sẽ chạy trực tiếp trên phần cứng. Bạn viết mã trên máy tính và tải mã đó xuống vi điều khiển thông qua một thiết bị gọi là trình lập trình.
Vi điều khiển không phải là máy tính mạnh. Chúng có bộ xử lý nhỏ và không có nhiều bộ nhớ. Nhưng vì được thiết kế để đơn giản nhất có thể, nên vi điều khiển có thể sử dụng rất ít năng lượng. Tuỳ thuộc vào chức năng của chương trình, SparkFun Edge có thể chạy trong nhiều tuần chỉ với một pin cúc áo!
Kiến thức bạn sẽ học được
- Biên dịch chương trình mẫu cho SparkFun Edge trên máy tính
- Triển khai chương trình trên thiết bị của bạn
- Thay đổi chương trình rồi triển khai lại
Bạn cần có
Bạn sẽ cần những phần cứng sau:
- Máy tính chạy Linux hoặc MacOS
- Bảng SparkFun Edge
- Bộ lập trình SparkFun USB-C Serial Basic
- Cáp USB-C sang USB-A (Nếu đang dùng máy tính có cổng USB-C, hãy mua cáp USB-C sang USB-C)
- (không bắt buộc) Pin lithium dạng cúc 3V 20mm (CR2032) để chạy suy luận mà không cần trình lập trình và cáp
Bạn sẽ cần có phần mềm sau:
- Git (kiểm tra xem Git đã được cài đặt hay chưa bằng cách chạy
gittrên dòng lệnh) - Python 3 (kiểm tra xem đã cài đặt hay chưa bằng cách chạy
python3hoặcpython --versiontrên dòng lệnh) - Pip cho Python 3 ( câu trả lời hữu ích trên StackOverflow)
- Tạo 4.2.1 trở lên (kiểm tra xem đã cài đặt chưa bằng cách chạy
make --versiontrên dòng lệnh) - Trình điều khiển SparkFun Serial Basic
2. Thiết lập phần cứng
Vi điều khiển SparkFun Edge đi kèm với một tệp nhị phân được cài đặt sẵn có thể chạy mô hình lời nói. Trước khi ghi đè mô hình này bằng phiên bản của riêng mình, trước tiên, hãy chạy mô hình này.
Tăng sức mạnh cho bàn cờ bằng cách:
- Lắp pin cúc áo vào giắc cắm pin ở mặt sau của bảng (với mặt "+" của pin hướng lên trên. Nếu bo mạch của bạn có sẵn pin, hãy rút miếng nhựa ra và đẩy pin vào để đảm bảo pin được lắp hoàn chỉnh)

- Nếu không có pin cúc áo, bạn có thể dùng thiết bị lập trình cơ bản qua cổng nối tiếp USB-C của SparkFun để cấp nguồn cho bo mạch. Để gắn thiết bị này vào bảng, hãy thực hiện các bước sau:
- Tìm đầu cắm 6 chân ở bên cạnh SparkFun Edge.
- Cắm SparkFun USB-C Serial Basic vào các chân này, đảm bảo các chân có nhãn "BLK" và "GRN" trên mỗi thiết bị được căn chỉnh đúng cách.
- Kết nối cáp USB-C giữa SparkFun USB-C Serial Basic và máy tính.

Sau khi bạn bật nguồn cho bo mạch bằng cách lắp pin hoặc kết nối trình lập trình USB, bo mạch sẽ khởi động và bắt đầu nghe bằng micrô. Đèn màu xanh dương sẽ bắt đầu nhấp nháy.
Mô hình học máy trên bảng được huấn luyện để nhận dạng các từ "có" và "không", cũng như phát hiện sự hiện diện và vắng mặt của lời nói. Thiết bị này truyền đạt kết quả bằng cách bật đèn LED có màu. Bảng sau đây cho biết ý nghĩa của từng màu đèn LED:
Kết quả phát hiện | Màu đèn LED |
"Có" | Vàng |
"Không" | Đỏ |
Lời nói không xác định | Xanh lục |
Không phát hiện thấy giọng nói nào | Không có đèn LED nào sáng |
Dùng thử
Đưa bảng lên miệng và nói "có" vài lần. Bạn sẽ thấy đèn LED màu vàng nhấp nháy. Nếu không có gì xảy ra khi bạn nói "có", hãy thử một số cách sau:
- Giữ bảng cách miệng khoảng 25 cm
- Tránh tạp âm quá mức
- Lặp lại từ "có" nhiều lần liên tiếp (thử nói "có có có")
3. Thiết lập phần mềm
Giờ đây, chúng ta sẽ tự tải xuống, cài đặt và chạy mô hình lời nói trên vi điều khiển. Để làm việc này, trước tiên, chúng ta sẽ tải mã nguồn cho chương trình này và các phần phụ thuộc cần thiết để tạo chương trình. Chương trình này được viết bằng C++ và phải được biên dịch thành một tệp nhị phân trước khi được tải xuống bảng. Tệp nhị phân là tệp chứa chương trình ở dạng có thể chạy trực tiếp bằng phần cứng SparkFun Edge.
Hướng dẫn sau đây dành cho Linux hoặc MacOS.
Tải kho lưu trữ TensorFlow xuống
Bạn có thể tìm thấy mã này trong kho lưu trữ TensorFlow trên GitHub, tại vị trí sau:
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/micro
Mở một cửa sổ dòng lệnh trên máy tính, chuyển đến thư mục nơi bạn thường lưu trữ các dự án mã hoá, tải kho lưu trữ TensorFlow xuống rồi nhập thư mục đã tạo, như minh hoạ dưới đây:
cd ~ # change into your home (or any other) directory git clone --depth 1 https://github.com/tensorflow/tensorflow.git cd tensorflow
Tải các phần phụ thuộc Python xuống
Chúng ta sẽ sử dụng Python 3 để chuẩn bị tệp nhị phân và cài đặt ROM đó vào thiết bị. Các tập lệnh Python phụ thuộc vào một số thư viện nhất định. Chạy lệnh sau để cài đặt các phần phụ thuộc này:
pip3 install pycrypto pyserial --user
4. Tạo và chuẩn bị tệp nhị phân
Chúng ta sẽ tạo tệp nhị phân và chạy các lệnh để chuẩn bị tải tệp này xuống thiết bị.
Tạo tệp nhị phân
Để tải tất cả các phần phụ thuộc cần thiết xuống và tạo tệp nhị phân, hãy chạy lệnh sau:
make -f tensorflow/lite/micro/tools/make/Makefile TARGET=sparkfun_edge micro_speech_bin
Nếu bản dựng hoạt động thành công, dòng cuối cùng của đầu ra sẽ có dạng như sau:
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
Để xác nhận rằng tệp nhị phân đã được tạo thành công, hãy chạy lệnh sau:
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"
Bạn sẽ thấy Binary was successfully created được in ra bảng điều khiển! Nếu bạn thấy Binary is missing, thì đã xảy ra vấn đề với quy trình xây dựng và bạn cần gỡ lỗi.
Chuẩn bị tệp nhị phân
Tệp nhị phân phải được ký bằng khoá mã hoá để triển khai cho thiết bị. Bây giờ, chúng ta sẽ chạy một số lệnh để ký tệp nhị phân để có thể tải tệp này xuống SparkFun Edge.
Nhập lệnh sau để thiết lập một số khoá mật mã giả mà chúng ta có thể dùng cho mục đích phát triển:
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
Bây giờ, hãy chạy lệnh sau để tạo tệp nhị phân đã ký:
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
Thao tác này sẽ tạo tệp main_nonsecure_ota.bin. Giờ đây, chúng ta sẽ chạy một lệnh khác để tạo phiên bản cuối cùng của tệp. Phiên bản này có thể dùng để flash thiết bị bằng tập lệnh trình tải khởi động mà chúng ta sẽ dùng ở bước tiếp theo:
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
Bây giờ, bạn sẽ có một tệp có tên là main_nonsecure_wire.bin trong thư mục mà bạn đã chạy các lệnh. Đây là tệp mà chúng ta sẽ ghi vào thiết bị.
5. Chuẩn bị sẵn sàng nạp tệp nhị phân
Thao tác nhấp nháy là gì?
SparkFun Edge lưu trữ chương trình mà nó hiện đang chạy trong bộ nhớ flash 512 kilobyte. Nếu muốn bảng chạy một chương trình mới, chúng ta phải gửi chương trình đó đến bảng. Bảng sẽ lưu chương trình đó vào bộ nhớ flash, ghi đè mọi chương trình đã lưu trước đó.
Quá trình này được gọi là "flash" và chúng ta sẽ dùng nó để gửi chương trình đến bảng.
Gắn trình lập trình vào bảng
Để tải các chương trình mới xuống bảng mạch, chúng ta sẽ sử dụng trình lập trình nối tiếp cơ bản USB-C của SparkFun. Thiết bị này cho phép máy tính giao tiếp với vi điều khiển qua USB.
Để gắn thiết bị này vào bảng, hãy thực hiện các bước sau:
- Tìm đầu cắm 6 chân ở bên cạnh SparkFun Edge.
- Cắm SparkFun USB-C Serial Basic vào các chân này, đảm bảo các chân có nhãn "BLK" và "GRN" trên mỗi thiết bị được căn chỉnh đúng cách.

Gắn trình lập trình vào máy tính
Chúng ta sẽ kết nối bảng mạch với máy tính qua USB. Để lập trình cho bảng mạch, chúng ta cần biết tên mà máy tính đặt cho thiết bị. Cách tốt nhất để thực hiện việc này là liệt kê tất cả các thiết bị của máy tính trước và sau khi gắn thiết bị đó, rồi xem thiết bị nào là thiết bị mới.
Trước khi kết nối thiết bị qua USB, hãy chạy lệnh sau:
If you are using Linux: ls /dev/tty* If you are using MacOS: ls /dev/cu*
Lệnh này sẽ xuất ra danh sách các thiết bị được đính kèm, có dạng như sau:
/dev/cu.Bluetooth-Incoming-Port /dev/cu.MALS /dev/cu.SOC
Bây giờ, hãy kết nối trình lập trình với cổng USB trên máy tính. Nhập lại lệnh sau:
If you are using Linux: ls /dev/tty* If you are using MacOS: ls /dev/cu*
Bạn sẽ thấy một mục bổ sung trong đầu ra, như trong ví dụ bên dưới. Mặt hàng mới của bạn có thể có tên khác. Mục mới này là tên của thiết bị.
/dev/cu.Bluetooth-Incoming-Port /dev/cu.MALS /dev/cu.SOC /dev/cu.wchusbserial-1450
Trước tiên, chúng ta sẽ tạo một biến môi trường để xác định tên thiết bị:
export DEVICENAME=put your device name here
Tiếp theo, chúng ta sẽ tạo một biến môi trường để chỉ định tốc độ truyền dữ liệu (là tốc độ mà dữ liệu sẽ được gửi đến thiết bị):
export BAUD_RATE=921600
6. Cài đặt ROM tệp nhị phân
Chạy tập lệnh để cài đặt ROM cho bảng
Để cài đặt ROM cho bo mạch, chúng ta phải đưa bo mạch vào trạng thái "trình tải khởi động" đặc biệt để chuẩn bị nhận tệp nhị phân mới. Sau đó, chúng ta sẽ chạy một tập lệnh để gửi tệp nhị phân đến bảng.
Hãy làm quen với các nút sau trên bảng:

Thực hiện các bước sau để đặt lại và cài đặt ROM cho bảng:
- Đảm bảo bo mạch được kết nối với trình lập trình và toàn bộ thiết bị được kết nối với máy tính qua USB.
- Bắt đầu bằng cách giữ nút có đánh dấu
14trên bảng. Tiếp tục giữ cho đến Bước 6. - Vẫn giữ nút được đánh dấu
14, để đặt lại bảng về trạng thái trình tải khởi động, hãy nhấp vào nút được đánh dấuRSTđể đặt lại bảng. - Vẫn giữ nút được đánh dấu
14, hãy dán lệnh sau vào thiết bị đầu cuối rồi nhấn phím Enter để kích hoạt lệnh đó (Để thuận tiện, bạn có thể dán lệnh này vào thiết bị đầu cuối trước khi bắt đầu giữ nút, nhưng đừng nhấn phím Enter cho đến khi bạn thực hiện bước này)
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
- Vẫn giữ nút có đánh dấu
14, giờ đây bạn sẽ thấy nội dung tương tự như sau xuất hiện trên màn hình:
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...]
- Dừng giữ nút đánh dấu
14trên bảng sau khi thấySending Data Packet of length 8180(bạn vẫn có thể giữ nút này). Chương trình sẽ tiếp tục in các dòng trên thiết bị đầu cuối. Cuối cùng, mã sẽ có dạng như sau:
[...lots more Sending Data Packet of length 8180...] Sending Data Packet of length 8180 Sending Data Packet of length 6440 Sending Reset Command. Done.
Nếu bạn thấy Done, thì điều này cho biết quá trình nhấp nháy đã thành công. Nếu đầu ra của chương trình kết thúc bằng lỗi, hãy kiểm tra xem Sending Reset Command có được in hay không. Nếu vậy, có thể quá trình nhấp nháy đã thành công mặc dù có lỗi.
Trên máy Linux, bạn có thể gặp phải NoResponse Error. Điều này là do trình điều khiển nối tiếp ch34x đã được cài đặt cùng với trình điều khiển nối tiếp hiện có. Bạn có thể giải quyết vấn đề này như sau:
Bước 1: Cài đặt lại phiên bản chính xác của thư viện ch34x. Đảm bảo rằng thiết bị đã rút phích cắm khỏi máy tính trong quá trình cài đặt.
git clone https://github.com/juliagoda/CH341SER.git cd CH341SER/ make sudo insmod ch34x.ko sudo rmmod ch341
Bước 2: Cắm USB của bảng và chạy:
dmesg | grep "ch34x"
Bạn sẽ thấy một thông báo như sau:
[ 1299.444724] ch34x_attach+0x1af/0x280 [ch34x] [ 1299.445386] usb 2-13.1: ch34x converter now attached to ttyUSB0
Nếu trình điều khiển được dùng không phải là "ch34x" (ví dụ: ch341), hãy thử tắt trình điều khiển khác bằng cách chạy:
rmmod <non-ch34x driver name>
Rút rồi cắm lại thiết bị và đảm bảo rằng trình điều khiển đang dùng là "ch34x".
7. Bản minh hoạ
Dùng thử chương trình
Sau khi bạn nạp thành công chương trình vào bảng mạch, hãy nhấn vào nút được đánh dấu
Nhấn RST để khởi động lại bảng và bắt đầu chương trình. Nếu đèn LED màu xanh dương bắt đầu nhấp nháy, thì quá trình cài đặt đã thành công. Nếu không, hãy di chuyển xuống phần "Nếu cách này không hiệu quả thì sao?" bên dưới.

Mô hình học máy trên bảng được huấn luyện để nhận dạng các từ "có" và "không", cũng như phát hiện sự hiện diện và vắng mặt của lời nói. Thiết bị này truyền đạt kết quả bằng cách bật đèn LED có màu. Bảng sau đây cho biết ý nghĩa của từng màu đèn LED:
Kết quả phát hiện | Màu đèn LED |
"Có" | Vàng |
"Không" | Đỏ |
Lời nói không xác định | Xanh lục |
Không phát hiện thấy giọng nói nào | Không có đèn LED nào sáng |
Dùng thử
Đưa bảng lên miệng và nói "có" vài lần. Bạn sẽ thấy đèn LED màu vàng nhấp nháy. Nếu không có gì xảy ra khi bạn nói "có", hãy thử một số cách sau:
- Giữ bảng cách miệng khoảng 25 cm
- Tránh tạp âm quá mức
- Lặp lại từ "có" nhiều lần liên tiếp (thử nói "có có có")
Điều gì sẽ xảy ra nếu cách này không hiệu quả?
Sau đây là một số vấn đề có thể xảy ra và cách gỡ lỗi:
Vấn đề: Sau khi nhấp nháy, không có đèn LED nào sáng.
Giải pháp: Thử nhấn nút RST hoặc ngắt kết nối rồi kết nối lại bo mạch với trình lập trình. Nếu không có cách nào trong số này hiệu quả, hãy thử nạp lại chương trình cho bảng.
Vấn đề: Đèn LED màu xanh dương sáng lên nhưng rất mờ.
Giải pháp: Thay pin vì pin sắp hết. Ngoài ra, bạn có thể cấp nguồn cho bo mạch bằng máy tính thông qua trình lập trình và cáp.
8. Đọc kết quả gỡ lỗi (không bắt buộc)
Xem lại phần này nếu bạn gặp vấn đề và cần gỡ lỗi mã một cách chi tiết. Để hiểu điều gì đang xảy ra trong một vi điều khiển khi mã của bạn chạy, bạn có thể in thông tin gỡ lỗi thông qua kết nối nối tiếp của bo mạch. Bạn dùng máy tính để kết nối với bảng và hiển thị dữ liệu mà bảng đang gửi.
Mở một kết nối nối tiếp
Theo mặc định, mã mẫu SparkFun Edge của chúng tôi sẽ ghi lại mọi lệnh thoại cùng với độ tin cậy của lệnh. Để xem đầu ra của bảng, bạn có thể chạy lệnh sau:
screen ${DEVICENAME} 115200
Ban đầu, bạn có thể thấy một đầu ra có dạng như sau: (Đầu ra này chỉ xuất hiện nếu bảng được đặt lại sau khi kết nối, nếu không, bạn có thể bắt đầu thấy thông tin gỡ lỗi)
Apollo3 Burst Mode is Available
Apollo3 operating in Burst Mode (96MHz)
Hãy thử đưa ra một số lệnh bằng cách nói "có" hoặc "không". Bạn sẽ thấy thông tin gỡ lỗi in bảng cho từng lệnh:
Heard yes (202) @65536ms
Trong nhật ký ở trên, yes đề cập đến lệnh. Số 202 cho biết mức độ tin cậy rằng lệnh đã được nghe (200 là mức tối thiểu). Cuối cùng, 65536ms đề cập đến khoảng thời gian đã trôi qua kể từ lần đặt lại gần đây nhất của vi điều khiển.
Để ngừng xem đầu ra gỡ lỗi, hãy nhấn Ctrl+A, ngay sau đó nhấn phím K, rồi nhấn phím Y.
Viết nhật ký gỡ lỗi
Bạn có thể thấy mã ghi lại thông tin này trong tệp command_responder.cc mà bạn vừa làm việc:
tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc
Để ghi dữ liệu, bạn có thể gọi phương thức error_reporter->Report(). Nó hỗ trợ các mã thông báo printf tiêu chuẩn để nội suy chuỗi. Bạn có thể dùng các mã thông báo này để đưa thông tin quan trọng vào nhật ký:
error_reporter->Report("Heard %s (%d) @%dms", found_command, score, current_time);
Phương thức này sẽ hữu ích khi bạn tự thực hiện các thay đổi đối với mã trong phần tiếp theo.
9. Mở rộng mã (không bắt buộc)
Giờ đây, bạn đã biết cách tạo và cài đặt ROM cho SparkFun Edge, bạn có thể bắt đầu thử nghiệm với mã và triển khai mã đó cho thiết bị để xem kết quả.
Đọc mã
Một nơi phù hợp để bắt đầu đọc mã là tệp sau đây: command_responder.cc.
tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc
Bạn có thể xem tệp này trên GitHub tại đây.
Phương thức trong tệp này, RespondToCommand, được gọi khi phát hiện thấy một lệnh thoại. Đoạn mã hiện có sẽ bật một đèn LED khác tuỳ thuộc vào việc bạn nghe thấy lệnh "có", "không" hay một lệnh không xác định. Đoạn mã sau đây minh hoạ cách hoạt động của việc này:
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);
}
Đối số found_command chứa tên của lệnh đã được phát hiện. Bằng cách kiểm tra ký tự đầu tiên, tập hợp các câu lệnh if này sẽ xác định đèn LED nào cần bật.
Phương thức RespondToCommand được gọi bằng một số đối số:
void RespondToCommand(tflite::ErrorReporter* error_reporter,
int32_t current_time, const char* found_command,
uint8_t score, bool is_new_command) {
error_reporterđược dùng để ghi thông tin gỡ lỗi (sẽ nói thêm về vấn đề này sau).current_timebiểu thị thời gian phát hiện thấy lệnh.found_commandcho biết câu lệnh nào đã được phát hiện.scorecho biết mức độ tin cậy khi chúng tôi phát hiện một lệnh.is_new_commandcho chúng ta biết đây có phải là lần đầu tiên nghe thấy lệnh này hay không.
score là một số nguyên từ 0 đến 255, biểu thị xác suất phát hiện được một lệnh. Mã mẫu chỉ coi một lệnh là hợp lệ nếu điểm số lớn hơn 200. Dựa trên kết quả kiểm thử của chúng tôi, hầu hết các lệnh hợp lệ đều nằm trong khoảng từ 200 đến 210.
Sửa đổi mã
Bảng SparkFun Edge có 4 đèn LED. Hiện tại, chúng tôi đang nhấp nháy đèn LED màu xanh dương để cho biết quá trình nhận dạng đang diễn ra. Bạn có thể thấy thông tin này trong tệp 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);
}
Vì chúng ta có một nhóm gồm 4 đèn LED, hãy sửa đổi chương trình để sử dụng các đèn này làm chỉ báo trực quan về score của một lệnh nhất định. Điểm thấp sẽ chỉ có một đèn LED sáng, còn điểm cao sẽ có nhiều đèn sáng.
Để đảm bảo chúng ta có thể biết chương trình đang chạy, chúng ta sẽ làm cho đèn LED màu đỏ nhấp nháy liên tục thay vì màu xanh dương. Các đèn LED màu xanh dương, xanh lục và vàng ở bên cạnh sẽ được dùng để cho biết cường độ của score gần đây nhất. Để đơn giản, chúng ta sẽ chỉ bật các đèn LED đó nếu từ "có" được nói ra. Nếu phát hiện thấy một từ khác, đèn LED sẽ tắt.
Để thực hiện thay đổi này, hãy thay thế toàn bộ mã trong tệp command_responder.cc bằng đoạn mã sau:
#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);
}
}
}
}
Nếu phát hiện thấy một lệnh mới, is_new_command sẽ là true. Chúng ta sẽ xoá các đèn LED màu xanh dương, xanh lục và vàng, sau đó bật lại các đèn này tuỳ thuộc vào giá trị của found_command và score.
Tạo lại và flash
Sau khi thay đổi mã, hãy kiểm thử bằng cách chạy tất cả các bước trong phần Tạo và chuẩn bị tệp nhị phân.
10. Các bước tiếp theo
Xin chúc mừng! Bạn đã tạo thành công trình phát hiện lời nói đầu tiên trên một vi điều khiển!
Chúng tôi hy vọng bạn đã thích phần giới thiệu ngắn gọn này về việc phát triển bằng TensorFlow Lite cho Vi điều khiển. Ý tưởng về học sâu trên vi điều khiển là một ý tưởng mới mẻ và thú vị. Chúng tôi khuyến khích bạn thử nghiệm ý tưởng này!
Tài liệu tham khảo
- Huấn luyện mô hình của riêng bạn để hiểu các lệnh khác nhau, vì giờ đây bạn đã có kinh nghiệm làm việc với chương trình cơ bản. Lưu ý: Khoá đào tạo sẽ kéo dài vài giờ!
- Tìm hiểu thêm về TensorFlow Lite cho Vi điều khiển ( Trang web, GitHub).
- Hãy thử các ví dụ khác và chạy chúng trên SparkFun Edge (nếu được hỗ trợ).
- Tham khảo cuốn sách TinyML: Machine Learning with TensorFlow on Arduino and Ultra-Low Power Micro-Controllers (TinyML: Học máy bằng TensorFlow trên Arduino và bộ vi điều khiển có công suất cực thấp) của O'Reilly. Cuốn sách này giới thiệu về học máy trên các thiết bị nhỏ và hướng dẫn một số dự án thú vị. Lớp học lập trình này dựa trên Chương 7 và 8 của cuốn sách.

Cảm ơn bạn và chúc bạn có những giây phút xây dựng vui vẻ!