Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
UNIVERSIDADE REGIONAL DE BLUMENAU
CENTRO DE CIÊNCIAS EXATAS E NATURAIS
CURSO DE CIÊNCIA DA COMPUTAÇÃO – BACHARELADO
PROTÓTIPO DE SOFTWARE DE RECONHECIMENTO DE
VOZ PARA NAVEGAÇÃO EM JOGOS, UTILIZANDO REDE
NEURAL ARTIFICIAL
DERLEI BRANCHER
BLUMENAU 2011
2011/1-13
DERLEI BRANCHER
PROTÓTIPO DE SOFTWARE DE RECONHECIMENTO DE
VOZ PARA NAVEGAÇÃO EM JOGOS, UTILIZANDO REDE
NEURAL ARTIFICIAL
Trabalho de Conclusão de Curso submetido à Universidade Regional de Blumenau para a obtenção dos créditos na disciplina Trabalho de Conclusão de Curso II do curso de Ciência da Computação — Bacharelado.
Prof. Jacques Robert Heckmann, Mestre - Orientador
BLUMENAU 2011
2011/1-13
PROTÓTIPO DE SOFTWARE DE RECONHECIMENTO DE
VOZ PARA NAVEGAÇÃO EM JOGOS, UTILIZANDO REDE
NEURAL ARTIFICIAL
Por
DERLEI BRANCHER
Trabalho aprovado para obtenção dos créditos na disciplina de Trabalho de Conclusão de Curso II, pela banca examinadora formada por:
______________________________________________________ Presidente: Prof. Jacques Robert Heckmann, Mestre – Orientador, FURB
______________________________________________________ Membro: Prof. Mauro Marcelo Mattos, Doutor – FURB
______________________________________________________ Membro: Prof. Marcel Hugo, Mestre – FURB
Blumenau, 30 de junho de 2011
Dedico este trabalho a todos os amigos, professores e familiares que contribuíram diretamente para realização deste, através de conselhos, apoio, conhecimento compartilhado, etc.
AGRADECIMENTOS
Em primeiro lugar, gostaria de agradecer à minha família por estarem sempre presentes
em minha caminhada, aconselhando, apoiando e incentivando na realização deste curso, pois
sem eles não teria chegado até aqui.
A Deus, pela força conferida nos momentos difíceis.
Aos amigos, que conheci antes e durante o percurso do curso, nos momentos de
dificuldades e alegrias que passamos juntos, meus agradecimentos.
À minha namorada, Carolina B. Laurentino, pelo apoio e conselhos nas horas difíceis.
Aos magníficos professores do curso, pela dedicação, apoio conferido e conhecimento
compartilhado durante esta fase.
Ao coordenador do curso, José Roque Voltolini da Silva, pela paciência de sempre
estar disponível para conversar e ajudar, encorajado sempre a continuar e nunca desistir dos
meus objetivos.
Em especial ao professor Marcel Hugo, pela disponibilidade, paciência e colaboração
indispensável de informação referente à elaboração deste trabalho.
E ao professor Jacques Robert Heckmann, por ter me aceito como orientando, por toda
sua dedicação, tempo, paciência, ajuda e por ter acreditado sempre na conclusão deste
trabalho, aconselhando e encorajando a nunca desistir dos meus objetivos.
Se A é o sucesso, então A é igual a X mais Y mais Z. O trabalho é X; Y é o lazer; e Z é manter a boca fechada.
Albert Einstein
RESUMO
O trabalho apresenta a especificação e a implementação de um protótipo de software, capaz de reconhecer um subconjunto de comandos de voz para navegação de um jogo, no formato de labirinto 2D, utilizando rede de Kohonen. A navegação do jogo é realizada através de palavras faladas por um locutor, captadas por um microfone e tratadas. O tratamento destes dados realizou-se através das médias. Na etapa seguinte, esses são submetidos para a rede neural artificial para reconhecimento do comando. Isto é realizado para cada palavra falada e captada pelo microfone. Obteve-se uma taxa de acerto de 70% na utilização de até 6 comandos distintos captados pelo mesmo locutor.
Palavras-chave: Navegação de um jogo. Rede de Kohonen. Rede neural artificial.
ABSTRACT
This work presents the specification and implementation of a software prototype that can recognize a subset of voice commands for game navigation, in a 2D maze, using Kohonen network. The game navigation is accomplished through words spoken by a narrator, captured by a microphone and processed. The treatment of these data took place through the medium. In the next step, they are submitted to the artificial neural network to recognize the command. This is done for every word spoken and captured by the microphone. It was obtained a hit rate of 70% in the use of up to six different commands captured by the same speaker.
Key-words: Navigation of a game. Kohonen map. Artificial neural network.
LISTA DE ILUSTRAÇÕES
Figura 1 – Fases para obter-se o reconhecimento de voz ......................................................... 17
Figura 2 – Exemplo de amplitude e frequência ........................................................................ 18
Figura 3 – Exemplo de frequência do sinal alta e baixa ........................................................... 18
Figura 4 – Comparação entre uma TA alta e baixa .................................................................. 19
Figura 5 – Sinal analógico ........................................................................................................ 20
Figura 6 – Sinal analógico dividido em nove instantes de tempo iguais e contínuos, com os
pontos de interesse representados .......................................................................... 20
Figura 7 – Valores digitalizados do sinal analógico ................................................................. 20
Figura 8 – Reprodução do sinal digitalizado ............................................................................ 21
Figura 9 – Forma de onda contínua representada entre 0 a 255 ............................................... 22
Figura 10– Exemplo de palavras com tamanhos diferentes ..................................................... 23
Figura 11 – Exemplo de eliminação do ciclo negativo ............................................................ 24
Quadro 1 – Fórmula para taxa de redução ................................................................................ 25
Figura 12 – Exemplo de igualação de sinais em uma estrutura de 15 posições ....................... 26
Figura 13 – Exemplo de aplicação do sinal mediano sobre uma forma de onda ..................... 26
Quadro 2 – Fórmula para normalização do sinal ...................................................................... 26
Figura 14 – Exemplo de normalização do sinal X e Y ............................................................. 27
Figura 15 – Exemplo de construção hexagonal ........................................................................ 29
Figura 16 – Exemplo de mapa de Kohonen na forma bidimensional, onde todos os neurônios
da camada da saída estão amplamente conectados às entradas ............................. 30
Figura 17 – Neurônio artificial ................................................................................................. 31
Quadro 3 – Fórmula linear para taxa de aprendizagem ............................................................ 32
Figura 18 – Vizinhança contendo vários raios topológicos em torno de uma construção
topológica quadrada ............................................................................................... 33
Quadro 4 – Fórmula para o cálculo da distância euclidiana do neurônio artificial .................. 34
Quadro 5 – Cálculo referente ao exemplo de identificação do neurônio artificial ganhador ... 34
Quadro 6 – Fórmula para cálculo da adaptação dos pesos sinápticos dos neurônios artificiais
............................................................................................................................... 34
Quadro 7 – Cálculo referente ao exemplo de adaptação do neurônio artificial ganhador ........ 35
Quadro 8 – Fórmula de redução da taxa de aprendizagem no ajuste fino da RNA .................. 35
Quadro 9 – Fórmula para realizar o ajuste fino dos pesos sinápticos dos neurônios artificiais36
Figura 19 – Diagrama de casos de uso ..................................................................................... 42
Figura 20 – Diagrama de classes do pacote controle com suas respectivas relações ............... 44
Figura 21 – Diagrama de classes do pacote visão com suas respectivas relações .................... 46
Figura 22 – Diagrama de sequência representando os passos necessários para obter-se o
reconhecimento de voz .......................................................................................... 47
Figura 23 – Diagrama de atividade para obter-se o reconhecimento de voz ............................ 48
Figura 24 – Formato do arquivo de entrada para recriação de uma RNA ................................ 48
Figura 25 – Tela principal ........................................................................................................ 54
Figura 26 – Tela log rede .......................................................................................................... 55
Figura 27 – Tela sobre .............................................................................................................. 55
Figura 28 – Armazenar áudio ................................................................................................... 56
Figura 29 – Tela criar rede ....................................................................................................... 57
Figura 30 – Tela parâmetros rede ............................................................................................. 57
Figura 31 – Tela treinar rede .................................................................................................... 57
Figura 32 – Tela testar rede ...................................................................................................... 58
Figura 33 – Tela mapa rede ...................................................................................................... 58
Figura 34 – Tela ajuste rede ..................................................................................................... 58
Figura 35 – Salvar rede ............................................................................................................. 59
Figura 36 – Recriar rede ........................................................................................................... 59
Quadro 10 – Atalhos das opções dos menus ............................................................................ 59
Quadro 11 – Taxa de acerto obtida pela RNA ......................................................................... 60
Quadro 12 – Eficiência da RNA implementada no protótipo em relação aos dos trabalhos
correlatos ............................................................................................................... 60
Quadro 13 – Características do protótipo implementado e dos trabalhos correlatos ............... 61
Quadro 14 – Caso de uso 01, criar rede .................................................................................... 66
Quadro 15 – Caso de uso 02, visualizar parâmetros da rede .................................................... 66
Quadro 16 – Caso de uso 03, treinar rede ................................................................................ 66
Quadro 17 – Caso de uso 04, testar rede .................................................................................. 67
Quadro 18 – Caso de uso 05, visualizar mapa da rede ............................................................. 67
Quadro 19 – Caso de uso 06, ajustar rede ................................................................................ 67
Quadro 20 – Caso de uso 07, visualizar log da rede ................................................................ 67
Quadro 21 – Caso de uso 08, salvar rede ................................................................................. 68
Quadro 22 – Caso de uso 09, recriar rede ................................................................................ 68
Quadro 23 – Caso de uso 10, reproduzir áudio ........................................................................ 68
Quadro 24 – Caso de uso 11, suspender áudio ......................................................................... 68
Quadro 25 – Caso de uso 12, reproduzir áudio ........................................................................ 68
Quadro 26 – Caso de uso 13, armazenar áudio ........................................................................ 69
Quadro 27 – Caso de uso 14, visualizar sobre .......................................................................... 69
Quadro 28 – Código classe busca de sinais .............................................................................. 73
Quadro 29 – Código classe pré-processamento ........................................................................ 77
Quadro 30 – Código classe Kohonen ....................................................................................... 81
Quadro 31 – Código classe neurônio ........................................................................................ 83
Quadro 32 – Código classe labirinto ........................................................................................ 87
LISTA DE SIGLAS
API – Application Programming Interface
ENIAC – Eletronic Numerical Integrator And Calculator
FURB – Fundação Universidade Regional de Blumenau
Hz – Hertz
IA – Inteligência Artificial
LVQ – Learning Vector Quantization
OO – Orientação a Objeto
OpenGL – Open Graphics Library
RF – Requisito Funcional
RNA – Rede Neural Artificial
RNF – Requisito Não-Funcional
SOM – Self-Organizing Map
TA – Taxa de Amostragem
TRF – Transformada Rápida de Fourier
UC – Casos de uso
UML – Unified Modeling Language
SUMÁRIO
1 INTRODUÇÃO .................................................................................................................. 14
1.1 OBJETIVOS DO TRABALHO ........................................................................................ 14
1.2 ESTRUTURA DO TRABALHO ...................................................................................... 15
2 FUNDAMENTAÇÃO TEÓRICA .................................................................................... 16
2.1 RECONHECIMENTO DE VOZ ...................................................................................... 16
2.2 BUSCA DE SINAIS.......................................................................................................... 17
2.2.1 Características das Ondas Sonoras .................................................................................. 18
2.2.2 Taxa de amostragem ....................................................................................................... 19
2.2.3 Quantização ..................................................................................................................... 19
2.2.4 Número de canais ............................................................................................................ 21
2.2.5 Representação dos sinais digitalizados ........................................................................... 21
2.2.6 Detecção do silêncio ....................................................................................................... 22
2.3 PRÉ-PROCESSAMENTO ................................................................................................ 22
2.3.1 Etapas envolvidas no pré-processamento........................................................................ 23
2.3.2 Sinal amostrado ............................................................................................................... 23
2.3.3 Eliminação do ciclo negativo .......................................................................................... 24
2.3.4 Sinal reduzido ................................................................................................................. 24
2.3.5 Forma de onda através de médias ................................................................................... 25
2.3.6 Sinal mediado .................................................................................................................. 25
2.3.7 Normalização do sinal ..................................................................................................... 26
2.4 PROCESSAMENTO ......................................................................................................... 27
2.4.1 Inteligência artificial ....................................................................................................... 27
2.4.2 Rede neural artificial ....................................................................................................... 28
2.4.3 Rede de Kohonen ............................................................................................................ 29
2.4.3.1 Construção topológica .................................................................................................. 29
2.4.3.2 O neurônio artificial ...................................................................................................... 30
2.4.3.3 Iterações ........................................................................................................................ 31
2.4.3.4 Taxa de aprendizagem .................................................................................................. 32
2.4.3.5 Vizinhança .................................................................................................................... 32
2.4.3.6 Rotulação dos neurônios artificiais ganhadores ........................................................... 33
2.4.3.7 Identificação do neurônio artificial ganhador ............................................................... 33
2.4.3.8 Adaptação dos neurônios artificiais .............................................................................. 34
2.4.3.9 Ajuste fino da rede ........................................................................................................ 35
2.4.3.10 Funcionamento da rede .......................................................................................... 36
2.5 TRABALHOS CORRELATOS ........................................................................................ 38
2.5.1 Uma interface de reconhecimento de voz para o sistema de gerenciamento de central de
informação de fretes ........................................................................................................ 38
2.5.2 Reconhecimento de voz dependente de locutor utilizando redes neurais artificiais ....... 39
2.5.3 Protótipo para o reconhecimento de palavras através da fala ......................................... 40
3 DESENVOLVIMENTO DO PROTÓTIPO .................................................................... 41
3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO ....................... 41
3.2 ESPECIFICAÇÃO ............................................................................................................ 41
3.2.1 Diagrama de casos de uso ............................................................................................... 42
3.2.2 Diagramas de classes ...................................................................................................... 43
3.2.3 Diagrama de sequência ................................................................................................... 46
3.2.4 Diagrama de atividade .................................................................................................... 47
3.2.5 Formato do arquivo de entrada para recriação de uma RNA .......................................... 48
3.3 IMPLEMENTAÇÃO ........................................................................................................ 49
3.3.1 Técnicas e ferramentas utilizadas.................................................................................... 50
3.3.2 Classe BuscaDeSinais .............................................................................................. 50
3.3.3 Classe PreProcessamento ....................................................................................... 51
3.3.4 Classe Kohonen ............................................................................................................ 52
3.3.5 Classe Neuronio .......................................................................................................... 53
3.3.6 Classe Labirinto ........................................................................................................ 53
3.3.7 Operacionalidade da implementação .............................................................................. 54
3.4 RESULTADOS E DISCUSSÃO ...................................................................................... 60
4 CONCLUSÕES .................................................................................................................. 62
4.1 EXTENSÕES .................................................................................................................... 62
REFERÊNCIAS BIBLIOGRÁFICAS ................................................................................. 64
APÊNDICE A – Cenários dos UC apresentados na especificação do protótipo .............. 66
APÊNDICE B – Código das classes relevantes ao foco do protótipo implementado ....... 70
14
1 INTRODUÇÃO
Desde o surgimento do primeiro computador eletrônico reconhecido pela história em
1946, o Eletronic Numerical Integrator And Calculator (ENIAC), que tinha por propósito
efetuar cálculos eletronicamente em milissegundos, realizando assim tarefas árduas para a
época, o computador vem sendo aperfeiçoando a cada dia que passa, tornando-se um
equipamento rotineiro ao cotidiano, o que no passado era um sonho inacessível (TAFNER;
XEREZ; RODRIGUES FILHO, 1995, p. 48-49).
A utilização do computador não ficou restrita a cálculos. Atualmente ele é utilizado
para diversos objetivos distintos, como por exemplo, a utilização na comunicação, diversão,
automação e controle de recursos variados, através de uma programação realizada para a
interpretação e execução destes processos. Nesta evolução, a computação vem estudando há
alguns anos técnicas para tornar o computador “inteligente”, dando origem à área denominada
Inteligência Artificial (IA).
Classificada como subárea da IA, as Redes Neurais Artificiais (RNA) definem técnicas
que simulam os neurônios biológicos, com o objetivo de fazer com que as aplicações
computacionais possam adquirir e aplicar conhecimento (STARKE, 1996, p. 10).
Diante de tal evolução, começaram a surgir no mercado diversas aplicações que
incorporavam técnicas de RNA para reconhecimento de padrões, sendo um deles a voz
(LOESCH; SARI, 1996, p. 5). Porém, para torná-las aptas para uso, demandam um esforço
considerável na fase de treinamento da RNA (STARKE, 1996, p. 8).
Considerando o que foi dito anteriormente, pretendeu-se neste trabalho pesquisar e
estudar técnicas existentes dentro de RNA voltadas para reconhecimento de voz, pré-
processamento dos sinais captados, com objetivo de encontrar uma solução de modelagem
adequada para sua construção, obtendo-se por fim o reconhecimento de voz, de uma forma
mais rápida e eficiente.
1.1 OBJETIVOS DO TRABALHO
O objetivo geral deste trabalho é desenvolver um protótipo de software para
reconhecimento de voz restrito a um conjunto de palavras que, por sua vez, servirão como
15
comandos para navegação em um jogo, como forma de demonstrar os resultados obtidos.
Os objetivos específicos do trabalho são:
a) implementar uma RNA capaz de reconhecer um subconjunto de comandos para
navegação em jogos;
b) criar um sistema de tratamento de sinal de áudio, responsável por capturar a voz do
operador do jogo e transformá-la em informação de entrada para RNA;
c) construir um estudo de caso demonstrando a aplicação da RNA para navegação em
um jogo na forma de um labirinto 2D;
d) detalhar os resultados da RNA proveniente da solução do problema;
e) comparar o desempenho da RNA implementada com as dos trabalhos correlatos
pesquisados.
1.2 ESTRUTURA DO TRABALHO
No capítulo dois é descrita a fundamentação teórica estudada para o desenvolvimento
do trabalho. São abordados temas como reconhecimento de voz, busca de sinais, pré-
processamento e processamento. Por último, são apresentados três trabalhos correlatos.
No capítulo três são descritas as etapas realizadas para o desenvolvimento do
protótipo, detalhando os requisitos, a especificação, a implementação e a operacionalidade do
protótipo. São apresentados também os resultados encontrados com a finalização do trabalho.
Por fim, o capítulo quatro traz a conclusão deste trabalho bem como sugestões para
extensões futuras.
16
2 FUNDAMENTAÇÃO TEÓRICA
As seções seguintes foram organizadas de forma a apresentar as etapas necessárias
para auxiliar no desenvolvimento do protótipo. Assim sendo na seção 2.1 é apresentado o
conceito, o objetivo, as abordagens e as fases necessárias para obter-se o reconhecimento de
voz. Na seção 2.2 é apresentado as características, o comportamento do som para realizar a
busca de sinais. Na seção 2.3 é apresentado o conceito e as etapas necessárias para realização
do pré-processamento do sinal digitalizado. Na seção 2.4 é apresentado o conceito e as
características para realização do processamento dos sinais digitalizados. Por fim, na seção
2.5, são descritos três trabalhos correlatos ao trabalho proposto, que foram de grande valia no
desenvolvimento do presente trabalho.
2.1 RECONHECIMENTO DE VOZ
A manifestação da atividade mental mais comum do ser humano é através da fala. É
caracterizada como o meio mais rico para comunicação entre as pessoas, mas não tão comum
entre o homem e o computador (SAVADOVSKY, 1988, p. 1).
O reconhecimento de voz tem por objetivo induzir que a comunicação entre o homem
e o computador seja semelhante à comunicação realizada entre as pessoas. Pode-se realizar
esta comunicação das seguintes formas: de maneira escrita, que consiste no reconhecimento
de caracteres, figuras ou desenhos e um processamento de linguagem; ou de maneira oral,
definido por sinais sonoros como a fala ou outro tipo de som (STARKE, 1996, p. 8).
Para fazer utilização do recurso de reconhecimento de voz, podem-se utilizar duas
abordagens: o método global e o método analítico. No método global (ou reconhecimento de
palavras) utilizam-se técnicas de reconhecimento de forma, comparando-as globalmente com
as diversas formas de referência armazenadas. É considerada insuficiente quando faz-se uso
de grandes vocabulários (ou fala contínua). O método analítico, por sua vez, consiste na
segmentação da fala em constituintes elementares (fonemas, meias-sílabas e sílabas). Após
este processo, para reconstrução da fala basta levar em conta os aspectos léxicos, sintáticos e
semânticos em etapas sucessivas (HUGO, 1995).
Starke (1996, p. 9-10) descreve que há quatro fases separadas para obter-se o
17
reconhecimento de voz (Figura 1):
a) busca de sinais: que consiste em capturar o som do meio externo, dito sinal
analógico, que deverá ser transformado em informações (sinais digitais), que por
sua vez, serão processadas pelo computador;
b) pré-processamento: é uma forma de pré-processar os sinais digitalizados que serão
processados, objetivando a otimização deste processo e garantir maior sucesso na
fase seguinte;
c) processamento: nesta fase utilizam-se sinais digitalizados pré-processados a fim de
que reconheça-se as palavras. Nesta fase normalmente utiliza-se técnicas de RNA.
É considerada a mais demorada das fases, pois além de organizar os padrões
apresentados, aperfeiçoa-se a estrutura da RNA, tornando-se possível de distinções
futuras de padrões similares;
d) verificação de resultados: compara-se a saída produzida pela fase de
processamento e a saída desejada, verificando-se se o resultado obtido foi
equivalente ao resultado desejado.
Fonte: Hugo (1995).
Figura 1 – Fases para obter-se o reconhecimento de voz
2.2 BUSCA DE SINAIS
Bruns (1995, p. 12) descreve que para compreender-se o que acontece quando uma
pessoa ouve um som, é necessário conhecer seu comportamento, bem como seus conceitos e
características. A seguir, na seção 2.2.1, são descritas as características das ondas sonoras. Na
seção 2.2.2, descreve-se sobre a taxa de amostragem. Na seção 2.2.3, é descrito sobre a
18
quantização. Na seção 2.2.4, é descrito sobre o número de canais. Na seção 2.2.5, é descrito
sobre a representação dos sinais digitalizados. Por fim, na seção 2.2.6, é descrito sobre a
detecção do silêncio.
2.2.1 Características das Ondas Sonoras
Um dos elementos que caracterizam uma onda sonora é a sua amplitude, que é obtida
pelo maior ponto ao longo da sua curvatura em cada instante de tempo (Figura 2). Quanto
maior for esta amplitude, maior será a intensidade do volume existente naquele instante de
tempo. O nível de volume é medido por uma unidade logarítmica chamada Decibéis
(BRUNS, 1995, p. 13).
Fonte: adaptado de Tafner (1996).
Figura 2 – Exemplo de amplitude e frequência
Outro elemento a ser destacado é a frequência da onda. Ela é determinada pelo número
de vezes que a onda se repete durante certo instante de tempo (Figura 2). Quanto maior a
frequência do sinal, mais agudo será o som, do contrario será mais grave (Figura 3). A
frequência é medida por uma unidade chamada Hertz (Hz) (BRUNS, 1995, p. 14).
Fonte: Tafner (1996).
Figura 3 – Exemplo de frequência do sinal alta e baixa
19
2.2.2 Taxa de amostragem
A Taxa de Amostragem (TA) é um parâmetro importante quando refere-se à qualidade
do som a ser digitalizado. Seu valor equivale à quantidade de pontos digitalizados do sinal
analógico por segundo. Quanto maior a TA, maior será a fidelidade com que o som
digitalizado terá em relação ao som analógico, ou seja, menor perda de informação (Figura 4).
Para atender os limites da audição humana, essa TA não necessita exceder os 44.100 Hz, de
acordo com os critérios estabelecidos por Nyquist (MACHADO, 2001).
Fonte: Bruns (1995, p. 17).
Figura 4 – Comparação entre uma TA alta e baixa
Bruns (1995, p. 18) descreve que os critérios estabelecidos por Nyquist, sugerem a
escolha de uma TA que seja duas vezes a frequência de maior valor encontrada na onda de
som.
Cabe salientar que, antes de fazer a digitalização do som analógico, deverá ocorrer
uma divisão de tempo em intervalos iguais e constantes, para que haja representatividade dos
pontos de interesse (BRUNS, 1995, p. 17).
2.2.3 Quantização
Ela representa quantos bits são necessários para representar cada ponto de interesse da
TA do som a ser digitalizado. A quantização é mais importante que a TA, para que mantenha-
se a fidelidade do som digitalizado em relação ao som analógico (MACHADO, 2001).
Machado (2001) exemplifica a importância da quantização na digitalização do som da
seguinte forma. Considerando um simples sinal analógico (Figura 5), dividido em nove
20
instantes de tempo iguais e contínuos, cujo pontos de interesse estão representados na Figura
6. Se for adotada uma quantização de 2 bits, ou seja, 4 valores possíveis para cada ponto de
interesse da TA, obtém-se os valores (Figura 7) digitalizados do sinal analógico (Figura 6). A
Figura 8 representa a reprodução do sinal digitalizado pela Figura 5. Comparando a Figura 8
em relação à Figura 5, percebe-se que não há nenhuma semelhança entre o sinal analógico e o
sinal digitalizado, devido à digitalização ocorrer utilizando um baixo valor de quantização.
Desta forma, o aumento da TA pouco contribuiria para melhora da fidelidade do sinal
digitalizado. Porém um aumento da quantização melhoraria significativamente o sinal
digitalizado para este exemplo.
Fonte: Machado (2001).
Figura 5 – Sinal analógico
Fonte: Machado (2001).
Figura 6 – Sinal analógico dividido em nove instantes de tempo iguais e contínuos, com os pontos de interesse representados
Fonte: Machado (2001).
Figura 7 – Valores digitalizados do sinal analógico
21
Fonte: Machado (2001).
Figura 8 – Reprodução do sinal digitalizado
Deve-se salientar que a partir de um determinado valor de quantização, ter-se-ia,
também de aumentar a TA segundo o que define Nyquist. Resumidamente, a quantização
sozinha não garante qualidade da digitalização do sinal (MACHADO, 2001).
2.2.4 Número de canais
Normalmente na digitalização do som pode-se escolher entres as opções de um ou dois
canais de áudio. Um canal refere-se ao som monofônico e dois canais referem-se ao som
estereofônico. Dependendo do tipo de recursos de hardware utilizado para realizar a
digitalização, poderão existir mais opções de canais disponíveis para serem utilizadas. A
escolha de um número maior de canais influencia somente em uma possível alteração na
forma de onda de cada um deles de forma independente quando necessário, para que se possa
representar um maior envolvimento sonoro para quem ouve. Porém, a utilização de mais
canais desnecessariamente, só aumentaria a quantidade de informações a serem digitalizadas
(MACHADO, 2001).
2.2.5 Representação dos sinais digitalizados
Os sinais digitalizados obtidos são na realidade, diversos pontos de amplitudes
valorados em determinado espaço de tempo, armazenados em um vetor de bytes. Estes
valores normalmente são inteiros e quantizados utilizando 256 variações possíveis, ficando
entre um limite inferior e superior representado por 0 a 255 (Figura 9), ou em outros casos por
-128 a 127 (BRUNS, 1995, p. 18).
22
Fonte: adaptado de Tafner (1996).
Figura 9 – Forma de onda contínua representada entre 0 a 255
2.2.6 Detecção do silêncio
Quando ocorre a busca por sinais, pode-se encontrar espaços de tempo que
representem ruídos ou silêncios, irrelevantes para uso neste tipo de aplicação, podendo ser
desprezados. Sendo de conhecimento que os sinais digitalizados são representados dentro de
uma faixa de valores, com limite inferior e superior, seria possível determinar uma região
média de valores dentro desta faixa, para representar a baixa amplitude do sinal captado,
significando ter detectado ruído ou silêncio em um instante de tempo pré-definido para
caracterizar tal operação (BRUNS, 1995, p. 19).
2.3 PRÉ-PROCESSAMENTO
O pré-processamento é a etapa responsável por refinar os sinais digitalizados na etapa
de busca de sinais a serem processados pela RNA na fase seguinte, de forma a garantir um
maior sucesso na operação e otimização (BRUNS, 1995, p. 22).
Tafner (1996) descreve que esta fase é necessária por três motivos:
a) identificar os sinais digitalizados mais significativos;
b) diminuir a quantidade de sinais para submissão na RNA;
c) melhorar a representação do sinal digitalizado em relação ao sinal analógico.
A seguir na seção 2.3.1, descrevem-se as etapas envolvidas no pré-processamento. Na
seção 2.3.2, é descrito sobre o sinal amostrado. Na seção 2.3.3, é descrito sobre a eliminação
do ciclo negativo. Na seção 2.3.4, é descrito sobre o sinal reduzido. Na seção 2.3.5, é descrito
23
sobre a forma de onda através de médias. Na seção 2.3.6, é descrito sobre o sinal mediado.
Por fim, na seção 2.3.7, é descrito sobre a normalização do sinal.
2.3.1 Etapas envolvidas no pré-processamento
Tafner (1996) propõe quatro etapas para realizar o pré-processamento dos sinais
digitalizados obtidos na fase de busca de sinais:
a) eliminação do ciclo negativo do sinal digitalizado;
b) redução do sinal digitalizado detectando a forma de onda;
c) mediação do sinal reduzido;
d) normalização do sinal reduzido.
2.3.2 Sinal amostrado
O sinal digitalizado, agora referenciado como sinal amostrado, é mantido dentro do
computador através de uma série de números. Adotando uma taxa de amostragem de 8.000
Hz, com apenas 1 segundo de digitalização, haverão sido digitalizados 8.000 valores,
representando assim o sinal analógico digitalizado. Importante salientar que o tamanho do
vetor, ou valores digitalizados, não é fixo e variam conforme o tempo que a digitalização
perdurar (Figura 10) (TAFNER, 1996).
Fonte: Tafner (1996).
Figura 10– Exemplo de palavras com tamanhos diferentes
24
2.3.3 Eliminação do ciclo negativo
Esta etapa visa eliminar todos os valores do sinal amostrado abaixo da linha do
silêncio, sem perturbar a ordem dos sinais (ou vetor) e a eliminação dos mesmos.
Resumidamente, basta atribuir o valor 128 para os valores abaixo da linha do silêncio, nas
representações utilizando faixa de valores entre 0 a 255. Nas representações utilizando faixa
de valores entre -128 a 127, deverá ser atribuído valor 0 para os valores abaixo da linha do
silêncio. Um exemplo visual resultante deste processo pode ser visualizado na Figura 11
(TAFNER, 1996).
Fonte: adaptado de Tafner (1996).
Figura 11 – Exemplo de eliminação do ciclo negativo
2.3.4 Sinal reduzido
Esta etapa faz-se necessária pela quantidade de valores digitalizados para um simples
sinal analógico e a quantidade de entradas disponíveis na RNA para o processamento.
Relembrando o exemplo da seção 2.3.3 Sinal amostrado, no qual após 1 segundo de
digitalização foram gerados 8.000 valores por segundo para serem processados pela RNA,
devendo possuir para isso então 8.000 entradas, o que não seria viável. Isso ocorre por duas
questões: a primeira, pelo tempo de processamento exigido por uma RNA desta magnitude. A
segunda, mesmo com 8.000 entradas, não seria uma quantidade exata de entradas para todos
os tipos de sinais amostrados a serem apresentados para RNA, devido à variação do tempo
que cada uma delas leva para ser digitalizadas, tendo-se de criar e treinar uma nova RNA a
cada sinal amostrado, tornando-se impossível a realização do reconhecimento de voz, sobre
estes aspectos (TAFNER, 1996).
Sabendo-se então que somente uma forma de onda do sinal é necessária para o
processamento e o reconhecimento de voz, deve-se inicialmente calcular uma taxa de redução
(Quadro 1). A cada novo sinal amostrado, cria-se uma estrutura para armazenar os valores
25
desta forma de onda, levando em conta que a capacidade de armazenamento desta estrutura
deverá ser igual à quantidade de entradas da RNA utilizada para o processamento dos valores.
Escolhe-se um método para formar esta faixa de onda. Após isto, basta somente percorrer a
estrutura que armazena os sinais amostrados e a cada contabilização da taxa de redução,
calcular um novo valor com base no método de formação da faixa de onda escolhida, a ser
armazenada nesta nova estrutura criada (TAFNER, 1996).
qtdEntostratamSinalAmducaotaxa =Re
onde: taxaReducao = taxa de redução tamSinalAmostra = tamanho do sinal amostrado qtdEnt = quantidade de entradas da RNA
Quadro 1 – Fórmula para taxa de redução
2.3.5 Forma de onda através de médias
Uma forma simples de reduzir a quantidade de valores dos sinais amostrados, é através
de médias aritméticas, que são calculadas a cada contabilização da taxa de redução
especificada na seção anterior. Diante disto, deverá ser criada uma variável que fique
contabilizando a soma dos valores do sinal amostrado, até que se chegue a hora de realizar a
redução, dividindo a soma dos valores contabilizados pela taxa de redução. A variável de
somatório deverá ser zerada a cada redução, até o final do processo para contabilização dos
valores (BRUNS, 1995, p. 22).
2.3.6 Sinal mediado
Após a realização desta etapa que reduz o sinal para cerca de 33%, igualando 3 sinais
consecutivos pelo maior valor existente entre eles, reforçando assim a identidade da forma de
onda existente (Figura 12). Está redução deverá ocorrer sem perturbar a ordem da estrutura
original, nem a remoção de nenhuma posição, somente a alteração dos valores seguindo a
regra mencionada acima (TAFNER, 1996).
26
Fonte: Tafner (1996).
Figura 12 – Exemplo de igualação de sinais em uma estrutura de 15 posições
A Figura 13 representa uma forma de onda antes e depois da aplicação desta técnica.
Fonte: Tafner (1996).
Figura 13 – Exemplo de aplicação do sinal mediano sobre uma forma de onda
2.3.7 Normalização do sinal
Esta fase procura normalizar a intensidade do sinal gerada pela fala de uma mesma
palavra em diferentes alturas, porém com a mesma forma de onda. A fórmula para realizar
esta anulação de intensidade do sinal é conhecida como método matemático de normalização
(Quadro 2). Esta fórmula determina que cada valor da estrutura seja multiplicado pelo valor
da intensidade e dividido pelo maior valor encontrado dentro desta mesma estrutura
(TAFNER, 1996).
( ) ( )raValEstrutu
valIntentravalEstrututvalNormmax
*=
sendo: valNorm(t) = valor normalizado em um dado tempo t valEstrutura(t) = valor da estrutura que armazena a forma de onda em um dado tempo t valInten = valor da intensidade maxValEstrutura = maior valor encontrado dentro da estrutura
Quadro 2 – Fórmula para normalização do sinal
Para efeitos de exemplificar estes ajustes, será considerado o valor especifico de 150
27
para normalização da intensidade do sinal. Diante disto basta imaginar dois sinais, X e Y com
a mesma forma de onda, porém, com intensidades de sinais diferentes, sendo que os valores
assumidos para X={80, 90, 85, 70, 75} e Y={160, 180, 170, 140, 150} (Figura 14)
(TAFNER, 1996).
Fonte: Tafner (1996).
Figura 14 – Exemplo de normalização do sinal X e Y
2.4 PROCESSAMENTO
O processamento é a fase responsável por organizar os padrões submetidos em uma
estrutura específica, a fim de aperfeiçoá-los para futuras distinções de outros padrões
similares, para obter-se o reconhecimento de voz. A seguir na seção 2.4.1, é apresentado um
breve histórico sobre IA, bem como algumas definições. Na seção 2.4.2, é apresentada uma
breve contextualização sobre RNA e definições. Por fim, na seção 2.4.3, é apresentada as
características da rede de Kohonen.
2.4.1 Inteligência artificial
IA é uma das ciências mais recentes, cujas pesquisas começaram logo após a segunda
guerra mundial. Porém somente recebeu esta titulação em 1956. Atualmente abrange uma
variedade de subcampos, desde áreas de uso geral, percepção e aprendizado, até lógica em
jogos, reduzindo e automatizando tarefas intelectuais usualmente praticadas por humanos,
colocando-se como um campo universal (RUSSELL; NORVIG, 2004, p. 3).
28
IA pode ser definida, segundo Haykin (2001, p. 59), como desenvolvimento de
algoritmos para uso em computadores, para realização de operações ligadas ao conhecimento,
defendendo que os humanos fazem tal tarefa atualmente de maneira mais aperfeiçoada. Luger
(2004, p. 23) expõe a IA como um derivado da computação que compreende a automação do
comportamento inteligente. Tafner, Xerez e Rodrigues Filho (1995, p. 17) subentendem que
IA é um conjunto de técnicas de programação aplicado em determinados problemas, para
procurar assemelhar a solução dos mesmos como os homens o fariam.
2.4.2 Rede neural artificial
RNAs também são denotadas como sistemas neuromórficos, computadores biológicos,
neurocomputação, processamento paralelo distribuído e neuro-computadores (LOESCH;
SARI, 1996, p. 5). Procuram simular o funcionamento do sistema nervoso. Considerada
também como subárea de estudos da IA, as RNAs desde seu surgimento nos anos 1980, têm
sido aplicadas com sucesso na resolução de diversos problemas. Algumas aplicações voltadas
para controle de qualidade, previsão de preço de ações, reconhecimento de padrões (voz,
caracteres, face, manuscrito), escolha de rotas, entre outros. O conceito de RNA vem dos anos
1940, época em que não havia ainda computadores, deduzindo-se que as RNA são
independentes de computadores para seu funcionamento e utilização. Mas quando aplicadas
em algoritmos computacionais, resultam em soluções rápidas e na qualidade do processo que
atualmente é indispensável (TAFNER; XEREZ; RODRIGUES FILHO, 1995, p. 15-54).
Pode-se definir RNA, segundo Loesch e Sari (1996, p. 5), como um sistema
computacional que pode ser implementado tanto em hardware como em software, que tem
como objetivo imitar habilidades do sistema nervoso biológico, através de neurônios
artificiais simples interconectados. Tafner, Xerez e Rodrigues Filho (1995, p. 45) escrevem
que uma RNA é uma rede fortemente paralela com elementos interconectados
hierarquicamente, aptos a interagir com o mundo real da mesma forma que o sistema nervoso
biológico realiza. Haykin (2001, p. 28) define RNA como sendo um processador compacto,
paralelamente distribuído com diversas unidades de processamento simples com objetivo
natural de armazenar conhecimento e torná-lo utilizável, semelhante ao cérebro humano.
29
2.4.3 Rede de Kohonen
A rede de Kohonen, também conhecida como Mapas de auto-organização, ou Self-
Organizing Map (SOM) é uma variação da rede Feedforward, com treinamento não
supervisionado. A sua estrutura, características, bem como seus conceitos são descritos nas
seções seguintes. A seguir na seção 2.4.3.1, é descrito sobre a construção topológica. Na
seção 2.4.3.2, é descrito sobre o neurônio artificial. Na seção 2.4.3.3, é descrito sobre as
iterações. Na seção 2.4.3.4, é descrito sobre a taxa de aprendizagem. Na seção 2.4.3.5, é
descrito sobre a vizinhança. Na seção 2.4.3.6, é descrito sobre a rotulação dos neurônios
artificiais ganhadores. Na seção 2.4.3.7, é descrito sobre a identificação do neurônio artificial
ganhador. Na seção 2.4.3.8, é descrito sobre a adaptação dos neurônios artificiais. Na seção
2.4.3.9, é descrito sobre o ajuste fino da rede. Por fim, na seção 2.4.3.10, é descrito sobre o
funcionamento da rede.
2.4.3.1 Construção topológica
Considerada uma rede de duas dimensões, que não possui nenhuma imposição quanto
a sua forma de construção topológica, podendo ser hexagonal (Figura 15), retangular,
triangular, quadrada. Uma das propriedades fundamentais da rede de Kohonen é modificar-se
a si própria (TAFNER, 1996).
Fonte: Tafner (1996).
Figura 15 – Exemplo de construção hexagonal
Os neurônios artificiais têm a propriedade de competirem entre si para serem
ganhadores, a cada padrão apresentado em quaisquer umas das suas fases de operação. Assim
o neurônio ganhador, bem como seus respectivos vizinhos, respeitando um raio topológico,
são alterados. Desta forma, responderão melhor a futuras apresentações similares destes
padrões (TAFNER, 1996).
30
A rede de Kohonen possui duas camadas, a de entrada e a de saída. (BRUNS, 1995,
p.30). Um exemplo (Figura 16) de mapa de Kohonen na forma bidimensional, onde cada
neurônio artificial da camada de saída está amplamente ligado a todas as entradas e cada um
deles, representa uma saída em potencial para cada padrão apresentado.
Fonte: Tafner (1996).
Figura 16 – Exemplo de mapa de Kohonen na forma bidimensional, onde todos os neurônios da camada da saída estão amplamente conectados às entradas
Tafner (1996) descreve este comportamento de ligação, com objetivo de fazer com que
a rede simule identicamente o funcionamento da atividade cerebral humana. Esta teoria está
fundamentada, em função das células nervosas corticais estarem arranjadas anatomicamente
interligadas aos seus estímulos (sensores). Comprovou-se também através de estudos, que
mesmo que as células estejam conectadas e coligadas entre si, conforme a atividade cerebral
exercida em certo momento, pode-se destacar-se regiões diferenciadas com atividades mais
intensificadas.
2.4.3.2 O neurônio artificial
O neurônio artificial também conhecido como elemento de processamento (Figura 17)
como alguns definem, é a base de tudo. Possui sua forma de funcionamento muito parecida
com a dos neurônios biológicos, tendo uma ou mais conexões de entrada com a possibilidade
de disparos em uma única saída. As conexões de entrada podem ser consideradas como
estímulos para o neurônio artificial, as quais são conduzidas simultaneamente até o núcleo do
neurônio artificial. Os pesos sinápticos das conexões de entrada são partes importantes dos
neurônios, comparáveis com os dentritos (prolongamentos dos neurônios biológicos
especializados na recepção de estímulos) realizando sinapse com outros neurônios biológicos.
Estes pesos sinápticos representam o grau de importância de uma entrada sobre um
determinado neurônio artificial. Os mesmos são alterados conforme a intensidade do sinal de
31
entrada apresentado (TAFNER; XEREZ; RODRIGUES FILHO, 1995, p. 56-58).
Tafner (1996) ainda descreve que o conhecimento da rede reside nos valores de seus
pesos sinápticos.
Fonte: adaptado de Tafner, Xerez e Rodrigues Filho (1995, p. 53).
Figura 17 – Neurônio artificial
Segundo Loesch e Sari (1996, p. 20) têm-se duas funções dentro dos neurônios
artificiais: a de somatório e a de transferência. A função de somatório, também chamada de
ativação em muitos casos, tem por objetivo realizar uma soma ponderada das conexões de
entrada com seus respectivos pesos sinápticos, atendendo assim a função de transferência. A
função de transferência, também chamada de limiar lógico, tem por objetivo a ativação do
neurônio artificial, existindo um valor que quando alcançado gera um sinal de saída pela
função, podendo ser contínuo ou descontínuo.
Contudo, no caso da rede de Kohonen, como em algumas outras, esta função de
transferência é igual ao nível de somatório, realizado entre as entradas e seus respectivos
pesos sinápticos (TAFNER; XEREZ; RODRIGUES FILHO, 1995, p. 60).
2.4.3.3 Iterações
Normalmente o processo de treinamento da rede é o mais demorado. Em média são
recomendadas 500 iterações para cada neurônio artificial da camada de saída. Vale salientar
que chegou-se a esta conclusão através de observações realizadas pelo próprio Kohonen.
Nada impede que se obtenha sucesso com menos ou mais iterações. Como forma de
exemplificar o que foi descrito, supondo a existência de 5 neurônios artificiais na camada de
saída, tem-se então uma média de 2500 iterações para o processo de treinamento da rede. A
quantidade de entradas e de padrões a serem apresentados para o treinamento da rede, não
influenciam na quantidade das iterações (TAFNER, 1996).
32
2.4.3.4 Taxa de aprendizagem
Tafner, Xerez e Rodrigues Filho (1995, p. 130) descrevem que a taxa de aprendizagem
é indispensável para o treinamento da rede. Ela é um termo escalar que regulariza o
treinamento. É necessário que esta taxa de aprendizagem seja um valor escalar entre 0 e 1.
Este valor com o passar do tempo de treinamento tem tendência a diminuir, de forma
monotônica. A regra para diminuição do valor pode ser linear (Quadro 3), exponencial ou
inversamente proporcional.
)/)(1)(()( ntittat∝ = − onde: (t) = taxa de aprendizagem calculada em um dado tempo t ∝ ta(t) = taxa aprendizagem informada em um dado tempo t i(t) = iteração atual em um dado tempo t n = quantidade total de iterações
Quadro 3 – Fórmula linear para taxa de aprendizagem
2.4.3.5 Vizinhança
Esta característica da rede de Kohonen é importante para definição de um raio
topológico, ou espacial em torno do neurônio artificial ganhador, para alterações do mesmo e
de seus respectivos vizinhos quando necessário. A melhor forma de organização da
vizinhança é começando-a extensa, para viabilizar a geração de regiões características para
cada conjunto de padrões apresentados, diminuindo-a monotonicamente com o tempo de
processamento da rede, a fim de melhorar a resolução espacial do mapa característico. Nesta
linha de procedimento, no final do processo, a vizinhança pode-se reduzir ao próprio neurônio
ganhador (TAFNER; XEREZ; RODRIGUES FILHO, 1995, p. 126-127).
Tafner, Xerez e Rodrigues Filho (1995, p. 128) descrevem ainda que o ajuste da
vizinhança pode ser traduzido como uma série de estímulos aos neurônios artificiais vizinhos
ao ganhador, como forma de terem a mesma condição de aprendizado, para que em futuras
apresentações de padrões semelhantes possam concorrer de forma similar.
A Figura 18 apresenta um exemplo de vizinhança contendo vários raios topológicos
em torno de uma construção topológica quadrada.
33
Fonte: adaptado de Tafner, Xerez e Rodrigues Filho (1995, p. 53).
Figura 18 – Vizinhança contendo vários raios topológicos em torno de uma construção topológica quadrada
2.4.3.6 Rotulação dos neurônios artificiais ganhadores
Após o ordenamento do mapa característico da rede, é preciso identificar os neurônios
artificiais que reagem aos padrões apresentados para rede, para eventuais identificações
futuras e procedimentos sobre este mapa. Isto pode ser feito utilizando rótulos para os
neurônios artificiais, onde os mesmos receberão, por exemplo, um nome referente ao padrão
ao qual eles reagem. Nada impede que ao final desta rotulação, haja mais de um neurônio
artificial referenciado para um mesmo padrão.
2.4.3.7 Identificação do neurônio artificial ganhador
Para realização das etapas de treinamento, testes, ajustes (ou rotulação) e operação da
rede é fundamental que seja identificado o neurônio artificial ganhador. A identificação é
obtida encontrando o neurônio artificial que contiver a menor distância euclidiana dentre
todos os existentes, quando submeter-se um padrão para rede, em qualquer uma das etapas
mencionadas anteriormente. Esta distância euclidiana é calculada através da soma ponderada
das conexões de entrada com seus respectivos pesos sinápticos para cada um dos neurônios
artificiais existentes (TAFNER, 1996).
Seja a entrada x={x1, x2, x3, ..., xn} em um tempo t e os pesos w={wi1, wi2, wi3, ..., win}
em um mesmo tempo t, desta forma o cálculo da distância euclidiana do neurônio artificial i é
34
expressa pela fórmula do Quadro 4.
∑=
−=n
jijji twtxtd
1
2))()(()(
onde: di(t) = distância do neurônio artificial i no tempo t i = indexação do neurônio artificial n = numero de entradas (quantidade de x e, respectivamente, quantidade de w por neurônio artificial) j = indexação das entradas e dos pesos xj(t) = entrada j no tempo t wij(t) = peso j do neurônio artificial i no tempo t
Quadro 4 – Fórmula para o cálculo da distância euclidiana do neurônio artificial
Para exemplificar este cálculo, seja a entrada x={2, 10, 6, 3, 8} e os pesos sinápticos
do neurônio artificial três w={4, 7, 1, 9, 5}, a distância euclidiana seria igual a 86 (Quadro 5). d3 = (x1 -w31)
2 + (x2 -w32)2 + (x3 -w )2 + (x4 -w34)
2 + (x5 -w35)2
33
d3 = (2 -4)2 + (10 -7)2 + (6 -1)2 + (3 -9)2 + (8 -5)2
d3 = (-2)2 + (3)2 + (5)2 + (-6)2 + (3)2
d3 = 4 +9 +25 +36 +9 Quadro 5 – Cálculo referente ao exemplo de identificação do neurônio artificial ganhador
2.4.3.8 Adaptação dos neurônios artificiais
A adaptação dos neurônios artificiais é um item importante para formação do mapa
característico. Para que aconteça o treinamento é necessário que haja uma mudança. Esta
mudança está relacionada aos pesos sinápticos das entradas de cada um dos neurônios
existentes na rede, respeitando o raio topológico da vizinhança em dado instante para
realização deste ajuste (TAFNER, 1996).
Tafner, Xerez e Rodrigues Filho (1995, p. 130) descrevem que a adaptação de cada um
dos pesos sinápticos, existentes dentro de cada neurônio artificial da rede, acontece através da
fórmula apresentada no Quadro 6.
[ ])()(
)()()()()(
)1(tvseitvsei
twtwtxtatw
twi
i
i
iii
∉∈
⎭⎬⎫
⎩⎨⎧ −+
=+
onde: wi(t) = peso do neurônio artificial i no tempo t i = indexação do neurônio artificial e vizinhança a(t) = taxa de aprendizagem no tempo t x(t) = entrada no tempo t v (t) = vizinho i no tempo t i
Quadro 6 – Fórmula para cálculo da adaptação dos pesos sinápticos dos neurônios artificiais
Para exemplificar este cálculo, seja a entrada x={2, 10, 6}, os pesos sinápticos do
neurônio artificial três w={4, 7, 1} e a taxa de aprendizagem 0.9 neste mesmo tempo t, os
35
novos pesos sinápticos para o neurônio três seriam iguais a 2.2, 9.7 e 5.5 (Quadro 7). w3 = {4 +0.9*(2 -4), 7 +0.9*(10 -7), 1 +0.9*(6 -1)} w3 = {4 +0.9*(-2), 7 +0.9*(3), 1 +0.9*(5)} w = {4 -1.8, 7 +2.7, 1 +4.5} 3
Quadro 7 – Cálculo referente ao exemplo de adaptação do neurônio artificial ganhador
2.4.3.9 Ajuste fino da rede
O ajuste fino da rede é recomendado para casos em que a rede for utilizada para
distinções de padrões, onde as respostas são agrupadas em sub-conjuntos, considerando-as
como uma decisão. Após o treinamento, estas regiões de neurônios podem apresentar limites
de valores muito próximos, ou até iguais. Para a solução deste problema, Kohonen criou três
variações de métodos de quantização de vetor de aprendizado, conhecido como Learning
Vector Quantization (LVQ). Estes métodos reforçam os pesos sinápticos dos neurônios
artificiais que em determinado padrão submetido apresentam uma identificação correta ou
incorreta (HUGO, 1995).
Este ajuste deve acontecer logo após o treinamento e da rotulação dos neurônios
artificiais. Aconselha-se a criação de um novo conjunto de treinamento contendo padrões
similares aos do treinamento, que devem ser procedidos da mesma forma do treinamento,
porém com algumas diferenças:
a) o número de iterações deve ser menor do que utilizado na fase de treinamento, já
que esta fase não trata de uma ordenação e sim de um ajuste fino em certos
neurônios artificiais;
b) recomenda-se iniciar a taxa de aprendizagem com valores baixos, em tordo de 0.01
ou 0.02. A taxa de redução para aprendizagem deve ser bem pequena durante as
iterações (Quadro 8);
c) a vizinhança deve ser ignorada.
100000/)()( ttat∝ = onde: (t) = taxa de aprendizagem calculada em um dado tempo t ∝ ta(t) = taxa aprendizagem informada em um dado tempo t Quadro 8 – Fórmula de redução da taxa de aprendizagem no ajuste fino da RNA
Nesta fase os ajustes dos pesos (Quadro 9) são diferentes e assemelha-se a um
treinamento supervisionado.
36
[ ][ ] etsex
ctsextwtxtatwtwtxtatw
twii
iii
∈∈
⎭⎬⎫
⎩⎨⎧
−−−+
=+)()(
)()()()()()()()(
)1(
onde: wi(t) = peso do neurônio i no tempo t i = indexação do neurônio a(t) = taxa de aprendizagem no tempo t x(t) = entrada no tempo t c = classificação correta conforme rótulo e = classificação errada conforme rótulo
Quadro 9 – Fórmula para realizar o ajuste fino dos pesos sinápticos dos neurônios artificiais
2.4.3.10 Funcionamento da rede
Os passos para realização do treinamento, teste (ou rotulação), ajuste e operação da
rede de Kohonen serão descritos abaixo sob a forma de um algoritmo computacional.
Tafner (1996) descreve que o algoritmo de treinamento deve seguir as seguintes
etapas:
a) atribuir a quantidade de iterações;
b) atribuir a taxa de aprendizagem;
c) iniciar os pesos sinápticos dos neurônios artificiais com valores aleatórios e baixos
(devem ser sempre abaixo dos valores das entradas a serem submetidos);
d) atribuir o raio da vizinhança;
e) apresentar um de padrão para entrada da rede;
f) calcular a distância euclidiana para cada neurônio artificial existente na rede;
g) selecionar o neurônio ganhador, ou seja, que apresentou a menor distância
euclidiana;
h) ajustar os pesos sinápticos do neurônio artificial ganhador, como de todos que
pertencerem à sua vizinhança;
i) alterar a taxa de aprendizagem;
j) se necessário, alterar o raio da vizinhança;
k) caso haja mais padrões para serem apresentados, voltar para o item e.
A rede neural será considerada treinada, somente após todo conjunto de padrões de
treinamento tiver sido apresentado e os critérios de treinamento terem sido satisfeitos.
Terminado o treinamento, inicia-se a etapa de teste (ou rotulação) dos neurônios artificiais, na
qual os pesos sinápticos não serão mais ajustados. Nesta fase é reapresentando o conjunto de
padrões do treinamento, para serem identificados os neurônios artificiais que reagem aos
37
mesmos para ganharem sua devida rotulação. Aconselha-se também criar e apresentar um
novo conjunto de padrões semelhantes, para reforçar a eficácia do treinamento da rede
(TAFNER, 1996).
Tafner (1996) descreve que o algoritmo de teste (ou rotulação) deve seguir as seguintes
etapas:
a) atribuir a quantidade de iterações (será a quantidade de padrões apresentados);
b) os pesos sinápticos dos neurônios artificiais devem já estar atribuídos, ou ser
atribuídos, conforme os valores obtidos na fase de treinamento da rede;
c) apresentar um padrão para entrada da rede;
d) calcular a distância euclidiana para cada neurônio artificial existente na rede;
e) selecionar o neurônio ganhador, ou seja, que apresentou a menor distância
euclidiana;
f) atribuir um rótulo para o neurônio artificial, conforme o nome do padrão
correspondente que ele acaba de reconhecer;
g) caso haja mais padrões para serem apresentados, voltar para o item c.
Reconhecendo-se os padrões apresentados de forma adequada, considera-se que a rede
está apta para utilização. Pode-se ainda, antes de tornar a rede operacional, submeter um novo
conjunto de padrões similares aos apresentados anteriormente, para realizar o ajuste fino da
rede (TAFNER, 1996).
Tafner (1996) descreve que o algoritmo de ajuste fino deve seguir as seguintes etapas:
a) atribuir a quantidade de iterações;
b) atribuir a taxa de aprendizagem;
c) os pesos sinápticos dos neurônios artificiais devem já estar atribuídos, ou ser
atribuídos, conforme os valores obtidos na fase de treinamento da rede;
d) apresentar um padrão para entrada da rede;
e) calcular a distância euclidiana para cada neurônio artificial existente na rede;
f) selecionar o neurônio ganhador, ou seja, que apresentou a menor distância
euclidiana;
g) ajustar os pesos sinápticos do neurônio artificial ganhador, conforme as regras
estabelecidas para ajuste fino da rede;
h) alterar a taxa de aprendizagem;
i) caso haja mais padrões para serem apresentados, voltar para o item d.
Após esta etapa a rede está pronta para a operação.
Tafner (1996) descreve que o algoritmo de operação deve seguir as seguintes etapas:
38
a) os pesos sinápticos dos neurônios artificiais devem já estar atribuídos, ou ser
atribuídos, conforme os valores obtidos na fase de treinamento, ou de ajuste fino
da rede;
b) apresentar um padrão para a entrada da rede;
c) calcular a distância euclidiana para cada neurônio artificial existente na rede;
d) selecionar o neurônio ganhador, ou seja, que apresentou a menor distância
euclidiana;
e) verificar qual o padrão que o mesmo reconheceu;
f) caso haja mais padrões para serem apresentados, voltar para o item b.
2.5 TRABALHOS CORRELATOS
Na busca por trabalhos correlatos foram encontrados inúmeras aplicações semelhantes
ao trabalho proposto. Dentre eles foram escolhidos três aplicações cujas características
enquadram-se nos principais objetivos deste trabalho. Os trabalhos são: “Uma Interface de
Reconhecimento de Voz para o Sistema de Gerenciamento de Central de Informação de
Fretes” (HUGO, 1995), “Reconhecimento de Voz Dependente de Locutor Utilizando Redes
Neurais Artificiais” (BRAGA, 2006) e o “Protótipo para o Reconhecimento de Palavras
Através da Fala” (BRUNS, 1995).
2.5.1 Uma interface de reconhecimento de voz para o sistema de gerenciamento de central
de informação de fretes
Neste trabalho (HUGO, 1995) procura demonstrar a viabilidade e potencialidade dos
sistemas comandados por voz, construindo um protótipo de software capaz de responder em
tempo real a um comando falado por um usuário.
Foram utilizadas técnicas de RNA para realizar o reconhecimento das palavras faladas.
A interface de voz construída para reconhecer as palavras, que operam um protótipo do
Sistema Gerenciador de Central de Informação de Fretes (SGCIF) em Windows, aplica o
modelo de rede de Kohonen, alcançando uma taxa média de acerto de 84,84% no
39
reconhecimento. O autor optou por utilizar a rede de Kohonen devido aos seguintes motivos:
a própria audição humana cria estruturas auto-organizáveis durante a fase de aprendizagem; a
rede de Kohonen foi originalmente concebida para trabalhar em aplicações de reconhecimento
de fala; a relação entre os benefícios dos potenciais desta rede em comparação ao tempo
despendido para o treinamento é bom, se comparado com outros modelos, como por exemplo,
o de Backpropagation.
O desenvolvimento do trabalho através dos seus estágios permitiu uma evolução
segura, garantindo que os resultados alcançados em cada estágio auxiliassem e não
interferissem na busca da solução. O objetivo de controlar a operação dos menus do SGCIF
através da voz foi atingido, demonstrando que a utilização de RNA é viável em aplicações
desta natureza.
2.5.2 Reconhecimento de voz dependente de locutor utilizando redes neurais artificiais
Neste trabalho (BRAGA, 2006) descreve o uso de uma RNA do tipo SOM, aplicada
para reconhecimento de voz através do modelo de subdivisão fonética. A escolha desta RNA
originou-se por querer refazer-se algumas pequenas diferenças do experimento de Kohonen
conhecido como datilógrafo fonético (conversão da linguagem falada em texto escrito).
Utilizou-se técnicas de pré-processamento e extração de características do sinal da fala
através do modelo Cepstrum (análise espectral homomórfica ou resultado da Transformada
Rápida de Fourier (TRF)). Relatou-se desde técnicas de pré-ênfase (etapa para aplicação de
filtro para compensar a atenuação nas altas frequências de voz gerada pelo processo de
produção da fala), até os métodos de extração de coeficientes Mel-Cepstrais (advindos do
método Cepstrum, são obtidos pela representação em frequência de escala de mel, que são
unidades de medidas da frequência de um tom) de energia. Foi criada e definida uma base de
dados contendo os padrões fonéticos de frases do português para o treinamento da rede
utilizando 20 locutores homens e 20 locutores mulheres.
O sistema teve como objetivo facilitar o entendimento e ajudar pesquisadores que
trabalham na área de reconhecimento de voz. Foram desenvolvidos três experimentos:
reconhecimento de vogais, fonemas e frases. Os resultados obtidos foram razoáveis, quando
levada em consideração a complexidade do problema. Com isso mostra-se que a rede SOM é
bastante adequada a este tipo de problema.
40
2.5.3 Protótipo para o reconhecimento de palavras através da fala
Neste trabalho (BRUNS, 1995) descreve a idéia do reconhecimento de palavras através
da fala com a utilização da rede de Kohonen. Na qual foram estudadas diferentes e mais
aprofundadas formas de pré-processamento de sinais digitalizados, incorporando a essa idéia
uma aplicação para a prática do reconhecimento dos comandos falados.
O trabalho aborda desde a entrada dos sons através de um microfone, até a
manipulação dos padrões utilizados no processamento pela RNA. Permite também a
verificação dos resultados numa forma simplificada. A captura de sinais é realizada através da
placa de som, sendo explorado o pré-processamento de sinais através de médias e o pré-
processamento através da TRF.
O conhecimento adquirido pela RNA foi aplicado com sucesso sob forma de um
protótipo que reconhece determinadas palavras associadas a padrões previamente treinados,
demonstrado o resultado obtido com o ganho no uso de cada um dos pré-processamentos de
sinais, em diferentes conjuntos de palavras.
41
3 DESENVOLVIMENTO DO PROTÓTIPO
As seções seguintes descrevem os requisitos principais do problema a ser trabalhado, a
especificação, a implementação e, por último, os resultados e discussão obtidas com o
desenvolvimento do protótipo.
3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO
O protótipo de software de reconhecimento de voz para navegação em jogos,
utilizando RNA deve:
a) disponibilizar uma interface para apresentação do jogo (Requisito Funcional –
RF);
b) captar os sinais de áudio do meio externo através de microfone (RF);
c) digitalizar o áudio utilizando técnicas de pré-processamento (RF);
d) armazenar em arquivos os pesos sinápticos das entradas dos neurônios artificiais
da RNA treinada (RF);
e) permitir ao usuário a navegação pelo jogo através de comandos de voz (RF);
f) ser implementado utilizando linguagem de programação Java (Requisito Não-
Funcional – RNF);
g) ser implementado utilizando ambiente de programação NetBeans na versão 6.9 ou
superior (RNF);
h) utilizar Open Graphics Library (OpenGL) para tratamento gráfico do jogo em 2D
(RNF).
3.2 ESPECIFICAÇÃO
Nesta seção são apresentadas as especificações do protótipo e do formato do arquivo
de entrada para recriar uma RNA. As especificações do protótipo foram modeladas utilizando
a ferramenta Entreprise Architect (versão 7.1), sendo utilizado o paradigma da Orientação a
42
Objetos (OO) e a Unified Modeling Language (UML) para criação dos diagramas de casos de
uso, classes, sequência e de atividade.
3.2.1 Diagrama de casos de uso
O protótipo implementado possui 14 Casos de Uso (UC) como pode ser observado na
Figura 19.
Figura 19 – Diagrama de casos de uso
Existem duas formas para iniciar a operação do protótipo: a primeira é criar uma nova
rede e a segunda, recriar uma rede através de um arquivo contendo os dados de uma rede
criada e salva anteriormente.
Na primeira forma existe uma sequência a ser seguida de UCs para o bom
funcionamento do protótipo. Começa-se pela criação de uma nova rede (UC01), submetendo
na sequência um conjunto de amostras para realizar o treinamento da rede (UC03).
Posteriormente submete-se mais um conjunto de amostras para efetuar o teste da rede (UC04)
e, por fim, mais um conjunto de amostras para realizar o ajuste fino da rede (UC06). Na
segunda forma, basta recriar a rede (UC09) através de um arquivo de uma rede salva
43
anteriormente.
Após a criação ou recriação de uma rede, pode-se obter o reconhecimento de voz
iniciando a captura do áudio (UC10), pronunciando na sequência um comando por voz e, por
fim, suspendendo a captura do áudio (UC11).
Com exceção dos UCs de criação da rede (UC01), recriação da rede (UC09),
visualização do log da rede demonstrando as operações realizadas (UC07) e de visualização
do sobre (UC14), os demais somente poderão ser executados após a criação ou recriação de
uma rede.
Os demais UC restantes não descritos anteriormente, têm funções como visualização
dos parâmetros da rede (UC02), visualização do mapa da rede demonstrando a função de cada
um dos neurônios presentes na rede (UC05), salvamento dos dados da rede ativa para futuras
recriações (UC08), reprodução de um áudio que acaba de ser captado (UC12) e, por fim,
armazenamento de um áudio captado (UC13).
Os cenários do diagrama de UC apresentados na Figura 19 encontram-se no apêndice
A.
3.2.2 Diagramas de classes
Os diagramas de classes fornecem uma representação de como estão estruturadas as
classes e suas respectivas relações. Diante disto são apresentados dois diagramas de classes
para facilitar o entendimento referente à implementação do protótipo.
No primeiro diagrama (Figura 20), são apresentadas as classes responsáveis pelo
controle de processamento do protótipo para realização do reconhecimento de voz.
No segundo diagrama (Figura 21), são apresentadas as classes responsáveis por
permitir e controlar as possíveis interações com o usuário e a representação das informações
resultantes nas telas durante a execução do protótipo.
Dentro deste diagrama (Figura 21), encontra-se a classe TelaPrincipal responsável
por centralizar todas as telas existentes do protótipo e também de fazer requisições quando
necessárias às classes responsáveis pelo controle e processamento do protótipo.
44
Figura 20 – Diagrama de classes do pacote controle com suas respectivas relações
As classes ilustradas na Figura 20 são:
a) Labirinto: é responsável por controlar e gerenciar o jogo de labirinto na interface
gráfica;
b) BuscaDeSinais: é responsável por controlar a captação, reprodução e gravação do
sinal de áudio captado pelo protótipo;
c) CapturaThread: é responsável por capturar o áudio;
d) ReproducaoThread: é responsável por reproduzir o áudio que acaba de ser
captado;
e) PreProcessamento: é responsável por controlar e gerenciar uma estrutura que
realiza o tratamento sobre o áudio captado na busca de sinais, para submeter
posteriormente a RNA para os devidos procedimentos;
f) Kohonen: é responsável por controlar e gerenciar uma estrutura necessária para
45
gerenciamento de uma rede de Kohonen;
g) Neuronio: é responsável por simular o funcionamento e a estrutura básica de um
neurônio artificial empregado na RNA.
As classes ilustradas na Figura 21 são:
a) TelaCriar: é responsável por controlar e gerenciar as entradas necessárias para
criação de RNA;
b) TelaParametros: é responsável por apresentar os parâmetros referente a RNA
ativa;
c) TelaTreinar: é responsável por controlar e gerenciar as entradas necessárias para
realização do treinamento da RNA;
d) TelaMapa: é responsável por apresentar o mapa característico da RNA com a
função de cada um dos neurônios existentes na estrutura;
e) TelaTestar: é responsável por controlar e gerenciar as entradas necessárias para
realização do teste da RNA;
f) TelaAjustar: é responsável por controlar e gerenciar as entradas necessárias para
realização do ajuste fino da RNA;
g) TelaLog: é responsável por apresentar informações referentes aos procedimentos
executados no protótipo implementado durante sua execução;
h) TelaSobre: é responsável por apresentar informações referente ao protótipo
implementado.
46
Figura 21 – Diagrama de classes do pacote visão com suas respectivas relações
3.2.3 Diagrama de sequência
O diagrama de sequência representa um conjunto de passos necessários, para que o
protótipo execute uma determinada ação com base nas interações do usuário.
O diagrama de sequência (Figura 22) está representando os passos necessários para
47
obter-se o reconhecimento de voz pelo protótipo implementado. Este diagrama corresponde
aos UC10 e UC11.
Figura 22 – Diagrama de sequência representando os passos necessários para obter-se o
reconhecimento de voz
3.2.4 Diagrama de atividade
O diagrama de atividade representa um conjunto de fluxos necessários para executar
uma determinada ação, com base na interação do usuário.
O reconhecimento de voz do protótipo implementado, ocorre conforme as atividades
expressas na Figura 23.
48
Figura 23 – Diagrama de atividade para obter-se o reconhecimento de voz
3.2.5 Formato do arquivo de entrada para recriação de uma RNA
O formato do arquivo de entrada para recriação da RNA é apresentado na Figura 24.
Foi utilizada como forma de exemplificação uma pequena rede possuindo 3 entradas para
cada um dos 2 neurônios artificiais da camada competitiva.
Figura 24 – Formato do arquivo de entrada para recriação de uma RNA
49
Este arquivo (Figura 24) guarda tanto informações sobre os parâmetros da rede, como
também de seus respectivos neurônios. Da 1ª até a 6ª linha do arquivo referem-se aos
parâmetros da rede. Da 7ª até a 13ª linha do arquivo referem-se às informações dos
parâmetros do primeiro neurônio da rede e assim sucessivamente, respeitando o mesmo
formato de armazenamento para outros neurônios da rede. Vale salientar que a quantidade de
linhas para armazenar as informações referentes aos neurônios da rede não é fixa e depende
dos parâmetros estabelecidos da rede.
Assim sendo, a 1ª linha guarda a quantidade de entradas da rede. A 2ª linha guarda a
quantidade de linhas de neurônios da camada competitiva da rede. A 3ª linha guarda a
quantidade de colunas de neurônios da camada competitiva da rede. A 4ª linha guarda o fator
de aprendizado da rede, seu valor no entanto consiste em 0 pois já ocorreu o treinamento. A 5ª
linha guarda o raio topológico da vizinhança do neurônio ganhador da rede, seu valor também
consiste em 0 pois já ocorreu o treinamento. A 6ª linha guarda a quantidade de iterações
utilizadas para realizar o treinamento da rede.
Como já mencionado acima, da 7ª linha em diante, é reservado para guardar
informações referentes aos neurônios existentes na rede, seguindo certas regras. A 7ª linha é
reservada em branco para demonstrar que um novo conjunto de informação será representado,
neste caso para um neurônio. A 8ª e 9ª linha guardam informações referentes ao
posicionamento do primeiro neurônio da camada competitiva da rede, sendo o primeiro valor
a linha e o segundo a coluna. A 10ª linha é reservada para guardar a função (rótulo) do
neurônio quando presente. Neste caso ela encontra-se em branco, pois não há nenhuma função
atribuída para a posição. Da 11ª até a 13ª linha guardam informações referentes aos pesos
sinápticos deste neurônio. Estas informações podem variar de tamanho conforme os
parâmetros da rede.
Deste ponto em diante têm-se as informações do segundo neurônio da rede, iniciando
na 14ª até a 20ª linha do arquivo.
3.3 IMPLEMENTAÇÃO
Nesta seção são descritas informações referentes às técnicas e ferramentas utilizadas na
implementação do protótipo, bem como a implementação propriamente dita das principais
etapas do protótipo. Por fim, é apresentado a operacionalidade da implementação.
50
3.3.1 Técnicas e ferramentas utilizadas
O protótipo, foi implementado utilizando linguagem de programação Java, sobre o
paradigma da OO. Para codificação do protótipo, foi utilizado o ambiente de desenvolvimento
NetBeans (versão 6.9.1).
A implementação do protótipo utilizou duas bibliotecas externas do Java, a Gluegen-
rt e a Jogl.
Essas bibliotecas dão suporte ao desenho gráfico na linguagem Java. São
desenvolvidas na própria linguagem Java, compatível com as versões 1.4 ou superior e
possuem código aberto. Através de sua utilização é possível criar, visualizar e interagir no
labirinto 2D.
As técnicas realizadas para obtenção dos resultados propostos neste trabalho foram
divididas em 5 principais classes, são elas: a BuscaDeSinais, a PreProcessamento, a
Kohonen, a Neuronio e a Labirinto, que serão melhor descritas a seguir. As demais classes,
porém, não são descritas minunciosamente aqui, pois dispensam maiores comentários já que
as mesmas focam mais na interação com o usuário e visualização dos resultados obtidos.
3.3.2 Classe BuscaDeSinais
A classe BuscaDeSinais é responsável por controlar a captação, reprodução e
gravação do sinal de áudio captado pelo protótipo. Para obterem-se os recursos de captura e
reprodução, contou-se com o auxílio de recursos provenientes de uma Application
Programming Interface (API) chamada JavaSound. A seguir salientam-se algumas
características adotadas para manipulação deste sinal de áudio no protótipo.
Algumas informações importantes são dadas na inicialização desta classe, são elas: a
taxa de amostragem, a quantização e o número de canais. Nesta fase tentou-se trabalhar com a
menor quantidade de dados possíveis, porém com um mínimo de qualidade necessária do
sinal de áudio para que se obtivesse o reconhecimento de voz.
Para a taxa de amostragem utilizou-se 16.000 valores para cada segundo de áudio
captado. Este valor foi estabelecido devido à qualidade de som captada nos testes do
protótipo. Abaixo deste valor verificou-se que havia uma perda significativa das
51
características do sinal de áudio e, acima disto, não havia uma melhora significativa desta
qualidade.
Para quantização do som captado utilizou-se 8 valores para cada taxa de amostragem
digitalizada. Utilizando-se opção de 16 valores, duplicava-se a quantidade de dados
digitalizados, o que não trazia nenhum ganho significativo na qualidade do sinal de áudio
digitalizado.
Para o número de canais a escolha foi utilizar somente 1canal de áudio, caracterizado
como som monofônico. Considerou-se isto suficiente para o uso neste tipo de aplicação. A
opção de 2 canais não era conveniente, pois gerava-se o dobro de valores digitalizados, sendo
informação duplicada para ser processada posteriormente.
O código completo desta classe BuscaDeSinais encontra-se no apêndice B.
3.3.3 Classe PreProcessamento
A classe PreProcessamento é responsável por controlar e gerenciar uma estrutura
que realiza o tratamento do sinal de áudio captado na busca de sinais, para submetê-lo
posteriormente à RNA para os devidos procedimentos. Cabe salientar algumas características
adotadas nesta fase de preparação do sinal de áudio captado.
A representação dos sinais digitalizados neste protótipo é realizada por valores inteiros
e quantizados utilizando 256 valores possíveis. Estes valores foram representados dentro de
uma faixa de -128 a 127.
Diante disto realizou-se como a primeira etapa do processo a eliminação do ciclo
negativo do sinal de áudio captado, atribuindo o valor zero para os valores abaixo da linha do
silêncio.
Considerando a captura de um sinal de áudio representando o comando esquerda,
gerou-se um total de 31.200 (trinta e um mil e duzentos) valores digitalizados. A partir disto
eliminou-se o silêncio do inicio e do fim do sinal de áudio.
Esta eliminação do silêncio não foi implementada conforme havia sido descrito na
fundamentação teórica. O procedimento modificado foi percorrer o vetor que armazena o
sinal de áudio digitalizado nas duas extremidades, descartando todos os valores até que fosse
encontrado uma sequência contínua maior e igual a 25 valores maiores que 0. Diante desta
eliminação, os valores digitalizados reduziram para cerca de 19.994 (dezenove mil e
novecentos e noventa e quatro). Porém esta técnica de processamento, em ambientes com
52
ruídos frequentes e altos, pode não surtir efeito como o esperado. Este valor é uma média que
originou-se de observações realizadas nos sinais digitalizados de diferentes padrões captados.
A próxima etapa a ser trabalhada é a redução através das médias, conforme descrito na
fundamentação teórica, utilizando a fórmula do Quadro 1. Cabe salientar que esta taxa de
redução da fórmula é representada por um valor inteiro e é arredondado para cima sempre que
ocorrer a existência de um valor fracionário.
A etapa seguinte é a mediação do sinal, que ocorre conforme descrito na
fundamentação teórica.
Após, realizando-se a normalização, a qual, por sua vez, ocorre conforme foi descrito
na fundamentação teórica utilizando a fórmula do Quadro 2.
A partir deste passo, o sinal de áudio digitalizado é considerado tratado e é armazenado
em uma lista pronto para ser processado pela RNA.
O código completo desta classe PreProcessamento encontra-se no apêndice B.
3.3.4 Classe Kohonen
A classe Kohonen é responsável por controlar e gerenciar uma estrutura necessária para
gerenciamento de uma rede de Kohonen. Cabe salientar algumas características adotadas
nesta fase para o processamento do sinal de áudio digitalizado.
As formas disponíveis para construção topológica da RNA são: a topologia quadrada e
a topologia retangular. Estas podem ser escolhidas na hora de criação de uma nova RNA
conforme a atribuição da quantidade de linhas e colunas da camada competitiva.
A quantidade de iterações a ser realizada para efetuar o treinamento e ajuste o fino dos
pesos sinápticos na RNA é estabelecida pelo usuário conforme achar necessários para o bom
funcionamento da RNA. Foi descrita neste trabalho uma média para esses valores na
fundamentação teórica.
A taxa de aprendizagem para o treinamento da RNA é decrementada conforme a
fórmula descrita no Quadro 4, ou seja, linearmente. Este valor inicial pode ser escolhido pelo
usuário e deve ser um valor escalar entre 0 e 1.
A vizinhança do neurônio ganhador é estabelecida por padrão, pela metade do maior
valor encontrado entre a quantidade de linha e coluna da camada competitiva da RNA e,
arredondada para baixo caso seja um valor fracionário. Este valor correspondente à
vizinhança do neurônio que pode ser alterado pelo usuário desde que seja um valor inteiro.
53
Esta vizinhança é decrementada conforme a quantidade total de iterações a serem realizadas.
Para o ajuste fino da rede, a vizinhança não é levada em conta.
O código completo desta classe Kohonen encontra-se no apêndice B.
3.3.5 Classe Neuronio
A classe Neuronio é responsável por simular o funcionamento e a estrutura básica de
um neurônio artificial empregado na RNA. Cabe salientar certas características empregadas
nesta classe.
O atributo funcao é responsável por armazenar qual é o padrão ao qual o neurônio
responde durante o funcionamento da RNA. Esta informação corresponde à primeira letra do
nome do arquivo que representa o padrão que apresentou-se sensível ao neurônio durante a
fase de teste (ou rotulação). Cada neurônio só poderá responder a um e somente a um padrão
existente.
A geração dos pesos sinápticos iniciais para os neurônios das RNAs criadas, são
gerados de forma aleatória, recebendo valores escalares entre 0 e 1.
O neurônio vencedor nas etapas de treinamento, teste (ou rotulação), ajuste fino e de
operação é aquele que apresentar a menor distância euclidiana dentre todos os existentes na
RNA, levando em conta o mesmo sinal de áudio apresentado. Para realização deste cálculo é
utilizada a fórmula estabelecida no Quadro 4.
O ajuste de pesos ocorre conforme a fórmula estabelecida no Quadro 6.
O ajuste fino dos pesos ocorre conforme a fórmula estabelecida no Quadro 9.
O código completo desta classe Neuronio encontra-se no apêndice B.
3.3.6 Classe Labirinto
A classe Labirinto é responsável por controlar e gerenciar o jogo de labirinto na
interface gráfica. Nela existe um método movimentoLabirinto, que controla as coordenadas
do ponto na tela, atribuindo um movimento ao ponto conforme um valor inteiro recebido. Os
demais métodos são responsáveis por: inicialização, desenho do labirinto, desenho do ponto e
captura dos eventos do teclado, não relevantes de comentários para este trabalho.
54
O código completo desta classe Labirinto encontra-se no apêndice B.
3.3.7 Operacionalidade da implementação
A operacionalidade do protótipo é bastante simplificada. Neste exemplo é utilizado
uma rede de pequeno porte para reconhecer somente 1 comando de voz.
Ao executar o protótipo o usuário irá visualizar duas telas: a tela principal e a tela
Log Rede. A tela principal (Figura 25), além de apresentar na parte superior uma barra de
menus com as funcionalidades existentes no protótipo, apresenta o jogo de labirinto em 2D. A
tela Log Rede (Figura 26), por sua vez, apresenta as principais operações realizadas durante a
execução do protótipo.
A barra de menus (Figura 25) possui 3 entradas. A primeira entrada Geral possui
funções relacionadas ao protótipo. A segunda entrada Áudio possui funções relacionadas ao
áudio. A terceira entrada Rede possui funções relacionadas à RNA.
O menu Geral possui as opções:
a) Sobre: que apresenta a tela sobre (Figura 27), constando informações referentes
ao protótipo;
b) Fechar: encerra o protótipo.
Figura 25 – Tela principal
55
Figura 26 – Tela log rede
Figura 27 – Tela sobre
O menu Áudio possui as opções:
a) Capturar: ativa a captura do áudio até que haja a suspensão;
b) Suspender: interrompe a captura do áudio para realizar na sequência e de forma
automática o reconhecimento de voz;
c) Reproduzir: reproduz o áudio que acaba de ser capturado;
d) Armazenar: armazena o áudio que acabou de ser capturado (Figura 28).
56
Figura 28 – Armazenar áudio
O menu Rede possui as opções:
a) Criar: criar uma RNA informando a quantidade de entradas, a quantidade de
linhas e colunas da camada competitiva. Para este exemplo utilizou-se 5 linhas por
5 colunas, resultando um total de 25 neurônios, possuindo 10 entradas cada um
deles (Figura 29);
b) Visualizar parâmetros: apresenta os parâmetros referentes à RNA ativa (Figura
30);
c) Treinar: realiza o treinamento da RNA permitindo informar um valor para o raio
topológico (vizinhança), um valor para o fator de aprendizado (taxa de
aprendizado), um valor para quantidade de iterações e possibilitando selecionar um
conjunto de amostras. Neste exemplo foi utilizado valor 2 para o raio topológico,
valor 0.9 para o fator de aprendizado, valor 1000 para quantidade de iterações e 5
amostras de áudio distintas representando o comando de voz Direita (Figura 31);
d) Testar: realiza o teste na RNA com base em um conjunto de amostras,
apresentando as coordenadas de posição de cada neurônio que sofreu ativação na
camada competitiva para cada amostra. Neste exemplo utilizou-se um novo
conjunto contendo 5 novas amostras de áudio representando o comando de voz
Direita (Figura 32);
e) Visualizar mapa: apresenta o mapa da RNA sinalizando quais os neurônios
sofrem ativação aos padrões apresentados, podendo haver mais do que um padrão
sinalizando o mesmo neurônio. Para este exemplo foi apresentado somente 1
padrão, que resultou em somente um tipo de sinalização representada no mapa,
pela primeira letra correspondente ao comando de voz Direita (Figura 33);
57
f) Ajustar: realiza o ajuste fino da RNA informando a quantidade de iterações, o
eurônios
A através de informações armazenadas em um arquivo
fator de aprendizado e um conjunto de amostras. Neste exemplo foi utilizado 3
iterações, um fator de aprendizado com valor 0.02 e um novo conjunto contendo 5
amostras de áudio distintas representando o comando de voz Direita (Figura 34);
g) Visualizar log: apresenta as principais operações realizadas na RNA durante
sua execução, como já havia sido mencionado anteriormente (Figura 26);
h) Salvar: salva as informações referentes à RNA e de seus respectivos n
em arquivo (Figura 35);
i) Recriar: recria uma RN
(Figura 36).
Figura 29 – Tela criar rede
Figura 30 – Tela parâmetros rede
Figura 31 – Tela treinar rede
58
Figura 32 – Tela testar rede
Figura 33 – Tela mapa rede
Figura 34 – Tela ajuste rede
59
Figura 35 – Salvar rede
Figura 36 – Recriar rede
As opções dos menus possuem atalhos, estes são descritos no Quadro 10.
menu principal sub-menus teclas de atalho Geral Sobre F1
Fechar F4 Áudio Capturar Control + C
Suspender Control + S Reproduzir Control + R Armazenar Control + A
Rede Criar Option + C Visualizar parâmetros Option + P Treinar Option + T Testar Option + E Visualizar mapa Option + M Ajustar Option + A Visualizar log Option + L Salvar Option + S Recriar Option + R
Quadro 10 – Atalhos das opções dos menus
60
3.4 RESULTADOS E DISCUSSÃO
Para avaliar os resultados da implementação do protótipo realizado, foi definido um
conjunto de padrões a ser apresentados para a RNA. Este conjunto é composto por 6 padrões
distintos (esquerda, direita, prossiga, retorne, fechar, inicio), referindo-se aos
comandos utilizados na navegação do labirinto. Para cada comando foram realizadas 15
capturas, totalizando 90 ao todo.
Quanto à criação da RNA, utilizou-se uma construção topológica quadrada de 5 linhas
por 5 colunas. O valor para quantidade de entradas foi igual a 100. Utilizou-se 2.500 iterações
para realização do treinamento, iniciando-o com uma taxa de aprendizado com valor igual a
0.9. A vizinhança na fase de treinamento iniciou-se esparsa com valor igual a 2. Para o ajuste
fino dos pesos sinápticos da RNA, utilizou-se 1.250 iterações, iniciando-o com uma taxa de
aprendizado com valor igual a 0.02.
Para cada uma das fases (treinamento, teste e ajuste fino) realizadas para preparar a
RNA, utilizou-se 5 amostras de cada padrão distintos dos capturados anteriormente.
Finalizando a etapa de preparação, foram submetidas para a RNA novas amostras,
sendo 10 de cada padrão. Todas estas capturas mencionadas foram realizadas por um mesmo
locutor em um ambiente controlado. Os resultados obtidos com a operacionalidade do
protótipo podem ser observados no Quadro 11. Comandos esquerda direita prossiga retorne fechar inicioTaxa de acerto 70 % 80 % 60 % 70 % 60 % 80 %
Quadro 11 – Taxa de acerto obtida pela RNA
No Quadro 12 é comparada a eficiência da RNA implementada no protótipo com as
dos trabalhos correlatos. Destaca-se nesta comparação que existem diferentes quantidades de
neurônios para realização do processamento dos sinais, como também a quantidade de
padrões submetidos e distintos, tipo de pré-processamento adotado, RNA utilizadas e
abordagem para obter-se o reconhecimento.
Protótipo implementado
(BRAGA, 2006) SGCIF (HUGO, 1995)
(BRUNS, 1995)
Pré-processamento através de pré-ênfase
39.31% Até 50 frases
Pré-processamento através de TRF
62.25% Até 4 palavras
87% Até 4 palavras
Pré-processamento através de Médias
70% Até 6 palavras
86.75% Até 4 palavras
58.8% Até 4 palavras
Quadro 12 – Eficiência da RNA implementada no protótipo em relação aos dos trabalhos correlatos
No Quadro 13 são comparadas as características do presente protótipo com as dos
61
trabalhos correlatos. Estas características foram levantas como forma de visualizar as
semelhanças e diferenças existentes entre cada aplicação. A escolha dos critérios de avaliação
deu-se principalmente focando as técnicas abordadas durante a concepção das ferramentas.
Protótipo implementado
(BRAGA, 2006) SGCIF (HUGO, 1995)
(BRUNS, 1995)
Pré-processamento através de pré-ênfase Pré-processamento
através de TRF Pré-processamento através de Médias
Utilização da rede de Grossberg
Utilização da rede de Kohonen
Implementação do LQV1
Comandos reconhecidos por palavras
Comandos reconhecidos por frases
Dependente de locutor
Linguagem de programação Java
Passível de extensão
Quadro 13 – Características do protótipo implementado e dos trabalhos correlatos
Diante do exposto conclui-se que os resultados alcançados com o reconhecimento de
voz através dos testes realizados foram satisfatórios. Obteve-se uma taxa de acerto em torno
de 70% com 6 padrões distintos para o reconhecimento de voz, em um ambiente controlado e
captados por um mesmo locutor. Comparando com os trabalhos correlatos apresentados
(Quadro 12), destacou-se os resultados obtidos (HUGO, 1995) utilizando as mesmas técnicas
do protótipo implementado, atingindo uma taxa de acerto de 86.75, porém este utiliza
somente 4 padrões distintos para o reconhecimento de voz. Uma diferença pequena se
comparada à complexidade de haver utilizado 2 palavras a mais nos testes e uma camada
competitiva menor de aproximadamente 25 neurônios contra 81. Utilizou-se uma arquitetura
de pequeno porte, visando obter uma ótima eficiência quanto ao tempo gasto para realizar a
preparação da RNA para obter-se o reconhecimento de voz.
62
4 CONCLUSÕES
Mesmo sendo alvo de estudos há mais de 30 anos, um sistema voltado para
reconhecimento de voz sempre será um desafio, pois existem muitas particularidades
existentes para sua construção.
Os resultados alcançados com o término da implementação do protótipo foram
considerados satisfatórios. Porém o protótipo implementado ainda demanda de estudos
voltados para o seu aperfeiçoamento. Esta conclusão deve-se à existência de uma taxa de erro
em torno de 30%, que em ambientes não controlados pode aumentar de forma significativa.
Se esta forma de controle for aplicada ao comando de jogos que necessitem de alta interação
com o usuário, pode tornar-se inviável, prejudicando o desempenho do jogo.
No início deste trabalho foram identificados objetivos e requisitos necessários para que
a sua realização pudesse ser possível. Ao término do mesmo, pode-se notar que todos estes
objetivos e requisitos foram alcançados.
No entanto, destaca-se uma importante limitação encontrada no uso do protótipo,
referente à existência de ruídos em ambientes, na qual, não é possível obter-se a forma de
onda correta resultante das palavras, após a remoção do silêncio pelo algoritmo
implementado.
Por fim, escolheu-se a utilização de médias para realizar o pré-processamento do sinal
de áudio e da rede de Kohonen devido aos bons resultados alcançados e observados nos
trabalhos correlatos.
4.1 EXTENSÕES
Existem pontos que podem ser agregados ou incrementados no protótipo elaborado
neste trabalho. Como sugestão pode-se citar:
a) investigar qual seria a quantidade necessária de amostras para realização do
treinamento, teste e ajuste finos da RNA, para cada padrão desejado, bem como, a
forma de apresentação destes padrões para RNA (intercalada ou sequencial),
visando obter melhores resultados;
b) realizar o reconhecimento de voz utilizando o canal do microfone aberto
63
constantemente, melhorando a implementação do algoritmo de detecção do
silêncio;
c) investigar outras formas de realizar o pré-processamento do sinal de áudio, bem
como de outras técnicas de RNA, verificando a eficiência de seu uso;
d) investigar a existência de variações nos resultados obtidos em diferentes RNA
geradas, devido aos seus respectivos valores de inicialização atribuídos aos pesos
sinápticos dos neurônios artificiais, bem como, a existências de neurônios
artificiais que nunca vencem as amostras apresentadas para RNA;
e) realizar o tratamento de colisão do labirinto e atualizar para ambiente 3D.
64
REFERÊNCIAS BIBLIOGRÁFICAS
BRAGA, Petrônio L. Reconhecimento de voz dependente de locutor utilizando redes neurais artificiais. 2006. 85 f. Trabalho de Conclusão de Curso (Engenharia da Computação) – Departamento de Ciências Computacionais, Escola Politécnica da Universidade de Pernambuco, Recife. Disponível em: <http://dsc.upe.br/~tcc/20061/PetronioBraga.pdf>. Acesso em: 19 set. 2010.
BRUNS, Fábio A. Protótipo para o reconhecimento de palavras através da fala. 1995. 68 f. Trabalho de Conclusão de Curso (Bacharelado em Ciência da Computação) – Centro de Ciências Exatas e Naturais, Universidade Regional de Blumenau, Blumenau.
HAYKIN, Simon. Redes neurais: princípios e prática. 2. ed. Tradução Paulo Martins Engel. Porto Alegre: Bookman, 2001.
HUGO, Marcel. Uma interface de reconhecimento de voz para o sistema de gerenciamento de central de informação de fretes. 1995. Não paginado. Dissertação (Mestrado em Engenharia) – Programa de Pós-Graduação em Engenharia de Produção, Universidade Federal de Santa Catarina, Florianópolis. Disponível em: <http://www.eps.ufsc.br/disserta/hugo/indice/index.html>. Acesso em: 19 set. 2010.
LOESCH, Claudio; SARI, Solange T. Redes neurais artificiais: fundamentos e modelos. Blumenau: Ed. da FURB, 1996.
LUGER, George F. Inteligência artificial: estruturas e estratégias para a solução de problemas complexos. 4. ed. Tradução Paulo Martins Engel. Porto Alegre: Bookman, 2004.
MACHADO, André C. Tradutor de arquivos MIDI para texto utilizando linguagem funcional CLEAN. 2001. Dissertação (Mestrado em Engenharia Elétrica) – Pós-Graduação em Engenharia Elétrica, Universidade Federal de Uberlândia, Uberlândia. Disponível em: <http://www.demac.ufu.br/andrecampos/textos/textos.htm>. Acesso em: 10 maio 2011.
RUSSELL, Stuart J.; Norvig Peter. Inteligência artificial. 2. ed. Tradução Vandenberg D. de Souza. Rio de Janeiro: Elsevier, 2004.
SAVADOVSKY, Pedro. Introdução ao projeto de interfaces em linguagem natural. São Paulo: SID Informática SA, 1988.
STARKE, Julio F. Comparativo entre modelos de redes neurais aplicadas ao reconhecimento da fala. 1996. 71 f. Trabalho de Conclusão de Curso (Bacharelado em Ciência da Computação) - Centro de Ciências Exatas e Naturais, Universidade Regional de Blumenau, Blumenau.
TAFNER, Malcon A.; XEREZ, Marcos; RODRIGUES FILHO, Iilson W. Redes neurais artificiais: introdução e princípios de neurocomputação. Blumenau: Ed. da FURB, 1995.
65
TAFNER, Malcon A. Reconhecimento de palavras faladas isoladas usando redes neurais artificiais. 1996. Não paginado. Dissertação (Mestrado em Engenharia) – Programa de Pós-Graduação em Engenharia de Produção, Universidade Federal de Santa Catarina, Florianópolis. Disponível em: <http://www.eps.ufsc.br/disserta96/tafner/index/index.htm#fig>. Acesso em: 11 maio 2011.
66
APÊNDICE A – Cenários dos UC apresentados na especificação do protótipo
Os UC01, UC02, UC03, UC04, UC05, UC06, UC07, UC08 e UC09 relacionado ao
menu Rede é detalhado no Quadro 14, Quadro 15, Quadro 16, Quadro 17, Quadro 18, Quadro
19, Quadro 20, Quadro 21 e Quadro 22.
UC01 – Criar rede Pré-condições O protótipo deve estar inicializado. Cenário principal 1. O usuário escolhe a função Criar no menu Rede.
2. O usuário informa os dados requeridos pelo protótipo e aciona o botão Criar. 3. O protótipo valida os dados. 4. O protótipo cria a RNA e retorna para tela principal.
Fluxo alternativo No passo 2, caso o usuário queira cancelar a criação da RNA, basta acionar o botão Fechar, retornando para tela principal.
Exceção No passo 3, caso o protótipo não valide os dados, o mesmo apresenta uma mensagem de erro.
Pós-condição Criação de uma RNA conforme os dados informados. Quadro 14 – Caso de uso 01, criar rede
UC02 – Visualizar parâmetros da rede Pré-condições O protótipo deve estar inicializado e ter uma RNA ativa. Cenário principal 1. O usuário escolhe a função Visualizar parâmetros no menu Rede.
2. O protótipo apresenta os parâmetros da RNA ativa. 3. O usuário retorna para tela principal acionando o botão Fechar.
Pós-condição Visualização dos parâmetros da RNA ativa. Quadro 15 – Caso de uso 02, visualizar parâmetros da rede
UC03 – Treinar rede Pré-condições O protótipo deve estar inicializado e ter uma RNA ativa. Cenário principal 1. O usuário escolhe a função Treinar no menu Rede.
2. O usuário informa os dados requeridos pelo protótipo e aciona o botão Abrir para selecionar as amostras para realizar o treinamento da RNA. 3. O protótipo valida os dados. 4. O protótipo realiza o treinamento da RNA e retorna para tela principal após o treinamento ter sido realizado.
Fluxo alternativo No passo 2, caso o usuário queira cancelar o treinamento da RNA, basta acionar o botão Fechar, retornando para tela principal.
Exceção No passo 3, caso o protótipo não valide os dados, o mesmo apresenta uma mensagem de erro.
Pós-condição Realização do treinamento da RNA conforme os dados informados. Quadro 16 – Caso de uso 03, treinar rede
67
UC04 – Testar rede Pré-condições O protótipo deve estar inicializado e ter uma RNA ativa. Cenário principal 1. O usuário escolhe a função Testar no menu Rede.
2. O usuário aciona o botão Abrir para selecionar as amostras para realizar o teste da RNA. 3. O protótipo realiza o teste da RNA. 4. O usuário retorna para tela principal após o teste ter sido realizado acionando o botão Fechar.
Fluxo alternativo No passo 2, caso o usuário queira cancelar o teste da RNA, basta acionar o botão Fechar, retornando para tela principal.
Pós-condição Realização do teste na RNA conforme os dados informados. Quadro 17 – Caso de uso 04, testar rede
UC05 – Visualizar mapa da rede Pré-condições O protótipo deve estar inicializado, ter uma RNA ativa e ter sido pelo menos
realizado algum teste na RNA para a correta visualização. Cenário principal 1. O usuário escolhe a função Visualizar mapa no menu Rede.
2. O protótipo apresenta o mapa da RNA ativa. 3. O usuário retorna para tela principal acionando o botão Fechar.
Pós-condição Visualização do mapa da RNA ativa. Quadro 18 – Caso de uso 05, visualizar mapa da rede
UC06 – Ajustar rede Pré-condições O protótipo deve estar inicializado, ter uma RNA ativa e ter sido pelo menos
realizado algum teste na RNA para o correto funcionamento. Cenário principal 1. O usuário escolhe a função Ajustar no menu Rede.
2. O usuário informa os dados requeridos pelo protótipo e aciona o botão Abrir para selecionar as amostras para realizar o ajuste da RNA. 3. O protótipo valida os dados. 4. O protótipo realiza o ajuste da RNA. 5. O usuário retorna para tela principal após o ajuste ter sido realizado acionando o botão Fechar.
Fluxo alternativo No passo 2, caso o usuário queira cancelar o ajuste da RNA, basta acionar o botão Fechar, retornando para tela principal.
Exceção No passo 3, caso o protótipo não valide os dados, o mesmo apresenta uma mensagem de erro.
Pós-condição Realização do teste da RNA conforme os dados informados. Quadro 19 – Caso de uso 06, ajustar rede
UC07 – Visualizar log da rede Pré-condições O protótipo deve estar inicializado. Cenário principal 1. O usuário escolhe a função Visualizar log no menu Rede.
2. O protótipo apresenta o log de operações. 3. O usuário retorna para tela principal acionando o botão Fechar.
Fluxo alternativo No passo 2, caso o usuário queira limpar o log, basta acionar o botão Limpar. Pós-condição Visualização do log de operações da RNA.
Quadro 20 – Caso de uso 07, visualizar log da rede
68
UC08 – Salvar rede Pré-condições O protótipo deve estar inicializado e ter uma RNA ativa. Cenário principal 1. O usuário escolhe a função Salvar no menu Rede.
2. O usuário informa os dados requeridos pelo protótipo para salvar a RNA ativa e aciona o botão Salvar. 3. O protótipo salva a RNA e retorna para tela principal.
Fluxo alternativo No passo 2, caso o usuário queira cancelar o processo de salvamento da RNA ativa, basta acionar o botão Cancelar, retornando para tela principal.
Pós-condição Salva a RNA conforme os dados informados. Quadro 21 – Caso de uso 08, salvar rede
UC09 – Recriar rede Pré-condições O protótipo deve estar inicializado. Cenário principal 1. O usuário escolhe a função Recriar no menu Rede.
2. O usuário seleciona uma RNA para recriar e aciona o botão Abrir. 3. O protótipo recria a RNA selecionada e retorna para tela principal.
Fluxo alternativo No passo 2, caso o usuário queira cancelar o processo de recriação da RNA, basta acionar o botão Cancelar, retornando para tela principal.
Pós-condição Recria uma RNA escolhida. Quadro 22 – Caso de uso 09, recriar rede
Os UC10, UC11, UC12 e UC13 relacionado ao menu Áudio é detalhado nos Quadro
23, Quadro 24, Quadro 25 e Quadro 26.
UC10 – Capturar áudio Pré-condições O protótipo deve estar inicializado e ter uma RNA ativa. Cenário principal 1. O usuário escolhe a função Capturar no menu Áudio.
2. O protótipo inicializa a captura do áudio. Pós-condição Inicializa a captura do áudio para o reconhecimento de voz.
Quadro 23 – Caso de uso 10, reproduzir áudio
UC11 – Suspender áudio Pré-condições O protótipo deve estar inicializado, ter uma RNA ativa e a captura do áudio
ativada. Cenário principal 1. O usuário escolhe a função Suspender no menu Áudio.
2. O protótipo suspender a captura do áudio armazenando. Pós-condição Suspende a captura do áudio para o reconhecimento de voz.
Quadro 24 – Caso de uso 11, suspender áudio
UC12 – Reproduzir áudio Pré-condições O protótipo deve estar inicializado, ter uma RNA ativa e possuir um áudio
capturado. Cenário principal 1. O usuário escolhe a função Reproduzir no menu Áudio.
2. O protótipo reproduz o áudio captado. Pós-condição Reproduz o áudio captado.
Quadro 25 – Caso de uso 12, reproduzir áudio
69
UC13 – Armazenar áudio Pré-condições O protótipo deve estar inicializado, ter uma RNA ativa e possuir um áudio
capturado. Cenário principal 1. O usuário escolhe a função Armazenar no menu Áudio.
2. O usuário informa os dados requeridos pelo protótipo para salvar o áudio capturado e aciona o botão Salvar. 3. O protótipo salva o áudio capturado e retorna para tela principal.
Fluxo alternativo No passo 2, caso o usuário queira cancelar o processo de salvar o áudio capturado, basta acionar o botão Cancelar, retornando para tela principal.
Pós-condição Salva o áudio capturado conforme os dados informados. Quadro 26 – Caso de uso 13, armazenar áudio
O UC14 relacionado ao menu Geral é detalhado no Quadro 27.
UC14 – Visualizar sobre Pré-condições O protótipo deve estar inicializado. Cenário principal 1. O usuário escolhe a função Sobre no menu Geral.
2. O protótipo apresenta as informações do protótipo. 3. O usuário retorna para tela principal acionando o botão Fechar.
Pós-condição Visualização das informações referente ao protótipo. Quadro 27 – Caso de uso 14, visualizar sobre
70
APÊNDICE B – Código das classes relevantes ao foco do protótipo implementado
O código completo das classes:
a) BuscaDeSinais: é apresentado no Quadro 28;
b) PreProcessamento: é apresentada no Quadro 29;
c) Kohonen: é apresentado no Quadro 30;
d) Neuronio: é apresentado no Quadro 31;
e) Labirinto: é apresentada no Quadro 32.
71
public class BuscaDeSinais { private AudioFormat audioFormat; private TargetDataLine targetDataLine; private ByteArrayOutputStream byteArrayOutputStream; private SourceDataLine sourceDataLine; private AudioInputStream audioInputStream; private boolean stopCapture; private TelaLog telaLog = null; // Inicializa a classe setando as caracteristicas do áudio a ser manibulado. public BuscaDeSinais() { this.audioFormat = new AudioFormat(16000.0F, 8, 1, true, false); } // Método que dispara a captura do áudio. public void capturar() { try { this.targetDataLine = (TargetDataLine) AudioSystem.getLine(new DataLine.Info(TargetDataLine.class, this.audioFormat)); this.targetDataLine.open(this.audioFormat); this.stopCapture = false; new CapturaThread().start(); } catch (LineUnavailableException ex) { this.telaLog.escreverLog("Exceção na captura do som! " + ex); } } public void setTelaLog(TelaLog _telaLog) { this.telaLog = _telaLog; } // Método que suspende pela captura do áudio. public void suspender() { this.stopCapture = true; this.targetDataLine.stop(); telaLog.escreverLog("Captura parada!"); } // Retorna um array de bytes contendo os valores do áudio captado. public byte[] getArrayBytes() { return this.byteArrayOutputStream.toByteArray(); } // Responsável para captura do áudio. public class CapturaThread extends Thread { private byte tempBuffer[] = new byte[1000]; @Override public void run() { try { byteArrayOutputStream = new ByteArrayOutputStream(); targetDataLine.start(); telaLog.escreverLog("\nCapturando!"); while (!stopCapture) { byteArrayOutputStream.write(this.tempBuffer, 0, targetDataLine.read(this.tempBuffer, 0, this.tempBuffer.length)); } targetDataLine.flush(); targetDataLine.close(); byteArrayOutputStream.close(); } catch (Exception ex) { telaLog.escreverLog("Exceção na thread de captura do som! " + ex); } } }
72
// Método responsável por gravar em arquivo o áudio captado. public void gravar(String nomeArquivo) { try { this.telaLog.escreverLog("Salvando arquivo de áudio! "); File diretorioAudio = new File(System.getProperty("user.dir") + "/Audios"); // Cria diretório Áudio se não existir. if (!diretorioAudio.exists()) { diretorioAudio.mkdir(); } File diretorioGravado = new File(diretorioAudio + "/Gravado"); // Cria diretório Gravado se não existir. if (!diretorioGravado.exists()) { diretorioGravado.mkdir(); } File arquivo = new File(diretorioGravado.getAbsolutePath() + "/" + nomeArquivo); byte[] audioData = this.byteArrayOutputStream.toByteArray(); this.audioInputStream = new AudioInputStream(new ByteArrayInputStream(audioData), this.audioFormat, audioData.length / this.audioFormat.getFrameSize()); AudioSystem.write(this.audioInputStream, AudioFileFormat.Type.WAVE, arquivo); this.telaLog.escreverLog("Arquivo de áudio salvo com sucesso! "); } catch (IOException ex) { this.telaLog.escreverLog("Exceção na gravação do som! " + ex); } } // Método que dispara a reprodução do áudio. public void reproducao() { try { byte[] audioData = this.byteArrayOutputStream.toByteArray(); this.audioInputStream = new AudioInputStream(new ByteArrayInputStream(audioData), this.audioFormat, audioData.length / this.audioFormat.getFrameSize()); this.sourceDataLine = (SourceDataLine) AudioSystem.getLine(new DataLine.Info(SourceDataLine.class, this.audioFormat)); this.sourceDataLine.open(this.audioFormat); new ReproducaoThread().start(); } catch (LineUnavailableException ex) { this.telaLog.escreverLog("Exceção na reprodução do som! " + ex); } } // Responsável para reprodução do audio. public class ReproducaoThread extends Thread { private byte tempBuffer[] = new byte[1000]; @Override public void run() { try { int cont; sourceDataLine.start(); telaLog.escreverLog("\nReproduzindo!"); while ((cont = audioInputStream.read(this.tempBuffer, 0, this.tempBuffer.length)) > 0) { sourceDataLine.write(this.tempBuffer, 0, cont); } sourceDataLine.drain(); sourceDataLine.close(); telaLog.escreverLog("Reprodução parada!");
73
} catch (Exception ex) { telaLog.escreverLog("Exceção na thread de reprodução do som! " + ex); } } } }
Quadro 28 – Código classe busca de sinais
74
public class PreProcessamento { private int qtdEntradasRede; private ArrayList<String> arrayNomesArqsTratamento = new ArrayList<String>(); private ArrayList<float[]> listaArraysPRede = new ArrayList<float[]>(); private byte[] arraySinalOriginal; private byte[] arraySinalComSilencio; private float[] arrayPRede = null; private TelaLog telaLog = null; // Método inicializa a classe e atribui a qtd entradas da rede. public PreProcessamento(int _qtdEntradasRede) { this.qtdEntradasRede = _qtdEntradasRede; } public void setTelaLog(TelaLog _telaLog) { this.telaLog = _telaLog; } // Método que adiciona os nomes dos arquivos selecionados em uma lista para futuros processamentos. public void addNomesArquivosTratamento(String _nomeArqs) { this.arrayNomesArqsTratamento.add(_nomeArqs); } // Método que limpa a lista que possui os nomes dos arquivos e listas dos arrays processados. public void removerNomesArquivosTratamento() { this.arrayNomesArqsTratamento.removeAll(this.arrayNomesArqsTratamento); this.listaArraysPRede.removeAll(this.listaArraysPRede); } // Método que interage sobre a lista dos nomes dos arquivos armazenando e após o processo adiciona na lista de arraysPRede. public void tratarArqs() { for (String arq : this.arrayNomesArqsTratamento) { AudioInputStream stream = null; try { stream = AudioSystem.getAudioInputStream(new File(arq)); int tamanhoArray = (int) (stream.getFrameLength() * stream.getFormat().getFrameSize()); this.arraySinalOriginal = new byte[tamanhoArray]; stream.read(this.arraySinalOriginal); processarAudio(); } catch (UnsupportedAudioFileException ex) { this.telaLog.escreverLog("Arquivo de audio não suportado no tratarArqs! " + ex); } catch (IOException ex) { this.telaLog.escreverLog("Problema de I/O no tratarArqs! " + ex); } finally { try { stream.close(); } catch (IOException ex) { this.telaLog.escreverLog("Problema ao fechar stream no tratarArqs! " + ex); } } } } // Método que recebe o array, faz o processamento do mesmo e adiciona na lista de arraysPRede. public void audioCaptado() { this.telaLog.escreverLog("Pré-processamento do sinal de áudio captado!"); removerNomesArquivosTratamento();
75
this.arrayNomesArqsTratamento.add(System.getProperty("user.dir") + "/Audios/Gravado/temp.wav"); tratarArqs(); new File(System.getProperty("user.dir") + "/Audios/Gravado/temp.wav").delete(); this.telaLog.escreverLog("Pré-processamento do sinal de áudio captado concluído!"); } // Método que centraliza todas as chamadas necessárias para o processamento do áudio. private void processarAudio() { eliminaParteNegativaDoSinal(); eliminarSilencioInicioEFimAmostra(); sinalReduzidoAtravesMedias(); sinalMediado(); normalizacaoSinal(); armazenar(); } // Elimina parte negativa do sinal amostrado. private void eliminaParteNegativaDoSinal() { for (int i = 0; i < this.arraySinalOriginal.length; i++) { if (this.arraySinalOriginal[i] < 0) { this.arraySinalOriginal[i] = 0; } } } // Eliminação do silêncio do inicio e final do sinal de áudio digitalizado. private void eliminarSilencioInicioEFimAmostra() { int cont = 0; int indiceInicio = 0; // Identifica uma seqüência inicial continua maior que 0. for (int i = 0; i < this.arraySinalOriginal.length; i++) { if (this.arraySinalOriginal[i] > 0) { cont++; if (indiceInicio == 0) { indiceInicio = i; } } else if (cont >= 25) { break; } else { cont = 0; indiceInicio = 0; } } cont = 0; int indiceFinal = 0; // Identifica uma seqüência final continua maior que 0. for (int i = this.arraySinalOriginal.length - 1; i >= 0; i--) { if (this.arraySinalOriginal[i] > 0) { cont++; if (indiceFinal == 0) { indiceFinal = i; } } else if (cont >= 25) { break; } else { cont = 0; indiceFinal = 0; } } cont = 0;
76
this.arraySinalComSilencio = new byte[(indiceFinal - indiceInicio) + 1]; // Extrai a amostra do som tirando o silêncio do array original. for (int i = indiceInicio; i <= indiceFinal; i++) { this.arraySinalComSilencio[cont] = this.arraySinalOriginal[i]; cont++; } } // Reduz o sinal de áudio digitalizado através das medias. private void sinalReduzidoAtravesMedias() { // Taxa de redução. float taxaReducao = this.arraySinalComSilencio.length / (float) this.qtdEntradasRede; // Taxa de redução com arrdondamento para cima. BigDecimal valorArredondado = new BigDecimal(taxaReducao).setScale(0, BigDecimal.ROUND_CEILING); // Cria uma estrutura de armazenamento do tamanho da quantidade de entradas da rede. this.arrayPRede = new float[this.qtdEntradasRede]; int indexArrayPRede = 0; int soma = 0; int contCorte = 0; // Pega um valor de média dentro da faixa para de corte e atribui para o array. for (int i = 0; i < this.arraySinalComSilencio.length; i++) { soma += this.arraySinalComSilencio[i]; contCorte++; if (contCorte == valorArredondado.intValue()) { this.arrayPRede[indexArrayPRede] = soma / (float) valorArredondado.intValue(); indexArrayPRede++; soma = 0; contCorte = 0; } } // Caso reste sobras estas serram colocadas na última posição do array. if (contCorte > 0) { this.arrayPRede[indexArrayPRede] = soma / (float) valorArredondado.intValue(); } } // Iguala 3 sinais consecutivos pelo valor mais alto entre eles. (Uma forma de redução) private void sinalMediado() { // Estrutura temporária para armazenar os valores mediados. float tempArrayPRede[] = new float[this.qtdEntradasRede]; int indexArrayPRedeTemp = 0; float maxValor = Integer.MIN_VALUE; int contCorte = 0; // Realiza a mediação do sinal enquanto corte for == 3. for (int i = 0; i < this.arrayPRede.length; i++) { if (this.arrayPRede[i] > maxValor) { maxValor = this.arrayPRede[i]; } contCorte++; if (contCorte == 3) { for (int j = indexArrayPRedeTemp; j <= i; j++) { tempArrayPRede[j] = maxValor; indexArrayPRedeTemp++;
77
} maxValor = Integer.MIN_VALUE; contCorte = 0; } } // Caso reste sobras estas serram colocadas na última posição do array temp. if (contCorte > 0) { for (int i = indexArrayPRedeTemp; i < indexArrayPRedeTemp + contCorte; i++) { tempArrayPRede[i] = maxValor; } } // Copia o tempArrayPRede para o arrayPRede. System.arraycopy(tempArrayPRede, 0, this.arrayPRede, 0, this.arrayPRede.length); } // Normaliza a intensidade do sinal em torno do valor 150. private void normalizacaoSinal() { float maiorValor = Integer.MIN_VALUE; // Encontra maior valor dentro do vetor arrayPRede para efetuar a normalização. for (int i = 0; i < this.arrayPRede.length; i++) { if (this.arrayPRede[i] > maiorValor) { maiorValor = this.arrayPRede[i]; } } // Realiza a normalização do sinal. for (int i = 0; i < this.arrayPRede.length; i++) { this.arrayPRede[i] = (this.arrayPRede[i] * 150) / (float) maiorValor; } } // Método que armazena na listaArraysPRede o array tratado. private void armazenar() { this.listaArraysPRede.add(this.arrayPRede); } // Método que retorna a listaArraysPRede. public ArrayList<float[]> getListaArraysPRede() { return this.listaArraysPRede; } }
Quadro 29 – Código classe pré-processamento
78
public class Kohonen { private int qtdEntradas; private int qtdLin; private int qtdCol; private float fatorAprendizagem; private int raioTopologico; private int qtdInteracoes; private ArrayList<Neuronio> neuronios = new ArrayList<Neuronio>(); private ArrayList<float[]> treinamento = new ArrayList<float[]>(); private int pLin; private int pCol; private TelaLog telaLog = null; // Construtor responsável por criar uma nova RNA. public Kohonen(int _qtdEntradas, int _qtdLin, int _qtdCol) { this.neuronios.removeAll(this.neuronios); this.qtdEntradas = _qtdEntradas; this.qtdLin = _qtdLin; this.qtdCol = _qtdCol; } // Método responsáver por cria os neurônios da RNA nova conforme a quantidade de linhas e colunas informadas. public void criarRede() { for (int lin = 0; lin < this.getQtdLin(); lin++) { for (int col = 0; col < this.getQtdCol(); col++) { this.neuronios.add(new Neuronio(lin + 1, col + 1, this.qtdEntradas)); } } this.telaLog.escreverLog("RNA criada com sucesso!"); } // Construtor responsável por recriar a RNA com base em um arquivo contendo os dados necessários para isto. public Kohonen(String _arquivo, TelaLog _telaLog) { this.telaLog = _telaLog; File arquivo = new File(_arquivo); BufferedReader in = null; try { if (arquivo.exists()) { this.neuronios.removeAll(this.neuronios); in = new BufferedReader(new FileReader(arquivo.getAbsolutePath())); this.qtdEntradas = Integer.parseInt(in.readLine()); this.qtdLin = Integer.parseInt(in.readLine()); this.qtdCol = Integer.parseInt(in.readLine()); this.fatorAprendizagem = Float.parseFloat(in.readLine()); this.raioTopologico = Integer.parseInt(in.readLine()); this.qtdInteracoes = Integer.parseInt(in.readLine()); in.readLine(); // Recria os neurônios da RNA. for (int qtdN = 0; qtdN < this.qtdLin * this.qtdCol; qtdN++) { int linha = Integer.parseInt(in.readLine()); int coluna = Integer.parseInt(in.readLine()); char funcao = in.readLine().charAt(0); float[] vetPesos = new float[this.qtdEntradas]; // Atribui os pesos ao neurônio recriados. for (int vP = 0; vP < vetPesos.length; vP++) { vetPesos[vP] = Float.parseFloat(in.readLine()); } // Add os neurônios a lista de neurônios. this.neuronios.add(new Neuronio(linha, coluna, this.qtdEntradas, vetPesos, funcao));
79
in.readLine(); } } this.telaLog.escreverLog("RNA recriada com sucesso!"); } catch (IOException ex) { this.telaLog.escreverLog("Problema em ler o arquivo para criação da Rede Neural! " + ex); } finally { try { if (in != null) { in.close(); } } catch (IOException ex) { this.telaLog.escreverLog("Problema em fechar o Buffer de leitura da criação da Rede Neural Artificial! " + ex); } } } // Método responsável por salvar os dados referente a uma RNA. public void salvarRede(String nomeArquivo) { File arquivo = new File(nomeArquivo); PrintWriter out = null; try { out = new PrintWriter(arquivo); out.println(this.qtdEntradas); out.println(this.getQtdLin()); out.println(this.getQtdCol()); out.println(this.fatorAprendizagem); out.println(this.raioTopologico); out.println(this.qtdInteracoes); out.println(); // Salva os neurônios existentes na RNA. for (int n = 0; n < this.neuronios.size(); n++) { out.println(this.neuronios.get(n).getLinha()); out.println(this.neuronios.get(n).getColuna()); out.println(this.neuronios.get(n).getFuncao()); float[] vetPesos = this.neuronios.get(n).getPesosVetor(); // Salva os pesos do neurônio da RNA. for (int vP = 0; vP < vetPesos.length; vP++) { out.println(vetPesos[vP]); } out.println(); } this.telaLog.escreverLog("RNA salva com sucesso!"); } catch (IOException ex) { this.telaLog.escreverLog("Problema na gravação do arquivo da Rede Neural Artificial! " + ex); } finally { out.close(); } } public void setTelaLog(TelaLog _telaLog) { this.telaLog = _telaLog; } // Método que retorna a quantidade de entradas da RNA. public int getQtdEntradas() { return this.qtdEntradas; } public int getQtdLin() { return this.qtdLin; } public int getQtdCol() {
80
return this.qtdCol; } // Método responsável por atribuir os valores necessários para realizar o treinamento da RNA. public void setDadosTreinamento(float _fatorAprendizagem, int _raioTopologico, int _qtdInteracoes) { this.fatorAprendizagem = _fatorAprendizagem; this.raioTopologico = _raioTopologico; this.qtdInteracoes = _qtdInteracoes; } // Método responsável por remover todas as amostras encontrada na lista de treinamento da RNA. public void removeTodasAmostrasParaTreinamento() { this.treinamento.removeAll(this.treinamento); } // Método responsável por adicionar as amostras a lista de treinamento da RNA. public void addAmostraTreinamento(float[] _vetAmostra) { this.treinamento.add(_vetAmostra); } // Método responsável por retornar a lista de neurônios existentes na RNA. public ArrayList<Neuronio> getNeuronios() { return this.neuronios; } // Método que realiza o teste na RNA retornando o neurônio ganhador para uma amostra apresentada. public Neuronio testarRede(float[] _vetAmostra) { neuronioGanhador(_vetAmostra); Neuronio neuronio = null; // Percorre os neurônios existentes na RNA até encontrar o neurônio correspondente a linha e coluna pesquisado. for (int n = 0; n < this.neuronios.size(); n++) { if (this.neuronios.get(n).getLinha() == this.pLin && this.neuronios.get(n).getColuna() == this.pCol) { neuronio = this.neuronios.get(n); break; } } return neuronio; } // Método que identifica o neurônio ganhador para uma amostra apresentada. private void neuronioGanhador(float[] _vetAmostra) { float menorValor = Float.MAX_VALUE; this.pLin = 0; this.pCol = 0; // Percorre a lista de neurônios afim de encontrar o neurônio suscetível a amostra apresentada. for (int n = 0; n < this.neuronios.size(); n++) { float valor = this.neuronios.get(n).treinamentoEFuncionamentoDoNeuronio(_vetAmostra); if (valor < menorValor) { menorValor = valor; this.pLin = this.neuronios.get(n).getLinha(); this.pCol = this.neuronios.get(n).getColuna(); } } } // Realiza o treinamento da RNA.
81
public void treinarRede() { // Realiza um cálculo para saber quando será realizado o decremento do raio topológico. BigDecimal valorArredondadoPDecrementoRaio = new BigDecimal(this.qtdInteracoes / (float) this.raioTopologico).setScale(0, BigDecimal.ROUND_CEILING); int contInt = 0; // Qtd de iterações para o treinamento. for (int intr = 0; intr < this.qtdInteracoes; intr++) { // Submete as amostras existentes na lista de treinamento para a RNA. for (int trein = 0; trein < this.treinamento.size(); trein++) { neuronioGanhador(this.treinamento.get(trein)); // Faz o ajuste de pesos nos neurônios vizinhos ao ganhador quando necessário, incluindo o mesmo. for (int n = 0; n < this.neuronios.size(); n++) { if (this.neuronios.get(n).getLinha() >= this.pLin - this.raioTopologico && this.neuronios.get(n).getLinha() <= this.pLin + this.raioTopologico) { if (this.neuronios.get(n).getColuna() >= this.pCol - this.raioTopologico && this.neuronios.get(n).getColuna() <= this.pCol + this.raioTopologico) { this.neuronios.get(n).ajusteDePesos(this.fatorAprendizagem, this.treinamento.get(trein)); } } } } contInt++; // Decrementa o raio topológico conforme a quantidade de iterações realizadas quando necessário. if (valorArredondadoPDecrementoRaio.intValue() == contInt) { this.raioTopologico--; contInt = 0; } // Decrementa o fator de aprendizagem. this.fatorAprendizagem = this.fatorAprendizagem * (1 - (intr + 1) / (float) this.qtdInteracoes); } } }
Quadro 30 – Código classe Kohonen
82
public class Neuronio { private int pLinha; private int pColuna; private float[] matrizDePesos; private char funcao; // Inicializa a clase gerando pesos sinápticos aleatoriamente. public Neuronio(int _PLinha, int _PColuna, int tamanhoEntrada) { this.pLinha = _PLinha; this.pColuna = _PColuna; this.matrizDePesos = new float[tamanhoEntrada]; this.funcao = ' '; geraPesos(); } // Inicializa a classe através de dados existentes. public Neuronio(int _PLinha, int _PColuna, int tamanhoEntrada, float[] _MatrizDePesos, char _funcao) { this.pLinha = _PLinha; this.pColuna = _PColuna; this.matrizDePesos = new float[tamanhoEntrada]; this.matrizDePesos = _MatrizDePesos; this.funcao = _funcao; } // Método responsável por gerar os pesos sinápticos do neurônio. private void geraPesos() { Random r = new Random(); for (int i = 0; i < this.matrizDePesos.length; i++) { this.matrizDePesos[i] = r.nextFloat(); } } // Método utilizado tanto para realizar o treinamento quanto para o funcionamento do nerônio. public float treinamentoEFuncionamentoDoNeuronio(float[] _matrizDeEntrada) { float valor = 0; for (int i = 0; i < this.matrizDePesos.length; i++) { valor += Math.pow((_matrizDeEntrada[i] - this.matrizDePesos[i]), 2); } return valor; } // Método utilizado para realizar o ajuste de pesos do neurônio. public void ajusteDePesos(float taxaAprendizagem, float[] _matrizDeEntrada) { for (int i = 0; i < this.matrizDePesos.length; i++) { this.matrizDePesos[i] = this.matrizDePesos[i] + taxaAprendizagem * (_matrizDeEntrada[i] - this.matrizDePesos[i]); } } // Método utilizado para realizar o ajuste fino de pesos do neurônio. public void ajusteFinoDePesos(float taxaAprendizagem, float[] _matrizDeEntrada, boolean positivo) { for (int i = 0; i < this.matrizDePesos.length; i++) { if (positivo) { this.matrizDePesos[i] = this.matrizDePesos[i] + taxaAprendizagem * (_matrizDeEntrada[i] - this.matrizDePesos[i]); } else { this.matrizDePesos[i] = this.matrizDePesos[i] - taxaAprendizagem * (_matrizDeEntrada[i] - this.matrizDePesos[i]); } } }
83
// Retorna o número da linha que está posicionado o neurônio na camada competitiva. public int getLinha() { return this.pLinha; } // Retorna o número da coluna que está posicionado o neurônio na camada competitiva. public int getColuna() { return this.pColuna; } // Retorna a função do neurônio. public char getFuncao() { return this.funcao; } // Atribui a função do neurônio. public void setFuncao(char _funcao) { this.funcao = _funcao; } // Retorna a matriz de pesos do neurônio. public float[] getPesosVetor() { return this.matrizDePesos; } }
Quadro 31 – Código classe neurônio
84
public class Labirinto implements GLEventListener, KeyListener { private GL gl; private GLU glu; private GLAutoDrawable glDrawable; private int xPonto = 27; private int yPonto = -27; // Método responsável por iniciar as váriáveis necessárias para o desenho gráfico. @Override public void init(GLAutoDrawable glad) { this.gl = glad.getGL(); this.glu = new GLU(); this.glDrawable = glad; this.glDrawable.setGL(new DebugGL(this.gl)); this.gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f); this.glu.gluOrtho2D(-31.0f, 31.0f, -30.0f, 30.0f); } // Método que realiza o desenho do labirinto e do ponto em cada atualização. @Override public void display(GLAutoDrawable glad) { this.gl.glClear(this.gl.GL_COLOR_BUFFER_BIT); labirinto(); ponto(); this.gl.glFlush(); } // Método que realiza a captura dos eventos de teclado. @Override public void keyPressed(KeyEvent ke) { movimentoLabirinto(ke.getKeyCode()); } // Método que realiza o movimento do ponto no labirinto conforme um código recebido. public void movimentoLabirinto(int codigo) { // Esquerda. if (codigo == 37) { if (this.xPonto > -27) { this.xPonto -= 6; } } else // Prossiga. if (codigo == 38) { if (this.yPonto < 27) { this.yPonto += 6; } } else // Direita. if (codigo == 39) { if (this.xPonto < 27) { this.xPonto += 6; } } else // Retorne. if (codigo == 40) { if (this.yPonto > -27) { this.yPonto -= 6; } } else // Inicio. if (codigo == 73) { this.xPonto = 27; this.yPonto = -27; } this.glDrawable.repaint(); } // Método responsável por realizar o desenho do ponto. private void ponto() {
85
this.gl.glColor3f(0, 0, 1); this.gl.glPointSize(30); this.gl.glBegin(this.gl.GL_POINTS); this.gl.glVertex2f(this.xPonto, this.yPonto); this.gl.glEnd(); } // Método responsável por realizar o desenho do labirinto. public void labirinto() { this.gl.glColor3f(1, 0, 0); this.gl.glLineWidth(2); this.gl.glBegin(this.gl.GL_LINES); // Quadro. //----------------------------------------------------------------- // Linha vertical esquerda. this.gl.glVertex2f(-30.0f, 30.0f); this.gl.glVertex2f(-30.0f, -24.0f); // Linha vertical esquerda superior pequena. this.gl.glVertex2f(-24.0f, 30.0f); this.gl.glVertex2f(-24.0f, 24.0f); // Linha vertical direita. this.gl.glVertex2f(30.0f, 24.0f); this.gl.glVertex2f(30.0f, -30.0f); // Linha vertical direita inferior pequena. this.gl.glVertex2f(24.0f, -24.0f); this.gl.glVertex2f(24.0f, -30.0f); //----------------------------------------------------------------- // Linha horizontal superior. this.gl.glVertex2f(-24.0f, 24.0f); this.gl.glVertex2f(30.0f, 24.0f); // Linha horizontal inferior. this.gl.glVertex2f(-30.0f, -24.0f); this.gl.glVertex2f(24.0f, -24.0f); //----------------------------------------------------------------- // Linhas: // Linha 1. this.gl.glVertex2f(-24.0f, 18.0f); this.gl.glVertex2f(-18.0f, 18.0f); this.gl.glVertex2f(6.0f, 18.0f); this.gl.glVertex2f(12.0f, 18.0f); this.gl.glVertex2f(12.0f, 18.0f); this.gl.glVertex2f(18.0f, 18.0f); this.gl.glVertex2f(18.0f, 18.0f); this.gl.glVertex2f(24.0f, 18.0f); // Linha 2. this.gl.glVertex2f(-30.0f, 12.0f); this.gl.glVertex2f(-24.0f, 12.0f); this.gl.glVertex2f(-18.0f, 12.0f); this.gl.glVertex2f(-12.0f, 12.0f); this.gl.glVertex2f(6.0f, 12.0f); this.gl.glVertex2f(12.0f, 12.0f); this.gl.glVertex2f(18.0f, 12.0f); this.gl.glVertex2f(24.0f, 12.0f); // Linha 3. this.gl.glVertex2f(-24.0f, 6.0f); this.gl.glVertex2f(-18.0f, 6.0f); this.gl.glVertex2f(-6.0f, 6.0f); this.gl.glVertex2f(0.0f, 6.0f); this.gl.glVertex2f(0.0f, 6.0f); this.gl.glVertex2f(6.0f, 6.0f); this.gl.glVertex2f(12.0f, 6.0f); this.gl.glVertex2f(18.0f, 6.0f); // Linha 4. this.gl.glVertex2f(-24.0f, 0.0f); this.gl.glVertex2f(-18.0f, 0.0f); this.gl.glVertex2f(-12.0f, 0.0f); this.gl.glVertex2f(-6.0f, 0.0f); this.gl.glVertex2f(12.0f, 0.0f); this.gl.glVertex2f(18.0f, 0.0f);
86
this.gl.glVertex2f(18.0f, 0.0f); this.gl.glVertex2f(24.0f, 0.0f); // Linha 5. this.gl.glVertex2f(-30.0f, -6.0f); this.gl.glVertex2f(-24.0f, -6.0f); this.gl.glVertex2f(-24.0f, -6.0f); this.gl.glVertex2f(-18.0f, -6.0f); this.gl.glVertex2f(-12.0f, -6.0f); this.gl.glVertex2f(-6.0f, -6.0f); this.gl.glVertex2f(-6.0f, -6.0f); this.gl.glVertex2f(0.0f, -6.0f); this.gl.glVertex2f(0.0f, -6.0f); this.gl.glVertex2f(6.0f, -6.0f); this.gl.glVertex2f(12.0f, -6.0f); this.gl.glVertex2f(18.0f, -6.0f); this.gl.glVertex2f(18.0f, -6.0f); this.gl.glVertex2f(24.0f, -6.0f); // Linha 6. // Linha 7. this.gl.glVertex2f(-24.0f, -18.0f); this.gl.glVertex2f(-18.0f, -18.0f); this.gl.glVertex2f(-18.0f, -18.0f); this.gl.glVertex2f(-12.0f, -18.0f); this.gl.glVertex2f(-12.0f, -18.0f); this.gl.glVertex2f(-6.0f, -18.0f); this.gl.glVertex2f(6.0f, -18.0f); this.gl.glVertex2f(12.0f, -18.0f); this.gl.glVertex2f(18.0f, -18.0f); this.gl.glVertex2f(24.0f, -18.0f); this.gl.glVertex2f(24.0f, -18.0f); this.gl.glVertex2f(30.0f, -18.0f); //----------------------------------------------------------------- // Colunas: // Coluna 1. this.gl.glVertex2f(-24.0f, 24.0f); this.gl.glVertex2f(-24.0f, 18.0f); this.gl.glVertex2f(-24.0f, 12.0f); this.gl.glVertex2f(-24.0f, 6.0f); this.gl.glVertex2f(-24.0f, 6.0f); this.gl.glVertex2f(-24.0f, 0.0f); this.gl.glVertex2f(-24.0f, -6.0f); this.gl.glVertex2f(-24.0f, -12.0f); this.gl.glVertex2f(-24.0f, -18.0f); this.gl.glVertex2f(-24.0f, -24.0f); // Coluna 2. this.gl.glVertex2f(-18.0f, 18.0f); this.gl.glVertex2f(-18.0f, 12.0f); this.gl.glVertex2f(-18.0f, -6.0f); this.gl.glVertex2f(-18.0f, -12.0f); // Coluna 3. this.gl.glVertex2f(-12.0f, 18.0f); this.gl.glVertex2f(-12.0f, 12.0f); this.gl.glVertex2f(-12.0f, 6.0f); this.gl.glVertex2f(-12.0f, 0.0f); this.gl.glVertex2f(-12.0f, -6.0f); this.gl.glVertex2f(-12.0f, -12.0f); // Coluna 4. this.gl.glVertex2f(-6.0f, 24.0f); this.gl.glVertex2f(-6.0f, 18.0f); this.gl.glVertex2f(-6.0f, 18.0f); this.gl.glVertex2f(-6.0f, 12.0f); this.gl.glVertex2f(-6.0f, 6.0f); this.gl.glVertex2f(-6.0f, 0.0f); this.gl.glVertex2f(-6.0f, -12.0f); this.gl.glVertex2f(-6.0f, -18.0f); // Coluna 5. this.gl.glVertex2f(-0.0f, 24.0f); this.gl.glVertex2f(-0.0f, 18.0f); this.gl.glVertex2f(-0.0f, 18.0f);
87
this.gl.glVertex2f(-0.0f, 12.0f); this.gl.glVertex2f(-0.0f, 6.0f); this.gl.glVertex2f(-0.0f, 0.0f); this.gl.glVertex2f(-0.0f, -12.0f); this.gl.glVertex2f(-0.0f, -18.0f); this.gl.glVertex2f(-0.0f, -18.0f); this.gl.glVertex2f(-0.0f, -24.0f); // Coluna 6. this.gl.glVertex2f(6.0f, 18.0f); this.gl.glVertex2f(6.0f, 12.0f); this.gl.glVertex2f(6.0f, 6.0f); this.gl.glVertex2f(6.0f, 0.0f); this.gl.glVertex2f(6.0f, -6.0f); this.gl.glVertex2f(6.0f, -12.0f); // Coluna 7. this.gl.glVertex2f(12.0f, 24.0f); this.gl.glVertex2f(12.0f, 18.0f); this.gl.glVertex2f(12.0f, -6.0f); this.gl.glVertex2f(12.0f, -12.0f); this.gl.glVertex2f(12.0f, -12.0f); this.gl.glVertex2f(12.0f, -18.0f); // Coluna 8. this.gl.glVertex2f(18.0f, -6.0f); this.gl.glVertex2f(18.0f, -12.0f); // Coluna 9. this.gl.glVertex2f(24.0f, 12.0f); this.gl.glVertex2f(24.0f, 6.0f); this.gl.glVertex2f(24.0f, 6.0f); this.gl.glVertex2f(24.0f, 0.0f); this.gl.glVertex2f(24.0f, -6.0f); this.gl.glVertex2f(24.0f, -12.0f); this.gl.glEnd(); } }
Quadro 32 – Código classe labirinto