Índice:

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

Vídeo: Sistema Autônomo Localizador De Vazamentos: 11 etapas

Vídeo: Sistema Autônomo Localizador De Vazamentos: 11 etapas
Vídeo: Microvazamento de fluído (gás)? Detecte sem desinstalar as unidades de seu ar condicionado, 2024, Novembro
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 na 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 de graduandos de engenharia mecatrônica Eneo Juliano Bovino, Felipe Xavier, Lucas de Sousa Rodrigues, Rogério Ap. Gomes Polo e 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 e Felipe Crispim da Silva Salvagnini.

Etapa 1: Lista De Materiais

Lista De Materiais
Lista De Materiais

Para realização do projeto, os seguintes materiais foram utilizados:

1 Arduino devido

1 Dragonboard 410c

2 Drivers para motor de corrente contínua contendo cada um:

4 Transistores BC548

4 Diodos 1n4007

4 resistores 4k7Ω ¼ W

1 Driver para servo motor contendo:

1 Transistores BC548

1 Diodos 1N4007

1 Resistores 4k7Ω ¼ W

1 mouse USB

1 teclado USB

1 monitor

1 cabo HDMI

1 Robô De Esteiras - Plataforma Zumo

1 Mini dispositivo de cremalheira e engrenagem

1 servo motor 9g

Etapa 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 como peças foram fabricadas por uma impressora 3D, devido ao fato de se tratar de um protótipo e ao curto tempo de execução, fixou-se o dispositivo na plataforma zumo, utilizando fita dupla face, conforme vídeo.

Etapa 3: Acionamento dos Motores

Obtenção do Áudio
Obtenção do Áudio

Para executar o movimento 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 e o segundo driver para um servo motor.

Etapa 4: Obtenção do Áudio

Para obter o espectro de áudio das vibrações do solo, foi utilizado um dispositivo desenvolvido como parte do TCC de Engenharia Mecatrônica dos formandos Lucas Nunes Monteiro e Felipe C. da Silva Salvagnini, maiores detalhes sobre o TCC e sobre o dispositivo podem ser solicitados através do envie um email para [email protected].

Este dispositivo utiliza-se de um sensor piezoelétrico e uma placa de circuito que realiza uma filtragem 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 respeitadas 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.

A aquisição é habilitada e desabilitada através da interrupção do Arduino DEVIDO.

Etapa 5: Configuração do 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, gerado pelo dispositivo de sensoriamento e transferida para processamento dos algoritmos na DRAGONBOARD 410c, foi usado o Arduino DUE para fazer uso de uma entrada analógica com maior poder de processamento, isso foi necessário para que o Escudo de interfaceamento Grove Seeed Sensor Mezzanine instalado na DRAGONBOARD 410c, que possui um microcontrolador ATmega 328, não possui poder de processamento para essa operação.

O Arduino DEVIDO foi projetado para receber os comandos enviados da plataforma QUALCOMM DRAGONBOARD 410c via comunicação serial.

As ações configuradas no Arduino foram:

Realizar a aquisição dos dados;

Transmitir os dados capturados para um DRAGONBOARD 410c;

Segue uma programação:

# include # define Numb_Sample 3000 #define DAC_Input A0

# define SERVO 7

#define PosServoMin 4 #define PosServoMax 6 #define Período 60 unsigned int Scont = 0, SNow = PosServoMin; sem sinal longo int DAC [Numb_Sample], ind = Numb_Sample; vazio TC3_Handler () {TC_GetStatus (TC1, 0); if (ind <Numb_Sample) DAC [ind ++] = analogRead (DAC_Input); if (Scont

1); // ciclo de trabalho de 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}

void setup ()

