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ô hình học sâu trên Bảng phát triển SparkFun Edge. Chúng tôi sẽ làm việc với mô hình phát hiện lời nói tích hợp sẵn của bo 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à "no" được nói qua hai micrô trên bảng mạch.
Công nghệ học máy trên vi điều khiển
Công nghệ học máy có thể được dùng để tạo ra các công cụ thông minh giúp người dùng sống dễ dàng hơn, chẳng hạn như Trợ lý Google. Tuy nhiên, những trải nghiệm này thường đòi hỏi nhiều hoạt động tính toán hoặc tài nguyên, trong đó có thể bao gồm một máy chủ đám mây mạnh mẽ hoặc một máy tính để bàn. Tuy nhiên, hiện có thể chạy dự đoán học máy trên phần cứng nhỏ, tiết kiệm năng lượng, chẳng hạn như vi điều khiển.
Bộ vi điều khiển cực kỳ thông dụng, rẻ tiền, tiêu tốn rất ít năng lượng và rất đáng tin cậy. Chúng là một phần của tất cả các loại thiết bị gia dụng, chẳng hạn như thiết bị gia dụng, ô tô và đồ chơi. Trên thực tế, mỗi năm có khoảng 30 tỷ thiết bị chạy 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 bộ vi điều khiển nhỏ bé, chúng ta có thể nâng cao trí tuệ 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 hay kết nối Internet đáng tin cậy. Hãy tưởng tượng những thiết bị thông minh có thể thích ứng với thói quen hằng ngày của bạn, các cảm biến công nghiệp thông minh có khả năng hiểu được sự khác biệt giữa vấn đề và hoạt động bình thường, cùng những đồ chơi kỳ diệu có thể giúp trẻ học tập theo những cách thú vị và vui vẻ.
TensorFlow Lite cho vi điều khiển (Phần mềm)
TensorFlow là bộ khung máy học 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, là một phiên bản được tối ưu hoá của TensorFlow, nhằm chạy các mô hình tensorflow trên các thiết bị nhỏ và tương đối tiết kiệm năng lượng như điện thoại di động.
TensorFlow Lite cho vi điều khiển là một khung phần mềm, một phiên bản được tối ưu hoá của TensorFlow, được nhắm mục tiêu để chạy các mô hình tensorflow trên phần cứng nhỏ, tiết kiệm năng lượng như vi điều khiển. Thư viện tuân thủ những điều kiện ràng buộc bắt buộc trong các môi trường nhúng này, tức là có kích thước nhị phân nhỏ, không cần hỗ trợ hệ điều hành hay bất kỳ thư viện C hoặc C++ tiêu chuẩn nào hay quy trình 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 bộ vi điều khiển: một chiếc máy tính nhỏ bé 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 thiết bị gửi và nhận tín hiệu kỹ thuật số đến các thiết bị khác. Chiếc máy tính bảng này có 4 đèn LED điều khiển bằng phần mềm, với những màu sắc mà bạn ưa thích theo Google.
Không giống như máy tính, bộ 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 bộ vi điều khiển thông qua một thiết bị gọi là lập trình viên.
Bộ vi điều khiển không phải là máy tính mạnh. Các thiết bị này có bộ xử lý nhỏ và không có nhiều bộ nhớ. Nhưng do chúng được thiết kế đơn giản nhất có thể nên bộ vi điều khiển có thể sử dụng rất ít năng lượng. Tuỳ vào chức năng của chương trình, SparkFun Edge có thể hoạt động trong nhiều tuần chỉ với một pin đồng xu!
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ị
- Thay đổi rồi triển khai lại chương trình
Bạn cần có
Bạn sẽ cần có phần cứng sau:
- Máy tính Linux hoặc MacOS
- Bảng SparkFun Edge
- Lập trình viên SparkFun USB-C Serial Basic
- Cáp USB-C sang USB-A (Nếu bạn dùng máy tính USB-C, hãy chuyển sang dùng cáp USB-C sang USB-C)
- (không bắt buộc) pin lithium tế bào đồng xu 3V 20 mm (CR2032) để chạy dự đoán mà không cần lập trình viên và cáp
Bạn sẽ cần có phần mềm sau:
- Git (kiểm tra xem ứng dụng đã được cài đặt hay chưa bằng cách chạy
git
trên dòng lệnh) - Python 3 (kiểm tra xem ứng dụng đã được cài đặt hay chưa bằng cách chạy
python3
hoặcpython --version
trên dòng lệnh) - Pip cho Python 3 ( câu trả lời StackOverflow hữu ích)
- Tạo phiên bản 4.2.1 trở lên (kiểm tra xem ứng dụng đã được cài đặt chưa bằng cách chạy
make --version
trên dòng lệnh) - Trình điều khiển cơ bản của SparkFun Serial Basic
2. Thiết lập phần cứng
Bộ 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ẫu lời nói. Trước khi chúng ta ghi đè phiên bản 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 cường sức mạnh cho bàn phím của bạn bằng cách:
- Lắp một pin hình đồng xu vào đầu nối 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 lắp pin sẵn, hãy lấy miếng giấy ra khỏi nhựa và đẩy pin ra để đảm bảo đã lắp pin vào hoàn chỉnh)
- Nếu không có pin đồng xu, bạn có thể sử dụng thiết bị của lập trình viên SparkFun USB-C Serial Basic để cấp nguồn cho bo mạch. Để gắn thiết bị này vào bo mạch của bạn, hãy thực hiện các bước sau:
- Tìm tiêu đề có 6 ghim ở cạnh của SparkFun Edge.
- Cắm SparkFun USB-C Serial Basic vào các chân này, đảm bảo rằng các chân có nhãn "BLK" và "GRN" trên mỗi thiết bị được sắp xếp chính xác.
- Kết nối cáp USB-C giữa SparkFun USB-C Serial Basic với máy tính.
Sau khi bạn cấp 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ẽ bật lên 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 này được huấn luyện để nhận dạng các từ "có" và "no" cũng như để phát hiện sự có mặt và không có tiếng nói. Thiết bị này truyền đạt kết quả bằng cách chiếu sáng đèn LED có màu. Bảng sau đây trình bày ý 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 flash LED màu vàng. Nếu không có gì xảy ra khi bạn nói "có", thì bạn có thể thử một số cách sau:
- Giữ bảng khoảng 10 inch từ miệng bạn
- Tránh tạp âm quá mức
- Lặp lại "có" vài lần liên tiếp (hãy thử nói "có, có")
3. Thiết lập phần mềm
Bây giờ, chúng ta sẽ tự tải xuống, cài đặt và chạy mẫu lời nói trên bộ vi điều khiển. Để làm được điều này, trước tiên, chúng ta sẽ tải mã nguồn xuống cho chương trình này cùng các phần phụ thuộc cần thiết để tạo nó. Chương trình được viết bằng C++, phải được biên dịch thành tệp nhị phân trước khi được tải xuống bảng. Tệp nhị phân là một 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.
Các hướng dẫn sau đây được viết cho Linux hoặc MacOS.
Tải kho lưu trữ TensorFlow xuống
Mã này có trong kho lưu trữ TensorFlow trên GitHub, ở 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, thay đổi sang thư mục bạn thường lưu trữ các dự án lập trình, 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 tôi sẽ sử dụng Python 3 để chuẩn bị tệp nhị phân và cài đặt ROM tệp đó vào thiết bị. Các tập lệnh Python phụ thuộc vào một số thư viện được cung cấp. 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ệp đó để tải xuống thiết bị.
Tạo tệp nhị phân
Để tải tất cả các phần phụ thuộc bắt buộc 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 kết quả sẽ hiện 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
, tức là đã xảy ra vấn đề trong quy trình xây dựng và cần được gỡ lỗi.
Chuẩn bị tệp nhị phân
Tệp nhị phân phải được ký bằng các khoá mã hoá để triển khai trên thiết bị. Bây giờ, chúng ta sẽ chạy một số lệnh. Lệnh này sẽ ký tệp nhị phân của chúng ta để bạn có thể tải tệp đó xuống SparkFun Edge.
Nhập lệnh sau để thiết lập một số khoá mã hoá giả mà chúng ta có thể dùng cho việc 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 một 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
. Bây giờ, 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 có thể dùng để cài đặt ROM thiết bị bằng tập lệnh trình tải khởi động mà chúng ta sẽ sử dụng trong 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 chúng ta sẽ cài đặt ROM vào thiết bị.
5. Hãy chuẩn bị cài đặt ROM tệp nhị phân
Cài đặt ROM là gì?
SparkFun Edge lưu trữ chương trình 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 nó đến bảng. Bộ nhớ này sẽ lưu trữ nó trong bộ nhớ flash, ghi đè lên bất kỳ chương trình nào đã được lưu trước đó.
Quá trình này được gọi là "nhấp nháy" và chúng ta sẽ sử dụng quá trình này để gửi chương trình lên bảng.
Đính kèm lập trình viên vào bảng
Để tải các chương trình mới xuống bảng, chúng ta sẽ sử dụng trình lập trình nối tiếp SparkFun USB-C Serial Basic. Thiết bị này cho phép máy tính của bạn giao tiếp với bộ vi điều khiển qua USB.
Để gắn thiết bị này vào bo mạch của bạn, hãy thực hiện các bước sau:
- Tìm tiêu đề có 6 ghim ở cạnh của SparkFun Edge.
- Cắm SparkFun USB-C Serial Basic vào các chân này, đảm bảo rằng các chân có nhãn "BLK" và "GRN" trên mỗi thiết bị được sắp xếp chính xác.
Đính kèm lập trình viên vào máy tính của bạn
Chúng tôi sẽ kết nối bo mạch với máy tính của bạn qua USB. Để lập trình bảng, chúng tôi cần biết tên mà máy tính đặt cho thiết bị. Cách tốt nhất để làm việc này là liệt kê tất cả thiết bị của máy tính trước và sau khi gắn thiết bị, đồng thời xem xem thiết bị nào mới.
Trước khi gắn 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*
Thao tác này sẽ xuất ra danh sách các thiết bị đí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 lập trình viên với cổng USB của 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 kết quả, như trong ví dụ dưới đây. 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 độ baud. Đây là tốc độ gửi dữ liệu đến thiết bị:
export BAUD_RATE=921600
6. Cài đặt ROM tệp nhị phân
Chạy tập lệnh để truyền nhanh bảng của bạn
Để cài đặt ROM bảng, chúng ta phải đặt nó vào một "trình tải khởi động" đặc biệt trạng thái 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 lê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 bảng:
- Đảm bảo bo mạch được kết nối với lập trình viên và toàn bộ quá trình thiết lập được kết nối với máy tính của bạn qua USB.
- Bắt đầu giữ nút được đánh dấu
14
trên bảng. Tiếp tục giữ nút này cho đến Bước 6. - Vẫn giữ nút được đánh dấu là
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
, dán lệnh sau vào thiết bị đầu cuối của bạn và nhấn Enter để chạy 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 không nhấn Enter cho đến khi bạn đế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 là
14
, giờ đây bạn sẽ thấy nội dung 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 được đánh dấu
14
trên bảng sau khi thấySending Data Packet of length 8180
(nhưng bạn có thể tiếp tục 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 có nghĩa là đã cài đặt ROM thành công. Nếu kết quả của chương trình kết thúc kèm theo lỗi, hãy kiểm tra xem Sending Reset Command
có được in hay không. Nếu có, việc cài đặt ROM có thể đã thành công dù có lỗi.
Trên máy Linux, bạn có thể gặp 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 đúng phiên bản thư viện ch34x. Đảm bảo rút phích cắm thiết bị 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ó bo mạch rồi 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 sử dụng không phải là "ch34x" (ví dụ: ch341), hãy thử vô hiệu hoá 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 được sử dụng là "ch34x".
7. Bản minh hoạ
Dùng thử chương trình
Sau khi nháy bảng của bạn thành công, hãy nhấn vào nút được đánh dấu
RST
để khởi động lại bảng và khởi động chương trình. Nếu đèn LED màu xanh dương bắt đầu nhấp nháy thì có nghĩa là đèn LED nhấp nháy thành công. Nếu không, hãy cuộn xuống phần "Nếu tính năng này không hoạt động thì sao?" ở bên dưới.
Mô hình học máy trên bảng này được huấn luyện để nhận dạng các từ "có" và "no" cũng như để phát hiện sự có mặt và không có tiếng nói. Thiết bị này truyền đạt kết quả bằng cách chiếu sáng đèn LED có màu. Bảng sau đây trình bày ý 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 flash LED màu vàng. Nếu không có gì xảy ra khi bạn nói "có", thì bạn có thể thử một số cách sau:
- Giữ bảng khoảng 10 inch từ miệng bạn
- Tránh tạp âm quá mức
- Lặp lại "có" vài lần liên tiếp (hãy thử nói "có, có")
Nếu tính năng này không hiệu quả thì sao?
Dưới đây là một số vấn đề có thể xảy ra và cách khắc phục:
Vấn đề: Sau khi nhấp nháy, không có đèn LED nào bật sáng.
Giải pháp: Thử nhấn vào nút RST
hoặc ngắt kết nối rồi kết nối lại bảng khỏi lập trình viên. Nếu những cách trên không hiệu quả, hãy thử nhấp nháy lại bảng.
Vấn đề: Đèn LED màu xanh dương đang sáng nhưng tối rất mờ.
Giải pháp: Thay pin khi pin sắp hết. Hoặc bo mạch có thể được máy tính cung cấp năng lượng nhờ lập trình viên và cáp.
8. Đọc kết quả gỡ lỗi (không bắt buộc)
Hãy 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 được điều gì đang xảy ra trong bộ vi điều khiển khi mã của bạn chạy, bạn có thể in thông tin gỡ lỗi qua kết nối nối tiếp của bảng. Bạn sử dụng máy tính của mình để kết nối với bảng và hiển thị dữ liệu mà bảng đang gửi.
Mở 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 những lệnh đó. Để xem kết quả của bảng, bạn có thể chạy lệnh sau:
screen ${DEVICENAME} 115200
Ban đầu, bạn có thể thấy kết quả như sau: (Chỉ xuất hiện nếu bảng được đặt lại sau khi kết nối, nếu không thì 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 vài lệnh bằng cách nói "có" hoặc "no". Bạn sẽ thấy thông tin gỡ lỗi in bảng cho mỗi lệnh:
Heard yes (202) @65536ms
Trong nhật ký trên, yes
tham chiếu đến lệnh. Số 202
cho biết mức độ tin cậy mà lệnh đã nghe thấy (với 200 là mức tối thiểu). Cuối cùng, 65536ms
là khoảng thời gian đã trôi qua kể từ lần đặt lại gần đây nhất cho bộ vi điều khiển.
Để dừng xem kết quả gỡ lỗi, hãy nhấn Ctrl+A
, ngay trước phím K
, sau đó nhấn phím Y
.
Ghi nhật ký gỡ lỗi
Bạn có thể xem 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 nhật ký dữ liệu, bạn có thể gọi phương thức error_reporter->Report()
. Lớp này hỗ trợ các mã thông báo printf
chuẩn cho nội suy chuỗi mà bạn có thể dùng để đưa thông tin quan trọng vào nhật ký của mình:
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 thực hiện các thay đổi của riêng mình đối với mã trong phần tiếp theo.
9. Mở rộng mã (không bắt buộc)
Giờ đây, khi đã biết cách tạo và cài đặt ROM SparkFun Edge, bạn có thể bắt đầu chơi bằng mã và triển khai mã đó cho thiết bị của mình để xem kết quả.
Đọc mã
Tệp sau đây command_responder.cc.
là nơi phù hợp để bắt đầu đọc mã
tensorflow/lite/micro/examples/micro_speech/sparkfun_edge/command_responder.cc
Bạn có thể xem tệp trên GitHub tại đây.
Phương thức RespondToCommand
trong tệp này sẽ được gọi khi phát hiện có lệnh thoại. Mã hiện tại sẽ bật một đèn LED khác nhau, tuỳ thuộc vào việc người dùng nghe thấy "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 tính năng 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 đã phát hiện. Bằng cách kiểm tra ký tự đầu tiên, tập hợp câu lệnh if
này sẽ xác định đèn LED nào sẽ sáng.
Phương thức RespondToCommand được gọi với 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
dùng để ghi nhật ký thông tin gỡ lỗi (bạn sẽ tìm hiểu thêm ở phần sau).current_time
thể hiện thời gian phát hiện lệnh.found_command
cho chúng tôi biết lệnh nào đã được phát hiện.score
cho chúng tôi biết mức độ tự tin của mình khi phát hiện thấy một lệnh.is_new_command
cho chúng tôi biết liệu đây có phải là lần đầu tiên nghe lệnh này hay không.
score
là một số nguyên từ 0 đến 255 thể hiện 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 thử nghiệm của chúng tôi, hầu hết các lệnh hợp lệ đều nằm trong khoảng 200-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 lam để cho biết tính năng nhận dạng đang diễn ra. Bạn có thể xem nội dung 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 ngân hàng gồm 4 đèn LED, hãy sửa đổi chương trình để sử dụng chúng làm chỉ báo trực quan cho score
của một lệnh nhất định. Điểm thấp sẽ xứng đáng với một đèn LED sáng, và điểm cao sẽ dẫn đến nhiều đèn.
Để đảm bảo có cách nhận biết chương trình đang chạy, chúng tôi sẽ liên tục nhấp nháy đèn LED màu đỏ thay vì màu xanh dương. Các đèn LED màu xanh dương, xanh lục và vàng liền kề sẽ được dùng để cho biết độ mạnh của score
gần đây nhất. Để đơn giản, chúng tôi sẽ chỉ bật những đèn LED đó nếu từ "có" sẽ được đọc. Nếu phát hiện thấy một từ khác, đèn LED sẽ sáng.
Để thực hiện thay đổi này, hãy thay thế tất cả 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ẽ có giá trị là true. Chúng ta sẽ làm rõ các đèn LED màu xanh dương, xanh lục và vàng, sau đó bật lại các đèn LED tuỳ thuộc vào giá trị của found_command
và score
.
Tạo lại và cài đặt ROM
Sau khi bạn thay đổi mã, hãy kiểm thử mã 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 bộ 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ề quá trình phát triển bằng TensorFlow Lite dành cho Vi điều khiển. Ý tưởng học sâu về vi điều khiển là một phương pháp mới và thú vị. Chúng tôi khuyến khích bạn tham gia và thử nghiệm!
Tài liệu tham khảo
- Đào tạo mô hình của riêng bạn để hiểu các lệnh khác nhau, giờ đây bạn đã có kinh nghiệm làm việc với chương trình cơ bản. Lưu ý: Quá trình đào tạo sẽ mất 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 rồi thử chạy trên SparkFun Edge nếu được hỗ trợ.
- Hãy tham khảo cuốn sách của O'Reilly TinyML: Machine Learning with TensorFlow trên Arduino và Bộ điều khiển vi mô công suất cực thấp của O'Reilly. Cuốn sách này giới thiệu công nghệ học máy trên các thiết bị nhỏ bé và hướng dẫn thực hiệ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à Chương 8 của sách.
Cảm ơn và chúc bạn xây dựng vui vẻ!