Detectar Tosse com TinyML no Arduino Nano para Detecção Precoce de Gripe
Componentes e Materiais
| Arduino Nano 33 BLE Sense | × | 1 |
Aplicativos e Serviços Online
| Edge Impulse Studio |
Sobre o Projeto
Existe uma enorme necessidade de soluções baratas e facilmente implantáveis para detecção precoce de COVID-19 e outras gripes. Junto com a ONU, Hackster, Edge Impulse e muitos outros, lançamos recentemente o Desafio UN Covid Detect & Protect, visando criar soluções facilmente implantáveis para prevenção e detecção de gripe em países em desenvolvimento. Neste tutorial, mostramos como usar machine learning Edge Impulse em um Arduino Nano BLE Sense para detectar a presença de tosse em áudio em tempo real. Construímos um dataset de amostras de tosse e ruído de fundo, e aplicamos um modelo TinyML altamente otimizado, para construir um sistema de detecção de tosse que roda em tempo real em menos de 20 kB de RAM no Nano BLE Sense. Esta mesma abordagem se aplica a muitas outras aplicações de correspondência de padrões de áudio embarcado, como cuidado de idosos, segurança e monitoramento de máquinas. Este projeto e dataset foram originalmente iniciados por Kartik Thakore para ajudar no esforço contra COVID-19.
Primeiros Passos
Este tutorial tem os seguintes requisitos:
- Entendimento básico de desenvolvimento de software e Arduino
- Arduino IDE ou CLI instalado
- Telefone móvel Android ou iOS
- Arduino Nano BLE Sense ou placa equivalente Cortex-M4+ com microfone (opcional)
Usaremos o Edge Impulse, uma plataforma online de desenvolvimento para machine learning em dispositivos edge. Crie uma conta gratuita aqui. Faça login, e dê um nome ao seu novo projeto clicando no título. Chamamos o nosso de "Arduino Cough Tutorial".
Coletando o Dataset
O primeiro passo em qualquer projeto de machine learning é coletar um dataset que represente amostras conhecidas de dados que gostaríamos de corresponder em nosso dispositivo Arduino. Para começar, criamos um pequeno dataset com 10 minutos de áudio em duas classes: "tosse" e "ruído". Mostraremos como importar este dataset para seu projeto Edge Impulse, adicionar suas próprias amostras ou até iniciar seu próprio dataset do zero. Este dataset é pequeno e tem um número limitado de amostras de tosse e ruído de fundo suave. Portanto, o dataset é apropriado apenas para experimentação, e o modelo produzido neste tutorial consegue diferenciar apenas entre ruído de fundo silencioso e uma pequena gama de tosses. Encorajamos você a estender o dataset com uma gama mais ampla de tosses, ruídos de fundo e outras classes como fala humana para melhorar o desempenho.
Nota: Forçar-se a tossir é muito desgastante para as cordas vocais, tenha cuidado ao coletar dados e testar!
Primeiro, baixe nosso dataset de tosse e extraia o arquivo no seu PC no local de sua escolha: https://cdn.edgeimpulse.com/datasets/cough.zip
Você pode importar este dataset para seu projeto Edge Impulse usando o Edge Impulse CLI Uploader. Instale o Edge Impulse CLI seguindo estas instruções de instalação.
Abra um terminal ou prompt de comando, e navegue até a pasta onde extraiu o arquivo.
Execute:
$ edge-impulse-uploader --clean
$ edge-impulse-uploader --category training training/*
$ edge-impulse-uploader --category testing testing/*
Você será solicitado para seu usuário, senha e projeto Edge Impulse onde deseja adicionar o dataset. As amostras do dataset agora estarão visíveis na página Data acquisition. Clicando em uma amostra, podemos ver como ela se parece e ouvir o áudio clicando no botão play abaixo de cada gráfico.
10 minutos de dados de tosse e ruído são suficientes para começar. Você pode opcionalmente estender o dataset com suas próprias amostras de tosse e ruído de fundo. Podemos coletar novas amostras de dados diretamente de dispositivos na página Data acquisition. Amostras de áudio em formato WAV também podem ser carregadas usando o Edge Impulse CLI Uploader.
A maneira mais fácil de começar é coletar dados de áudio usando seu telefone móvel (tutorial completo aqui). Vá à página Devices e clique no botão '+ Connect a new device' no canto superior direito. Selecione 'Use your mobile phone'. Isso produzirá um QR code único para abrir uma aplicação web no navegador do seu telefone. Fotografe o QR code e selecione abrir o link.
A aplicação web conectará com seu projeto Edge Impulse e deve parecer com isto:
Agora podemos coletar amostras de dados de áudio diretamente do telefone na página Data acquisition do Edge Impulse. Na seção 'Record new data', digite um rótulo 'tosse' ou 'ruído', certifique-se que 'Microphone' está selecionado como Sensor, e clique 'Start sampling'. Seu telefone coletará uma amostra de áudio e a adicionará ao seu dataset.
Coletar dados de áudio diretamente da placa Nano BLE Sense também é suportado. Siga estas instruções para instalar o firmware e daemon Edge Impulse. Uma vez que o dispositivo esteja conectado ao Edge Impulse, você pode coletar amostras de dados como com seu telefone móvel acima.
Criando seu Impulso
Em seguida, selecionaremos blocos de processamento de sinal e machine learning na página Create impulse. O impulso começará em branco, com blocos Raw data e Output feature. Mantenha as configurações padrão de 1000 ms Window size e 500 ms Window increase. Isso significa que nossos dados de áudio serão processados 1s por vez, iniciando a cada 0.5s. Usar uma janela pequena economiza memória no dispositivo embarcado, mas significa que precisamos de dados de tosse sem grandes pausas entre tosses.
Clique em 'Add a processing block' e selecione o bloco Audio (MFCC). Em seguida, clique em 'Add a learning block' e selecione o bloco Neural Network (Keras). Clique em 'Save Impulse'. O bloco de áudio extrairá um espectrograma para cada janela de áudio, e o bloco de rede neural será treinado para classificar o espectrograma como 'tosse' ou 'ruído' baseado em nosso dataset de treinamento. Seu impulso resultante será assim:
Em seguida, geraremos features do dataset de treinamento na página MFCC. Esta página mostra como o espectrograma extraído se parece para cada janela de 1 segundo de qualquer amostra do dataset. Podemos deixar os parâmetros nos padrões.
Clique no botão 'Generate features', que processará todo o dataset de treinamento com este bloco de processamento. Isso cria o conjunto completo de features que será usado para treinar nossa Rede Neural no próximo passo. Pressione 'Generate features' para iniciar o processamento, isso levará alguns minutos.
Agora podemos prosseguir para configurar e treinar nossa rede neural na página NN Classifier. A rede neural padrão funciona bem para sons contínuos como água corrente. Detecção de tosse é mais complicada, então configuraremos uma rede mais rica usando convolução 2D no espectrograma de cada janela. Convolução 2D processa o espectrograma de áudio de forma similar à classificação de imagens. Pressione o canto superior direito da seção 'Neural Network settings' e selecione 'Switch to Keras (expert) mode'.
Substitua a definição 'Neural network architecture' pelo código abaixo e defina 'Minimum confidence rating' para '0.70'. Então clique em 'Start training'. O treinamento levará alguns segundos.
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, InputLayer, Dropout, Flatten, Reshape, BatchNormalization, Conv2D, MaxPooling2D, AveragePooling2D
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.constraints import MaxNorm
# arquitetura do modelo
model = Sequential()
model.add(InputLayer(input_shape=(X_train.shape[1], ), name='x_input'))
model.add(Reshape((int(X_train.shape[1] / 13), 13, 1), input_shape=(X_train.shape[1], )))
model.add(Conv2D(10, kernel_size=5, activation='relu', padding='same', kernel_constraint=MaxNorm(3)))
model.add(AveragePooling2D(pool_size=2, padding='same'))
model.add(Conv2D(5, kernel_size=5, activation='relu', padding='same', kernel_constraint=MaxNorm(3)))
model.add(AveragePooling2D(pool_size=2, padding='same'))
model.add(Flatten())
model.add(Dense(classes, activation='softmax', name='y_pred', kernel_constraint=MaxNorm(3)))
# controle da taxa de aprendizado
opt = Adam(lr=0.005, beta_1=0.9, beta_2=0.999)
# treinar a rede neural
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
model.fit(X_train, Y_train, batch_size=32, epochs=9, validation_data=(X_test, Y_test), verbose=2)
A página mostrará o desempenho do treinamento e desempenho no dispositivo, que deve parecer com isto dependendo do seu dataset:
Nosso algoritmo de detecção de tosse Arduino está pronto para testar!
Treinamento e Teste
A página Live classification permite testar o algoritmo tanto com os dados de teste existentes que vieram com o dataset, quanto transmitindo dados de áudio do seu telefone móvel ou dispositivo Arduino. Podemos começar com um teste simples escolhendo qualquer amostra de teste e pressionando 'Load sample'. Isso classificará a amostra de teste e mostrará os resultados:
Também podemos testar o algoritmo com dados ao vivo. Comece com seu telefone móvel atualizando a página do navegador no seu telefone que abrimos anteriormente. Selecione seu dispositivo na seção 'Classify new data' e pressione 'Start sampling'. Você pode similarmente transmitir amostras de áudio do seu Nano BLE Sense quando conectado ao projeto via edge-impulse-daemon como na etapa de coleta de dados.
Implantação
Podemos implantar facilmente nosso algoritmo de detecção de tosse no telefone móvel. Vá à janela do navegador no seu telefone e atualize, depois pressione o botão 'Switch to classification mode'. Isso construirá automaticamente o projeto em um pacote WebAssembly e o executará no seu telefone continuamente (sem nuvem necessária depois disso, pode até modo avião!)
Em seguida, podemos implantar o algoritmo no Nano BLE Sense indo à página Deployment. Selecione 'Arduino Nano 33 BLE Sense' sob 'Build firmware' e clique 'Build'.
Isso construirá um firmware completo para o Nano BLE Sense incluindo seu algoritmo mais recente. Siga as instruções na tela para gravar sua placa Arduino com o binário.
Uma vez que o Arduino seja gravado, podemos abrir uma porta serial para o dispositivo enquanto está conectado via USB a 115.200 baud. Uma vez a porta serial aberta, pressione enter para obter um prompt e então:
> AT+RUNIMPULSE
Inferencing settings:
Interval: 0.06 ms.
Frame size: 16000
Sample length: 1000 ms.
No. of classes: 2
Starting inferencing, press 'b' to break
Recording...
Recording done
Predictions (DSP: 495 ms., Classification: 84 ms., Anomaly: 0 ms.):
cough: 0.01562
noise: 0.98438
Starting inferencing in 2 seconds...
Recording...
Recording done
Predictions (DSP: 495 ms., Classification: 84 ms., Anomaly: 0 ms.):
cough: 0.01562
noise: 0.98438
Starting inferencing in 2 seconds...
Recording...
Recording done
Predictions (DSP: 495 ms., Classification: 84 ms., Anomaly: 0 ms.):
cough: 0.86719
noise: 0.13281
Starting inferencing in 2 seconds...
Recording...
Recording done
Predictions (DSP: 495 ms., Classification: 84 ms., Anomaly: 0 ms.):
cough: 0.01562
noise: 0.98438
Trabalhos Futuros
O céu é o limite com TinyML, sensores e Edge Impulse no Arduino. Aqui estão algumas ideias para trabalhos futuros:
- Estenda o dataset padrão com suas próprias tosses e sons de fundo, lembre-se de retreinar periodicamente e testar. Você pode configurar testes unitários na página Testing para garantir que o modelo ainda funciona conforme é estendido.
- Adicione uma nova classe e dados para sons humanos que não são tosse, como fala de fundo, bocejos, etc.
- Comece com um novo dataset, coletando amostras de áudio para detectar algo novo. Dica: Você pode fazer upload apenas dos dados da classe ruído deste dataset para começar!
- Destes instruções, implante como Arduino Library como parte de um Arduino Sketch para mostrar detecção de tosse usando LED ou display.
- Faça uso de outros sensores como o acelerômetro de 3 eixos do Nano BLE Sense seguindo este tutorial.
Processo de manufatura
- Sensor K30 CO₂: Monitoramento de Qualidade do Ar Interno em Tempo Real
- Facilitando Comunicação Surdo-Cego com 1Sheeld e Arduino
- Mealheiro Inteligente: Controlar Aceitador de Moedas com Arduino Nano
- Controlar um LED via Bluetooth com Arduino – Guia DIY Simples
- Integrando Sensor de Impressão Digital Capacitivo DFRobot com Arduino ou ESP8266
- Projeto HMI Interativo com Nextion, Arduino Mega e Sensores
- Braço Robótico 6 GDL Controlado por Nunchuk com Arduino Mega
- Avaliando Saúde de Plantas com TinyML: Guia Prático
- Sistema de Monitoramento de Incêndio Florestal em Tempo Real com Alertas SMS
- Medição Precisa de Radiação Solar com Arduino UNO e Ethernet Shield