{Serial.begin (115200); pinMode (DAC_Input, INPUT); TimerStart (TC1, 0, TC3_IRQn, 1500); // Iniciar o Timer // TC_Stop (TC1, 0); pinMode (SERVO, OUTPUT); }

void loop ()

{/ * // while (! Serial.available ()); char rc; // = Serial.read (); índice interno = 0; if (rc == 0) {while (! Serial.available ()); rc = Serial.read (); switch (rc) {caso 1: índice = 0; while (! Serial.available ()); while ((rc = Serial.read ())! = 0xFF) {indice << = 8; índice + = rc; while (! Serial.available ()); } Serial.print (0); Serial.print (2); SendNumber (DAC [índice]); Serial.print (0xFF); pausa; caso 3: while (! Serial.available ()); if ((Serial.read ()) == 0xFF) {SNow = PosServoMax; atraso (500); ind = 0; // TC_Start (TC1, 0); while (ind <Numb_Sample); // TC_Stop (TC1, 0); SNow = PosServoMin; atraso (500); Serial.print (0); Serial.print (4); Serial.print (0xFF); } pausa; }} else if (rc == '2') {Serial.print ("Test Servo Motor / 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; atraso (100); SNow = PosServoMin; atraso (100); }

Etapa 6: Interfaceamento Das Tecnologias

Interfaceamento Das Tecnologias
Interfaceamento Das Tecnologias

Para a comunicação dos dados entre o Arduíno DUE e o DRAGONBOARD 410c, boletim utilizou-se uma interface da figura acima, o que não foi possível, então optou-se pelo uso de uma interface USB CDC entre o Arduino DUE e o DRAGONBOARD 410c, que necessitaria da recompilação do KERNEL da DRAGONBOARD 410c, que não se fez por causa do curto tempo disponível.

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

Configuração Da DRAGONBOARD 410c (Python)
Configuração Da DRAGONBOARD 410c (Python)

Foi configurada para enviar ao Arduino DEVIDO os comandos para realizar a aquisição de dados e transmitir os dados obtidos. Segue o código abaixo.

Observação: Uma abordagem aplicada sem código, não funcionou devido aos níveis de tensão utilizados pelo Arduíno DUE e o Mezanino serem incompatíveis. Por isso optou-se pelo interfaceamento USB, que necessitaria da recompilação do KERNEL na DRAGONBOARD 410c para que uma porta fosse criada corretamente para uma comunicação.

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, paridade = serial. PARITY_NONE, stopbits = serial. STOPBITS_ONE, bytesize = serial. EIGHTBITS)

ser.isOpen ()

imprimir ('Digite seus comandos abaixo. / r / nInsira "sair" para sair do aplicativo.')

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 a coleta dos dados ser.write (1) # Envia o comando para o Arduino DUE transmitir os dados coletados

lista =

para i no intervalo (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)

Etapa 8: INTERPRETAÇÃO DOS ARQUIVOS DE AUDIO

INTERPRETAÇÃO DOS ARQUIVOS DE ÁUDIO
INTERPRETAÇÃO DOS ARQUIVOS DE ÁUDIO

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, fornecida 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 conversão foi 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 download.

Esse algoritmo não se faz necessário para o funcionamento do sistema, já que o Arduino DUE já enviar esses dados em um array de valores numéricos.

# codificação: utf-8

# Leitura e conversão dos áudios para csv

# MÓDULOS UTILIZADOS

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

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

def audio_to_csv (file_name): 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 (data_size-1) 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 (sinal), pd. DataFrame (Time)], axis = 1) df.to_csv (file_name + '.csv', index = False) return df

# CARREGANDO DATA FRAME 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) df_sem_vazamento.columns = 'amp' time]

# GRÁFICO DO ESPECTRO DE AUDIO

figura, (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 = {'fontsize': 20, 'fontweight': 'bold'}) ax1.set_xlabel ('Tempo [s]', fontdict = {'fontsize': 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 = {'fontsize': 16}) ax2.set_ylim ([- 4e8, 4e8]) figure.tight_layout (h_pad = 5) plt.show ()

Etapa 9: 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
Análise Visual Do Sinal

Com o PYTHON 3 é realizado uma transformação 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 como várias 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 pode identificar a existência de algum vazamento na tubulação. Estes gráficos servirão para validação das análises realizadas pelo algoritmo de detecção 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 intervalo de frequências.

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

importar pandas como pd importar numpy como np importar onda de matplotlib importar pyplot como plt # Função que realiza uma transformação de Fourier e plota os gráficos para análise de Fourier (df_list): Fs = 44100; # Taxa de amostragem em Hz Ts = 1,0 / Fs; # Intervalo de amostragem y = pd.concat (df_list) t = y ['tempo'] # 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 [intervalo (n // 2)] Y = np.fft.fft (y) / n Y = Y [intervalo (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 ('Tempo') ax [0].set_ylabel ('Amplitude') 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 o carregamento 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 se init * 44100> len (df) ou final * 44100> len (df): init = (len (df) / 44100) -delta se init = 100) & (df [' freq '] <= 800)] mx = classificado (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 maiores amplitudes:", np.mean (mx [-50:]) // df ['amp']. mean () * 100, "%", sep = "") print ("10 maiores amplitudes:", np.mean (mx [-10:]) // df ['amp']. mean () * 100, "%", sep = "") print ("Amplitude maior:", 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

Etapa 10: Algoritmo Em R Para Extração Das Características Dos Dados

Algoritmo Em R Para Extração Das Características Dos Dados
Algoritmo Em R Para Extração Das Características Dos Dados
Algoritmo Em R Para Extração Das Características Dos Dados
Algoritmo Em R Para Extração Das Características Dos Dados

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

Este primeiro algoritmo realiza uma extração identificada, onde é necessário saber se o arquivo de áudio trata-se de uma amostra vazamento detectado ou não, isso por que os dados fornecidos desse processo servirão para o treinamento da rede usar neural.

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

Estas características ou caraterísticas são propriedades acústicas compostas por várias informações referentes ao espectro de áudio capturado, abaixo seguirá uma descrição (em inglês) dessas características.

Este algoritmo faz parte de um projeto disponível no GitHub e pode ser acessado através deste link, o mesmo foi modificado para atender às especificações do projeto.

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

Características extraídas:

  • meanfreq: frequência média (em kHz)
  • sd: desvio padrão da frequência
  • mediana: frequência mediana (em kHz)
  • Q25: primeiro quantil (em kHz)
  • Q75: terceiro quantil (em kHz)
  • IQR: intervalo interquantil (em kHz)
  • skew: skewness (veja a nota na descrição specprop)
  • kurt: curtose (ver nota na descrição specprop)
  • sp.ent: entropia espectral
  • sfm: planura espectral
  • modo: modo de frequência
  • centróide: centróide de frequência (ver specprop)
  • picof: frequência de pico (frequência com maior energia)
  • meanfun: média da frequência fundamental medida através do sinal acústico
  • minfun: frequência fundamental mínima medida através do sinal acústico
  • maxfun: frequência fundamental máxima medida através do sinal acústico
  • meandom: média da frequência dominante medida através do sinal acústico
  • mindom: mínimo de frequência dominante medido através do sinal acústico
  • maxdom: máximo da frequência dominante medida através do sinal acústico
  • dfrange: faixa de frequência dominante medida através do sinal acústico
  • modindx: índice de modulação. Calculado como a diferença absoluta acumulada entre as medições adjacentes de frequências fundamentais divididas pela faixa de frequência
  • rótulo: vazamento ou sem vazamento

Algoritmo usado:

pacotes <- c ('tuneR', 'seewave', 'fftw', 'caTools', 'randomForest', 'warbleR', 'mice', 'e1071', 'rpart', 'xgboost', 'e1071') se (length (setdiff (packages, rownames (installed.packages ())))> 0) {install.packages (setdiff (packages, rownames (installed.packages ())))}

biblioteca (tuneR)

library (seewave) library (caTools) library (rpart) library (rpart.plot) library (randomForest) library (warbleR) library (mouse) library (xgboost) library (e1071)

specan3 <- function (X, bp = c (0, 22), wl = 2048, threshold = 5, parallel = 1) {# Para usar o processamento paralelo: biblioteca (devtools), install_github ('nathanvan / parallelsugar') if (class (X) == "data.frame") {if (all (c ("sound.files", "selec", "start", "end")% em% 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 stop (paste (paste (c ("sound.files", "selec", "start", "end") [! (c ("sound.files", "selec", "start", "end")% in% colnames (X))], collapse = ","), "coluna (s) não encontrada (s) no quadro de dados"))} else stop ("X não é um quadro de dados") #se houver NAs no início ou parada final if (any (is.na (c (final, início)))) stop ("NAs encontrados no início e / ou no fim") # se o final ou início não forem paragens numéricas if (all (class (end)! = "numeric" & class (start)! = "numeric")) stop ("'end' e 'selec' devem ser numéricos") #if qualquer início maior que final stop if (any (end - start <0)) stop (paste ("O início é mais alto que o en d em ", comprimento (que (fim - início20)) parar (colar (comprimento (que (fim - início> 20))," seleção (ões) mais longa que 20 segundos ")) opções (show.error.mensagens = VERDADEIRO) #if bp não é vetor ou comprimento! = 2 stop if (! is.vector (bp)) stop ("'bp' deve ser um vetor numérico de comprimento 2") else {if (! comprimento (bp) == 2) stop ("'bp' deve ser um vetor numérico de comprimento 2")} #return aviso se nem todos os arquivos de som forem encontrados 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 (length (sound)). arquivos)) - comprimento (único (sound.files [(sound.files% in% fs)])), "arquivo (s).wav não encontrado (s)")) #contar número de arquivos de som no diretório de trabalho e se 0 parar d <- which (sound.files% in% fs) if (length (d) == 0) {stop ("Os arquivos.wav não estão no diretório de trabalho")} else {start <- start [d] end <- end [d] selec <- selec [d] sound.files <- sound.files [d]} # Se o paralelo não for numérico if (! is.numeric (parallel)) stop ("'paralelo' deve ser um vetor numérico de comprimento 1 ") if (qualquer (! (paralelo %% 1 == 0), paralelo 1) {options (warn = -1) if (all (Sys.info () [1] ==" Windows ", requireNamespace (" parallelsugar ", quietly = TRUE) == TRUE)) lapp <- função (X, FUN) parallelsugar:: mclapply (X, FUN, mc.cores = parallel) else if (Sys.info () [1] == "Windows") {cat ("Os usuários do Windows precisam instalar o pacote 'parallelsugar' para computação paralela (você não está fazendo isso agora!)") Lapp <- pbapply:: pblapply} else lapp <- function (X, FUN) parallel:: mclapply (X, FUN, mc.cores = parallel)} else lapp <- pbapply:: pblapply options (warn = 0) if (parallel == 1) cat ("Medindo parâmetros acústicos:") x <- as.data.frame (lapp (1: comprimento (início), função (i) {r <- tuneR:: readWave (arquivo.path (getwd (), sound.files ), de = início , para = fim , unidades = "segundos") b teto ([email protected]/2000) - 1) b [2] <- teto ([email protected]/2000) - 1 #frequency análise de espectro songpec <- seewave:: spec (r, f = [email protected], plot = FALSE) análise <- seewave:: specprop (songpec, f = [email protected], flim = c (0, 280/1000), plot = FALSE) #salvar parâmetros meanfreq <- análise $ média / 1000 dp <- análise $ sd / 1000 mediana <- análise $ mediana / 1000 Q25 < - análise $ QQ75 <- análise $ QIQR <- análise $ IQR / 1000 skew <- análise $ skewness kurt <- análise $ kurtosis sp.ent <- análise $ sh sfm <- análise $ sfm modo <- análise $ modo / 1000 centróide <- análise $ cent / 1000 #Frequência com picos de amplitude picof <- 0 # seewave:: fpeaks (songpec, f = [email protected], wl = wl, nmax = 3, plot = FALSE) [1, 1] # Parâmetros de frequência fundamental ff <- seewave:: fund (r, f = [email protected], ovlp = 50, threshold = threshold, 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 frequência dominantes y <- seewave:: dfreq (r, f = [email protected], wl = wl, ylim = c (0, 280/1000), ovlp = 0, plot = F, threshold = threshold, bandpass = b * 1000, fftw = TRUE) [, 2] meandom <- mean (y, na.rm = TRUE) mindom <- min (y, na.rm = TRUE) maxdom <- max (y, na.rm = VERDADEIRO) dfrange <- (maxdom - mindom) duração <- (fim - início ) # mudanças de cálculo do índice de modulação <- vetor () para (j em que (! é. na (y))) {alterar <- abs (y [j] - y [j + 1]) alterações <- anexar (alterações, alterar)} if (mindom == maxdom) modindx <-0 else modindx <- média (alterações, na.rm = T) / dfrange #save retorno de resultados (c (duração, médiafreq, sd, mediana, Q25, Q75, IQR, inclinação, kurt, sp.ent, sfm, modo, centróide, picof, médiafun, minfun, maxfun, meandom, mindom, maxdom, dfrange, modindx))})) #change result names rownames (x) <- c ("duration", "meanfreq", "sd", "median", "Q25", "Q75", "IQR", "skew", "kurt", "sp.ent", "sfm", "mode", "centroid", "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 ("sound.files", "selec") rownames (x) <- c (1: nrow (x)) return (x)}

processFolder <- function (folderName) {# Comece com data.frame vazio. data <- data.frame () # Obtém a lista de arquivos na pasta. list <- list.files (folderName, '\. wav') # Adiciona a lista de arquivos a data.frame para processamento. for (fileName in list) {row <- data.frame (fileName, 0, 0, 20) data <- rbind (data, row)} # Defina os nomes das colunas. nomes (dados) <- c ('sound.files', 'selec', 'start', 'end') # Mover para a pasta para processamento. setwd (folderName) # Processar arquivos. acústica <- specan3 (dados, paralelo = 1) # Volte para a pasta pai. setwd ('..') acústica}

gender <- function (filePath) {if (! exists ('genderBoosted')) {load ('model.bin')} # Caminhos de configuração. currentPath <- getwd () fileName <- basename (filePath) path <- dirname (filePath) # Define o diretório para ler o arquivo. setwd (path) # Comece com data.frame vazio. data <- data.frame (fileName, 0, 0, 20) # Define os nomes das colunas. nomes (dados) <- c ('sound.files', 'selec', 'start', 'end') # Processar arquivos. acústica <- specan3 (dados, paralelo = 1) # Caminho de restauração. setwd (currentPath) predict (genderCombo, newdata = acoustics)}

# Carregar dados

vazamento <- pasta de processo ('caminho para o macarrão com samples de áudio com vazamento') without_leakage <- pasta de processo ('caminho para o macarrão com samples de áudio sem vazamento')

# Definir rótulos.

vazamento $ rótulo <- 1 sem vazamento $ rótulo <- 2 dados <- rbind (vazamento, sem vazamento) dados $ rótulo <- fator (dados $ rótulo, rótulos = c ('vazamento', 'sem vazamento'))

# Remova as colunas não utilizadas.

data $ duration <- NULL data $ sound.files <- NULL data $ selec <- NULL data $ peakf <- NULL

# Remova as linhas contendo NA's.

data <- data [complete.cases (data),]

# Escreva o conjunto de dados csv.

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

Etapa 11: Rede Neural

Rede Neural
Rede Neural

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

A rede neural utilizada é do tipo MLP (Multilayer Perceptron), este modelo é treinado com dados obtidos e após esse treinamento o modelo implantado no sistema conseguirá realizar a identificação automática do sinal de recompensa, informando se determinado ponto um vazamento ou não.

Foi necessário realizar uma filtragem dos dados de entrada, pois algumas características estavam diminuindo a taxa de acerto da rede ao melhorar-la. Não foi realizada nenhuma avaliação estatística 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 obtido 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 é utilizado para treinar o modelo da rede e retornar um taxa de acerto do mesmo. Nenhum sistema de detecção de algoritmo um pouco diferente seria usado, pois ele realizaria o treino ou receberia um modelo já treinado da nuvem ou de alguma fonte e com esse modelo realizaria como predições para cada leitura realizada.

# codificação: 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 classificação_reportar como cr de sklearn.metrics importar confusão_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 (alfa = 0,0001, learning_rate_init = 0,0001, hidden_layer_sizes = (50, 50, 50, 50), max_iter = 10000, ativação = 'tanh', solver = 'lbfgs')

# Treinando modelo

modelo.fit (X_train, Y_train) result = 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 (relatório)

Recomendado: