
Clasificación del audio:
Paso 1: Recopilación del conjunto de datos necesarios para el análisis de audio:
Obtuve archivos de audio del conjunto de datos de Kaggle para diferentes tipos de aleteo de mosquitos y abejas. También puedes descargarlos desde allí. El archivo es grande, pero no necesitamos tantos datos, ya que la memoria de nuestro dispositivo es pequeña. Por lo tanto, nos limitaremos a 200 archivos de audio de cada clase, con una duración de un segundo cada uno. De forma similar, puedes obtenerlos de esta manera para la motosierra, la langosta y el grillo. También puedes grabar tus propios datos si tienes una habitación silenciosa con insectos; sería mucho mejor, preciso y emocionante, pero no pude hacerlo debido a mis estresantes exámenes escolares. Nota: Si cargamos directamente los datos de audio descargados para el proceso de entrenamiento, no funcionará porque la arquitectura del micrófono sería diferente y el dispositivo no reconocería nada. Por lo tanto, una vez descargados los archivos, debemos grabarlos de nuevo con el micrófono Artemis para poder entrenar con los datos exactos que se usarán para ejecutar la inferencia. Configuremos nuestro IDE de Arduino para Artemis Redboard ATP; consulta el siguiente enlace.
https://learn.sparkfun.com/tutorials/hookup-guide-for-the-sparkfun-redboard-artemis-atp
Te encantará esta increíble tabla.
Select the board as Artemis ATP then from File->Examples->Sparkfun Redboard Artemis Example->PDM->Record_to_wav
Junto con el código, se incluye un script de Python que debes ejecutar para grabar audio desde el micrófono integrado. Es muy necesario, ya que los archivos de audio provienen de diferentes micrófonos, por lo que podría existir la posibilidad de que la placa no reconozca las frecuencias con precisión y trate el sonido como ruido.
(Consejo: Durante la grabación, modifica la columna de aire moviendo la fuente de sonido lentamente de un lado a otro, como si simularas un insecto real acercándose a los micrófonos, para obtener mejores resultados. Lo intenté y mejoré la precisión).
#!/usr/bin/python
from __future__ import division
«»»
Author: Justice Amoh
Date: 11/01/2019
Description: Python script to stream audio from Artemis Apollo3 PDM microphone
«»»
import sys
import serial
import numpy as np
import matplotlib.pyplot as plt
from serial.tools import list_ports
from time import sleep
from scipy.io import wavfile
from datetime import datetime
# Controls
do_plot = True
do_save = True
wavname = ‘recording_%s.wav’%(datetime.now().strftime(«%m%d_%H%M»))
runtime = 50#100 # runtime in frames, sec/10, set it according to your audio duration default is 5 seconds, I set it to 4 minutes as per my audio duration
# Find Artemis Serial Port
ports = list_ports.comports()
try:
sPort = [p[0] for p in ports if ‘cu.wchusbserial’ in p[0]][0]
except Exception as e:
print ‘Cannot find serial port!’
sys.exit(3)
# Serial Config
ser = serial.Serial(sPort,115200)
ser.reset_input_buffer()
ser.reset_output_buffer()
# Audio Format & Datatype
dtype = np.int16 # Data type to read data
typelen = np.dtype(dtype).itemsize # Length of data type
maxval = 32768. # 2**15 # For 16bit signed
# Plot Parameters
delay = .00001 # Use 1us pauses – as in matlab
fsamp = 16000 # Sampling rate
nframes = 10 # No. of frames to read at a time
buflen = fsamp//10 # Buffer length
bufsize = buflen*typelen # Resulting number of bytes to read
window = fsamp*10 # window of signal to plot at a time in samples
# Variables
x = [0]*window
t = np.arange(window)/fsamp # [x/fsamp for x in range(10)]
#—————
# Plot & Figures
#—————
plt.ion()
plt.show()
# Configure Figure
with plt.style.context((‘dark_background’)):
fig,axs = plt.subplots(1,1,figsize=(7,2.5))
lw, = axs.plot(t,x,’r’)
axs.set_xlim(0,window/fsamp)
axs.grid(which=’major’, alpha=0.2)
axs.set_ylim(-1,1)
axs.set_xlabel(‘Time (s)’)
axs.set_ylabel(‘Amplitude’)
axs.set_title(‘Streaming Audio’)
plt.tight_layout()
plt.pause(0.001)
# Start Transmission
ser.write(‘START’) # Send Start command
sleep(1)
for i in range(runtime):
buf = ser.read(bufsize) # Read audio data
buf = np.frombuffer(buf,dtype=dtype) # Convert to int16
buf = buf/maxval # convert to float
x.extend(buf) # Append to waveform array
# Update Plot lines
lw.set_ydata(x[-window:])
plt.pause(0.001)
sleep(delay)
# Stop Streaming
ser.write(‘STOP’)
sleep(0.5)
ser.reset_input_buffer()
ser.reset_output_buffer()
ser.close()
# Remove initial zeros
x = x[window:]
# Helper Functions
def plotAll():
t = np.arange(len(x))/fsamp
with plt.style.context((‘dark_background’)):
fig,axs = plt.subplots(1,1,figsize=(7,2.5))
lw, = axs.plot(t,x,’r’)
axs.grid(which=’major’, alpha=0.2)
axs.set_xlim(0,t[-1])
plt.tight_layout()
return
# Plot All
if do_plot:
plt.close(fig)
plotAll()
# Save Recorded Audio
if do_save:
wavfile.write(wavname,fsamp,np.array(x))
print «Recording saved to file: %s»%wavname
Una vez grabado el audio, puedes usar cualquier divisor de audio para dividir los archivos de audio en fragmentos de 1 segundo cada uno. Usé el siguiente fragmento de código con Jupyter Notebook para lograr el paso anterior.
from pydub import AudioSegment
from pydub.utils import make_chunks
myaudio = AudioSegment.from_file(«myAudio.wav» , «wav»)
chunk_length_ms = 1000 # pydub calculates in millisec
chunks = make_chunks(myaudio, chunk_length_ms) #Make chunks of one sec
#Export all of the individual chunks as wav files
for i, chunk in enumerate(chunks):
chunk_name = «chunk{0}.wav».format(i)
print «exporting», chunk_name
chunk.export(chunk_name, format=»wav»)
Utilicé Audacity para limpiar mis archivos de audio descargados antes de cortarlos, también hay funciones increíbles que puedes usar para saber si tu audio es puro o no, espectrograma de audio.
Una vez segmentados los archivos de audio, estará listo para entrenarlos para Artemis. Sin embargo, deberá realizar ajustes para que funcionen a la perfección, ya que los datos pueden contener mucho ruido debido al entorno de trabajo. Por ello, le recomiendo entrenar también el conjunto de datos de fondo para que funcione incluso con ruido peculiar constante. El fondo contiene todo el segmento de audio recortado en Audacity y algo de ruido distintivo.
Para el entrenamiento, usé Google Colab. A continuación se muestran imágenes completas del proceso de entrenamiento. Debes subir estos archivos durante el entrenamiento en el notebook de Colab y ejecutarlo en la GPU. En mi caso, tardé casi dos horas. Tuve que entrenar tres veces porque el notebook se desconectaba constantemente debido a mi lenta conexión a internet. Así que primero entrené un conjunto pequeño de datos: abejas, mosquitos (sin clasificación genética ni de raza) y motosierra. Después, entrené todo el conjunto de datos dos veces y, por suerte, lo logré.
Paso 2: Entrenamiento de los datos de audio
Entrenamiento de audio n.° 1: Etiquetas = mosquito, abeja, motosierra
Una vez finalizado el entrenamiento, debemos congelar el modelo y convertirlo en un modelo ligero para su uso en el dispositivo Edge. Adjuntaré el código junto con todos los comentarios necesarios.
Entrenamiento de audio n.° 2: Etiquetas = aedes, culex, anopheles, abeja, motosierra
Descarga todos los archivos generados en los pasos anteriores. También necesitas generar un archivo de microcaracterísticas para cada archivo de audio de clase. Lo explicaré al codificar el dispositivo. También puedes consultar la documentación de TensorFlow Lite para microcontroladores para más información.
Clasificación de datos:
Paso 1: Recopilación de datos de sensores para comportamientos deseados y no deseados
1) Altura de la planta: Usé mi proyecto anterior para determinar la altura de la planta de arroz después de la germinación, pero tampoco fue suficiente, ya que podía mantener mi dispositivo encendido mientras no hubiera conectividad con SigFox en India. Así que, independientemente de la lectura obtenida, utilicé funciones estadísticas matemáticas de Excel y la técnica de regresión para encontrar todos los demás puntos, además de añadir algo de ruido. Lamento mucho tener un conjunto de datos pequeño para el aprendizaje automático, pero afortunadamente se adapta a mi aplicación. Si algún día lo convierto en un producto empresarial, ampliaría mi conjunto de datos generando datos sintéticos
2) Predicción de incendios: Utilicé el sensor combinado ambiental rápido para recopilar las lecturas normales, así como las del estado del incendio. Para los incendios, necesitamos mediciones de humedad, temperatura, COV total y CO2. Básicamente, creamos un modelo de clasificación mediante la técnica de regresión para realizar predicciones. Utilicé el código de ejemplo del sensor para obtener todas las lecturas. Esta función es esencial para la detección de incendios forestales.
3) Adaptación al invernadero: Utilicé el módulo quiic VCNL4040 para detectar los niveles de luz ambiental y un sensor ambiental combinado para la detección de temperatura y CO2. Con base en los datos, el dispositivo puede predecir cuándo adaptarse al modo invernadero para proteger los cultivos. Se puede optimizar aún más para proteger los cultivos de tormentas de granizo o nevadas intensas.
Paso 2: Entrenamiento de los datos mediante aprendizaje profundo
Nunca realice ningún entrenamiento sin normalizarlo, ya que no verá que su modelo mejore su precisión. A continuación se muestran algunas imágenes de mi proceso de entrenamiento; son suficientes para que cualquiera pueda comprender lo que sucede durante el mismo.
Training #1: Fire prediction
Utilicé el optimizador «adam» y la pérdida «binary_crossentropy»; funcionaron mejor que cualquier otro método; puede usar el que prefiera. Se siguió el mismo paso de entrenamiento para otros conjuntos de datos. También se utiliza la función sigmoidea como función de activación para la capa de salida, ya que es adecuada para datos no lineales y predicciones binarias.
Entrenamiento #2: Predicción de la adaptación a los efectos del efecto invernadero
Se utilizó la misma configuración del modelo de regresión para la red neuronal que la del modelo de predicción de incendios. La predicción de salida ayudará al usuario a determinar, basándose en los datos relevantes del sensor, si las plantas reciben suficiente CO2, luz y calor. De lo contrario, el dispositivo puede tomar medidas para adaptarse al efecto invernadero (explico cómo hacerlo cuando codifiquemos el dispositivo).
Entrenamiento n.° 3: Seguimiento del crecimiento de las plantas
En este caso, en lugar del optimizador Adam, se utilizó rmsprop y mse como función de pérdida. En este caso, entrené la red neuronal subyacente para identificar el patrón de crecimiento en función de los días. Por lo tanto, la usaré para calcular la altura de la planta a partir del modelo en función de los días y comprobar con las lecturas de mi sensor si los valores difieren mucho, lo que significa que la planta no está creciendo bien en esa temporada.
Una vez que hayamos completado todos los pasos de nuestra capacitación, nos dirigiremos a la programación del dispositivo.
Preparando nuestro código:
Aquí describiré todos los archivos de encabezado comunes a todas las implementaciones de nuestro proyecto.
#include «xyz_model_data.h»
El modelo que entrenamos, convertimos y transformamos en C++ usando xxd
#include «tensorflow/lite/experimental/micro/kernels/all_ops_resolver.h»
Una clase que permite al intérprete cargar las operaciones utilizadas por nuestro modelo
#include «tensorflow/lite/experimental/micro/micro_error_reporter.h»
Una clase que puede registrar errores y generar resultados para ayudar con la depuración.
#include «tensorflow/experimental/lite/micro/micro_interpreter.h»
El intérprete de TensorFlow Lite para microcontroladores, que ejecutará nuestro modelo
#include «tensorflow/lite/schema/schema_generated.h»
El esquema que define la estructura de los datos de TensorFlow Lite FlatBuffer, utilizado para dar sentido a los datos del modelo en sine_model_data.h
#include «tensorflow/lite/version.h»
El número de versión actual del esquema, para que podamos comprobar que el modelo se definió con una versión compatible
//You need to install Arduino_Tensorflow_Lite library before proceeding.
#include <TensorFlowLite.h>
Un espacio de nombres se define antes de la función void setup(). Este espacio se utiliza para resolver conflictos de nombres entre diferentes paquetes. También es necesario asignar memoria para tensores y otras operaciones dependientes.
namespace
{
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
TfLiteTensor* input = nullptr;
TfLiteTensor* output = nullptr;
// Create an area of memory to use for input, output, and intermediate arrays.
// Finding the minimum value for your model may require some trial and error.
constexpr int kTensorArenaSize = 6 * 1024;
uint8_t tensor_arena[kTensorArenaSize];
} // namespace
Puede comenzar con el ejemplo de Arduino Tensorflow Lite en la sección de ejemplos de Arduino IDE y simplemente transferir los datos del modelo Lite convertido al archivo model_data.h y luego tomar cualquier acción en función del resultado del modelo previsto.
Programación, prueba de modelos y conexión del dispositivo Sparkfun Artemis:
Prueba n.° 1: Análisis de audio:
Comprobación de nuestro modelo de voz y visualización de los resultados en la pantalla OLED. Si no se siente seguro programando todo el proyecto, puede tomar un proyecto de ejemplo y modificarlo como base. De esta manera, aprenderá fácilmente a depurar. Las imágenes no se muestran en detalle, por lo que he subido los códigos, pero aún así deberá ajustarlos según su proyecto. También puede modificarlo fácilmente para enviar los resultados a un teléfono móvil o estaciones base en función de los sonidos detectados, como los de los mosquitos, para poder identificar fácilmente dónde hay mayor incidencia de estos insectos en la localidad y prevenir su reproducción, o crear un sistema de navegación automatizado para drones que rocíe insecticidas y pesticidas específicos en zonas agrícolas o informe a las agencias sobre la tala ilegal con total precisión. Vea a continuación las imágenes de los resultados de nuestra prueba.
Hemos completado nuestro entrenamiento y programación del modelo de análisis de audio para nuestro proyecto, ahora procederé con la programación de otros modelos de salida basados en valores.
Prueba n.° 2: Predicción de incendios:
Cargaremos el modelo de datos en la placa y realizaremos predicciones en tiempo real de los valores de nuestros sensores. Con base en esta predicción, mostraremos la notificación en la pantalla OLED, eliminando así la posibilidad de que se propaguen incendios en granjas. Esto me llevó mucho tiempo, ya que la placa me daba un error de compilación cada vez que lo intentaba. Gracias a la comunidad de Hackster, que me ayudó a subir el código correctamente.
Prueba n.° 3: Predicción de invernadero
Utilizaremos un sensor de detección de luz ambiental, temperatura y concentración de CO2 para predecir si hay suficiente luz, temperatura y CO2 para el crecimiento de las plantas. Si las condiciones no son normales, activaremos servomotores para proteger las plantas colocando una capa sobre la granja, similar a la de un invernadero.
Prueba n.° 4: Determinación de la altura de la planta
Hemos entrenado nuestro modelo para determinar la altura de la planta mediante regresión. Sin embargo, esta tiene una desventaja: determina los valores en una sola dirección lineal; por lo tanto, si se ejecuta indefinidamente, devolverá la altura de la planta en kilómetros algún día si no se establece un límite superior. Por lo tanto, detectaremos la altura de la planta en los días correspondientes y la compararemos con nuestro modelo para el día correspondiente. Verificaremos si la altura predicha por el modelo difiere significativamente de la altura medida. Si difiere significativamente, significa que existe alguna deficiencia nutricional.
He adjuntado todos los códigos, muy bien comentados y legibles, para que puedas implementar tu propio algoritmo. No pierdas tiempo pensando en códigos, invierte tu tiempo en optimizar tu conjunto de datos de entrenamiento.
No tengo impresora 3D, así que usé una caja de plástico para construir mi modelo. Durante la presentación de la idea, también tuvimos que especificar cómo sería nuestro proyecto. Aquí está la instalación (no es un jardín, ya que no tengo uno), pero me esforcé al máximo para ser innovador y creativo. Lo siento, chicos, no pude encontrar piezas de repuesto para este hardware, pero el cableado es bastante sencillo, ya que usé sensores muy comunes y los sensores rápidos son plug and play. Todas las imágenes son lo suficientemente nítidas como para detallar los pines de mis sensores.
Puedes configurar tu dispositivo en el modo que quieras y donde quieras. También quería implementar la adaptación de humedad para mis plantas; lo terminaré más adelante.
Continuará en el próximo número de TECNOLOGIA HUMANIZADA
Sé el primero en comentar