Tabla de contenido:

Sistema Autônomo Localizador De Vazamentos: 11 pasos
Sistema Autônomo Localizador De Vazamentos: 11 pasos

Video: Sistema Autônomo Localizador De Vazamentos: 11 pasos

Video: Sistema Autônomo Localizador De Vazamentos: 11 pasos
Video: como identificar vazamento no sistema ar condicionado automotivo Giliard Mota 2024, Noviembre
Anonim
Sistema Autônomo Localizador De Vazamentos
Sistema Autônomo Localizador De Vazamentos

Este projeto consiste em um robô, que através da leitura realizada por um dispositivo, equipado com um sensor piezoelétrico, captura os espectros das vibrações no solo, pode identificar e localizar, com o processamento dos dados por uma rede neural, possíveis vazamentos de água em uma tubulação.

O processamento destes dados é realizado por algoritmos instalados en DRAGONBOARD 410c. Os dados também são enviados para um serviço na nuvem, responsável por auxiliar no processo de Integência Artificial do projeto.

Este projeto foi desenvolvido no Hackaton Qualcomm, durante a TecnoFACENS da Faculdade de Engenharia de Sorocaba (FACENS), participaram do projeto os graduuandos de engenharia mecatrônica Eneo Juliano Bovino, Felipe Xavier, Lucas de Sousa Rodrigues, Rogério Ap. Gomes Polo y Ronaldo P. Gomes Polo. Também participou do projeto o aluno Daniel de Castro Pacheco graduando de engenharia mecânica na Universidade Newton Paiva de Belo Horizonte. O projeto contou com o apoio dos graduandos de engenharia mecatrônica da FACENS, Lucas Nunes Monteiro y Felipe Crispim da Silva Salvagnini.

Paso 1: Lista de Materiais

Lista De Materiais
Lista De Materiais

Para realização deste projeto, os seguintes materiasis foram used:

1 Arduino debido

1 Dragonboard 410c

2 Drivers para motor de corrente continua contendo cada um:

4 Transistores BC548

4 diodos 1n4007

4 resistencias 4k7Ω ¼ W

1 Driver para servo motor contenido:

1 Transistores BC548

1 diodos 1N4007

1 Restaura 4k7Ω ¼ W

1 ratón USB

1 teclado USB

1 monitor

1 Cabo HDMI

1 Robô De Esteiras - Plataforma Zumo

1 Mini dispositivo de cremalheira e engrenagem

1 servomotor 9g

Paso 2: Adaptação Mecânica

Image
Image

Para a aquisição dos dados pelo sensor piezoelétrico, faz se necessário, o desenvolvimento de um dispositivo com pinhão e cremalheira, conforme desenhos anexados, neste caso as peças foram fabricadas por uma impressora 3D, devido ao fato de se tratar de um protótipo e ao curto tempo de ejecução, fixou-se o dispositivo na plataforma zumo, utilizando fita dupla face, conforme vídeo.

Paso 3: Acionamento Dos Motores

Obtenção Do Áudio
Obtenção Do Áudio

Para ejecutar a movimentação dos motores do robô ZUMO e do dispositivo de captura, fez-se necessária a montagem de dois drivers para os motores de corrente continua e um driver para o servo motor, conforme as figuras acima, sendo a primeira figura o driver para um motor de corrente continua ea segunda o driver para um servomotor.

Paso 4: Obtenção Do Áudio

Para obtenção do espectro de áudio das vibrações do solo, foi utilizado um dispositivo desenvolvido como parte do TCC de Engenharia Mecatrônica dos graduuandos Lucas Nunes Monteiro e Felipe C. da Silva Salvagnini, maiores detalhes sobre o TCC e sobre o dispositivo podem ser solicitados através do envíe un correo electrónico a [email protected].

Este dispositivo utiliza-se de um sensor piezoelétrico e uma placa de circuito que realiza una filtración e amplificação do sinal.

