Identificando pessoas através da voz

Testing my system. Imagem pertence a dvsgamming

O uso de sistemas de biometria para segurança está cada vez mais presente e utilizada no nosso dia a dia, entretanto essa autenticação tem que ser mais segura e transparente para o usuário. A interação com o sistema tende a ser cada vez mais natural e humano, de modo que usuários leigos possam se comunicar com o mínimo de esforço possível.

Cada identificador tem suas vantagens e desvantagens, como pode ser lido nesse artigo.

O artigo não contará com todos os códigos prontos, mas o mesmo se encontra no github para estudo. Todos os códigos desse artigo também poderão ser reproduzidos a partir de um laço.

Qual o problema?

Suponha que a privacidade de seu quarto é super importante para você e que a todo custo você queira mantê-lo trancado e só destrancar em sua presença. Para aumentar a segurança, você deseja que a porta só se abra após o reconhecimento de sua voz e com aquela palavra específica.

Cena de Os incríveis 1, pertence a: Walt Disney

Afinal, o que é a voz?

Sabemos que a voz humana é imitável, pelo menos para os nossos ouvidos, porém nosso ouvido não consegue ouvir todas as frequências e tem a péssima mania de associar ao próximo o suficiente, ou seja, se a voz for minimamente parecida com alguma que já conhecemos começamos a ouvi-la mais parecido com a nossa memória.

A voz é uma vibração que só se propaga em meios materiais (sólidos, líquidos ou gases), é um sinal contínuo que varia em função do tempo. Esse sinal antes analógico é convertido e/ou comprimido em digital através da captura por um microfone.

Am I a joke to you ?

Sinal digital

É um sinal mais eficiente por permitir compactação, porém só pode assumir um número pré-determinado de valores discretos, ou seja, danifica o valor do sinal pelo fato de uns e zeros não representarem fielmente o sinal original (analógico).

Miau em sinal digital. Mentira, imagem retirada do Wikipédia

Técnica

Para trabalhar com sons há diversas técnicas e diversos estudos a respeito na área, nossa abordagem será mais tradicional e eficiente. Nós iremos tratar o som como imagens, sim… isso mesmo, mas como ? Para isso alguns conceitos para facilitar o entendimento.

Thank you, next

Transformada de Fourier

A transformada de Fourier é uma técnica para a análise de frequência em uma distribuição de sinal, ou seja, resulta nas frequências decompostas a partir do tempo. A transformação tem como consequência a perda da informação relativa ao tempo, porém há técnicas para resolver esse problema, são algoritmos que operam em seguimentos curtos do sinal, permitindo a localização das frequências no tempo. Para o STFT (Short-time Fourier Transform), a analise do sinal é baseado em janelas deslizantes de tempo curto, ou seja, mostra características de frequência do sinal.

Imagem pertencente à nti-audio

Espectrograma

O espectrograma fornece informações sobre a energia do sinal em relação ao tempo e a frequência. É uma ferramenta capaz de extrair diversos atributos e características do som, formado a partir do cálculo de STFT aplicado ao sinal digital do som.

O espectrograma é a representação gráfica do processamento anterior aplicado ao sinal.

Espectrograma pertencente à librosa

Desenvolvimento

Para facilitar nosso desenvolvimento vamos utilizar as seguintes bibliotecas na linguagem Python 3.6:

Para o desenvolvimento da solução será necessário programarmos alguns módulos, que serão explicados unitariamente.

Captura do áudio

Para a captura e posteriormente classificação do áudio, será necessário obter o áudio proveniente de algum microfone no seu dispositivo. Para essa tarefa, criei uma biblioteca que nos permite gravar áudio de acordo com algumas configurações que iremos falar em breve.

Para que ele consiga baixar as dependências em seu ambiente, primeiro atualize seu pip. Após isso instale a biblioteca:

pip install loop-listen

Para utilizar é simples. Basta importar a biblioteca, colocar dentro de um laço a quantidade de áudios a serem gravados, dar um nome às gravações, decidir a abertura do microfone e a duração de cada gravação.

Se você precisar ajustar alguns parâmetros, aqui está o construtor da classe, mude o que precisar.

Cada gravação é salva no diretório:

./output/audio/

O ideal é que você grave uma grande quantidade de áudios com alguns ruídos de fundo. Nesse exemplo vou gravar cerca de 32.

Processamento do áudio

É a parte fundamental do problema, a configurações que iremos utilizar são:

  • Sample Rate de leitura: 22kHz
  • Duração do áudio: 2 segundos
  • Frequência Logarítmica
  • Sample Rate de processamento: 16kHz
  • STFT Window: 0,025
  • Hop Length: 40%
  • Número de bandas: 64
  • Aproveitamento central do áudio: 96%

Para isso, a biblioteca principal nessa parte é o Librosa para o carregar o áudio e o AudioProcessor para processar o áudio nas configurações citadas anteriormente.
O código abaixo mostra como será feito o processamento:

Você pode plotar a variável processed a partir da função plt.matshow()

A biblioteca AudioProcessor foi construída baseada no pré processamento da rede VGGish. Você é capaz de utilizá-la nesse exemplo sem maiores problemas.

Você irá aplicar esse processamento para todos os áudios que você gravou e os áudios retirados do dataset.

Combinação de dataset

Para que faça sentido a sua frase, iremos complementar nosso dataset com outro para que a rede aprenda exatamente qual a frase que você está falando. O dataset que iremos utilizar é o: Commom Voice, mas o que é esse conjunto de dados ?

Common Voice é uma base de dados com mais de 1400 horas de áudio gravadas e avaliados por pessoas reais, ou seja, é uma base robusta e possui um nível de confiança similar ao ImageNet. Todas as frases foram tiradas de textos de licenças abertas ou cedidas.

O que é necessário fazer nessa parte é baixar o dataset, fazer a conversão para o formato .wav e fazer o processamento que falamos anteriormente em uma quantidade similar ao que temos gravado.

Construção do Modelo

Agora que temos todos os passos acima cumpridos, precisamos dar vida ao nosso modelo. Ele será baseado em uma rede neural convolucional proposta por Yuma Sakashita e Masaki Aono.

.::Parâmetros::.
Total params: 1,829,446
Trainable params: 1,828,036
Non-trainable params: 1,410

Se você por acaso desejar fazer em outro framework, segue abaixo a representação das camadas.

Representação visual do modelo porposto por Sakashita e Aono

Após o treinamento, obtive os seguintes dados expressos em gráficos:

É possível visualizar que o modelo não chegou ao seu ápice e que sobre ajustou, mas para nosso experimento é o suficiente.

Separamos 30% dos dados para teste, de um total de 346, distribuídos em 314 áudios de vozes do Common Voice e 32 áudios da minha própria voz.

               precision    recall  f1-score   support

0 1.00 0.98 0.99 105
1 0.83 1.00 0.91 10

micro avg 0.98 0.98 0.98 115
macro avg 0.92 0.99 0.95 115
weighted avg 0.99 0.98 0.98 115

Conclusão

É possível com poucos dados distinguir vozes, ou seja, permite agora que você crie aplicações para dispositivos embarcados como raspberry, beaglebone ou até mesmo um arduino através de um servidor.

Eu entendo que a sua dúvida em relação à pré processamento para uma rede neural profunda, mas em termo de áudio há uma discordância grande em relação ao tipo de processamento que uma rede neural é capaz de fazer. Entre muitos artigos científicos, estão destacados o uso de pré processamento baseado em imagens, ou seja, espectrogramas.

Consideração final

Testei com mais 20 vozes de pessoas reais falando a mesma frase que eu, o resultado foi semelhante, ou seja, ele aprendeu a frase em si, bem como minha voz falando-a.



O código também disponível em: github.com/netoolii/person_by_voice

Se você achou esse artigo útil, bata palmas (ou muitas palmas, se você REALMENTE gostou!), para que outras pessoas também possam encontrar o artigo :-)
Qualquer dúvida, passa lá no meu
linkedin