As frequências de interesse para o projeto estão entre 100Hz e 800Hz. Para isso o dispositivo de sensoriamento foi configurado com uma frequência de amostragem de 3 kHz para que sejam respeitada as condições do teorema de amostragem de Nyquist, onde a frequência de aquisição deve estar pelo menos duas vezes acima das frequências estudadas.

Aquisição é habilitada e desabilitada através da interrupção do Arduino DUE.

Paso 5: Configuración de Arduino DUE (linguagem C)

Configuração Do Arduino DUE (linguagem C)
Configuração Do Arduino DUE (linguagem C)

Devido a grande quantidade de dados, cerca de 3000 pontos por segundo, do tipo inteiro de 32 bits, gerados pelo dispositivo de sensoriamento e necessários para processamento dos algoritmos na DRAGONBOARD 410c, foi used o Arduino DUE para fazer uso de uma entrada analógica com maior poder de proceso, isso foi necesario por que o Escudo de interfaz Grove Seeed Sensor Mezzanine instalado en DRAGONBOARD 410c, que puede ser un microcontrolador ATmega 328, no hay poder de proceso para operar.

O Arduino DUE foi establecido para recibir los comandos enviados de la plataforma QUALCOMM DRAGONBOARD 410c vía comunicação serial.

Como configuraciones adicionales sin formato Arduino:

Realizar aquisição dos dados;

Transmitir os dados obtidos para a DRAGONBOARD 410c;

Segue un programação:

# include # define Numb_Sample 3000 #define DAC_Input A0

#define SERVO 7

#define PosServoMin 4 #define PosServoMax 6 #define Period 60 unsigned int Scont = 0, SNow = PosServoMin; unsigned long int DAC [Numb_Sample], ind = Numb_Sample; anular TC3_Handler () {TC_GetStatus (TC1, 0); if (ind <Numb_Sample) DAC [ind ++] = analogRead (DAC_Input); si (Scont

1); // ciclo de trabajo del 50%

TC_SetRC (tc, canal, rc); TC_Start (tc, canal); tc-> TC_CHANNEL [canal]. TC_IER = TC_IER_CPCS | TC_IER_CPAS; // habilita os registradores tc-> TC_CHANNEL [canal]. TC_IDR = ~ (TC_IER_CPCS | TC_IER_CPAS); // desabilita os registradores NVIC_EnableIRQ (irq); // habilita interrupção}

configuración vacía ()

{Serial.begin (115200); pinMode (DAC_Input, INPUT); TimerStart (TC1, 0, TC3_IRQn, 1500); // Iniciar el temporizador // TC_Stop (TC1, 0); pinMode (SERVO, SALIDA); }

bucle vacío ()

{/ * // while (! Serial.available ()); char rc; // = Serial.read (); int indice = 0; if (rc == 0) {while (! Serial.available ()); rc = Serial.read (); switch (rc) {caso 1: índice = 0; while (! Serial.available ()); while ((rc = Serial.read ())! = 0xFF) {índice << = 8; índice + = rc; while (! Serial.available ()); } Serial.print (0); Serial.print (2); SendNumber (DAC [índice]); Serial.print (0xFF); rotura; caso 3: while (! Serial.available ()); if ((Serial.read ()) == 0xFF) {SNow = PosServoMax; retraso (500); ind = 0; // TC_Start (TC1, 0); while (ind <Numb_Sample); // TC_Stop (TC1, 0); SNow = PosServoMin; retraso (500); Serial.print (0); Impresión de serie (4); Serial.print (0xFF); } rotura; }} else if (rc == '2') {Serial.print ("Probar servomotor / n"); while (! Serial.available ()); rc = Serial.read (); if (rc == '1') {Serial.print ("Modo 1 / n"); SNow = PosServoMax; } if (rc == '2') {Serial.print ("Modo 2 / n"); SNow = PosServoMin; }} * / SNow = PosServoMax; retraso (100); SNow = PosServoMin; retraso (100); }

Paso 6: Interfaceamento Das Tecnologias

Interfaceamento Das Tecnologias
Interfaceamento Das Tecnologias

Para una comunicación de dos datos entre o Arduíno DUE ea DRAGONBOARD 410c, se utiliza una interfaz de figura acima, o que no se puede ejecutar un posible ejecutar, então optou-se pelo uso de uma interface USB CDC entre o Arduino DUE ea DRAGONBOARD 410c, que necessitaria da recompilação do KERNEL da DRAGONBOARD 410c, que não se fez por causa do curto tempo disponível.

Paso 7: Configuração Da DRAGONBOARD 410c (Python)

Configuración de DRAGONBOARD 410c (Python)
Configuración de DRAGONBOARD 410c (Python)

Foi configurada para enviar ao Arduino DUE os comandos para realizar una adquisición de datos y transmitir os dados obtidos. Segue código abaixo.

Observación: Un abordagem usado no código, no funcionou devido aos níveis de tensão utilizado pelo Arduíno DUE e o Mezzanine serem incompatíveis. Por isso optou-se pelo interfaceamento USB, que es necesaria la recompilación de KERNEL na DRAGONBOARD 410c para que un porta fosse criada corretamente para una comunicación.

import timeimport serial import pandas as pd import numpy as np

# Configuração da conexão serial

ser = serial. Serial (port = '/ dev / ttyAMC0', # tty96B0 ', baudrate = 250000, parity = serial. PARITY_NONE, stopbits = serial. STOPBITS_ONE, bytesize = serial. EIGHTBITS)

ser.isOpen ()

print ('Ingresa tus comandos a continuación. / r / nInserta "salir" para salir de la aplicación.')

entrada = 1

while 1: input = input (">>") if input == 'exit': ser.close () exit () elif input == 'read': ser.write (0) # Envia o comando para o Arduino DUE realizar una coleta dos dados ser.write (1) # Envia o comando para o Arduino DUE transmitir os dados coletados

lista =

para i en el rango (3000):

ser.write (i / 256) ser.write ((i <0: out = ser.read (2) if (out == 0x0002): atual = 0 c = ser.read (1) while (c! = 0xFF): atual << 8 atual + = cc = ser.read (1) lista.append (atual)

Paso 8: INTERPRETAÇÃO DOS ARQUIVOS DE AUDIO

INTERPRETAÇÃO DOS ARQUIVOS DE AUDIO
INTERPRETAÇÃO DOS ARQUIVOS DE AUDIO

Para poder realizar uma primeira análise dos dados obtidos através do sensor, se fez necessária a conversão dos arquivos no formato WAV, fornecidos pelos alunos autores do TCC e colaboradores do projeto, para valores numéricos, que são utilizados nos algoritmos de análise embarcados na DRAGONBOARD 410c. Para realizar esta conversación por escrito um algoritmo em PYTHON 3 que lê o arquivo WAV e salva os dados do espectro em um arquivo CSV. O algoritmo utilizado segue abaixo e em anexo para descargar.

Esse algoritmo não se faz necesario para el funcionamiento del sistema, já que o Arduino DUE já enviará esses dados em um array de valores numéricos.

# codificación: utf-8

# Leitura e conversão dos audios para csv

# MÓDULOS UTILIZADOS

import wave import numpy as np import pandas as pd import matplotlib.pyplot as plt

# FUNÇÃO PARA CONVERTER WAV EM DADOS DO ESPECTRO E SALVAR CSV

def audio_to_csv (nombre_archivo): wave_file = wave.open (file_name + '. wav', 'rb') data_size = wave_file.getnframes () sample_rate = wave_file.getframerate () time_step = 1 / sample_rate waveData = wave_file.readframes -size ()) signal = np.fromstring (waveData, dtype = 'int32') Time = np.linspace (start = 0, stop = data_size / sample_rate, num = data_size, endpoint = True) df = pd.concat ([pd. DataFrame (signal), pd. DataFrame (Time)], axis = 1) df.to_csv (file_name + '.csv', index = False) return df

# MARCO DE DATOS CARREGANDO COM OS DADOS DO AUDIO

file_name = 'Solo_com_Vazamento' df_vazamento = audio_to_csv (file_name) df_vazamento.columns = ['amp', 'time'] file_name = 'Solo_sem_Vazamento' df_sem_vazamento = audio_to_csv (file_name) 'tiempo_columna, # GRÁFICO DO ESPECTRO DE AUDIO

figure, (ax1, ax2) = plt.subplots (nrows = 2, ncols = 1, figsize = (20, 10)) ax1.plot (df_vazamento ['time'], df_vazamento ['amp']) ax1.set_title ('Solo com Vazamento', fontdict = {'tamaño de fuente': 20, 'tamaño de fuente': 'negrita'}) ax1.set_xlabel ('Tempo [s]', fontdict = {'tamaño de fuente': 16}) ax1.set_ylim ([-4e8, 4e8]) ax2.plot (df_sem_vazamento ['time'], df_sem_vazamento ['amp']) ax2.set_title ('Solo sem Vazamento', fontdict = {'fontsize': 20, 'fontweight': 'bold' }) ax2.set_xlabel ('Tempo [s]', fontdict = {'tamaño de fuente': 16}) ax2.set_ylim ([- 4e8, 4e8]) figure.tight_layout (h_pad = 5) plt.show ()

Paso 9: Analizar Visual Do Sinal

Análise Visual Do Sinal
Análise Visual Do Sinal
Análise Visual Do Sinal
Análise Visual Do Sinal
Análise Visual Do Sinal
Análise Visual Do Sinal

Com o PYTHON 3 é realizada a transformada de Fourier, este artificio matemático realiza a transformação do sinal do domínio do tempo para o domínio da frequência, onde se torna possível analisar as varias frequências, e suas amplitudes, que compõem aquele sinal. Pela análise visual do gráfico da transformada de Fourier um profissional com conhecimentos específicos poderá identificar una existência de algum vazamento na tubulação. Estes gráficos servirão para validação das análises realizados pelo algoritmo de detección automática.

Limitando o eixo das frequências entre 100Hz e 800Hz, fica claro a existência de vazamentos quando se observam distúrbios nesse range de frequências.

# codificación: utf-8 # Módulos utilizados para processamento da transformada de Fourier

import pandas as pd import numpy as np import wave from matplotlib import pyplot as plt # Función que realiza una transformación de Fourier y gráficos para análisis de Fourier (df_list): Fs = 44100; # Taxa de amostragem en Hz Ts = 1.0 / Fs; # Intervalo de amostragem y = pd.concat (df_list) t = y ['time'] # Vetor de tempos y = y ['amp'] # Vetor de amplitudes n = len (y) # Comprimento do sinal k = np. arange (n) T = n / Fs frq = k / T frq = frq [rango (n // 2)] Y = np.fft.fft (y) / n Y = Y [rango (n // 2)] tmp = pd. DataFrame () tmp ['amp'] = abs (Y) tmp ['freq'] = frq max_lim = max (tmp ['amp'] [(tmp ['freq']> = 100) & (tmp ['freq'] <= 800)]) fig, ax = plt.subplots (2, 1, figsize = (20, 10)) ax [0].plot (t, y) ax [0].set_xlabel ('Tiempo') ax [0].set_ylabel ('Amplitud') ax [1].plot (frq, abs (Y), 'r') ax [1].set_xlim ([100, 800]) ax [1].set_ylim ([0, max_lim]) ax [1].set_xlabel ('Freq (Hz)') ax [1].set_ylabel ('| Y (freq) |') plt.show () return frq, abs (Y) # Função que realiza a carga dos dados do CSV e chama a função de Fourier def read_csv (file_name, init, final): df = pd.read_csv (file_name + '.csv') df.columns = ['amp', ' time '] delta = final-init if init * 44100> len (df) o final * 44100> len (df): init = (len (df) / 44100) -delta if init = 100) & (df [' freq '] <= 800)] mx = ordenado (df [' amp ']) print ("Média das amplitudes:", np.round (np.mean (mx))) print ("Percentuais em relação a média das amplitudes.") print ("100 maiores amplitudes", np.mean (mx [-100:]) // df ['amp']. mean () * 100, "%", sep = "") print ("50 amplitudes maiores:", np.mean (mx [-50:]) // df ['amp']. mean () * 100, "%", sep = "") print ("10 amplitudes maiores:", np.mean (mx [-10:]) // df ['amp']. mean () * 100, "%", sep = "") print ("Amplitud mayor:", np.mean (mx [-1:]) // df ['amp']. mean () * 100, " % ", sep =" ") read_csv ('Solo_com_Vazamento', 2, 10) # Exemplo de gráficos para vazamentoread_csv ('Solo_sem_Vazamento', 2, 10) # Exemplo de gráficos para sem vazamento

Paso 10: Algoritmo Em R Para Extração Das Features Dos Dados

Algoritmo Em R Para Extração Das Features Dos Dados
Algoritmo Em R Para Extração Das Features Dos Dados
Algoritmo Em R Para Extração Das Features Dos Dados
Algoritmo Em R Para Extração Das Features Dos Dados

Utilizou-se um algoritmo em R para realizar o processamento e extração das features (características) dos dados obtidos.

Este primer algoritmo realiza uma extração identificada, onde é needário saber se o arquivo de áudio trata-se de uma amostra vazamento detectado ou não, isso por que os dados resultantes desse processso servirão para o treinamento da rede neural usado.

Para quando o sistema estiver em modo de operación um algoritmo um pouco diferente será ejecutado, onde não este fará a extração não identificada, gerando somente como características sem uma identificação.

Estas características ou caraterísticas são propiedades acústicas compuestas por varias informaciones referentes ao espectro de audio capturado, abaixo seguirá uma descrição (en inglés) destas características.

Este algoritmo faz parte de un proyecto no está disponible en GitHub y puede ser un acceso a través del enlace, o un mes para modificar para atender como especificações do projeto.

O software usado para rodar o algoritmo é gratuito, descargue el interpretador R e do R Studio.

Características extraídas:

  • meanfreq: frecuencia media (en kHz)
  • sd: desviación estándar de frecuencia
  • mediana: frecuencia mediana (en kHz)
  • Q25: primer cuantil (en kHz)
  • Q75: tercer cuantil (en kHz)
  • IQR: rango intercuantílico (en kHz)
  • sesgo: sesgo (ver nota en la descripción de specprop)
  • kurt: curtosis (ver nota en la descripción de specprop)
  • sp.ent: entropía espectral
  • sfm: planitud espectral
  • modo: modo de frecuencia
  • centroide: centroide de frecuencia (ver specprop)
  • peakf: frecuencia pico (frecuencia con mayor energía)
  • meanfun: promedio de la frecuencia fundamental medida a través de la señal acústica
  • minfun: frecuencia fundamental mínima medida a través de la señal acústica
  • maxfun: frecuencia fundamental máxima medida a través de la señal acústica
  • meandom: promedio de la frecuencia dominante medida a través de la señal acústica
  • mindom: mínimo de frecuencia dominante medida a través de la señal acústica
  • maxdom: máximo de la frecuencia dominante medida a través de la señal acústica
  • dfrange: rango de frecuencia dominante medida a través de la señal acústica
  • modindx: índice de modulación. Calculado como la diferencia absoluta acumulada entre mediciones adyacentes de frecuencias fundamentales dividida por el rango de frecuencia
  • etiqueta: fuga o sin_leakage

Algoritmo usado:

paquetes <- c ('tuneR', 'seewave', 'fftw', 'caTools', 'randomForest', 'warbleR', 'mouse', 'e1071', 'rpart', 'xgboost', 'e1071') si (length (setdiff (paquetes, nombres de filas (paquetes instalados ())))> 0) {install.packages (setdiff (paquetes, nombres de filas (paquetes instalados ())))}

biblioteca (tuneR)

biblioteca (seewave) biblioteca (caTools) biblioteca (rpart) biblioteca (rpart.plot) biblioteca (randomForest) biblioteca (warbleR) biblioteca (ratones) biblioteca (xgboost) biblioteca (e1071)

specan3 <- función (X, bp = c (0, 22), wl = 2048, umbral = 5, paralelo = 1) {# Para usar el procesamiento paralelo: biblioteca (devtools), install_github ('nathanvan / paralelsugar') if (class (X) == "data.frame") {if (all (c ("sound.files", "selec", "start", "end")% in% colnames (X))) {start <- as.numeric (unlist (X $ start)) end <- as.numeric (unlist (X $ end)) sound.files <- as.character (unlist (X $ sound.files)) selec <- as.character (unlist (X $ selec))} else detener (pegar (pegar (c ("archivos de sonido", "seleccionar", "iniciar", "finalizar") [! (c ("archivos de sonido", "seleccionar", "start", "end")% in% colnames (X))], collapse = ","), "columna (s) no encontrada en el marco de datos"))} else detener ("X no es un marco de datos") #si hay NA en el inicio o el final de la parada if (any (is.na (c (final, inicio)))) parada ("NA encontrados en el inicio y / o final") # si el final o el inicio no son numéricos parada if (all (class (end)! = "numeric" & class (start)! = "numeric")) stop ("'end' y 'selec' deben ser numéricos") #if cualquier inicio superior al final stop if (any (end - start <0)) stop (paste ("El inicio es más alto que el en d en ", length (which (end - start20)) stop (paste (length (which (end - start> 20))," selection (s) more than 20 sec ")) options (show.error.messages = TRUE) #if bp no es vector o longitud! = 2 stop if (! is.vector (bp)) stop ("'bp' debe ser un vector numérico de longitud 2") else {if (! length (bp) == 2) stop ("'bp' debe ser un vector numérico de longitud 2")} #return warning si no se encuentran todos los archivos de sonido fs <- list.files (path = getwd (), pattern = ".wav $", ignore.case = TRUE) if (length (unique (sound.files [(sound.files% in% fs)]))! = length (unique (sound.files))) cat (paste (length (unique (sound. files)) - length (unique (sound.files [(sound.files% en% fs)])), "archivo (s).wav no encontrado")) # contar el número de archivos de sonido en el directorio de trabajo y si 0 se detiene d <- which (sound.files% in% fs) if (length (d) == 0) {stop ("Los archivos.wav no están en el directorio de trabajo")} else {start <- start [d] end <- end [d] selec <- selec [d] sound.files <- sound.files [d]} # Si paralelo no es numérico if (! is.numeric (paralelo)) stop ("'paralelo' debe ser un vector numérico de longitud 1 ") si (cualquiera (! (paralelo %% 1 == 0), paralelo 1) {opciones (advertencia = -1) if (todos (Sys.info () [1] ==" Windows ", requireNamespace (" paralelsugar ", quietly = TRUE) == TRUE)) lapp <- función (X, FUN) paralelsugar:: mclapply (X, FUN, mc.cores = paralelo) else if (Sys.info () [1] == "Windows") {cat ("Los usuarios de Windows necesitan instalar el paquete 'paralelsugar' para computación paralela (¡no lo está haciendo ahora!)") Lapp <- pbapply:: pblapply} else lapp <- function (X, DIVERSIÓN) paralelo:: mclapply (X, DIVERSIÓN, mc.cores = paralelo)} else lapp <- pbapply:: pblapply options (warn = 0) if (paralelo == 1) cat ("Midiendo parámetros acústicos:") x <- as.data.frame (lapp (1: length (start), function (i) {r <- tuneR:: readWave (file.path (getwd (), sound.files ), from = inicio , hasta = final , unidades = "segundos") b techo ([email protected]/2000) - 1) b [2] <- techo ([email protected]/2000) - 1 #análisis de espectro de frecuencia Songspec <- seewave:: spec (r, f = [email protected], plot = FALSE) análisis <- seewave:: specprop (songspec, f = [email protected], flim = c (0, 280/1000), plot = FALSE) #save parameters meanfreq <- análisis $ mean / 1000 sd <- análisis $ sd / 1000 median <- análisis $ median / 1000 Q25 < - análisis $ QQ75 <- análisis $ QIQR <- análisis $ IQR / 1000 sesgo <- análisis $ sesgo kurt <- análisis $ curtosis sp.ent <- análisis $ sh sfm <- análisis $ modo sfm <- análisis $ modo / 1000 centroide <- análisis $ cent / 1000 #Frecuencia con picos de amplitud picof <- 0 # seewave:: fpeaks (songpec, f = [email protected], wl = wl, nmax = 3, plot = FALSE) [1, 1] # Parámetros de frecuencia fundamentales ff <- seewave:: fund (r, f = [email protected], ovlp = 50, umbral = umbral, fmax = 280, ylim = c (0, 280/1000), plot = FALSE, wl = wl) [, 2] meanfun <-mean (ff, na.rm = T) minfun <-min (ff, na.rm = T) maxfun <-max (ff, na.rm = T) #Parámetros de frecuencia dominante y <- seewave:: dfreq (r, f = [email protected], wl = wl, ylim = c (0, 280/1000), ovlp = 0, plot = F, umbral = umbral, paso de banda = b * 1000, fftw = TRUE) [, 2] meandom <- mean (y, na.rm = TRUE) mindom <- min (y, na.rm = TRUE) maxdom <- max (y, na.rm = TRUE) dfrange <- (maxdom - mindom) duration <- (end - start ) # cambios en el cálculo del índice de modulación <- vector () for (j en el que (! is. na (y))) {cambiar <- abs (y [j] - y [j + 1]) cambia <- añadir (cambios, cambiar)} if (mindom == maxdom) modindx <-0 else modindx <- mean (cambios, na.rm = T) / dfrange #save results return (c (duration, meanfreq, sd, median, Q25, Q75, IQR, skew, kurt, sp.ent, sfm, mode, centroid, peakf, meanfun, minfun, maxfun, meandom, mindom, maxdom, dfrange, modindx))})) #cambiar nombres de resultados nombres de filas (x) <- c ("duration", "meanfreq", "sd", "median", "Q25", "Q75", "IQR", "sesgar", "kurt", "sp.ent", "sfm", "modo", "centroide", "peakf", "meanfun", "minfun", "maxfun", "meandom", "mindom", "maxdom", "dfrange", "modindx") x <- data.frame (sound.files, selec, as.data.frame (t (x))) colnames (x) [1: 2] <- c ("archivos de sonido", "selec") nombres de filas (x) <- c (1: nrow (x)) return (x)}

processFolder <- function (folderName) {# Empiece con data.frame vacío. data <- data.frame () # Obtiene la lista de archivos en la carpeta. list <- list.files (folderName, '\. wav') # Agregar lista de archivos a data.frame para su procesamiento. for (fileName in list) {row <- data.frame (fileName, 0, 0, 20) data <- rbind (data, row)} # Establecer nombres de columna. names (data) <- c ('sound.files', 'selec', 'start', 'end') # Mover a la carpeta para procesar. setwd (nombrecarpeta) # Procesar archivos. acústica <- specan3 (datos, paralelo = 1) # Mover de nuevo a la carpeta principal. setwd ('..') acústica}

gender <- function (filePath) {if (! exist ('genderBoosted')) {load ('model.bin')} # Rutas de configuración. currentPath <- getwd () fileName <- basename (filePath) path <- dirname (filePath) # Establecer directorio para leer el archivo. setwd (ruta) # Empiece con data.frame vacío. data <- data.frame (fileName, 0, 0, 20) # Establecer nombres de columna. names (data) <- c ('sound.files', 'selec', 'start', 'end') # Procesar archivos. acústica <- specan3 (datos, paralelo = 1) # Restaurar ruta. setwd (ruta actual) predecir (genderCombo, newdata = acústica)}

# Cargar datos

fuga <- processFolder ('caminho para o pasta com samples de áudio com vazamento') without_leakage <- processFolder ('caminho para o pasta com samples de áudio sem vazamento')

# Establecer etiquetas.

fuga $ etiqueta <- 1 sin_fugas $ etiqueta <- 2 datos <- rbind (fuga, sin_fugas) datos $ etiqueta <- factor (datos $ etiqueta, etiquetas = c ('fuga', 'sin_fugas'))

# Eliminar columnas no utilizadas.

datos $ duración <- NULL datos $ sound.files <- NULL datos $ selec <- NULL datos $ peakf <- NULL

# Elimina filas que contienen NA.

datos <- datos [casos.completos (datos),]

# Escriba el conjunto de datos csv.

write.csv (data, file = 'features.csv', sep = ',', row.names = F)

Paso 11: Rede Neural

Rede Neural
Rede Neural

A ideia do uso de uma rede neural, é a de realizar um reconhecimento automatizado através dos dados coletados pelo dispositivo de sensoriamento.

A rede neural used é do tipo MLP (Multilayer Perceptron), este modelo é treinado com dados previamente identificados e após esse treinamento o modelo implantado no conseguirá realizar una identificación automática del recebido sinal, informando se naquele ponto existe um vazamento ou não.

Si es necesario realizar una filtración de dos días de entrada, pois algumas características estavam diminuindo a taxa de acerto da rede ao invés de melhora-la. Não foi realizado nenhuma abordagemística estat muito aprofundada, mas mesmo com um trabalho mais superficial pode-se chegar a algumas variáveis com bons desempenhos.

Para os testes realizados o modelo obteve um desempenho muito bom, alcançando na maioria dos testes uma taxa de acerto de 100%, como pode ser observado na imagem anexa.

Este algoritmo se utilizó para treinar o modelo da rede e retornar a taxa de acerto do mesmo. No sistema de detección um algoritmo um pouco diferente seria usado, pois ele realizaria o treino ou receberia um modelo já treinado da nuvem ou de alguma outra fonte e com esse modelo realizadoia as predições para cada leitura realizada.

# codificación: utf-8

importar pandas como pd

importar numpy como np de sklearn.model_selection importar train_test_split como tts de sklearn.neural_network importar MLPClassifier como MLP de sklearn.metrics importar clasificar_report como cr de sklearn.metrics importar confusion_matrix como cm

# Leitura dos dados do CSV

df = pd.read_csv ('features.csv') # Separação das entradas df_X = df [df.columns [: len (df.columns) -1] # Filtrando como entradas df_X = df_X

# Separando dados para treino e teste

X_train, X_test, Y_train, Y_test = tts (df_X, df_Y, test_size = 0.1)

# Criando modelo de rede neural

modelo = MLP (alpha = 0.0001, learning_rate_init = 0.0001, hidden_layer_sizes = (50, 50, 50, 50), max_iter = 10000, activación = 'tanh', solver = 'lbfgs')

# Treinando modelo

modelo.fit (X_train, Y_train) resultado = modelo.predict (X_test)

# Imprimindo resultados

report = cr (Y_test, result) mat = cm (y_pred = result, y_true = Y_test) print ("Matriz de confusão") print (mat, end = "\ n / n") print ("Relatório de Classificação") print (reporte)

Recomendado: