You are on page 1of 203

UNIVERSIDADE FEDERAL DE SANTA CATARINA

DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA


SISTEMAS DE INFORMAÇÃO

Redes Neurais Artificiais Aplicadas na Construção de Exercícios


para Verificação de Aprendizagem

João Carlos Testi Ferreira


Júnior Barbosa Dymow

Florianópolis, outubro de 2005


João Carlos Testi Ferreira
Júnior Barbosa Dymow

Redes Neurais Artificiais Aplicadas na Construção de Exercícios


para Verificação de Aprendizagem

Trabalho de Conclusão de Curso submetido à Universidade Federal de Santa Catarina como


parte dos requisitos para a obtenção do grau de Bacharel em Sistemas de Informação.

Orientação:
Prof. Dr. Jovelino Falqueto

Banca Examinadora:
Profª. Drª. Edla Maria Faust Ramos
Profª. Drª. Rosane Porto Seleme Heinzen

Florianópolis, outubro de 2005

ii
Redes Neurais Artificiais Aplicadas na Construção de Exercícios
para Verificação de Aprendizagem

João Carlos Testi Ferreira


Júnior Barbosa Dymow

Este Trabalho de Conclusão de Curso foi julgado adequado para a obtenção do título de
Bacharel em Sistemas de Informação, e aprovado em sua forma final pela Coordenadoria do
Curso de Bacharelado em Sistemas de Informação.

___________________________________________________
Orientador – Prof. Dr. Jovelino Falqueto

___________________________________________________
Co-orientador - Profª. Drª. Edla Maria Faust Ramos

___________________________________________________
Membro da Banca - Pro fª. Drª. Rosane Porto Seleme Heinzen

iii
AGRADECIMENTOS

Agradecemos ao apoio de nosso orientador, prof. Falqueto e à prof. Edla, não


somente pela orientação e apoio na elaboração deste trabalho, mas pelo prazer e
oportunidade de cursar disciplinas tendo-os como professores.
Agradecemos de forma especial a prof. Rosane, pois sem seu incondicional apoio não
teríamos atingido o objetivo do trabalho em área tão diversa de nossa formação. Sua
participação foi fundamental desde a proposição do assunto até a validação dos resultados
finais.
Lembramos ainda de todos os professores dos quais fomos alunos durante nossa
formação. Os conhecimentos adquiridos no decorrer do curso nos deram os subsídios
necessários para enfrentar este desafio.
Também lembramos com carinho de nossos familiares que nos apoiaram e
compreenderam nossa aventura no conhecimento.

iv
SUMÁRIO

LISTA DE FIGURAS ........................................................................................................................VIII

RESUMO ...............................................................................................................................................IX

RESUMO ...............................................................................................................................................IX

ABSTRACT ............................................................................................................................................ X

CAPÍTULO I ......................................................................................................................................... 11

1 INTRODUÇÃO ............................................................................................................................. 11

1.1 OBJETIVOS ........................................................................................................................... 12


1.1.1 OBJETIVOS ESPECÍFICOS.............................................................................................. 12
1.2 MOTIVAÇÃO ........................................................................................................................ 13
1.3 JUSTIFICATIVA ................................................................................................................... 14

CAPÍTULO II........................................................................................................................................ 15

2 INTELIGÊNCIA ARTIFICIAL .................................................................................................. 15

2.1 REDES NEURAIS ARTIFICIAIS ................................................................................................... 17


2.1.1 Rede Neural de uma Única Camada (Perceptron) ............................................................ 18
2.1.2 Rede Perceptron de Múltiplas Camadas (Multi-Layer Perceptron).................................. 19

CAPÍTULO III ...................................................................................................................................... 23

3 ENSINO À DISTÂNCIA............................................................................................................... 23

3.1 SOFTWARES EDUCACIONAIS .................................................................................................... 24


3.2 HIPERMÍDIA E HIPERTEXTO ..................................................................................................... 25
3.3 ASPECTOS DE USABILIDADE .................................................................................................... 26
3.4 A DISCIPLINA DE NEUROANATOMIA ........................................................................................ 28

CAPÍTULO IV ...................................................................................................................................... 29

4 A BIBLIOTECA DE CLASSES PARA CONSTRUÇÃO DE RNAS ....................................... 29

4.1 COMPOSIÇÃO DOS PACOTES .................................................................................................... 30


4.1.1 O Pacote redeNeural ......................................................................................................... 31
4.1.2 O Pacote funcoesSaida ...................................................................................................... 31
4.1.3 O Pacote manipulacaoArquivos ........................................................................................ 32
4.1.4 O Pacote geradoresCódigo................................................................................................ 33
4.2 SEU USO EM APLICAÇÕES........................................................................................................ 33

v
CAPÍTULO V........................................................................................................................................ 34

5 A APLICAÇÃO PARA GERAÇÃO DE REDES NEURAIS .................................................... 34

5.1 UTILIZANDO O GERADOR DE REDES NEURAIS ......................................................................... 35


5.1.1 Configurando a Rede ......................................................................................................... 35
5.1.2 Lendo um arquivo de padrões............................................................................................ 37
5.1.3 Configurando Aspectos de Treinamento............................................................................ 38
5.1.4 Treinando a rede................................................................................................................ 39
5.1.5 Salvando o código fonte da rede treinada ......................................................................... 40
5.2 EXEMPLO DE APLICAÇÃO COM RNA NA DISCIPLINA DE NEUROANATOMIA ............................. 41

CAPÍTULO VI ...................................................................................................................................... 45

6 CONCLUSÕES.............................................................................................................................. 45

6.1 O GERADOR DE REDES NEURAIS ............................................................................................. 45


6.2 O APLICATIVO PARA A DISCIPLINA DE NEUROANATOMIA ........................................................ 46
6.3 CONSIDERAÇÕES FINAIS .......................................................................................................... 47

7 REFERÊNCIAS ............................................................................................................................ 48

ANEXOS ................................................................................................................................................ 49

ANEXO 1 - DIAGRAMAS DE CLASSE ............................................................................................ 50

DIAGRAMA DE CLASSES DO PACOTE REDENEURAL .............................................................................. 50


DIAGRAMA DE CLASSES DO PACOTE FUNCOESSAIDA ........................................................................... 51
DIAGRAMA DE CLASSES DO PACOTE MANIPULACAOARQUIVOS ........................................................... 52
DIAGRAMA DE CLASSES DO PACOTE GERADORESCODIGO .................................................................... 53

ANEXO 2 – PADRÕES DE TREINAMENTO DA APLICAÇÃO................................................... 54

ANEXO 3 – DOCUMENTAÇÃO – FORMATO JAVADOC ........................................................... 55

CLASS REDENEURAL ........................................................................................................................... 55


CLASS TREINAREDE ............................................................................................................................ 66
CLASS PADROESTREINAMENTO ........................................................................................................... 73
INTERFACE FUNCAOSAIDA .................................................................................................................. 76
CLASS FUNCAOSIGMOIDAL ................................................................................................................. 78
CLASS FUNCAOTANGHIPERB .............................................................................................................. 81
CLASS LEITORPADROES ...................................................................................................................... 84
CLASS PERSISTENCIAREDE .................................................................................................................. 86
CLASS GRAVADORARQUIVOPESOS ..................................................................................................... 89
CLASS GERADORCODIGO .................................................................................................................... 91
CLASS GERADORCODIGOJS................................................................................................................. 95

vi
CLASS GERADORCODIGOJAVA ............................................................................................................ 97
CLASS GERADORCODIGOCPP ............................................................................................................. 99
CLASS GERADORCODIGOOP ............................................................................................................. 102

ANEXO 4 – FUNÇÃO RNAMLP ...................................................................................................... 104

ANEXO 5 – EXERCÍCIO COMPLETO HTML/JAVASCRIPT ................................................... 107

ANEXO 6 – QUESTIONÁRIO DE USO DO APLICATIVO HTML ............................................ 115

ANEXO 7 – CÓDIGO FONTE .......................................................................................................... 116

CLASSE REDENEURAL ....................................................................................................................... 116


CLASSE TREINAREDE ........................................................................................................................ 123
CLASSE PADROESTREINAMENTO ....................................................................................................... 130
CLASSE FUNCAOSAIDA...................................................................................................................... 132
CLASSE FUNCAOSIGMOIDAL ............................................................................................................. 133
CLASSE FUNCAOTANGHIPERB........................................................................................................... 134
CLASSE LEITORPADROES................................................................................................................... 135
CLASSE GRAVADORARQUIVOPESOS ................................................................................................. 140
CLASSE PERSISTENCIAREDE .............................................................................................................. 143
CLASSE GERADORCODIGO ................................................................................................................ 148
CLASSE GERADORCODIGOJAVA ........................................................................................................ 150
CLASSE GERACODIGOOP .................................................................................................................. 154
CLASSE GERACODIGOCPP ................................................................................................................ 158
CLASSE GERACODIGOJS ................................................................................................................... 162
CLASSE PRINCIPAL (INTERFACE GRÁFICA DA APLICAÇÃO) ................................................................ 166

vii
LISTA DE FIGURAS

Figura 1 - Esquema de Unidade McCulloch – Pitts ............................................................ 17


Figura 2 - Problema da Separabilidade Linear .................................................................. 19
Figura 3 - Perceptron de múltiplas camadas com uma camada escondida. Quatro.............. 20
variáveis de entrada, três variáveis de saída. Função de saída g(z) sigmoidal..................... 20
Figura 4 – Diagrama dos pacotes que compõem a biblioteca............................................. 30
Figura 5 – Diagrama simplificado de classes do pacote redeNeural .................................... 31
Figura 6 – Diagrama de classe simplificado do pacote funcoesSaida .................................. 32
Figura 7 – Diagrama simplificado de classes do pacote manipulacaoArquivos ..................... 32
Figura 8 – Diagrama simplificado de classes do pacote geradoresCodigo ........................... 33
Figura 9 - Tela inicial do Gerador de Redes Neurais......................................................... 35
Figura 10 - Tela de Configurações da Rede ...................................................................... 36
Figura 11 - Tela de Configurações do Treinamento........................................................... 38
Figura 12 - Gráfico de Evolução do Treinamento .............................................................. 40
Figura 13 - Aplicativo para Neuroanatomia em HTML e Javascript utilizando RNA............... 41
Figura 14 - Resultado do Exercício................................................................................... 42

viii
RESUMO

Podemos utilizar Redes Neurais Artificiais em praticamente qualquer área do


conhecimento. Esta se mostra muito eficiente no reconhecimento de padrões. A criação
destas redes, no entanto, normalmente é feita caso a caso. São construídas aplicações para
cada problema que queira se utilizar desta tecnologia. Hoje este tipo de tecnologia é
utilizada em diversas áreas. A união da IA com a WEB, através das RNA, pode ser muito
promissora, pois permite uma interatividade mais agradável, simplificada e com recursos
dinâmicos muito mais abrangentes. As características principais das RNA são as mesmas,
assim, estamos apresentando uma aplicação que permite a criação da RNA de forma
facilitada, fornecendo inclusive código fonte em algumas linguagens e/ou os pesos
resultantes do treinamento da rede para que tais configurações possam ser utilizadas em
uma aplicação desenvolvida em linguagem qualquer. Neste trabalho apresentamos um
exemplo de uso para ensino de Neuroanatomia pela WEB. No intuito de simplificar seu uso
para o usuário e também de reduzir o tamanho do código gerado, as RNA fornecidas pela
aplicação utilizam sempre a mesma função de saída. Esta não é uma limitação das RNA, mas
sim da aplicação, pois consideramos que o grau de dificuldade a ser imposto para o usuário
não justifica tal implementação.

ix
ABSTRACT

Artificial Neural Networks can be used in almost every area of knowledge. They are
very efficient in the recognition of standards. Creating these networks, however, is a process
in which every case is separatedly evaluated. Applications are built for each problem where
this kind of technology can be used. Nowadays, this kind of techology is used in several
areas. The union between AI and WEB, by the ANNs, can be very agreeable, since it allows a
clean and pleasing interactivity, with several dynamic resources. The main issues of the
ANNs are always the same, so we are presenting an application which allows an easy way of
creating these networks. This application can also supply the source code and / or
generated weights of the RNAs for use in other applications written in other languages. This
monograph presents a WEB use example for the Neuroanatomy discipline.
In order to simplify the use and reduce the source codes's size, the ANNs supplied by the
application always use the same activation function. This is not a RNA limition, and was
implemented with the intention of making the user's interaction easier.

x
CAPÍTULO I

1 INTRODUÇÃO

Durante muito tempo, as possibilidades de ensino não presencial foram bastante


limitadas, pois se resumiam a materiais escritos enviados de forma postal. Com o forte
desenvolvimento da tecnologia da informação presenciado nos últimos anos, a realidade
hoje é outra: um aluno que tenha disposição de procurar, provavelmente vai encontrar na
Internet muito material que precisa para estudar determinado assunto, apesar de nem
sempre ser material confiável.
Entretanto, a existência da informação de fácil alcance não necessariamente resulta
em um aprendizado mais efetivo. Para que isto ocorra, ela deve estar organizada de forma
didática e interativa, fazendo com que o aluno mantenha a atenção no tema tanto quanto
em uma aula de qualidade ministrada presencialmente, com amplos recursos audiovisuais.
O ensino não presencial tem sido incentivado por diversos governos nos últimos
anos, pois além de complementar o aprendizado acadêmico, em diversas situações ele gera
economia para as instituições de ensino. Por exemplo, o uso de ambientes virtuais que
simulem um laboratório pode proporcionar uma “aula prática” sem que tenha sido necessário
o uso de laboratório, que dependendo da disciplina, pode ter restrições quanto à obtenção
de materiais e equipamentos.
Porém, em diversos ambientes de aprendizado on-line os exercícios para verificação
de aprendizagem são concebidos de forma pouco eficiente. De forma geral, o aprendiz
responde a algumas questões objetivas e no final o sistema retorna a pontuação atingida e a
alternativa correta de cada questão. Caso o usuário deseje realizar o teste novamente,
geralmente são apresentadas as mesmas questões. Isto direciona o usuário ao acerto sem
que o conteúdo tenha sido, de fato, compreendido pelo aprendiz, pois ele já poderá saber
qual a alternativa correta, ou no mínimo, que aquela selecionada anteriormente está
incorreta.
Desta forma, pretende-se no presente trabalho utilizar Redes Neurais Artificiais no
processo de elaboração de exercícios para verificação de aprendizagem, permitindo que
estes sejam concebidos de forma dinâmica.
Como exemplo de aplicação desta tecnologia, será criado um exercício para avaliação
de aprendizagem em uma disciplina de Neuroanatomia, o qual funcionará em ambiente Web.
O fato de ter-se escolhido esta disciplina como ambiente de aplicação prática do uso
de uma RNA deu-se principalmente pelos seguintes motivos:
• Há interesse de utilizar um ambiente virtual para aprendizagem na UFSC nesta
área, o que torna mais objetiva a aplicação de exercícios on-line, e já existe um
trabalho com um tutorial sobre o tema, não sendo necessário, portanto,
desenvolver toda uma plataforma web para este fim. Será necessário apenas
integrar o módulo de exercícios à aplicação existente.
• Com base em diagnóstico (áreas afetadas do cérebro) identificar sintomas é um
caso que se encaixa perfeitamente ao uso de RNAs, pois depende de entradas
(áreas afetadas) e saídas (sintomas) bem definidas. É possível ainda fazer-se
uma inferência na ordem inversa: Dados os sintomas, pode-se identificar o
diagnóstico do paciente.
A obtenção de material para análise, em aulas práticas, é bastante restrita. Desta
forma, uma ferramenta computacional interativa que permita minimizar o uso de tais
materiais é de grande utilidade, pois evita problemas como custo de obtenção de cadáveres
para dissecação, alocação de laboratórios, possíveis problemas respiratórios causados pela
exposição continuada ao formol, etc. A própria extração do cérebro de um cadáver é uma
operação bastante delicada, e segundo Heinzen, não raro são os casos nos quais os órgãos
são danificados durante o procedimento.

1.1 OBJETIVOS

O objetivo do trabalho é a criação de uma aplicação que gere redes neurais artificiais
para serem utilizadas em exercícios mais adequados ao ensino a distância.
Devido às características de uma rede neural artificial, estas podem ser utilizadas
para qualquer fim para os quais estas sejam treinadas, entretanto este trabalho será voltado
na demonstração de seu uso na construção de exercícios.

1.1.1 OBJETIVOS ESPECÍFICOS

a) Desenvolver uma biblioteca de classes JAVA para construção de redes neurais artificiais.
Estas classes devem permitir a construção de uma rede neural de múltiplas camadas
qualquer (Multi-Layer Perceptron), permitir seu treinamento pelo método de retro-

12
propagação (Backpropagation), possibilitar seu salvamento em arquivo, e gerar arquivos
com o seu código fonte em linguagens de alto nível bem como uma linguagem de script
para uso na WEB;
b) Criar uma aplicação com interface gráfica, fazendo uso da biblioteca desenvolvida. Esta
aplicação deverá permitir a criação de redes neurais artificiais que permita, após
seutreinamento, gerar o código fonte em linguagens de alto nível em arquivo texto;
c) Elaborar um exercício em ambiente WEB utilizando-se do código gerado pela aplicação a
fim de demonstrar a sua aplicabilidade.

1.2 MOTIVAÇÃO

A Inteligência Artificial é uma área que fascina por ser aplicável a praticamente
qualquer área ou tema. Stuart Russell e Peter Norvig citam, na introdução de seu livro
“Inteligência Artificial”, que “... a IA é citada regularmente como ‘o campo em que eu mais
gostaria de estar’ por cientistas de outras disciplinas...”1. O interesse pela
interdisciplinaridade como forma de busca do conhecimento, construção de novas idéias,
solução de problemas, encontra na IA uma forte aliada. Usar IA para o ensino é uma boa
estratégia para tornar mais agradável a apresentação do modelo de aprendizagem, fazendo
que o aluno possa ter uma melhor interatividade com a ferramenta que lhe é oferecida.
A idéia do uso de IA na elaboração de exercícios de verificação de aprendizagem
surgiu ao constatar-se que a avaliação de conhecimento é um fator crítico em diversos
sistemas que se propõem ao ensino a distância, dadas as limitações apresentadas
anteriormente. Além disso, influiu na decisão de abordar este assunto o fato de podermos
contribuir com um trabalho já existente desenvolvido pela professora Rosane Porto Seleme
Heinzen em sua tese de doutorado, sobre uma aplicação para ensino de Neuroanatomia.
É interessante destacar que a área da saúde, em nível nacional, utiliza-se de alta
tecnologia na parte curativa da ciência. Entretanto, quanto à questão de ensino, as
tecnologias utilizadas estão muito aquém do desejável. Ferramentas interativas que
permitam simulações de situações reais podem trazer diversos benefícios educacionais e
econômicos. Obviamente, tais ferramentas dificilmente substituirão completamente uma
situação real. A idéia é apenas ter-se uma alternativa a ela.

1
RUSSELL, Stuart; NORVIG, Peter. Inteligência Artificial. Introdução.

13
1.3 JUSTIFICATIVA

O uso da WEB como auxiliar no ensino apresenta diversas vantagens que podem ser
aplicadas em algumas disciplinas, como a redução da necessidade de alocação de
laboratórios, da presença de professores em tempo integral e de aquisição de alguns
materiais. No caso específico da Neuroanatomia, há restrições do uso de peças anatômicas
pela sua pouca durabilidade, dificuldade de obtenção, possibilidade de contaminação e
indisponibilidade de auxílio aos alunos por parte de um monitor, visto a dificuldade de
alocação de pessoal para trabalhar em laboratórios de anatomia.
Mas para que tal forma de ensino possa ser viável, um ambiente que tenha este
propósito deve proporcionar mais do que apenas a exposição do conhecimento. Deve
interagir com o aluno, tornando-os co-autores da comunicação e da aprendizagem.
Conforme constata HEINZEN, “Observa-se uma ausência quanto à disponibilização de
ambientes virtuais inteligentes em disciplinas morfológicas nos cursos das áreas médicas e
biomédicas, com especial atenção à Neuroanatomia, uma vez que os sistemas de multimídia
disponíveis no mercado, são de difícil acesso aos alunos e professores, pelo alto custo
(BRYAN, 2001), incompatibilidade de material técnico, e por serem editados em diferentes
idiomas, além de apresentarem situações dissociadas da realidade brasileira (VILLELA,
1993)2”.
O uso de IA Conexionista para este trabalho, através de Redes Neurais Artificiais do
tipo Perceptron com múltiplas camadas, deve-se ao fato dos exercícios a serem propostos
tratarem de identificação de padrões (por exemplo, a partir de determinados sintomas,
identificar as possíveis áreas afetadas do cérebro), onde este tipo de abordagem é o mais
indicado por ter um algoritmo de funcionamento mais simples e apresentar uma alta
eficiência. A principal limitação desta abordagem é que ela pode ser vista com uma “caixa
preta”. A partir dos dados de entrada obtemos uma saída, mas não é possível identificar a
razão pela qual se chegou àquele resultado.

2
HEINZEN, Rosane Porto Seleme. Modelo de ambiente virtual para a aprendizagem de
Neuroanatomia. Introdução.

14
CAPÍTULO II

2 INTELIGÊNCIA ARTIFICIAL

Por muito tempo não se acreditou ser possível simular a inteligência em uma
máquina. Ainda há muita discussão sobre o que pode ser considerado como inteligência, de
fato. Vamos definir melhor, então, estas palavras:
“A palavra inteligência vem do latim inter (entre) e legere (escolher). Inteligência
significa aquilo que permite ao ser humano escolher entre uma coisa e outra.
Inteligência é a habilidade de realizar de forma eficiente uma determinada tarefa.”
“A palavra artificial vem do latim artificiale, significa algo que não é natural, isto é,
produzido pelo homem. Portanto, inteligência artificial é um tipo de inteligência
produzida pelo homem para dotar as máquinas de algum tipo de habilidade que
simula a inteligência do homem.3”.

O estudo da simulação da inteligência humana teve como seu precursor o trabalho de


Warren McCulloch e Walter Pitts, em 1943, onde eles propuseram um modelo matemático
para um neurônio. Através dos estados “ligado” ou “desligado”, uma “rede” de neurônios
poderia dar passagem a um sinal, desde que estivesse suficientemente estimulado. A partir
desta idéia, haveria meios de “treinar” esta rede para que esta pudesse, por exemplo, ser
utilizada no reconhecimento de padrões.
A partir de então diversos trabalhos surgiram, os quais poderiam ser hoje
classificados como IA. Entretanto Alan Turing foi o pioneiro no sentido de articular uma visão
completa sobre o tema em seu artigo “Computing Machinery and Intelligency”, publicado em
1950.
A literatura indica que o termo “Inteligência Artificial” data de 1956, sugerido por
John McCarthy, em um seminário organizado em Dartmouth, mas o próprio MacCarthy não
garantiu não ter ouvido ainda esta expressão. Neste seminário, dois pesquisadores do
Carnegie Tech, Allen Newell e Herbert Simon, apresentaram um programa de raciocínio, o
Logic Theorist, que era capaz de demonstrar teoremas matemáticos.

3
FERNANDES, Ana Maria da Rocha. Inteligência artificial: noções gerais. Cap. 1.

15
FERNANDES, citando SIMON e GANASCIA(1993)4 aponta, a partir dos diversos
campos de estudo, quatro abordagens para a IA:
• Cognitiva – Também conhecida como descendente ou simbólica, procura
reproduzir a forma de raciocínio humano, baseando-se em aspectos psicológicos e
algorítmicos. Os pioneiros neste tipo de abordagem foram John McCarty,
Marquem Minsky, Newell e Simon. Modelos de referência:
o Sistemas Baseados em Regras – Implementam comportamentos
inteligentes de especialistas humanos.
o Raciocínio Baseado em Casos – Problemas são resolvidos a partir da
consulta de casos já solucionados anteriormente, adaptando tais soluções
ao problema atual.
• Conexionista – Também denominada de biológica ou ascendente, procura
reproduzir o modelo de funcionamento do cérebro. Os primeiros a utilizar esta
abordagem foram McCulloch, Pitts, Rosenblatt e Widrow. Modelo de referência:
o Redes Neurais Artificiais – São conhecidas também como Redes
Neuronais, Modelo Conexionista, Neurocomputação, Modelo de
Processamento Paralelo Distribuído, Sistemas Neuromórficos e
Computadores Biológicos. Seu modelo de funcionamento consiste na
modelagem de prognóstico a partir do ajuste repetido de parâmetro.
• Evolucionista – Procura reproduzir a inteligência com base em mecanismos
evolutivos biológicos. Modelos de referência:
o Algoritmo Genético – Modelo de aprendizagem baseado na teoria de
seleção natural de Charles Darwin, onde apenas os indivíduos mais aptos
sobrevivem. Computacionalmente, os indivíduos são representados por
cromossomos que simulam o processo evolutivo;
o Programação Genética – Campo de estudo da IA voltado para a
construção de programas que visam imitar o processo natural da genética.
o Programação Evolutiva – Assemelha-se aos algoritmos genéticos,
dando maior ênfase na relação comportamental entre os parentes e seus
descendentes.

4
FERNANDES, Ana Maria da Rocha. Inteligência artificial: noções gerais. Cap. 1, p. 3, 4.

16
• Estatístico / Probabilístico – Utiliza modelos estatísticos para executar tarefas
de descoberta de conhecimento. Modelo de referência:
o Lógica Fuzzy – Também conhecida como lógica nebulosa, serve para
representar, manipular e modelar informações incertas.

2.1 Redes Neurais Artificiais

A IA Conexionista baseia-se na idéia de que se conseguirmos reproduzir o modelo do


cérebro humano, faremos emergir um comportamento inteligente deste modelo.
Três conceitos são essenciais para a compreensão das RNAs:
 Neurônio – Unidade computacional básica da rede;
 Arquitetura – Estrutura topológica pela qual os neurônios estão conectados;
 Aprendizagem – Processo que faz com que a rede se adapte para realizar uma
tarefa.
Existem algumas definições sobre o que é exatamente uma RNA. Segundo Kohonen
(1972) elas são redes massivamente paralelas e interconectadas, as quais interagem com o
mundo real da mesma forma que o sistema biológico. Já para Lippman (1997), RNAs são
sistemas físicos que podem adquirir, armazenar e utilizar conhecimentos experimentais.

Figura 1 - Esquema de Unidade McCulloch – Pitts

Uma RNA é composta por várias unidades de processamento, os neurônios, conforme


podemos ver na Figura 1. Estes são interconectados por canais de comunicação que
possuem um certo peso, representados na figura pela letra w. Cada neurônio realiza
operações apenas sobre as entradas (x) recebidas por suas conexões. De modo geral o

17
comportamento inteligente RNA é fruto das interações entre os neurônios. McCulloch e Pitts
resumem a operação do neurônio da seguinte forma:
• Um neurônio recebe um conjunto de sinais (x);
• Cada sinal é multiplicado por um número (w), proporcional à sua influência no
resultado final;
• É feita a soma ponderada dos sinais (Σ). Em seguida é aplicada sobre o resultado
uma função de saída. Se a saída desta função for superior a um limite estipulado –
função de limiar (threshold), é gerada uma saída excitatória (presença de sinal na
saída) ou inibitória (ausência de sinal na saída).

2.1.1 Rede Neural de uma Única Camada (Perceptron)


Uma RNA na qual as entradas estão diretamente conectadas às saídas, sem estágios
intermediários, é chamada de Rede Neural de uma Única Camada ou Rede Perceptron.
Embora este modelo de rede tenha a capacidade de representar funções booleanas bastante
complexas como a Função Maioria (saída 1 somente se mais da metade das entradas é igual
a 1), Minsky e Papert provaram que, independente do algoritmo de aprendizagem aplicado,
este modelo é incapaz de resolver problemas cujo plano de respostas não seja linearmente
separável, conforme podemos ver na Figura 2. Um exemplo disto é a função Ou Exclusivo
(XOR), que gera uma resposta 0 quando duas entradas X e Y forem iguais e resposta 1
quando X e Y tiverem valores diferentes. Podemos observar na Figura 2 que não podemos
“separar a área de respostas corretas” através de uma linha reta para o Ou Exclusivo.

18
Figura 2 - Problema da Separabilidade Linear

Esta limitação restringia bastante a aplicação prática de RNAs, fazendo com que os
estudos sobre o assunto despertassem pouco interesse durante a década de 70 e o início
dos anos 80.

2.1.2 Rede Perceptron de Múltiplas Camadas (Multi-Layer Perceptron)


A deficiência das redes de uma única camada foi superada, nos anos 80, por
Rumelhart, Hinto e Williams, através da inclusão de camadas intermediárias de neurônios e
de um algoritmo de aprendizagem por retro-propagação para correção de erros, conforme
podemos ver na Figura 3. Outra característica deste tipo de rede é o fato de que todos os
neurônios de uma camada estão diretamente conectados a todos os neurônios das camadas
vizinhas, tornando-a uma rede totalmente conectada.
Conforme podemos ver na Figura 3, as camadas das redes Perceptron de múltiplas
camadas (Multi-Layer Perceptron - MLP) são as seguintes:
• Camada de Entrada (x)– Onde os padrões são apresentados à rede;
• Camada(s) Intermediária(s) ou Escondida(s) (h)– Esta camada é a principal
responsável pela identificação de características dos padrões.
• Camada de saída (d)– Onde o resultado final é apresentado.

19
Figura 3 - Perceptron de múltiplas camadas com uma camada escondida. Quatro

variáveis de entrada, três variáveis de saída. Função de saída g(z) sigmoidal

• Algoritmo de Aprendizagem por Retro-propagação


Para que uma rede “aprenda” a identificar um padrão, primeiramente ela deve ser
treinada. Este treinamento ocorre da seguinte forma: é apresentado à rede um conjunto de
dados sabidamente corretos (padrão = entradas e suas saídas esperadas). Os sinais gerados
pelo padrão de entrada são processados por cada camada, redimensionados pelos pesos de
cada conexão (simulando a idéia da plasticidade das sinapses – ligações entre neurônios
biológicos) e por fim é gerada uma saída. Esta é comparada ao valor esperado, e se não
estiver correta, um valor de erro é calculado. Com base neste erro, são arbitradas correções,
as quais são propagadas a partir da saída até a camada de entrada, fazendo com que os
pesos das conexões sejam modificados. Com os novos pesos ajustados, o processo
recomeça e é refeito até que o erro detectado seja aceitável.
Conforme FALQUETO (apud Freemann), podemos definir o algoritmo de treinamento
em passos genéricos:
“...
0 – inicializar os pesos WHji e WOkj com elementos aleatórios

20
1 – aplicar o vetor de entrada do padrão p: Xp=(Xp1, Xp2, ... Xpn)
aos nós de entrada
2 – calcular os somatórios ponderados que chegam aos nós
escondidos: netHpj = ΣNi=1 WHij Xpi + βj (nó de viés), j = 1, ..., L
3 – calcular as saídas dos nós hpj = fHj(netHpj)
4 – ir para a camada de saída O, calcular os somatórios
ponderados que chegam aos nós de O netOpk = ΣLj=1WOkj hpj +
βOk (nó de viés), k = 1, ..., M
5 – calcular as saídas de Opk = fOk(netOpk)
6 – calcular as correções dos erros nos nós de saída (O)
WOkj(t+1) = WOkj(t) + η(YpkOpk) f’Ok(netOpk) hpj
∆Opk = (Ypk – Opk) f’Ok(netOpk)
7 – calcular as correções dos erros da camada escondida (H)
∆Hpj = f’Hj(netHpj) Σ(∆Opk WOkj)
(notar que a atualização dos pesos da camada (I· H) depende
de todas as parcelas de erro na camada de saída):
WHji(t+1)=WHji(t)+ηf’Hj(netHpj) xi Σ(Ypk Opk)f’Ok(netOpk)WOkj
...”

• Características do Treinamento por Retro-propagação


O algoritmo de Aprendizagem por Retro-propagação implementa um gradiente
descendente no quadrado da soma do erro em funções lineares (função de saída). O
resultado obtido é utilizado para corrigir os pesos. Somente uma parte do resultado é
utilizado. Para isso é utilizado um multiplicador entre 0 e 1, chamado neste algoritmo de
fator de aprendizagem. Quanto maior o multiplicador, mais rápido será a aprendizagem da
rede, pois maior parcela do fator de correção será aplicada. Entretanto, um valor muito alto
pode implicar em oscilação do treinamento, podendo até fazer com que a rede nunca seja
treinada. Um treinamento mais lento, ou seja, com um multiplicador pequeno, tende a ser
mais eficiente, garantindo uma melhor convergência para o resultado. Um problema que
pode ocorrer com um multiplicador muito pequeno, no entanto, é o super-treinamento.
Como o processo de aprendizagem acontece lentamente, a rede acaba perdendo a
capacidade de generalizar resultados, passando a ser eficiente somente nos padrões
utilizados no processo de treinamento. Assim, devemos ter como objetivo usar o maior

21
mutiplicador possível, mas que não deixe a rede em oscilação no treinamento. Um número
que costuma ser bom é o multiplicador (fator de aprendizagem) 0,25.
Outro fator importante na rede é a quantidade de nós intermediários (camada
escondida) que devem ser utilizados. A quantidade de nós a serem utilizados ainda não é um
tema muito bem compreendido. FALQUETO sugere em sua tese, como uma tentativa inicial,
o uso da média aritmética do número de nós das camadas de entrada e saída.
A quantidade e qualidade dos padrões a serem utilizados no processo também têm
relação direta com o sucesso do treinamento. Quanto mais diversificados forem estes
padrões, maiores as chances de se obter bom resultado. Nem sempre dispomos de um
conjunto adequado de padrões, sendo esta uma das grandes limitações do uso de redes
neurais.

22
CAPÍTULO III

3 ENSINO À DISTÂNCIA

O uso da Internet com aplicações WEB para ensino tem crescido nos últimos anos. A
idéia de ensino a distância não é nova, desde os anos 50 existiam cursos oferecidos à
distância onde a comuinicação se dava com o uso do correio. Através destes cursos por
correspondência as pessoas buscavam qualificar-se em alguma atividade. A procura por
estes dava-se principalmente nos locais onde cursos presenciais não eram oferecidos. Havia
muito preconceito com esta forma de ensino, pois existiam várias deficiências relacionadas a
ele. A começar quando o aluno tivesse dúvidas. Este teria que encaminhar uma carta e
aguardar a resposta, prejudicando em muito a eficiência do método. Outro fator era a
limitação dos recursos didáticos, pois todo o tema a ser estudado seria abordado por meio
de apostilas (mais tarde foram oferecidos cursos por meio de discos de vinil, fitas cassete e
fitas de vídeo), com recursos de apresentação bastante limitados.
Com o avanço tecnológico e da comunicação, a idéia de ensino à distância começa a
ganhar maior credibilidade, pois já existem meios do aluno tirar suas dúvidas no momento
em que elas surgem, e os meios de apresentação já podem ser bastante ricos, utilizando
textos, hipertextos, imagens, sons, vídeos e teleconferências. O ambiente de aprendizagem
pode ser configurável, adaptável ao aluno e às suas necessidades.
O uso de Inteligência Artificial é outra forma de melhorar a interatividade do aluno
com o curso oferecido. Quando usamos o termo “Tutorial Inteligente” estamos informando
que o tutorial faz uso de algum tipo de Inteligência Artificial. Com ela é possível melhorar a
adaptabilidade do ensino, corrigir formas de navegação através do curso, elaborar melhores
exercícios, tornar mais agradável a forma de apresentação do conteúdo. Este trabalho
apresenta o uso da IA na elaboração de exercícios, permitindo que estes sejam mais
eficientes, trabalhando com uma gama maior de variáveis de forma a torná-los mais
flexíveis, agradáveis e instrutivos.

23
3.1 Softwares Educacionais

De acordo com a proposta de Thomas Dwyer (em Galvis, 1988), podemos classificar
as aplicações computacionais para uso educativo em dois grupos: software com enfoque
algorítmico e software com enfoque heurístico. RAMOS define o primeiro caso como sendo
“predominante a ênfase na transmissão de conhecimento do sujeito que sabe para o sujeito
que deseja aprender. Neste caso, a função do criador do software é projetar uma
seqüência bem planejada para a apresentação do conteúdo. Este deve ser subdividido em
pequenas doses e permeado de atividades que exijam uma resposta ativa em cada etapa,
proporcionando avaliação imediata desta resposta juntamente com atividades de reforço (ou
feedback). Espera-se com isto conduzir o aprendiz a um objetivo previamente determinado”.
Quanto ao enfoque heurístico, ainda segundo RAMOS, “... o aspecto predominante é a
aprendizagem experimental ou por descobrimento, devendo o software criar um ambiente
rico em situações que o aluno deve explorar conjecturalmente 5”.
O aplicativo com o qual estamos trabalhando, oriundo da tese de doutorado de
Heinzen, tem características claras de um enfoque algorítmico e determinístico, pois se trata
de um tutorial. Entretanto, na parte de aplicação de exercícios, onde serão utilizadas as
RNAs, tem-se um enfoque muito mais heurístico, pois o sistema gerará um diagnóstico
aleatoriamente, e caberá ao aluno indicar os sintomas do paciente. Em aplicativos similares
que não utilizam RNAs, um problema na aplicação de exercícios ocorre quando o aluno erra
a resposta de uma questão e o sistema então realiza a mesma pergunta novamente. Por
tentativa e erro, o aluno em determinado momento acertará a questão. Com uma RNA bem
treinada, os parâmetros de um exercício (valores e condições fornecidas) poderão ser
gerados de forma aleatória, e o aluno terá diante de si sempre situações inéditas, o que
exigirá dele real conhecimento sobre o problema para solucioná-lo.
Embora existam muitas críticas quanto a aplicações educacionais algorítmicas,
existem situações onde realmente é necessário hierarquizar e direcionar o modo de
aprendizado, principalmente quando não existe nenhum conhecimento prévio do aprendiz
quanto ao assunto abordado. Mas na aplicação dos conhecimentos supostamente adquiridos,

5
RAMOS, Edla Maria Faust. Análise ergonômica do sistema hiperNet buscando o aprendizado
da cooperação e da autonomia. Cap. 5

24
exercícios gerados com o auxílio de RNAs podem realmente tornar o processo de
aprendizado mais dinâmico e interessante, criando situações não previamente planejadas.

3.2 Hipermídia e Hipertexto

Em um ambiente de ensino não presencial, deve-se observar que manter o interesse


de quem está estudando é um fator fundamental para que o método seja eficaz. Mesmo em
aulas presenciais, muitas vezes é difícil ter-se uma visão mais concreta do assunto em
questão sem uso de recursos audiovisuais. Em ensino a distância, estes recursos têm sua
importância ainda mais acentuada, pois diversas vezes uma imagem é fundamental para que
se possa entender determinado conceito. Neste fator, a Internet leva uma grande vantagem
quanto aos outros métodos de ensino a distância, pois conta com interatividade a partir de
dispositivos de hipermídia. Esta une os conceitos de não-linearidade, hipertexto, interface e
multimídia numa só linguagem. Diferentemente de multimídia, hipermídia não é a mera
reunião de mídias existentes, e sim a fusão destas a partir de elementos não-lineares.
Uma forma bastante comum de Hipermídia é o Hipertexto, sistema para a
visualização de informação cujos documentos contêm referências internas para outros
documentos (chamadas de hiperlinks ou simplesmente links). Antes mesmo do advento da
popularização da Internet e de outros ambientes hipermidiáticos, Pierre Lévy elaborou em
1990 uma definição para o termo “hipertexto” ainda totalmente aplicável aos ambientes
interativos hoje existentes: “Tecnicamente, um hipertexto é um conjunto de nós ligados por
conexões. Os nós podem ser palavras, páginas, imagens, gráficos ou partes de gráficos,
seqüências sonoras, documentos complexos que podem eles mesmos ser hipertextos. Os
itens de informação não são ligados linearmente, como em uma corda com nós, mas cada
um deles, ou a maioria, estende suas conexões em estrela, de modo reticular. Navegar em
um hipertexto significa portanto desenhar um percurso em uma rede que pode ser tão
complicada quanto possível. Porque cada nó pode, por sua vez, conter uma rede inteira 6”.
A não linearidade inerente a estas tecnologias permite ao aluno estudar conteúdos
sem que seja necessário seguir um roteiro rigoroso. Entretanto é necessário observar,
durante a criação de conteúdos dinâmicos, a correlação entre links disponíveis e o assunto
abordado, de forma que exista sempre uma lógica a ser seguida.

6
LÉVY, Pierre. As Tecnologias da Inteligência. Cap. 2

25
Quanto ao aprendizado, diversos autores defendem que a participação do aluno no
processo e a qualidade de aprendizagem estão diretamente conectadas. Pierre Lévy
argumenta que “O hipertexto ou a multimídia interativa adequam-se particularmente aos
usos educativos. É bem conhecido o papel fundamental do envolvimento pessoal do aluno
no processo de aprendizagem. Quanto mais ativamente uma pessoa participar da aquisição
de um conhecimento, mais ela irá integrar e reter aquilo que aprender. Ora, a multimídia
interativa, graças a sua dimensão reticular ou não linear, favorece uma atitude exploratória,
ou mesmo lúdica, face ao material a ser assimilado. É, portanto, um instrumento bem
adaptado a uma pedagogia ativa 7”.

3.3 Aspectos de Usabilidade

A liberdade de acesso em ambientes hipermidiáticos tem seu preço: quanto mais


opções existem para acessar as informações, maiores serão as quantidades de decisões que
o usuário deverá tomar. Isto pode muitas vezes caracterizar um problema de usabilidade,
pois se determinado recurso não é devidamente descrito ou não está visível de forma clara,
ou ele não será utilizado ou o será de forma errônea. Desta forma, deve-se também
observar layout das páginas, significância de ícones, intuitividade na navegação, dicas (hints)
explicativas em cada recurso disponível, entre outros fatores, de forma que o usuário tire o
máximo proveito do ambiente oferecido, evitando assim que ele o abandone devido a
frustrações no uso deste.
Na área de psicologia cognitiva, é interessante ressaltar algumas considerações feitas
por Barthet (1988:20): Que existem diferentes usuários, os quais não utilizam a mesma
lógica em uma determinada tarefa; que existe uma diferença fundamental entre a lógica de
funcionamento do computador e a lógica de utilização do computador pelos homens; que se
deve distinguir entre as tarefas previstas e as efetivamente executadas pelo usuário. Ele
ainda propõe três modelos de representação de um sistema: a conceitual (que descreve a
lógica geral do software), a interna (ponto de vista do programador) e externa (ponto de
vista do usuário). Dificilmente a visão sistêmica do usuário, mesmo sob a ótica da lógica de
utilização, será parecida com a do programador.

7
LÉVY, Pierre. As Tecnologias da Inteligência. Cap. 2

26
Seguindo a premissa de que a interação humana em diferentes contextos deve ser
considerada na elaboração de um sistema hipermidiático, Pierry Levy (1990) ressalta que
“(...) pessoas diferentes irão atribuir significados por vezes opostos a uma mensagem
idêntica. Isto porquê, se por um lado o texto é o mesmo para cada um, por outro o
hipertexto pode diferir completamente. O que conta é a rede de relações pela qual a
mensagem será capturada, a rede semiótica que o interpretante usará para captá-la 8”.
Coutaz (1990) faz uma relevante observação quanto aos desenvolvedores de
ferramentas: para atingir-se o objetivo concebido, na interação com o usuário a ferramenta
deve conduzi-lo a este objetivo.
Diante disso, utilizaremos alguns critérios de usabilidade propostos por Scapin e
Bastien no projeto do software gerador de RNAs:
• Condução: O usuário deve saber onde está e que caminhos poderá tomar. É
necessário que o aplicativo disponibilize de forma clara as ferramentas disponíveis
e as formas de acessá-las. Outro fator importante é o feedback imediato. Quando
o usuário realiza uma ação, o software deve informá-lo prontamente sobre o
andamento da tarefa solicitada. O agrupamento de itens na interface também é
um aspecto que deve ser considerado. Mesmo em aplicativos de pequeno porte
esta característica é fundamental para que o usuário tenha plena ciência do modo
de utilização de cada opção fornecida.
• Gestão de erros: O sistema deverá também sempre reduzir, quando possível, a
incidência de erros por parte do usuário. Controle de botões habilitados,
verificação de valores de entrada durante a digitação e mensagens claras são
características que devem ser observadas neste sentido.
• Homogeneidade / Coerência: A linguagem utilizada nos rótulos do aplicativo
deve ser clara, dizendo ao usuário exatamente qual a utilidade de cada comando.
Isto pode reduzir sensivelmente a incidência de erros de operação. Além disso,
muitas vezes o uso de padrões “de fato” na elaboração de interfaces torna o uso
do aplicativo mais intuitivo, pois a estrutura já é provavelmente conhecida do
usuário (por exemplo, um menu que tenha “Arquivo”, “Ferramentas”, “Ajuda”,
nesta ordem, está presente em grande parte dos aplicativos comerciais).

8
LÉVY, Pierre. As Tecnologias da Inteligência. Cap. 6

27
Existem outros aspectos ergonômicos não citados aqui, mas devido à pequena
dimensão do software, julgamos estes suficientes para atender aos principais requisitos de
usabilidade.

3.4 A disciplina de Neuroanatomia

A Neuroanatomia é o ramo da anatomia que se dedica ao estudo do sistema nervoso.


Esta disciplina é apresentada em sua forma teórica utilizando-se de materiais de apoio como
transparências, imagens de livros e mais recentemente programas em CD. Em suas aulas
práticas, utilizam-se de peças conservadas em álcool, formol ou glicerinadas. A durabilidade
destas peças é, no entanto, muito pequena.
Cada vez tem sido mais difícil obter estas peças para uso na disciplina. Existem
dificuldades legais, dificuldade na extração das peças para estudo e as peças obtidas
possuem pouca durabilidade. Isto tem motivado a busca por alternativas no auxílio
pedagógico com relação a esta disciplina.

28
CAPÍTULO IV

4 A BIBLIOTECA DE CLASSES PARA CONSTRUÇÃO DE RNAS

Como um dos objetivos deste trabalho, foi construída uma biblioteca de classes JAVA,
na versão 1.5, divididas em pacotes com finalidades bem delimitadas.
A razão para a escolha desta linguagem é a sua capacidade de execução em diversos
sistemas operacionais9 e porque esta tem sido a linguagem com maior ênfase no curso de
Sistemas de Informação na UFSC. Outro fato que consideramos foi que tanto a máquina
virtual quanto o ambiente de desenvolvimento para esta linguagem, onde foram utilizados as
IDEs Eclipse e Netbeans, são softwares de livre distribuição.
As atividades a serem executadas por esta biblioteca serão:
- Criar uma rede neural artificial;
- Treinar uma rede neural artificial;
- Manipular arquivos de entrada e saída;
- Gerar código fonte em linguagens de alto nível da rede neural artificial.
A atividade de criar a rede neural artificial implica em permitir que uma rede neural
qualquer possa ser criada, ou seja, com qualquer quantidade de nós de entrada, saída e
escondidos. Na sua criação seus pesos serão atribuídos com valores aleatórios.
Em uma rede neural artificial, cada nó ou neurônio pode ter uma função de saída
específica diferente das demais. Isso, no entanto, normalmente não é utilizado e cria uma
complexidade muito grande tanto na configuração da rede pelo usuário quanto na confecção
do código da aplicação. Assim, na construção desta biblioteca adotou-se uma única função
de saída para todos os nós, exatamente da forma como normalmente se usa na prática,
simplificando seu posterior uso.
A atividade de treinar a rede será feita através do recebimento de uma rede
previamente criada, de um arquivo com os padrões para treinamento e definição das
características do treinamento, tais como: quantidade de épocas, erro máximo admissível e
fator de aprendizagem.

9
A execução de aplicações JAVA em qualquer plataforma ou sistema operacional é possível
desde que a Máquina Virtual Java esteja instalada no ambiente onde a aplicação será utilizada.

29
A manipulação de arquivos referem-se a leitura do arquivo de padrões permitindo sua
validação (verificar sua compatibilidade em relação a rede a ser treinada) e a escrita de
arquivo contendo as informações da rede, permitindo que esta possa ser usada em
momento posterior sem ter que recria-la.
A geração de código em linguagem de alto nível compreende a geração em arquivo
texto de uma rede gerada e treinada em algumas linguagens, tais como: Java, C++, Object
Pascal e Javascript.
Para permitir que outras funções de saída possam ser incluídas na biblioteca, esta foi
implementada como interface em Java. Assim, havendo necessidade de utilizar outras
funções além das implementadas (sigmoidal e tangente hiperbólica), basta implementar esta
interface para a nova função.

4.1 Composição dos Pacotes

Em função das definições citadas anteriormente, a biblioteca construída para uso em


aplicações de rede neural é composta de quatro pacotes de classes, conforme podemos ver
na Figura 4:

Figura 4 – Diagrama dos pacotes que compõem a biblioteca

O critério para a criação destes pacotes foi a distribuição de responsabilidades de cada


classe, conforme a definição, de modo a facilitar a portabilidade para aplicações que possam
fazer uso delas. Assim, por exemplo, se o objetivo é construir uma aplicação de uma rede
neural para uso específico, apenas os pacotes redeneural e funcoesSaida precisam ser
importados.

30
4.1.1 O Pacote redeNeural
Este pacote contém as classes da rede neural propriamente dita e as classes
necessárias para seu treinamento, conforme a Figura 5:

Figura 5 – Diagrama simplificado de classes do pacote redeNeural

Este pacote contém todas as classes necessárias para a criação e treinamento de uma
rede neural.
A classe RedeNeural faz uso de uma função de saída, que é uma interface, conforme a
definição.
Conforme podemos ver na Figura 5, a classe RedeNeural agrega esta interface (-
funcao). Com esta estratégia, qualquer função implementada por esta interface pode ser
usada pela rede.
A classe TreinaRede utiliza a interface FuncaoSaida e RedeNeural e
PadroesTreinamento. A separação destas classes foi feita porque uma rede, depois de
treinada, não utiliza mais esta funcionalidade. Assim, o treinamento é um serviço inicial a ser
feito na rede, mas não faz parte dela.

4.1.2 O Pacote funcoesSaida


Este pacote foi criado, conforme citado, para flexibilizar o modelo a fim de que novas
funções de saída possam ser inseridas no pacote através do uso de uma interface, conforme
podemos ver na Figura 6:

31
Figura 6 – Diagrama de classe simplificado do pacote funcoesSaida

O uso da interface permite uma total flexibilização na inclusão de novas funções de


saída ao modelo. Foram implementadas no pacote as funções mais populares para este uso,
sigmoidal e tangente hiperbólica.

4.1.3 O Pacote manipulacaoArquivos


O conteúdo deste pacote são as classes responsáveis pela manipulação de arquivos
básicos para a construção de uma aplicação que se utilize desta biblioteca. Estão disponíveis
no pacote, conforme o diagrama, as seguintes classes:

Figura 7 – Diagrama simplificado de classes do pacote manipulacaoArquivos

No pacote temos a classe LeitorPadroes, responsável pela leitura do arquivo que


contém os padrões para o treinamento, inserindo as informações lidas na estrutura de dados
utilizada para no treinamento. A classe PersistenciaRede é responsável por fazer a gravação
e leitura em arquivo de uma Rede Neural e a classe GravadorArquivoPesos é responsável por
gravar em arquivo texto os pesos de uma rede para uso em alguma aplicação.
Este pacote normalmente será usado para aplicações que gerem novas redes.

32
4.1.4 O Pacote geradoresCódigo
Este é o último pacote do grupo. Nele estão contidas as classes responsáveis pela
geração dos códigos de uma Rede Neural em diversas linguagens. A estratégia adotada foi o
uso de uma classe abstrata. Ela é parcialmente implementada, ficando sob responsabilidade
das novas classes a implementação do método gerarFuncaoRNAMLP. As classes já
implementadas no pacote podem ser vistas no diagrama a seguir:

Figura 8 – Diagrama simplificado de classes do pacote geradoresCodigo

O diagrama de classes de cada um dos pacotes apresentados encontra-se no Anexo 1.

4.2 Seu Uso em Aplicações

Com este conjunto de pacotes, podemos construir aplicações que façam necessitem
fazer uso de redes neurais.
Com o uso desta biblioteca foi desenvolvida uma aplicação que permite construir o
código em linguagem de alto nível para ser utilizado em aplicativos que necessitem utiliza
este tipo de recurso. Em nosso exemplo, utilizaremos em um gerador de exercícios para
Neuroanatomia, de forma que sejam criados sempre exercícios novos a cada chamada da
aplicação.
Com objetivo de usabilidade, foram verificados os métodos de todas as classes que
poderiam ter sua execução de forma demorada. Os métodos candidatos foram treinar, da
classe TreinaRede, e lerDadosTreinamento, da classe LeitorPadroes. Estes métodos
podem ser demorados porque o tempo de treinamento de uma rede é muito variável e a
leitura de um arquivo de padrões poderá demorar se o arquivo for muito grande. Para
facilitar o uso em interface gráfica, estes métodos foram sobrecarregados, passando um
objeto barra de progresso (JProgressBar) como parâmetro, permitindo o uso desta
ferramenta para indicar ao usuário, em uma aplicação com interface gráfica, o andamento
da atividade que está sendo executada pela aplicação.

33
CAPÍTULO V

5 A APLICAÇÃO PARA GERAÇÃO DE REDES NEURAIS

Para a criação da aplicação proposta pelo trabalho, foi utilizada além da biblioteca
criada neste trabalho, a biblioteca javax.swing para criar uma interface gráfica amigável para
o usuário.
Para tornar mais fácil o seu uso, foram utilizados critérios de usabilidade em sua
confecção, tais como feed-back imediato, condução, gestão de erros e homogeneidade. Na
tela inicial do software, conforme a Figura 9, pode-se observar características de
homogeneidade. Foram utilizadas uma barra de menu e uma barra de ferramentas, ambas
de uso comum nos aplicativos comerciais. A forma de apresentação da barra de menu segue
o padrão mais adotado, tendo como itens de menu “Arquivo” e “Ajuda”. Dada a natureza da
aplicação, foi inserido ainda um menu “Rede”, que intui ao usuário que ações referentes à
rede encontram-se neste menu. Na barra de ferramentas, também seguindo um padrão
largamente adotado, estão os botões “Novo”, “Abrir”, “Salvar” e “Configurações”, além de
um outro referente a uma funcionalidade específica da aplicação, “Treinar”. A Figura 9
apresenta ainda um dos botões com um indicador em amarelo, chamado hint ou dica,
também freqüente em aplicações comerciais e que servem para auxiliar o usuário na
compreensão da finalidade do mesmo. Também temos presente na aplicação uma barra de
status, indicando ao usuário o que fazer, o que está sendo executado ou se algum problema
aconteceu.

34
Figura 9 - Tela inicial do Gerador de Redes Neurais

5.1 Utilizando o Gerador de Redes Neurais

O treinamento de uma rede depende de três configurações principais: A estrutura da


rede, a leitura de um arquivo que contenha os padrões que serão utilizados e as
configurações de treinamento. A configuração da rede deve ser feita antes da leitura do
arquivo de padrões, pois o aplicativo esperará que o arquivo lido esteja dentro das
configurações selecionadas.

5.1.1 Configurando a Rede


O aplicativo permite configurar uma rede por dois caminhos: Abrindo uma
configuração existente ou criando uma nova.
Para utilizar uma configuração de rede já salva anteriormente, deve-se clicar no
menu “Arquivo”, submenu “Abrir”, opção “Configurações de Rede”, e selecionar o arquivo
desejado.
Para configurar uma nova rede, deve-se primeiramente clicar no menu “Rede” depois
no submenu “Configurar” e então na opção “Rede”. A seguinte tela será exibida:

35
Figura 10 - Tela de Configurações da Rede

No primeiro item, “Quantidade Nós de Entrada”, deve ser informada a quantidade de


entradas da rede, ou seja, quantas variáveis, ou parâmetros, serão informados. Em seguida,
temos o item “Quantidade de Nós de Saída”, que é a quantidade de parâmetros resultantes.
O terceiro item, “Quantidade de Nós Escondidos”, informa quantos neurônios estarão
presentes na camada intermediária. A aplicação calcula automaticamente este valor e sugere
ao usuário que use o valor calculado, mas não o impede de usar outro valor. Em seguida,
temos a configuração do “Bias” (nó auxiliar de valor 1, presente na camada de entrada e na
camada escondida). O usuário poderá informar se deseja ou não utilizar este nó. Como
padrão, a opção selecionada é “Sim”.
O último parâmetro a ser configurado é o tipo de “Função de Saída” (função utilizada
para calcular a saída de cada nó), podendo ser “Sigmoidal” ou “Tangente Hiperbólica”.
Utilizamos como padrão o valor “Sigmoidal”.
Alterados os parâmetros, basta clicar no botão “Configurar”. Será exibida a
mensagem “Rede Configurada”.
É possível salvar os parâmetros de configuração selecionados clicando-se no menu
“Arquivo”, submenu “Salvar”, opção “Configurações de Rede”, e selecionar o caminho e

36
nome do arquivo. Caso a gravação seja bem sucedida, será exibida a mensagem
“Configurações gravadas com sucesso!”.
Quanto a aspectos de usabilidade, podemos destacar nesta tela a presença dos
botões com “?” ao lado de cada opção de configuração. Estes botões, ao serem clicados,
informam de forma resumida o que quer dizer cada um dos parâmetros. Além disso, a cada
opção acessada pelo usuário é exibida um texto de “ajuda contextual”, na barra inferior da
tela (barra de status).

5.1.2 Lendo um arquivo de padrões


Configurada a rede, pode-se então abrir um arquivo de padrões clicando-se no menu
“Arquivo”, submenu “Abrir”, opção “Arquivo de padrões”. O arquivo selecionado deve ser do
tipo texto pleno e estar no seguinte formato:

A;B;C
XXXX
XXXX
XXXX

Onde A é a quantidade de nós de entrada, B é a quantidade de nós de saída, C é a


quantidade de padrões que o arquivo contém, e X são os padrões. Por exemplo, um arquivo
de padrão com 3 nós de entrada, 1 nó de saída e 5 padrões teria o seguinte formato:

3;1;5
0001
0011
0101
1000
1010

Os três primeiros valores dos padrões seriam utilizados como entradas (no caso 000,
001, 010, 100 e 101) e o último valor (1, 1, 1, 0 e 0) seria utilizado como a saída esperada

37
para cada padrão. Logicamente, os valores dos padrões poderiam ser diferentes, mas o
cabeçalho (3;1;5) deveria ser como o exemplificado para a rede proposta.
Caso o arquivo lido esteja dentro das configurações selecionadas, será exibida a
mensagem “Arquivo Lido com Sucesso”, juntamente com um indicador de progresso da
leitura.

5.1.3 Configurando Aspectos de Treinamento


Neste ponto já temos a rede configurada e os padrões lidos. Pode-se agora
configurar alguns aspectos de treinamento clicando-se no menu “Rede”, submenu
“Configurar”, opção “Aspectos de Treinamento”. A seguinte tela será exibida:

Figura 11 - Tela de Configurações do Treinamento

O primeiro parâmetro a se configurar é o “Erro Máximo”, que informará basicamente


qual a tolerância para as saídas serem interpretadas com zero ou um. Um valor muito alto
poderia resultar em uma rede “mal treinada”, enquanto que um valor baixo demais poderia
causar “super-treinamento” (rede que produz acertos apenas com os dados de treinamento).
Como padrão, o valor selecionado é 0,1, que já é bem pequeno.

38
O “Número de Épocas Máximo” indica quantas vezes a rede poderá ter o conjunto de
padrões reaplicados às entradas para realizar o treinamento. Se durante o treinamento for
atingido este número e a rede ainda não estiver treinada (valores de saída dentro de um
erro aceitável), será exibida uma mensagem indicando que o treinamento não foi bem
sucedido. O valor padrão da aplicação é 1000.
O último parâmetro, “Fator de Aprendizagem” (valor padrão de 0,25), deve ser
preenchido com um valor entre 0 e 1. Este valor é o multiplicador da correção calculada para
os pesos. A cada padrão submetido ao treinamento é calculado um fator de correção que
será multiplicado por este valor para corrigir os pesos. Desta forma, quanto mais alto o valor
mais rápido a rede poderá ser treinada, mas ao mesmo tempo, a probabilidade de que ela
seja efetivamente treinada diminui, pois a chance de passar do ponto ótimo do peso
aumenta, causando oscilação no treinamento. Ao clicar-se no botão “Configurar”, será
exibida a mensagem “Treinamento Configurado”.
Da mesma forma que a tela citada anteriormente, esta possui botões de ajuda para
cada opção e uma ajuda contextual na barra de status quando cada opção é acessada. É
interessante ressaltar que a opção “Aspectos de Treinamento” só estará habilitada depois de
lidos os padrões de treinamento, o que auxilia na condução do uso do aplicativo e também
na gestão de erros, pois evita que o usuário tente treinar uma rede sem que existam
padrões previamente carregados na memória.

5.1.4 Treinando a rede


Completadas as configurações, pode-se então treinar a rede clicando-se no menu
“Rede”, opção “Treinar” (opção que também estará disponível apenas depois de carregados
os padrões de treinamento). Caso o treinamento seja bem sucedido, será exibida a
mensagem “Rede treinada com sucesso”, juntamente com um indicador de progresso e o
botão “Resultado”. Ao clicar-se neste botão, será exibido um gráfico demonstrando a
evolução da convergência dos valores de erro de saída rumo ao valor de erro configurado,
conforme a Figura 12.

39
Figura 12 - Gráfico de Evolução do Treinamento

A linha em azul, na base, indica o valor de erro configurado, enquanto que a


vermelha indica o valor de erro na saída a cada iteração.

5.1.5 Salvando o código fonte da rede treinada


A aplicação permite que, ao treinar-se uma rede, seu “código fonte” seja salvo para
que possa ser utilizado em outros aplicativos, em diversas linguagens. É isto que permite,
por exemplo, que uma rede treinada no software seja reproduzida em uma página HTML
(utilizando Javascript) proporcionando que novos dados sejam aplicados à entrada da rede e
esta calcule as saídas.
Para salvar o código fonte, deve-se clicar no menu “Arquivo”, submenu “Salvar”,
submenu “Código Fonte” e selecionar a linguagem desejada, lembrando que esta opção só
estará habilitada se uma rede for previamente treinada com sucesso. As opções disponíveis
são Java, C++, Object Pascal e Javascript. Será solicitado ao usuário digitar o “Limiar de
Saída” (função threshold), que é o limite que o programa utilizará para delimitar valores

40
entre 0 e 1. Por exemplo, se for digitado o valor 0.4, o programa considerará como 0 valores
menores que 0,4 e como 1 valores iguais ou acima disso.
Deve-se então selecionar o caminho e o nome do arquivo (sem a extensão, que será
inserida automaticamente de acordo com a linguagem selecionada). Caso o arquivo seja
salvo corretamente, será exibida a mensagem “Arquivo Gerado com Sucesso”.

5.2 Exemplo de aplicação com RNA na disciplina de Neuroanatomia

Para exemplificar o uso de redes neurais geradas pelo software, foi criado um
aplicativo em HTML para a disciplina de Neuroanatomia, que utiliza uma rede neural para
geração dinâmica de exercícios. Podemos ver a tela inicial deste aplicativo na Figura 13,
conforme a seguir:

Figura 13 - Aplicativo para Neuroanatomia em HTML e Javascript utilizando RNA

41
Este aplicativo funciona da seguinte maneira: a partir das áreas destacadas em
vermelho na figura que representa o cérebro humano, o aluno deverá selecionar quais
sintomas o paciente deverá apresentar caso estas estejam afetadas. Ao clicar em confirmar,
cada um dos sintomas marcados ou desmarcados corretamente estarão como verde, e cada
opção marcada ou desmarcada erroneamente estará em vermelho, conforme demonstrado
na Figura 14:

Figura 14 - Resultado do Exercício

Neste caso, o aluno teria acertado (conforme treinamento da rede) ao marcar as


opções “Dislexia” e “Alteração da Olfação”, mas teria errado ao deixar de marcar as opções
“Alteração Emocional” e “Alteração Sensorial Superficial dos Membros Inferiores”. Quando
ele clicar em “Tentar de Novo”, serão selecionadas novas áreas do cérebro. O número de

42
áreas selecionadas é aleatório, podendo ser ajustado um número máximo de áreas grifadas
simultaneamente.
Pode-se observar que esta aplicação permite vários exercícios dentro de um só, pois
como tanto as áreas selecionadas quanto a quantidade delas é aleatória, a quantidade de
possibilidades é bastante grande. Certamente que o acerto ao avaliar as respostas do aluno
dependerá da qualidade de treinamento da rede.
Para gerarmos a rede desta aplicação, utilizamos um arquivo de padrões contendo 76
registros que fornecem as dez entradas e suas respectivas 10 saídas, conforme Anexo 2.
As entradas correspondem às 10 regiões mapeadas do cérebro utilizadas neste
exercício são:
1. face medial superior do giro pré-central,
2. giro parahipocampal,
3. face medial do giro pré-central,
4. face medial do giro pós-central,
5. giro do cíngulo,
6. face medial do giro frontal superior,
7. área do sulco calcarino,
8. giro occipito temporal lateral e giro temporal inferior,
9. tálamo – região ventral posterior,
10. uncus.
Os padrões contêm dez saídas que correspondem a dez sintomas possíveis, a saber:
1. hemianopsia
2. dislexia
3. alteração emocional
4. alteração de memória
5. mal funcionamento do esfíncter anal/vesical
6. personalidade alterada
7. alteração da olfação
8. ataxia
9. hemiplegia dos membros inferiores
10. alteração sensorial superficial dos membros inferiores

43
A aplicação geradora da rede cria apenas a função javascript para identificação da
resposta conforme o que é apresentado na figura, o restante da página WEB é criada pelo
autor do exercício.
No Anexo 4 podemos ver a função gerada para o exercício apresentado. No Anexo 5
temos o código completo HTML/Javascript do exercício. A linha apresentada em destaque
refere-se a uma adaptação do código gerado para o uso da função de forma diferenciada,
permitindo que o resultado da rede seja lido em outro momento. Com base neste exemplo
podemos observar que o código gerado auxilia a criação do exercício, mas não o cria por
completo. Sua maior relevância está no fato de que a parte complexa de fato do código é a
que foi criada pela aplicação, ou seja a rede neural.

44
CAPÍTULO VI

6 CONCLUSÕES

De forma geral, obteve-se bons resultados com o desenvolvimento deste trabalho. O


maior aprofundamento na área de Inteligência Artificial, tanto de forma prática quanto
teórica, foi o que tornou o desenvolvimento do projeto possível.
A preocupação com aspectos ergonômicos durante o desenvolvimento da aplicação
objetivou apenas, em um primeiro momento, tornar o aplicativo mais adequado a questões
relevantes de usabilidade. No entanto, percebeu-se que o uso do aplicativo por terceiros foi
muito mais facilitado pelo fato de tais questões terem sido observadas.

6.1 O Gerador de Redes Neurais

O desenvolvimento da aplicação para geração de redes neurais, principal foco prático


deste trabalho, atingiu os objetivos esperados: a partir de configurações dos parâmetros da
rede, da leitura de arquivos de padrões dentro do formato esperado e das configurações de
treinamento, é possível obter-se uma rede treinada para qualquer problema que tenha como
parâmetros entradas / saídas. Contudo, a possibilidade e a qualidade do treinamento ficam
sujeitas às amostras apresentadas à rede (padrões) bem como às características
configuradas.
Entretanto, um aplicativo que somente treinasse uma rede teria utilidade duvidosa,
pois só informaria ao usuário que os padrões fornecidos são suficientes para que o
treinamento seja realizado. O fato de poder-se exportar a estrutura da rede, já com os
pesos adequados do treinamento, para diversas linguagens de programação, permite que o
uso do aplicativo seja sensivelmente ampliado, pois torna viável o desenvolvimento de novos
softwares que apenas façam uso de uma rede previamente treinada, como o exemplo
desenvolvido para a disciplina de Neuroanatomia.
É interessante ressaltar ainda que o perfil do usuário deste software é o de alguém
que já tenha algum conhecimento sobre IA, para que este tenha condições de configurar
corretamente os parâmetros estruturais e de treinamento da rede.

45
6.2 O aplicativo para a disciplina de Neuroanatomia

O aplicativo desenvolvido para a disciplina de Neuroanatomia, baseado em HTML e


Javascript, utilizou uma RNA gerada pelo Gerador de Redes Neurais, cujos padrões foram
formatados através de dados previamente fornecidos pela professora da disciplina, Rosane
Heinzen, que ao utilizar o software constatou que “O aplicativo apresenta uma interface de
fácil utilização. Associa a imagem real do cérebro humano a exercícios de múltipla escolha,
permitindo ao usuário relacionar o conteúdo teórico com o curso prático. Gera exercícios de
forma aleatória, apresentando resposta correta nos vinte (20) casos testados”.
Como o aplicativo é bastante simples, em princípio não é necessário nenhum
conhecimento prévio para utilizá-lo, pois basta selecionar os sintomas e clicar em um dos
dois botões existentes. Mas é claro que, para que se tenha uma taxa de acertos razoável,
são necessários conhecimentos prévios em Neuroanatomia.
Sete alunos do curso de Medicina interagiram com o software, sendo que todos ao
final responderam a uma pesquisa quanto ao uso, qualidade e pertinência do aplicativo
(síntese das respostas no Anexo 6). Todos consideraram que a utilização foi fácil, que a
qualidade das respostas foi boa / ótima, e que de forma geral exercícios on-line trazem
benefícios para o estudo prático individual, como destacou um dos alunos ao comentar que a
possibilidade de realização de exercícios de Neuroanatomia pela Internet “É bastante
importante para disponibilizar momentos fora de sala de aula ou fora do horário de monitoria
para alunos que não possam comparecer nos horários previstos, já que as peças de
Neuroanatomia, devido à sua friabilidade, têm um acesso mais restrito para utilização pelos
alunos”. Heinzen também comentou que “A disponibilização do aplicativo on line visa
propiciar o estudo individual para alunos dos cursos das Ciências da Saúde, Humanas e
Biológicas, flexibilizando o atual método tradicional de ensino/aprendizagem da disciplina de
Neuroanatomia na UFSC”.
Com uma rede bem treinada, é possível utilizar este HTML inclusive para avaliação de
aprendizado, pois mesmo que o aluno verifique o código HTML da página, não encontrará lá
as respostas, pois verá apenas a distribuição dos pesos da rede e sua estrutura. Isto se deve
a uma característica intrínseca das RNAs, o fato destas serem caixas-pretas (não se sabe
porquê chegou-se a determinado resultado, ou seja, qual a influência de cada entrada na
rede). Tal característica, muitas vezes considerada uma limitação, mostrou-se neste caso de
grande utilidade.

46
6.3 Considerações finais

Foi interessante e estimulante a oportunidade de pesquisa em áreas não tão


diretamente correlatas à Computação, como ensino a distância e Neuroanatomia. O trabalho
desenvolvido procurou, através do agrupamento destas áreas, demonstrar como é grande o
espectro de possibilidades nas quais o uso de IA pode ser uma opção.
Como trabalho futuro, existe a possibilidade de integração de um módulo inteligente
de aplicação de exercícios ao sistema de ensino on-line demonstrado na tese de doutorado
de Heinzen, o que proporcionaria um ambiente completo de aprendizado virtual para a
disciplina de Neuroanatomia. Cabe ressaltar que tal módulo poderia ser incluído em qualquer
sistema de ensino multimídia, o que enriqueceria substancialmente as possibilidades de
aprendizado.

47
7 REFERÊNCIAS

1. Russell, Stuart Jonathan; NORVIG Peter. Inteligência artificial. Rio de Janeiro:


Elsevier, 2004

2. FERNANDES, Ana Maria da Rocha. Inteligência artificial: noções gerais.


Florianópolis: Visual Books, 2003

3. OLIVEIRA NETTO, Alvim Antônio de. IHC – Interação humano computador:


modelagem e gerência de interfaces com o usuário. Florianópolis: Visual Books, 2004

4. MORGAN, Michael. Java 2 para programadores profissionais. Rio de Janeiro:


Ciência Moderna Ltda, 2000

5. JANDL JUNIOR, Peter. Introdução ao Java. São Paulo: Berkley Brasil, 2002

6. JANDL JUNIOR, Peter. Mais Java. São Paulo: Futura, 2003

7. SIKORA, Michael. Java: guia prático para programadores. Tradução de Altair


Dias Caldas de Moraes. Rio de Janeiro: Campus, 2003

8. HORSTMAN, Cay; CORNELL, Gary. CoreJava 2: fundamentos. Tradução de João


Eduardo Nóbrega Tortello. São Paulo: Makron Books, 2001

9. HORSTMAN, Cay; CORNELL, Gary. CoreJava 2: recursos avançados. Tradução de


João Eduardo Nóbrega. São Paulo: Pearson Education do Brasil, 2002

10. MEDEIROS, Ernani Sales de. Desenvolvendo software com UML 2.0: definitivo.
São Paulo: Pearson Makron Books, 2004

11. LEVY, Pierre. As tecnologias da inteligência: o futuro do pensamento na era da


informática. Rio de Janeiro: Ed. 34, 1993

12. ALVES, Lynn; NOVA, Cristiane. Educação a Distância São Paulo: Futura, 2003

13. FALQUETO, Jovelino. Inspiração biológica em IA. 2002. 164 f. Tese (Doutorado)
Universidade Federal de Santa Catarina. Florianópolis, 2002

14. HEINZEN, Rosane Porto Seleme. Modelo de ambiente virtual para a


aprendizagem de neuroanatomia. 2004. 127f. Tese (Doutorado) Universidade
Federal de Santa Catarina, Florianópolis, 2004

15. RAMOS, Edla Maria Faust; FAGUNDES, Lea da Cruz. Análise ergonômica do
sistema hiperNet buscando o aprendizado da cooperação e da autonomia.
1996. 353f. Tese (Doutorado) - Universidade Federal de Santa Catarina,
Florianópolis, 1996

48
ANEXOS

49
ANEXO 1 - DIAGRAMAS DE CLASSE

Diagrama de classes do pacote redeNeural

50
Diagrama de classes do pacote funcoesSaida

51
Diagrama de classes do pacote manipulacaoArquivos

52
Diagrama de classes do pacote geradoresCodigo

53
Anexo 2 – Padrões de Treinamento da Aplicação
10;10;76 10001100010010111000
10000000000000100000 00110010101000000111
01000000000001000000 11011000010011101001
00100000000000000010 00110011101100000111
00010000000000000001 10101010101010100110
00001000000010000000 01001101010111011000
00000100000000010000 10111010011010101011
00000010001000000000 11000101100101110100
00000001000100000000 10100111001100110010
00000000100000000100 01001100110011011100
00000000010000001000 10101001100110100110
10000000010000101000 00000111111100011100
01000000100001000100 11110000110001101111
00010010001000000001 01111011001111000011
10100000000000100010 10111001100110100111
00001010001010000000 01100011111101001110
00000000110000001100 10110110011000111011
00010100000000010001 10100111011100111010
01001000000011000000 11001111001111110000
00101000000010000010 10110101010100111011
00010000100000000101 11110011001101100011
10101000000010100010 10111010101010100111
01010100000001010001 11101110011011111010
00101010001010000010 11110101100101110111
00010101000100010001 10111100010010111011
00001010101010000100 10011111011110111001
00000101010100011000 10111101010110111011
00100100100000010110 01111110101011010111
01001000010011001000 00111111101110010111
11000100000001110000 01001111111111011100
00110010001000000011 00111111101110010111
11110000000001100011 01101111011111011010
00111100000010010011 10111111011110111011
00001111001110010000 01111111101111010111
00000011111100001100 10111101110110111111
10101010001010100010 11110011111101101111
00010101010100011001 11110111101101110111
01001010011011001000 10111110111010111111
00110100100000010111

54
ANEXO 3 – Documentação – Formato Javadoc

redeNeural

Class RedeNeural

java.lang.Object
redeNeural.RedeNeural

public class RedeNeural


extends java.lang.Object

Permite a criação de uma rede neural artificial para uso qualquer.


A função de saída a ser usada na rede neural deve ser do tipo FuncaoSaida, outra classe
(interface) pertencente ao pacote redeneural.

Version:
1.0.0
Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Constructor Summary
RedeNeural()
Contrutor vazio
Cria a rede com a seguinte característica:
- 2 nós de entrada
- 1 nó de saída
- 1 nó escondido
- bias na camada de entrada e camada escondida
- executa inicializaDefaults

RedeNeural(int nE, int nS, int nBias)


Contrutor com parametros
Cria a rede de acordo com os parâmetros informados.

55
Method Summary
void calculeNets()
Calcula os valores net da camada escondida e da camada de
saída

int getBias()
Getter do Bias

boolean getEstaTreinada()
Getter para estaTreinada

FuncaoSaida getFuncao()
Getter da função de saída

int getNosEntrada()
Getter da quantidade de nós de entrada.

int getNosEscondidos()
Getter da quantidade de nós escondidos

int getNosSaida()
Getter da quantidade de nós de saída

double[][] getPesosHI()
Getter dos pesos entre a camada de entrada e escondida

double[][] getPesosOH()
Getter do array de pesos entre a camada escondida e saída

double[] getSaida()
Getter para o vetor de saída

int getValorEntradas(int indice)


Getter para um valor da entrada

double getValorEscondidos(int indice)


Getter para um valor da camada escondida

double getValorPesosHI(int indiceJ, int indiceI)


Getter de um peso das camadas de entrada e escondida

double getValorPesosOH(int indiceK, int indiceJ)


Getter de um dos pesos entre a camada escondida e saída

56
double getValorSaidas(int indice)
Getter para um valor da saída

void inicializaPesos()
Inicializa os pesos com valores aleatórios

void reiniciaTreinamento()
Reinicia o treinamento da seguinte forma:
- define estaTreinada para false
- executa inicializaPesos

void setBias(int tB)


Setter do bias

void setEntrada(int[] vE)


Setter para os valores de entrada da rede

void setEstaTreinada(boolean et)


Setter para estaTreinada

void setFuncao(FuncaoSaida pFuncao)


Setter da função de saída

void setNosEntrada(int nE)


Setter da quantidade de nós de entrada.

void setNosEscondidos(int nE)


Setter da quantidade de nós escondidos
Redefine os arrays que dependem desta informação

void setNosSaida(int nS)


Setter da quantidade de nós de saída
Redefine os arrays que dependem desta informação

void setPesosHI(double[][] phi)


Setter do array de pesos entre a camada de entrada e
escondida

void setPesosOH(double[][] poh)


Setter dos pesos entre as camadas escondida e saída

57
Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Constructor Detail
RedeNeural

public RedeNeural()
Construtor vazio
Cria a rede com a seguinte característica:
- 2 nós de entrada
- 1 nó de saída
- 1 nó escondido
- bias na camada de entrada e camada escondida
- executa inicializaDefaults

RedeNeural

public RedeNeural(int nE,


int nS,
int nBias)
Contrutor com parametros
Cria a rede de acordo com os parâmetros informados.
Parameters:
nE - quantidade de nós de entrada

nS - quantidade de nós de saída

nBias - uso do bias, se 0 não usa, se 1 usa.

O número de nós escondidos será a média entre os nós de entrada e nós de saída.
O construtor executa inicializaDefaults

Method Detail
setNosEntrada

public void setNosEntrada(int nE)

58
throws java.lang.Exception
Setter da quantidade de nós de entrada.
Redefine os arrays que dependem desta informação.
Parameters:
nE - quantidade de nós de entrada

Throws:
java.lang.Exception - Lança exceção caso o número de nós de entrada

seja inferior a 1.

getNosEntrada

public int getNosEntrada()


Getter da quantidade de nós de entrada.
Returns:
retorna o número de nós de entrada como um inteiro.

setNosEscondidos

public void setNosEscondidos(int nE)


throws java.lang.Exception
Setter da quantidade de nós escondidos
Redefine os arrays que dependem desta informação
Parameters:
nE - quantidade de nós escondidos

Throws:
java.lang.Exception - lança exceção caso o número de nós escondidos

seja inferior a 1.

getNosEscondidos

public int getNosEscondidos()


Getter da quantidade de nós escondidos
Returns:
retorna a quantidade de nós escondidos como um inteiro.

setNosSaida

59
public void setNosSaida(int nS)
throws java.lang.Exception
Setter da quantidade de nós de saída
Redefine os arrays que dependem desta informação
Parameters:
nS - quantidade de nós de saída

Throws:
java.lang.Exception - lança exceção caso o número de nós de saída seja

inferior a 1.

getNosSaida

public int getNosSaida()


Getter da quantidade de nós de saída
Returns:
retorna a quantidade de nós de saída como um inteiro.

getFuncao

public FuncaoSaida getFuncao()


Getter da função de saída
Returns:
retorna a função de saída como uma FuncaoSaida.

setFuncao

public void setFuncao(FuncaoSaida pFuncao)


Setter da função de saída
Parameters:
pFuncao - função de aticação, do tipo FuncaoSaida (interface)

60
setBias

public void setBias(int tB)


throws java.lang.Exception
Setter do bias
Parameters:
tB - se 0 indica que não será usado bias, se 1 é usado bias

Throws:
java.lang.Exception - lança exceção se parâmetro for diferente de 0 ou 1.

getBias

public int getBias()


Getter do Bias
Returns:
retorna 1 se estiver usando bias e 0 se não estiver.

setEntrada

public void setEntrada(int[] vE)


throws java.lang.Exception
Setter para os valores de entrada da rede
Parameters:
vE - vetor de entrada do tipo int

Throws:
java.lang.Exception - lança exceção se a quantidade de entradas não for

compatível com tamanho do vetor. Se o tamanho for igual ao do vetor, o método


insere, se necessário, o bias. Se o tamanho do vetor for igual ao número de nós de
entrada mais o bias, a responsabilidade de deixar o bias na primeira posição é do
usuário.

61
getValorEntradas

public int getValorEntradas(int indice)


Getter para um valor da entrada
Parameters:
indice - indica qual nó deve ser retornado

Returns:
retorna o valor do nó referenciado por indice como um inteiro

getValorEscondidos

public double getValorEscondidos(int indice)


Getter para um valor da camada escondida
Parameters:
indice - indica qual nó deve ser retornado

Returns:
retorna o valor do nó referenciado por indice como um double

getValorSaidas

public double getValorSaidas(int indice)


Getter para um valor da saída
Parameters:
indice - indica qual nó deve ser retornado

Returns:
retorna o valor do nó referenciado por indice como um double

62
getSaida

public double[] getSaida()


throws java.lang.Exception
Getter para o vetor de saída
Returns:
retorna o vetor de saída do tipo double
Throws:
java.lang.Exception - lança exceção caso a rede não esteja treinada, pois

não há como gerar saidas.

getEstaTreinada

public boolean getEstaTreinada()


Getter para estaTreinada
Returns:
retorna true se a rede estiver treinada e false se não estiver.

setEstaTreinada

public void setEstaTreinada(boolean et)


Setter para estaTreinada
Parameters:
et - valor a ser atribuído a estaTreinada do tipo boolean

setPesosHI

public void setPesosHI(double[][] phi)


throws java.lang.Exception
Setter do array de pesos entre a camada de entrada e escondida
Parameters:
phi - array de pesos do tipo double

Throws:
java.lang.Exception - lança exceção se o tamanho do array não for igual

ao array com os pesos entre a camada de entrada e escondida

63
getValorPesosHI

public double getValorPesosHI(int indiceJ, int indiceI)


Getter de um peso das camadas de entrada e escondida
Parameters:
indiceJ - índice do array referente a camada escondida

indiceI - índice do array referente a camada de entrada

Returns:
valor do peso referenciado pelos indices i e j

getPesosHI

public double[][] getPesosHI()


Getter dos pesos entre a camada de entrada e escondida
Returns:
retorna o array de pesos entre a camada de entrada e escondida

setPesosOH

public void setPesosOH(double[][] poh) throws java.lang.Exception


Setter dos pesos entre as camadas escondida e saída
Parameters:
poh - array com os pesos

Throws:
java.lang.Exception - lança exceção se o array passado como parâmetro

for de tamanho diferente do array de pesos entre a camada escondida e saída

getValorPesosOH

public double getValorPesosOH(int indiceK,int indiceJ)


Getter de um dos pesos entre a camada escondida e saída
Parameters:
indiceK - índice que referencia o nó da saída

indiceJ - índice que referencia o nó da camada escondida

Returns:
retorna o valor do peso referenciado pelos índices j e k

64
getPesosOH

public double[][] getPesosOH()


Getter do array de pesos entre a camada escondida e saída
Returns:
retorna o array de pesos entre a camada escondida e saída

calculeNets

public void calculeNets()


Calcula os valores net da camada escondida e da camada de saída

inicializaPesos

public void inicializaPesos()


Inicializa os pesos com valores aleatórios

reiniciaTreinamento

public void reiniciaTreinamento()


Reinicia o treinamento da seguinte forma:
- define estaTreinada para false
- executa inicializaPesos

65
redeNeural

Class TreinaRede

java.lang.Object
redeNeural.TreinaRede

public class TreinaRede


extends java.lang.Object

Treinamento de uma rede neural artificial

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Constructor Summary
TreinaRede()
Construtor vazio
Usa os seguintes defaults:
- rede criada com construtor vazio - número máximo de épocas 1000 - fator de
aprendizagem 0.25 - Erro máximo 0.1

TreinaRede(RedeNeural rede, PadroesTreinamento pT,


int pEpocasMaximo, double pFatorAprendizagem, double pErroAceitavel)
Construtor com parâmetros

Method Summary
double calculeErroGlobal()
Calcula o erro global da época

void calculeFatoresCorrecao()
Calcula os fatores de correção
Para seu uso, o array saidasEsperadas deve ter sido
inicializado com a saida do treinamento

66
void calculeFatoresCorrecao(int padrao)
Calcula os fatores de correção

void corrigePesos()
Corrige os pesos entre as conexões

int getEpocasMaximo()
Getter da quantidade máxima de épocas

double getErroAceitavel()
Getter do erro aceitável

double getErroMaximo()
Getter do maior erro obtido

java.util.ArrayList getErrosMaximos()
Getter dos erros máximos das épocas

double getFatorAprendizagem()
Getter do fator de aprendizagem

int getQtdEpocasAtual()
getter da quantidade de épocas atual

int[] setEntradaSaidaDoPadrao(int padrao)


Setter dos arrays de valores padrão (entrada e
saída)

void setEpocasMaximo(int eM)


Setter da quantidade máxima de épocas

void setErroAceitavell(double eA)


Setter do erro aceitavel

void setFatorAprendizagem(double fA)


Setter do fator de aprendizagem

boolean treinar()
Treina a Rede Neural

67
Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Constructor Detail
TreinaRede

public TreinaRede(RedeNeural rede,


PadroesTreinamento pT,
int pEpocasMaximo,
double pFatorAprendizagem,
double pErroAceitavel)
Construtor com parâmetros
Parameters:
rede - rede a ser treinada

pT - padrões de treinamento a serem usados no treinamento

pEpocasMaximo - número máximo de épocas a ser treinada a rede

pFatorAprendizagem - fator de aprendizagem a ser aplicado no treinamento

pErroAceitavel - maior valor de erro a ser usado como referência na saída

TreinaRede

public TreinaRede()
Construtor vazio
Usa os seguintes defaults:
- rede criada com construtor vazio - número máximo de épocas 1000 - fator de
aprendizagem 0.25 - Erro máximo 0.1

68
Method Detail
getErrosMaximos

public java.util.ArrayList getErrosMaximos()


Getter dos erros máximos das épocas
Returns:
Maiores valores de erro obtidos em cada época em um ArrayList

getErroMaximo

public double getErroMaximo()


Getter do maior erro obtido
Returns:
retorna o maior erro obtido como double

getQtdEpocasAtual

public int getQtdEpocasAtual()


getter da quantidade de épocas atual
Returns:
quantidade de épocas atual como um inteiro

treinar

public boolean treinar()


throws java.lang.Exception
Treina a Rede Neural
Returns:
retorna true ou false se conseguiu treinar ou não
Throws:
java.lang.Exception

69
setEntradaSaidaDoPadrao

public int[] setEntradaSaidaDoPadrao(int padrao)


Setter dos arrays de valores padrão (entrada e saída)
Parameters:
padrao - índice do padrão a ser aplicado nos vetores de entrada e saída

esperada
Returns:
retorna o vetor de entrada

calculeErroGlobal

public double calculeErroGlobal()


Calcula o erro global da época
Returns:
retorna o valor do erro global como um double

calculeFatoresCorrecao

public void calculeFatoresCorrecao(int padrao)


Calcula os fatores de correção
Parameters:
padrao - indice que identifica o padrão utilizado no treinamento

calculeFatoresCorrecao

public void calculeFatoresCorrecao()


Calcula os fatores de correção
Para seu uso, o array saidasEsperadas deve ter sido inicializado com a saida do
treinamento

70
corrigePesos

public void corrigePesos()throws java.lang.Exception


Corrige os pesos entre as conexões
Throws:
java.lang.Exception - lança exceção se ocorrer erro na redefinição dos

pesos

setErroAceitavell

public void setErroAceitavell(double eA)


Setter do erro aceitavel
Parameters:
eA - valor do erro aceitável do tipo double

getErroAceitavel

public double getErroAceitavel()


Getter do erro aceitável
Returns:
retorna o erro aceitável como double

setEpocasMaximo

public void setEpocasMaximo(int eM)


Setter da quantidade máxima de épocas
Parameters:
eM - quantidade máxima de épocas do tipo inteiro

getEpocasMaximo

public int getEpocasMaximo()


Getter da quantidade máxima de épocas
Returns:
retorna o número máximo de épocas como inteiro

71
setFatorAprendizagem

public void setFatorAprendizagem(double fA)


Setter do fator de aprendizagem
Parameters:
fA - valor do fator de aprendizagem como double

getFatorAprendizagem

public double getFatorAprendizagem()


Getter do fator de aprendizagem
Returns:
retorna o valor do fator de aprendizagem como double

72
redeNeural

Class PadroesTreinamento

java.lang.Object
redeNeural.PadroesTreinamento

public class PadroesTreinamento


extends java.lang.Object

Padrões de treinamento para serem usados no treinamento da rede

Author:
Joao Carlos Testi Ferreira e Júnior Barbosa Dymow

Constructor Summary
PadroesTreinamento()
Construtor vazio
Inicializa com tamanho 1x1 os arrays de padrões de entrada e saída

PadroesTreinamento(int[][] pE, int[][] pS)


Construtor com parâmetros
Inicia os arrays com os arrays passados por parâmetro

Method Summary
int[][] getPadroesEntrada()
Getter dos padrões de entrada

int[][] getPadroesSaida()
Getter dos padrões de saída

void setPadroesTreinamento(int[][] pE, int[][] pS)


Setter dos arrays de padrões de entrada e saída

73
Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Constructor Detail
PadroesTreinamento

public PadroesTreinamento()
Construtor vazio
Inicializa com tamanho 1x1 os arrays de padrões de entrada e saída

PadroesTreinamento

public PadroesTreinamento(int[][] pE, int[][] pS)


Construtor com parâmetros
Inicia os arrays com os arrays passados por parâmetro
Parameters:
pE - array com os parâmetros de entrada

pS - array com os parâmetros de saída

Method Detail
setPadroesTreinamento

public void setPadroesTreinamento(int[][] pE, int[][] pS)


Setter dos arrays de padrões de entrada e saída
Parameters:
pE - array com os padrões de entrada

pS - array com os padrões de saída

74
getPadroesEntrada

public int[][] getPadroesEntrada()


Getter dos padrões de entrada
Returns:
retorna o array de padrões de entrada

getPadroesSaida

public int[][] getPadroesSaida()


Getter dos padrões de saída
Returns:
retorna o array de padrões de saída

75
funcoesSaida

Interface FuncaoSaida
All Known Implementing Classes:
FuncaoSigmoidal, FuncaoTangHiperb

public interface FuncaoSaida

Interface que define a função de saída

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Method Summary
double calcDerivada(double valor)
Método que deve se implementado para calcular o valor
de saída da derivada da função

double calcFuncao(double valor)


Método que deve ser implementado para calcular o
valor de saída da função

java.lang.String getNome()
Método a ser implementado para informar o nome da
função

76
Method Detail
calcFuncao

double calcFuncao(double valor)


Método que deve ser implementado para calcular o valor de saída da função
Parameters:
valor - valor a ser aplicado na função como double

Returns:
retorna a saída da função como double

calcDerivada

double calcDerivada(double valor)


Método que deve se implementado para calcular o valor de saída da derivada
da função
Parameters:
valor - a ser aplicado na derivada da função como double

Returns:
retorna a saída da derivada da função como double

getNome

java.lang.String getNome()
Método a ser implementado para informar o nome da função
Returns:
retorna o nome da função como String

77
funcoesSaida

Class FuncaoSigmoidal

java.lang.Object
funcoesSaida.FuncaoSigmoidal
All Implemented Interfaces:
FuncaoSaida

public class FuncaoSigmoidal


extends java.lang.Object
implements FuncaoSaida

Implementação da função de saída do tipo sigmoidal

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Constructor Summary
FuncaoSigmoidal()
construtor vazio

Method Summary
double calcDerivada(double valor)
Calcula o resultado da derivada da função

double calcFuncao(double valor)


Calcula o resultado da função

java.lang.String getNome()
Informa o nome da função de saída

78
Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Constructor Detail
FuncaoSigmoidal

public FuncaoSigmoidal()
construtor vazio

Method Detail
calcFuncao

public double calcFuncao(double valor)


Calcula o resultado da função
Specified by:
calcFuncao in interface FuncaoSaida

Parameters:
valor - valor a ser aplicado na função do tipo double

Returns:
retorna o resultado da função com tipo double

calcDerivada

public double calcDerivada(double valor)


Calcula o resultado da derivada da função
Specified by:
calcDerivada in interface FuncaoSaida

Parameters:
valor - valor a ser aplicado na derivada da função como double

Returns:
retorna o resultado da de derivada da função como double

79
getNome

public java.lang.String getNome()


Informa o nome da função de saída
Specified by:
getNome in interface FuncaoSaida

Returns:
retorna o nome da função como String

80
funcoesSaida

Class FuncaoTangHiperb

java.lang.Object
funcoesSaida.FuncaoTangHiperb
All Implemented Interfaces:
FuncaoSaida

public class FuncaoTangHiperb


extends java.lang.Object
implements FuncaoSaida

Implementação da função de saída do tipo tangente hiperbólica

Author:
João Carlos Testi Ferreira

Constructor Summary
FuncaoTangHiperb()
construtor vazio

Method Summary
double calcDerivada(double valor)
Calcula o resultado da derivada da função

double calcFuncao(double valor)


Calcula o resultado da função

java.lang.String getNome()
Informa o nome da função de saída

81
Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Constructor Detail
FuncaoTangHiperb

public FuncaoTangHiperb()
construtor vazio

Method Detail
calcFuncao

public double calcFuncao(double valor)


Calcula o resultado da função
Specified by:
calcFuncao in interface FuncaoSaida

Parameters:
valor - valor a ser aplicado na função do tipo double

Returns:
retorna o resultado da função com tipo double

calcDerivada

public double calcDerivada(double valor)


Calcula o resultado da derivada da função
Specified by:
calcDerivada in interface FuncaoSaida

Parameters:
valor - valor a ser aplicado na derivada da função como double

Returns:
retorna o resultado da de derivada da função como double

82
getNome

public java.lang.String getNome()


Informa o nome da função de saída
Specified by:
getNome in interface FuncaoSaida

Returns:
retorna o nome da função como String

83
manipulacaoArquivos

Class LeitorPadroes

java.lang.Object
manipulacaoArquivos.LeitorPadroes

public class LeitorPadroes


extends java.lang.Object

Le arquivo com os padrões de treinamento

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Constructor Summary
LeitorPadroes()
Construtor vazio

LeitorPadroes(java.lang.String pNomeArquivo)
Construtor com parâmetro

Method Summary
redeNeural.PadroesTreinamento lerDadosTreinamento()
Leitor dos padrões para treinamento

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

84
Constructor Detail
LeitorPadroes

public LeitorPadroes()
Construtor vazio

LeitorPadroes

public LeitorPadroes(java.lang.String pNomeArquivo)


Construtor com parâmetro
Parameters:
pNomeArquivo - nome do arquivo que contém os padrões

Method Detail
lerDadosTreinamento

public redeNeural.PadroesTreinamento lerDadosTreinamento()


throws
java.lang.Exception
Leitor dos padrões para treinamento
Returns:
quantidade de registros lidos
Throws:
lança - exceção de I/O ou erro de leitura no formato do arquivo
java.lang.Exception

85
manipulacaoArquivos

Class PersistenciaRede

java.lang.Object
manipulacaoArquivos.PersistenciaRede

public class PersistenciaRede


extends java.lang.Object

Persistência de rede neural artificial em arquivo texto

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Constructor Summary
PersistenciaRede()
Construtor vazio

PersistenciaRede(java.lang.String nArquivo)
Construtor com parâmetro

Method Summary
void gerarArquivoRede(java.lang.String nomeArquivo,
RedeNeural rna)
Cria o arquivo da rede

RedeNeural lerArquivoRede(java.lang.String nomeArquivo)


Leitor de rede neural artificial

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

86
Constructor Detail
PersistenciaRede

public PersistenciaRede()
Construtor vazio

PersistenciaRede

public PersistenciaRede(java.lang.String nArquivo)


Construtor com parâmetro
Parameters:
nArquivo - nome do arquivo onde será gravada a rede

Method Detail
gerarArquivoRede

public void gerarArquivoRede(java.lang.String nomeArquivo,


RedeNeural rna)
throws java.lang.Exception
Cria o arquivo da rede
Parameters:
nomeArquivo - nome do arquivo que conterá a rede

rna - rede a ser gravada

Throws:
java.lang.Exception - Lança exceção se não for possível criar o arquivo ou

escrever nele

87
lerArquivoRede

public RedeNeural lerArquivoRede(java.lang.String nomeArquivo)


throws java.lang.Exception
Leitor de rede neural artificial
Parameters:
nomeArquivo - nome do arquivo que contém a rede

Returns:
retorna a rede neural lida como RedeNeural
Throws:
java.lang.Exception - Lança exceção se não for possível ler o arquivo, tiver

nome de função inválida, número de campos inválido no registro, não conseguir criar
a rede lida.

88
manipulacaoArquivos

Class GravadorArquivoPesos

java.lang.Object
manipulacaoArquivos.GravadorArquivoPesos

public class GravadorArquivoPesos


extends java.lang.Object

Grava arquivo de pesos de uma rede neural artificial

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Constructor Summary
GravadorArquivoPesos()
Construtor vazio

GravadorArquivoPesos(java.lang.String nArquivo)
Construtor com parâmetros

Method Summary
boolean gerarArquivoPesos(java.lang.String nomeArquivo,
RedeNeural rna)
Gera o arquivo de pesos

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

89
Constructor Detail
GravadorArquivoPesos

public GravadorArquivoPesos()
Construtor vazio

GravadorArquivoPesos

public GravadorArquivoPesos(java.lang.String nArquivo)


Construtor com parâmetros
Parameters:
nArquivo - nome do arquivo onde serão gravados os pesos

Method Detail
gerarArquivoPesos

public boolean gerarArquivoPesos(java.lang.String nomeArquivo,


RedeNeural rna)
throws java.lang.Exception
Gera o arquivo de pesos
Parameters:
nomeArquivo - nome do arquivo onde serão gravados os pesos

rna - rede neural da qual ser~ao gravados os pesos

Returns:
retorna true se conseguiu gravar
Throws:
java.lang.Exception - lan'ca exce'c~ao se n~ao conseguir criar ou

escrever no arquivo

90
geradoresCodigo

Class GeradorCodigo

java.lang.Object
geradoresCodigo.GeradorCodigo
Direct Known Subclasses:
GeradorCodigoCPP, GeradorCodigoJava, GeradorCodigoJS, GeradorCodigoOP

public abstract class GeradorCodigo


extends java.lang.Object

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Field Summary
protected arquivo
java.io.BufferedWriter

protected extensaoArquivo
java.lang.String

protected fimComentarioBloco
java.lang.String

protected inicioComentarioBloco
java.lang.String

protected inicioComentarioLinha
java.lang.String

Constructor Summary
GeradorCodigo()
Creates a new instance of GeradorCodigo

91
Method Summary
void escrvComentLinha(java.lang.String comentario)
Escrever comentário de uma única linha

void escrvLnhComentBlco(java.lang.String comentario)


Escrever uma linha em um bloco de comentário

void finalizarComentarioBloco()
Inserir caracter(es) de final de comentário de bloco

void gerarArquivoEmDisco(java.lang.String nomeArquivo)


Gera em disco um arquivo vazio com o nome passado como parâmetro

void gerarFuncaoRNAMLP(int nosEntrada, int nosEscondidos,


int nosSaida, double[][] pesosHI, double[][] pesosOH, int bias,
double limiar)
Escreve a função com os dados da rede treinada no arquivo do tipo
selecionado

void iniComentBloco()
Inserir caracter(es) de início de comentário de bloco

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Field Detail
arquivo

protected java.io.BufferedWriter arquivo

inicioComentarioBloco

protected java.lang.String inicioComentarioBloco

92
fimComentarioBloco

protected java.lang.String fimComentarioBloco

inicioComentarioLinha

protected java.lang.String inicioComentarioLinha

extensaoArquivo

protected java.lang.String extensaoArquivo

Constructor Detail
GeradorCodigo

public GeradorCodigo()
Creates a new instance of GeradorCodigo

Method Detail
gerarArquivoEmDisco

public void gerarArquivoEmDisco(java.lang.String nomeArquivo)


throws java.lang.Exception
Gera em disco um arquivo vazio com o nome passado como parâmetro
Throws:
java.lang.Exception

escrvComentLinha

public void escrvComentLinha(java.lang.String comentario)


throws java.lang.Exception
Escrever comentário de uma única linha
Throws:
java.lang.Exception

iniComentBloco

public void iniComentBloco() throws java.lang.Exception


Inserir caracter(es) de início de comentário de bloco
Throws:
java.lang.Exception

93
escrvLnhComentBlco

public void escrvLnhComentBlco(java.lang.String comentario)


throws java.lang.Exception
Escrever uma linha em um bloco de comentário
Throws:
java.lang.Exception

finalizarComentarioBloco

public void finalizarComentarioBloco()


throws java.lang.Exception
Inserir caracter(es) de final de comentário de bloco
Throws:
java.lang.Exception

gerarFuncaoRNAMLP

public void gerarFuncaoRNAMLP(int nosEntrada,


int nosEscondidos,
int nosSaida,
double[][] pesosHI,
double[][] pesosOH,
int bias,
double limiar)
throws java.lang.Exception
Escreve a função com os dados da rede treinada no arquivo do tipo
selecionado
Throws:
java.lang.Exception

94
geradoresCodigo

Class GeradorCodigoJS

java.lang.Object
geradoresCodigo.GeradorCodigo
geradoresCodigo.GeradorCodigoJS

public class GeradorCodigoJS


extends GeradorCodigo

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Field Summary

Fields inherited from class geradoresCodigo.GeradorCodigo

arquivo, extensaoArquivo, fimComentarioBloco, inicioComentarioBloco,


inicioComentarioLinha

Constructor Summary
GeradorCodigoJS()
Creates a new instance of geradorCodigoJS

Method Summary
void gerarFuncaoRNAMLP(int nosEntrada, int nosEscondidos,
int nosSaida, double[][] pesosHI, double[][] pesosOH, int bias,
double limiar)
Escreve a função com os dados da rede treinada no arquivo do tipo
selecionado

95
Methods inherited from class geradoresCodigo.GeradorCodigo

escrvComentLinha, escrvLnhComentBlco, finalizarComentarioBloco,


gerarArquivoEmDisco, iniComentBloco

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Constructor Detail
GeradorCodigoJS

public GeradorCodigoJS()
Creates a new instance of geradorCodigoJS

Method Detail
gerarFuncaoRNAMLP

public void gerarFuncaoRNAMLP(int nosEntrada,


int nosEscondidos,
int nosSaida,
double[][] pesosHI,
double[][] pesosOH,
int bias,
double limiar)
throws java.lang.Exception
Description copied from class: GeradorCodigo
Escreve a função com os dados da rede treinada no arquivo do tipo
selecionado
Overrides:
gerarFuncaoRNAMLP in class GeradorCodigo

Throws:
java.lang.Exception

96
geradoresCodigo

Class GeradorCodigoJava

java.lang.Object
geradoresCodigo.GeradorCodigo
geradoresCodigo.GeradorCodigoJava

public class GeradorCodigoJava


extends GeradorCodigo

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Field Summary

Fields inherited from class geradoresCodigo.GeradorCodigo

arquivo, extensaoArquivo, fimComentarioBloco, inicioComentarioBloco,


inicioComentarioLinha

Constructor Summary
GeradorCodigoJava()
Creates a new instance of GeradorCodigoJava

Method Summary

97
Methods inherited from class geradoresCodigo.GeradorCodigo

escrvComentLinha, escrvLnhComentBlco, finalizarComentarioBloco,


gerarArquivoEmDisco, gerarFuncaoRNAMLP, iniComentBloco

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Constructor Detail
GeradorCodigoJava

public GeradorCodigoJava()
Creates a new instance of GeradorCodigoJava

98
geradoresCodigo

Class GeradorCodigoCPP

java.lang.Object
geradoresCodigo.GeradorCodigo
geradoresCodigo.GeradorCodigoCPP

public class GeradorCodigoCPP


extends geradoresCodigo.GeradorCodigo

Gera arquivo fonte em linguagem C++

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Field Summary

Fields inherited from class geradoresCodigo.GeradorCodigo

arquivo, extensaoArquivo, fimComentarioBloco, inicioComentarioBloco,


inicioComentarioLinha

Constructor Summary
GeradorCodigoCPP()
Construtor vazio Gera as variáveis relacionadas aos comentários e extensão de
arquivo

99
Method Summary
void gerarFuncaoRNAMLP(redeNeural.RedeNeural rna,
double limiar)
Implementação da função abstrata

Methods inherited from class geradoresCodigo.GeradorCodigo

escrvComentLinha, escrvLnhComentBlco, finalizarComentarioBloco,


gerarArquivoEmDisco, iniComentBloco

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Constructor Detail
GeradorCodigoCPP

public GeradorCodigoCPP()
Construtor vazio Gera as variáveis relacionadas aos comentários e extensão
de arquivo

100
Method Detail
gerarFuncaoRNAMLP

public void gerarFuncaoRNAMLP(redeNeural.RedeNeural rna,


double limiar)
throws java.lang.Exception
Implementação da função abstrata
Specified by:
gerarFuncaoRNAMLP in class geradoresCodigo.GeradorCodigo

Parameters:
rna - Rede neural com a qual será gerado o código fonte

limiar - limite entre o valor 0 e 1 da saída

Throws:
java.lang.Exception - lança exceção se não conseguir escrever no arquivo

101
geradoresCodigo

Class GeradorCodigoOP

java.lang.Object
geradoresCodigo.GeradorCodigo
geradoresCodigo.GeradorCodigoOP

public class GeradorCodigoOP


extends GeradorCodigo

Author:
João Carlos Testi Ferreira e Júnior Barbosa Dymow

Field Summary

Fields inherited from class geradoresCodigo.GeradorCodigo

arquivo, extensaoArquivo, fimComentarioBloco, inicioComentarioBloco,


inicioComentarioLinha

Constructor Summary
GeradorCodigoOP()
Creates a new instance of GeradorCodigoOP

Method Summary

Methods inherited from class geradoresCodigo.GeradorCodigo

escrvComentLinha, escrvLnhComentBlco, finalizarComentarioBloco,


gerarArquivoEmDisco, gerarFuncaoRNAMLP, iniComentBloco

102
Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll,


toString, wait, wait, wait

Constructor Detail
GeradorCodigoOP

public GeradorCodigoOP()
Creates a new instance of GeradorCodigoOP

103
ANEXO 4 – Função RNAMLP

function RNAMLP( valor1, valor2, valor3, valor4, valor5, valor6, valor7,


valor8, valor9, valor10 ) {
var entrada = [1, valor1, valor2, valor3, valor4, valor5, valor6,
valor7, valor8, valor9, valor10];
var saida = new Array(10);
var escondidos = new Array(11);
var pesosHI = [
[-1.2856558579221395, -3.3546024179427647, 0.13808980636806736,
0.7788557265218385, -3.663723505738529, 6.81433927597742,
1.590259488692084, 1.3171995432140704, -1.7705215160389425,
2.4569599466855405, -1.7627352741308377],
[-1.9030009103486898, -0.09222009260296783, 0.2545433888946836,
0.8248402873175982, -0.6306016081459316, -0.4864277843397504, -
1.0579876002364228, 5.455049306517363, 0.8614507683642678, -
2.2598068483598115, 0.48983030833878743],
[1.5791080355866962, 1.1126830859316539, 2.0806761486299226,
0.8358606741585255, -3.5825915527431857, -1.746707685515664, -
1.271711791890792, -1.2678650336258377, 1.6962225517309462, -
0.7583112393123117, 0.3146227849727759],
[1.3811458460364616, 2.566915117328856, -0.8639897042529363, -
1.6506867030635746, 0.29149801747624104, -3.7331368822106383,
0.9351214828477853, 0.7098301502871806, -1.0906826044844635,
1.1443098558699156, 0.07673126338924965],
[3.6407741333214414, -3.9364044933229114, -2.9948175942649438,
0.15315956057606944, -0.11850310790472499, -1.6023740558529822, -
0.5690093114567213, 0.2562284649306525, 0.40815497981415894, -
1.2591737931939333, 0.8574888383500717],
[-2.596313433400822, 1.6292312558561262, -1.0917510558689612,
5.617972865957996, 0.662377895827699, -0.5686429528598356,
0.2730521011060961, -0.41282611022348087, -1.227612200063836, -
0.22122377896824008, 0.7997339332332916],
[-3.031242348504958, 0.13600495222363043, 0.3658218944698372, -
1.350837240090895, 0.20141865197690725, 0.8090635718730524,
0.8594466356086035, 0.25316698147111577, -0.6989354794637509,
0.21713561161102007, 5.604808595088253],
[-3.3088183631140002, 0.9334181516336892, -1.0189313904658557, -
0.4214245180334989, 1.7757691468433698, -0.46226463189662415,
0.45941804628514243, -0.2891921720863641, 5.216286120029775,
0.4557248135224579, 0.07999525199370024],
[0.7750881490651261, 0.3002802604550937, 0.5310121453830041, -
0.6704508008707264, 2.940638295467867, -0.7324546957380885, -
4.261796141402154, 0.17579344703024402, -0.5202092888905405,
0.4332780965299074, 0.2827176150692071],
[-1.8494966523813985, -1.8319088315007193, 3.301291415089924,
0.8405531018459189, 1.6510731530166576, -1.285752065274323,
2.0501957031949294, 0.2104686173954527, -0.22885431381364849, -
0.5324394298815687, -0.1654749759645047],
[1.7904963312487412, 1.8903473799894446, -0.150120640765903, -
1.3496156794944019, 1.5601888334857037, 0.5856198123045506,
0.21248308661881335, -0.7534446033074967, -0.03927171079075187, -
4.399377418601928, -0.590704164543097],

104
]
var pesosOH = [[-0.787725138506782, 10.643922922017769, -
2.5923543300505765, -0.021685354539227538, -1.688350030152189, -
0.5381267010466972, -0.34513575689551396, -0.06799884581371239, -
0.3994258997081885, -0.40386133218184284, -2.3091975531337146],
[-3.830921890522562, 1.560252109939317, 1.9908369628655072, -
1.1776843598226274, -0.48202590732934353, -1.1788707361739668, -
0.7805217896712606, 10.566643532494298, -1.8902928361129037,
0.40499379824681897, -1.145568319493568],
[13.265903517655303, 0.9073707561793445, -4.021873891044608, -
9.500957123697356, -5.68125463646632, -1.0792962960197756,
1.1461402359045958, -0.6583422216693, -2.425142002040002, -
3.750297544763434, -0.045864516119610815],
[-2.3034363168091514, 0.7589655461662765, 3.6331641902942304, -
2.0601835274346043, -6.182752149984374, -3.3373148597372118,
0.8476556305409105, -1.4105053927947653, 2.4898437171701766,
8.90197479417717, -1.1082563249697226],
[-5.214673196217013, 0.289684903672961, 1.8653138607876867,
5.252415257814263, -8.802416489778418, 4.537764142421334,
1.1557448266025159, 1.9385986463863862, 0.17542132554483894, -
3.2788262825293715, 4.108821802711848],
[1.4812132332539296, -1.003181305943442, -3.8899523509534455,
2.405762478162071, -0.6085596103961814, 0.12813529047533911,
1.576509619487255, 2.2053410247159935, -10.02873096973665,
4.6382410567312835, 1.0114984126627093],
[-5.672910908176199, -0.1436856719356623, 0.5181772400775964,
0.26774045507871846, 0.23173776340482363, 0.7726011098634623,
10.3201692155927, 0.3924799711314042, -0.06517600365995121, -
0.5972605410724682, -0.5971845134496148],
[5.9551734423373235, -2.181143551720631, -1.945668502770097,
1.3303559090965538, -2.2590447380096585, -0.08693786150461995, -
0.198482287833655, 2.4171710408105627, 2.12090618024629, -
0.5813378580836922, -10.937177458423054],
[-1.364096656841394, 0.7615384771783854, -0.8478301558027015, -
2.2327765088195446, -1.8080383964432944, 10.684419262939869, -
1.8602724564093847, 1.3195984374207343, 0.050638164673315424,
0.07882040214924643, -2.1706674236879295],
[-6.013143734676788, -2.067581763652359, -8.661895495552908,
1.536019227651033, -1.222478374878116, 3.555332368838095,
0.6311249924674665, 4.147994058827936, 5.5402811175658275,
5.212886055989511, 2.9354627708783942],
]
for(j = 0; j < 11; j++) {
escondidos[j] = 0;
for(i = 0; i < 11; i++) {
escondidos[j] += pesosHI[j][i] * entrada[i];
}
}
escondidos[0] = 1;
for(j = 1; j < 11; j++){
escondidos[j] = (1/(1 + Math.exp(-escondidos[j])));
}
for(k = 0; k < 10; k++) {
saida[k] = 0;
for(j = 0; j < 11; j++){
saida[k] += pesosOH[k][j] * escondidos[j];
}
}

105
for(k = 0; k < 10; k++){
saida[k] = (1/(1 + Math.exp(-saida[k])));
}
for(k = 0; k < 10; k++){
saida[k] = saida[k] < 0.5 ? 0 : 1;
}
// --> O resultado é o vetor saida
}

106
ANEXO 5 – Exercício Completo HTML/javascript
<HTML>
<HEAD>
<STYLE>
H1 {
font-family: Arial;
font-size: 12pt;
font-weight: bold;
}
TD {
font-family: Arial;
font-size: 10pt;
}

BODY {
font-family: Arial;
font-size: 10pt;
}
</STYLE>
<TITLE>Exercício de Neuroanatomia</TITLE>
<SCRIPT>
var e = new Array(10);
var saida = new Array(10);
function RNAMLP( valor1, valor2, valor3, valor4, valor5, valor6, valor7,
valor8, valor9, valor10 ) {
var entrada = [1, valor1, valor2, valor3, valor4, valor5, valor6,
valor7, valor8, valor9, valor10];
var escondidos = new Array(11);
var pesosHI = [
[-1.2856558579221395, -3.3546024179427647, 0.13808980636806736,
0.7788557265218385, -3.663723505738529, 6.81433927597742,
1.590259488692084, 1.3171995432140704, -1.7705215160389425,
2.4569599466855405, -1.7627352741308377],
[-1.9030009103486898, -0.09222009260296783, 0.2545433888946836,
0.8248402873175982, -0.6306016081459316, -0.4864277843397504, -
1.0579876002364228, 5.455049306517363, 0.8614507683642678, -
2.2598068483598115, 0.48983030833878743],
[1.5791080355866962, 1.1126830859316539, 2.0806761486299226,
0.8358606741585255, -3.5825915527431857, -1.746707685515664, -
1.271711791890792, -1.2678650336258377, 1.6962225517309462, -
0.7583112393123117, 0.3146227849727759],
[1.3811458460364616, 2.566915117328856, -0.8639897042529363, -
1.6506867030635746, 0.29149801747624104, -3.7331368822106383,
0.9351214828477853, 0.7098301502871806, -1.0906826044844635,
1.1443098558699156, 0.07673126338924965],
[3.6407741333214414, -3.9364044933229114, -2.9948175942649438,
0.15315956057606944, -0.11850310790472499, -1.6023740558529822, -
0.5690093114567213, 0.2562284649306525, 0.40815497981415894, -
1.2591737931939333, 0.8574888383500717],
[-2.596313433400822, 1.6292312558561262, -1.0917510558689612,
5.617972865957996, 0.662377895827699, -0.5686429528598356,
0.2730521011060961, -0.41282611022348087, -1.227612200063836, -
0.22122377896824008, 0.7997339332332916],
[-3.031242348504958, 0.13600495222363043, 0.3658218944698372, -
1.350837240090895, 0.20141865197690725, 0.8090635718730524,

107
0.8594466356086035, 0.25316698147111577, -0.6989354794637509,
0.21713561161102007, 5.604808595088253],
[-3.3088183631140002, 0.9334181516336892, -1.0189313904658557, -
0.4214245180334989, 1.7757691468433698, -0.46226463189662415,
0.45941804628514243, -0.2891921720863641, 5.216286120029775,
0.4557248135224579, 0.07999525199370024],
[0.7750881490651261, 0.3002802604550937, 0.5310121453830041, -
0.6704508008707264, 2.940638295467867, -0.7324546957380885, -
4.261796141402154, 0.17579344703024402, -0.5202092888905405,
0.4332780965299074, 0.2827176150692071],
[-1.8494966523813985, -1.8319088315007193, 3.301291415089924,
0.8405531018459189, 1.6510731530166576, -1.285752065274323,
2.0501957031949294, 0.2104686173954527, -0.22885431381364849, -
0.5324394298815687, -0.1654749759645047],
[1.7904963312487412, 1.8903473799894446, -0.150120640765903, -
1.3496156794944019, 1.5601888334857037, 0.5856198123045506,
0.21248308661881335, -0.7534446033074967, -0.03927171079075187, -
4.399377418601928, -0.590704164543097],
]
var pesosOH = [[-0.787725138506782, 10.643922922017769, -
2.5923543300505765, -0.021685354539227538, -1.688350030152189, -
0.5381267010466972, -0.34513575689551396, -0.06799884581371239, -
0.3994258997081885, -0.40386133218184284, -2.3091975531337146],
[-3.830921890522562, 1.560252109939317, 1.9908369628655072, -
1.1776843598226274, -0.48202590732934353, -1.1788707361739668, -
0.7805217896712606, 10.566643532494298, -1.8902928361129037,
0.40499379824681897, -1.145568319493568],
[13.265903517655303, 0.9073707561793445, -4.021873891044608, -
9.500957123697356, -5.68125463646632, -1.0792962960197756,
1.1461402359045958, -0.6583422216693, -2.425142002040002, -
3.750297544763434, -0.045864516119610815],
[-2.3034363168091514, 0.7589655461662765, 3.6331641902942304, -
2.0601835274346043, -6.182752149984374, -3.3373148597372118,
0.8476556305409105, -1.4105053927947653, 2.4898437171701766,
8.90197479417717, -1.1082563249697226],
[-5.214673196217013, 0.289684903672961, 1.8653138607876867,
5.252415257814263, -8.802416489778418, 4.537764142421334,
1.1557448266025159, 1.9385986463863862, 0.17542132554483894, -
3.2788262825293715, 4.108821802711848],
[1.4812132332539296, -1.003181305943442, -3.8899523509534455,
2.405762478162071, -0.6085596103961814, 0.12813529047533911,
1.576509619487255, 2.2053410247159935, -10.02873096973665,
4.6382410567312835, 1.0114984126627093],
[-5.672910908176199, -0.1436856719356623, 0.5181772400775964,
0.26774045507871846, 0.23173776340482363, 0.7726011098634623,
10.3201692155927, 0.3924799711314042, -0.06517600365995121, -
0.5972605410724682, -0.5971845134496148],
[5.9551734423373235, -2.181143551720631, -1.945668502770097,
1.3303559090965538, -2.2590447380096585, -0.08693786150461995, -
0.198482287833655, 2.4171710408105627, 2.12090618024629, -
0.5813378580836922, -10.937177458423054],
[-1.364096656841394, 0.7615384771783854, -0.8478301558027015, -
2.2327765088195446, -1.8080383964432944, 10.684419262939869, -
1.8602724564093847, 1.3195984374207343, 0.050638164673315424,
0.07882040214924643, -2.1706674236879295],
[-6.013143734676788, -2.067581763652359, -8.661895495552908,
1.536019227651033, -1.222478374878116, 3.555332368838095,

108
0.6311249924674665, 4.147994058827936, 5.5402811175658275,
5.212886055989511, 2.9354627708783942],
]
for(j = 0; j < 11; j++) {
escondidos[j] = 0;
for(i = 0; i < 11; i++) {
escondidos[j] += pesosHI[j][i] * entrada[i];
}
}
escondidos[0] = 1;
for(j = 1; j < 11; j++){
escondidos[j] = (1/(1 + Math.exp(-escondidos[j])));
}
for(k = 0; k < 10; k++) {
saida[k] = 0;
for(j = 0; j < 11; j++){
saida[k] += pesosOH[k][j] * escondidos[j];
}
}

for(k = 0; k < 10; k++){


saida[k] = (1/(1 + Math.exp(-saida[k])));
}
for(k = 0; k < 10; k++){
saida[k] = saida[k] < 0.5 ? 0 : 1;
}
// --> O resultado é o vetor saida
}
function muda(obj) {
if (obj.style.visibility == "hidden") {
obj.style.visibility = '';
} else {
obj.style.visibility = 'hidden';
}
}
function desliga() {
iregiao8.style.visibility = 'hidden';
iregiao9.style.visibility = 'hidden';
iregiao10.style.visibility = 'hidden';
iregiao11.style.visibility = 'hidden';
iregiao12.style.visibility = 'hidden';
iregiao13.style.visibility = 'hidden';
iregiao14.style.visibility = 'hidden';
iregiao16.style.visibility = 'hidden';
iregiao17.style.visibility = 'hidden';
iregiao18.style.visibility = 'hidden';
}
function liga() {
iregiao8.style.visibility = '';
iregiao9.style.visibility = '';
iregiao10.style.visibility = '';
iregiao11.style.visibility = '';
iregiao12.style.visibility = '';
iregiao13.style.visibility = '';
iregiao14.style.visibility = '';
iregiao16.style.visibility = '';
iregiao17.style.visibility = '';
iregiao18.style.visibility = '';

109
}
function elege() {
return Math.floor(Math.random() * 10)
}
function corVerde(obj) {
obj.bgColor = '#00FF00';
}
function corVermelho(obj) {
obj.bgColor = '#FF0000';
}
function tiraCor() {
L1.bgColor = '#FFFFFF';
L2.bgColor = '#FFFFFF';
L3.bgColor = '#FFFFFF';
L4.bgColor = '#FFFFFF';
L5.bgColor = '#FFFFFF';
L5.bgColor = '#FFFFFF';
L7.bgColor = '#FFFFFF';
L8.bgColor = '#FFFFFF';
L9.bgColor = '#FFFFFF';
L10.bgColor = '#FFFFFF';
L1B.style.visibility = 'hidden';
L2B.style.visibility = 'hidden';
}
function entrada(n) {
e[0] = 0; e[1] = 0; e[2] = 0; e[3] = 0; e[4] = 0; e[5] = 0; e[6] =
0; e[7] = 0; e[8] = 0; e[9] = 0;
for(i = 0; i < n; i++) {
switch(elege()) {
case 0: e[0] = 1;
break;
case 1: e[1] = 1;
break;
case 2: e[2] = 1;
break;
case 3: e[3] = 1;
break;
case 4: e[4] = 1;
break;
case 5: e[5] = 1;
break;
case 6: e[6] = 1;
break;
case 7: e[7] = 1;
break;
case 8: e[8] = 1;
break;
case 9: e[9] = 1;
break;
}
}
for(i = 0; i < 10; i++) {
if(e[i] == 1) {
if(i == 0) iregiao8.style.visibility = '';
if(i == 1) iregiao9.style.visibility = '';
if(i == 2) iregiao10.style.visibility = '';
if(i == 3) iregiao11.style.visibility = '';
if(i == 4) iregiao12.style.visibility = '';

110
if(i == 5) iregiao13.style.visibility = '';
if(i == 6) iregiao14.style.visibility = '';
if(i == 7) iregiao16.style.visibility = '';
if(i == 8) iregiao17.style.visibility = '';
if(i == 9) iregiao18.style.visibility = '';
}
}
}
</SCRIPT>
</HEAD>
<BODY>
<IMG ID=Principal SRC="imagens/tratamentook.jpg" style="position: absolute;
left: 10px; top: 15px"></IMG>
<IMG ID=iregiao8 SRC="imagens/regiao8.gif" alt="face medial superior do
giro pré-central" style="position: absolute; left: 9px; top; 7px; z-index:
1; filter: alpha(opacity=50, FinishOpacity=15, Style=0)"></IMG>
<IMG ID=iregiao9 SRC="imagens/regiao9.gif" style="position: absolute; left:
9px; top; 7px; z-index: 1; filter: alpha(opacity=50, FinishOpacity=15,
Style=0)"></IMG>
<IMG ID=iregiao10 SRC="imagens/regiao10.gif" style="position: absolute;
left: 9px; top; 7px; z-index: 2; filter: alpha(opacity=50,
FinishOpacity=15, Style=0)"></IMG>
<IMG ID=iregiao11 SRC="imagens/regiao11.gif" style="position: absolute;
left: 9px; top; 7px; z-index: 3; filter: alpha(opacity=50,
FinishOpacity=15, Style=0)"></IMG>
<IMG ID=iregiao12 SRC="imagens/regiao12.gif" style="position: absolute;
left: 9px; top; 7px; z-index: 4; filter: alpha(opacity=50,
FinishOpacity=15, Style=0)"></IMG>
<IMG ID=iregiao13 SRC="imagens/regiao13.gif" style="position: absolute;
left: 9px; top; 7px; z-index: 5; filter: alpha(opacity=50,
FinishOpacity=15, Style=0)"></IMG>
<IMG ID=iregiao14 SRC="imagens/regiao14.gif" style="position: absolute;
left: 9px; top; 7px; z-index: 2; filter: alpha(opacity=50,
FinishOpacity=15, Style=0)"></IMG>
<IMG ID=iregiao16 SRC="imagens/regiao16.gif" style="position: absolute;
left: 9px; top; 7px; z-index: 3; filter: alpha(opacity=50,
FinishOpacity=15, Style=0)"></IMG>
<IMG ID=iregiao17 SRC="imagens/regiao17.gif" style="position: absolute;
left: 9px; top; 7px; z-index: 4; filter: alpha(opacity=50,
FinishOpacity=15, Style=0)"></IMG>
<IMG ID=iregiao18 SRC="imagens/regiao18.gif" style="position: absolute;
left: 9px; top; 7px; z-index: 5; filter: alpha(opacity=50,
FinishOpacity=15, Style=0)"></IMG>
<SCRIPT>
desliga();
entrada(5);
</SCRIPT>
<BR>
<H3 style="font-family: Arial; font-size: 12pt; font-weight: bold;
position: absolute; top: 325px">Indique os prováveis sintomas do paciente
com lesões nas <BR>regiões apresentadas em destaque:</H3>
<FORM name=form style="position: absolute; top: 363px">
<TABLE CELLSPACING=0 CELLPADDING=0>
<TR><TD ID=L1>
<INPUT TYPE=CHECKBOX NAME=hemianopsia> Hemianopsia
</TD>
<TD ID=L1A WIDTH=100>
</TD>

111
<TD ID=L1B BGCOLOR=#00FF00>CORRETO
</TD>
</TR>
<TR><TD ID=L2>
<INPUT TYPE=CHECKBOX NAME=dislexia> Dislexia
</TD>
<TD ID=L2A>
</TD>
<TD ID=L2B BGCOLOR=#FF0000 BORDER=1>INCORRETO
</TD>
</TR>
<TR><TD ID=L3>
<INPUT TYPE=CHECKBOX NAME=emocional> Alteração Emocional
</TD>
<TD ID=L3A>
</TD>
<TD ID=L3B BGCOLOR=#FFFFFF>
</TD></TR>
<TR><TD ID=L4>
<INPUT TYPE=CHECKBOX NAME=memoria> Alteracão da Memória
</TD>
<TD ID=L4A>
</TD>
<TD ID=L4B BGCOLOR=#FFFFFF>
</TD></TR>
<TR><TD ID=L5>
<INPUT TYPE=CHECKBOX NAME=esfincter> Mal Funcionamento do Esfincter
Anal/Vesical
</TD>
<TD ID=L5A>
</TD>
<TD ID=L5B BGCOLOR=#FFFFFF>
</TD></TR>
<TR><TD ID=L6>
<INPUT TYPE=CHECKBOX NAME=personalidade> Personalidade Alterada
</TD>
<TD ID=L6A>
</TD>
<TD ID=L6B BGCOLOR=#FFFFFF>
</TD></TR>
<TR><TD ID=L7>
<INPUT TYPE=CHECKBOX NAME=olfacao> Alteracao da Olfação
</TD>
<TD ID=L7A>
</TD>
<TD ID=L7B BGCOLOR=#FFFFFF>
</TD></TR>
<TR><TD ID=L8>
<INPUT TYPE=CHECKBOX NAME=ataxia> Ataxia
</TD>
<TD ID=L8A>
</TD>
<TD ID=L8B BGCOLOR=#FFFFFF>
</TD></TR>
<TR><TD ID=L9>
<INPUT TYPE=CHECKBOX NAME=hemiplegia> Hemiplegia dos Membros Inferiores
</TD>
<TD ID=L9A>

112
</TD>
<TD ID=L9B BGCOLOR=#FFFFFF>
</TD></TR>
<TR><TD ID=L10>
<INPUT TYPE=CHECKBOX NAME=parestesia> Alteração Sensorial Superficial dos
Membros Inferiores
</TD>
<TD ID=L10A>
</TD>
<TD ID=L10B BGCOLOR=#FFFFFF>
</TD></TR>
</TABLE>
<BR>
<INPUT TYPE=BUTTON NAME=bConfirma VALUE=CONFIRMA ONCLICK="confirma()">
<INPUT TYPE=BUTTON NAME=bRepete VALUE="TENTAR DE NOVO" ONCLICK="repete()">
</FORM>
<SCRIPT>
tiraCor();
function confirma() {
RNAMLP(e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9]);
if((form.hemianopsia.checked && saida[0] == 1) ||
(!form.hemianopsia.checked && saida[0] == 0) ) {
corVerde(L1);
} else {
corVermelho(L1);
}
if((form.dislexia.checked && saida[1] == 1) ||
(!form.dislexia.checked && saida[1] == 0)) {
corVerde(L2);
} else {
corVermelho(L2);
}
if((form.emocional.checked && saida[2] == 1)
||(!form.emocional.checked && saida[2] == 0)) {
corVerde(L3);
} else {
corVermelho(L3);
}
if((form.memoria.checked && saida[3] == 1) ||(!form.memoria.checked
&& saida[3] == 0)) {
corVerde(L4);
} else {
corVermelho(L4);
}
if((form.esfincter.checked && saida[4] == 1)
||(!form.esfincter.checked && saida[4] == 0)) {
corVerde(L5);
} else {
corVermelho(L5);
}
if((form.personalidade.checked && saida[5] == 1)
||(!form.personalidade.checked && saida[5] == 0)) {
corVerde(L6);
} else {
corVermelho(L6);
}
if((form.olfacao.checked && saida[6] == 1) ||(!form.olfacao.checked
&& saida[6] == 0)) {

113
corVerde(L7);
} else {
corVermelho(L7);
}
if((form.ataxia.checked && saida[7] == 1) || (!form.ataxia.checked
&& saida[7] == 0)) {
corVerde(L8);
} else {
corVermelho(L8);
}
if((form.hemiplegia.checked && saida[8] == 1)
||(!form.hemiplegia.checked && saida[8] == 0)) {
corVerde(L9);
} else {
corVermelho(L9);
}
if((form.parestesia.checked && saida[9] == 1)
||(!form.parestesia.checked && saida[9] == 0)) {
corVerde(L10);
} else {
corVermelho(L10);
}
L1B.style.visibility = '';
L2B.style.visibility = '';
}
function repete() {
location.reload();
}
</SCRIPT>
</BODY>

</HTML>

114
ANEXO 6 – Questionário de uso do aplicativo HTML

Sete alunos do curso de Medicina responderam ao questionário, cujas respostas


estão agrupadas a seguir:

1 – Quanto a facilidade de uso do aplicativo, você achou:

Fácil Razoavelmente Fácil Difícil


7 0 0

2 – O que você acha de disponibilizar exercícios de neuroanatomia na internet?

Muito Útil Razoavelmente Útil Nada Útil


7 0 0

3 – Quanto a qualidade das respostas do aplicativo, classifique:

Ótima Boa Ruim


4 3 0

4 – Quanto ao estímulo de estudo de Neuroanatomia, o aplicativo proporciona:

Sim Um pouco Não


Flexibilidade no estudo prático 7 0 0
Condições de estudo individual 7 0 0
Conforto na utilização 7 0 0
Manutenção do interesse no estudo da disciplina 6 1 0
Relação do conteúdo teórico ao prático 6 0 0

115
ANEXO 7 – Código Fonte

Classe RedeNeural

package redeNeural;
import funcoesSaida.*;
/*
* RedeNeural.java
*
* Created on 20 de Maio de 2005, 20:07
*/

/**
* Permite a criação de uma rede neural artificial para uso qualquer.<br>
* A função de saída a ser usada na rede neural deve ser do tipo FuncaoSaida,
outra classe (interface) pertencente ao pacote redeneural.
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
* @version 1.0.0
*/
public class RedeNeural implements java.io.Serializable {

private int nosEntrada;


private int nosEscondidos;
private int nosSaida;
private FuncaoSaida funcao;
private int bias;
private double pesosHI[][];
private double pesosOH[][];
private int entradas[];
private double escondidos[];
private double saidas[];
private boolean estaTreinada;

/**
* Contrutor vazio<br>
* Cria a rede com a seguinte característica:<br>
* - 2 nós de entrada<br>
* - 1 nó de saída <br>
* - 1 nó escondido<br>
* - bias na camada de entrada e camada escondida<br>
* - executa inicializaDefaults
**/
public RedeNeural() {
nosEntrada = 2;
nosSaida = 1;
bias = 1;
nosEscondidos = 1;
inicializaDefaults();
}

/**
* Contrutor com parametros<br>
* Cria a rede de acordo com os parâmetros informados.
* @param nE quantidade de nós de entrada<br>
* @param nS quantidade de nós de saída<br>
* @param nBias uso do bias, se 0 não usa, se 1 usa.<br>
* O número de nós escondidos será a média entre os nós de entrada e nós
de saída.<br>
* O construtor executa inicializaDefaults
**/
public RedeNeural(int nE, int nS, int nBias) {

116
nosEntrada = nE;
nosSaida = nS;
nosEscondidos = (int) (nosEntrada + nosSaida) / 2;
bias = nBias;
inicializaDefaults();
}

/**
* Cria os arrays utilizados pela classe e define a função de saída para
sigmoidal.<br>
* Executa reiniciaTreinamento.
*/
private void inicializaDefaults() {
pesosHI = new double[nosEscondidos + bias][nosEntrada + bias];
pesosOH = new double[nosSaida][nosEscondidos + bias];
entradas = new int[nosEntrada + bias];
escondidos = new double[nosEscondidos + bias];
saidas = new double[nosSaida];
funcao = new FuncaoSigmoidal();
reiniciaTreinamento();
}

/**
* Setter da quantidade de nós de entrada.<br>
* Redefine os arrays que dependem desta informação.
* @param nE quantidade de nós de entrada
* @throws Exception Lança exceção caso o número de nós de entrada seja
inferior a 1.
*/
public void setNosEntrada(int nE) throws Exception {
if(nE < 1)
throw new Exception("Número de nós de entradas deve ser maior que
zero!");
nosEntrada = nE;
pesosHI = new double[nosEscondidos + bias][nosEntrada + bias];
entradas = new int[nosEntrada + bias];
reiniciaTreinamento();
}

/**
* Getter da quantidade de nós de entrada.
* @return retorna o número de nós de entrada como um inteiro.
*/
public int getNosEntrada() {
return nosEntrada;
}

/**
* Setter da quantidade de nós escondidos<br>
* Redefine os arrays que dependem desta informação
* @param nE quantidade de nós escondidos
* @throws Exception lança exceção caso o número de nós escondidos seja
inferior a 1.
*/
public void setNosEscondidos(int nE) throws Exception {
if(nE < 1)
throw new Exception("Número de nós escondidos deve ser maior que
zero!");
nosEscondidos = nE;
pesosHI = new double[nosEscondidos + bias][nosEntrada + bias];
pesosOH = new double[nosSaida][nosEscondidos + bias];
escondidos = new double[nosEscondidos + bias];
reiniciaTreinamento();
}

117
/**
* Getter da quantidade de nós escondidos
* @return retorna a quantidade de nós escondidos como um inteiro.
*/
public int getNosEscondidos() {
return nosEscondidos;
}

/**
* Setter da quantidade de nós de saída<br>
* Redefine os arrays que dependem desta informação
* @param nS quantidade de nós de saída
* @throws Exception lança exceção caso o número de nós de saída seja
inferior a 1.
*/
public void setNosSaida(int nS) throws Exception {
if(nS < 1)
throw new Exception("Número de nós de saída deve ser maior que
zero!");
nosSaida = nS;
pesosOH = new double[nosSaida][nosEscondidos + bias];
saidas = new double[nosSaida];
reiniciaTreinamento();
}

/**
* Getter da quantidade de nós de saída
* @return retorna a quantidade de nós de saída como um inteiro.
*/
public int getNosSaida() {
return nosSaida;
}

/**
* Getter da função de saída
* @return retorna a função de saída como uma FuncaoSaida.
*/
public FuncaoSaida getFuncao() {
return funcao;
}

/**
* Setter da função de saída
* @param pFuncao função de saída, do tipo FuncaoSaida (interface)
*/
public void setFuncao(FuncaoSaida pFuncao) {
funcao = pFuncao;
reiniciaTreinamento();
}

/**
* Setter do bias
* @param tB se 0 indica que não será usado bias, se 1 é usado bias
* @throws Exception lança exceção se o parâmetro for diferente de 0 ou
1.
*/
public void setBias(int tB) throws Exception {
if(tB != 0 && tB != 1)
throw new Exception("Valor de bias deve ser zero ou um!");
bias = tB;
pesosHI = new double[nosEscondidos + bias][nosEntrada + bias];
pesosOH = new double[nosSaida][nosEscondidos + bias];
entradas = new int[nosEntrada + bias];

118
escondidos = new double[nosEscondidos + bias];
reiniciaTreinamento();
}

/**
* Getter do Bias
* @return retorna 1 se estiver usando bias e 0 se não estiver.
*/
public int getBias() {
return bias;
}

/**
* Setter para os valores de entrada da rede
* @param vE vetor de entrada do tipo int
* @throws Exception lança exceção se a quantidade de entradas não for
compatível
* com tamanho do vetor. Se o tamanho for igual ao do vetor, o método
insere, se
* necessário, o bias. Se o tamanho do vetor for igual ao número de nós
de entrada
* mais o bias, a responsabilidade de deixar o bias na primeira posição é
do usuário.
*/
public void setEntrada(int vE[]) throws Exception {
int i, j;
if(vE.length == (nosEntrada + bias)) {
for(i = 0; i < nosEntrada + bias; i++) {
entradas[i] = vE[i];
}
} else if(vE.length == nosEntrada){
if(bias == 1)
entradas[0] = 1;
for(i = bias, j = 0; i < nosEntrada + bias; i++, j++) {
entradas[i] = vE[j];
}
} else {
throw new Exception("Tamanho do vetor recebido incompatível com
vetor de entrada!");
}
}

/**
* Getter para um valor da entrada
* @param indice indica qual nó deve ser retornado
* @return retorna o valor do nó referenciado por indice como um inteiro
*/
public int getValorEntradas(int indice) {
return entradas[indice];
}

/**
* Getter para um valor da camada escondida
* @param indice indica qual nó deve ser retornado
* @return retorna o valor do nó referenciado por indice como um double
*/
public double getValorEscondidos(int indice) {
return escondidos[indice];
}

/**
* Getter para um valor da saída
* @param indice indica qual nó deve ser retornado
* @return retorna o valor do nó referenciado por indice como um double

119
*/
public double getValorSaidas(int indice) {
return saidas[indice];
}

/**
* Getter para o vetor de saída
* @return retorna o vetor de saída do tipo double
* @throws Exception lança exceção caso a rede não esteja treinada, pois
não há como gerar saidas.
*/
public double[] getSaida() throws Exception {
if(!estaTreinada) {
throw new Exception("Não é possível gerar saídas, pois a rede não
está treinada!");
}
return saidas;
}

/**
* Getter para estaTreinada
* @return retorna true se a rede estiver treinada e false se não
estiver.
*/
public boolean getEstaTreinada() {
return estaTreinada;
}

/**
* Setter para estaTreinada
* @param et valor a ser atribuído a estaTreinada do tipo boolean
*/
public void setEstaTreinada(boolean et) {
estaTreinada = et;
}

/**
* Setter do array de pesos entre a camada de entrada e escondida
* @param phi array de pesos do tipo double
* @throws Exception lança exceção se o tamanho do array não for igual ao
array com
* os pesos entre a camada de entrada e escondida
*/
public void setPesosHI(double phi[][]) throws Exception {
if(phi.length != (nosEscondidos + bias) || phi[0].length !=
(nosEntrada + bias)) {
throw new Exception("Tamanho da matriz recebida é inválido!");
}
pesosHI = phi;
}

/**
* Getter de um peso das camadas de entrada e escondida
* @param indiceJ índice do array referente a camada escondida
* @param indiceI índice do array referente a camada de entrada
* @return valor do peso referenciado pelos indices i e j
*/
public double getValorPesosHI(int indiceJ, int indiceI) {
return pesosHI[indiceJ][indiceI];
}

/**
* Getter dos pesos entre a camada de entrada e escondida
* @return retorna o array de pesos entre a camada de entrada e escondida

120
*/
public double[][] getPesosHI() {
return pesosHI;
}

/**
* Setter dos pesos entre as camadas escondida e saída
* @param poh array com os pesos
* @throws Exception lança exceção se o array passado como parâmetro for
de
* tamanho diferente do array de pesos entre a camada escondida e saída
*/
public void setPesosOH(double poh[][]) throws Exception {
if(poh.length != (nosSaida) || poh[0].length != (nosEscondidos +
bias)) {
throw new Exception("Tamanho da matriz recebida é inválido!");
}
pesosOH = poh;
}

/**
* Getter de um dos pesos entre a camada escondida e saída
* @param indiceK índice que referencia o nó da saída
* @param indiceJ índice que referencia o nó da camada escondida
* @return retorna o valor do peso referenciado pelos índices j e k
*/
public double getValorPesosOH(int indiceK, int indiceJ) {
return pesosOH[indiceK][indiceJ];
}

/**
* Getter do array de pesos entre a camada escondida e saída
* @return retorna o array de pesos entre a camada escondida e saída
*/
public double[][] getPesosOH() {
return pesosOH;
}

/**
* Calcula os valores net da camada escondida e da camada de saída
*/
public void calculeNets() {
int i, j, k;
double temp;
for(j = 0; j < nosEscondidos + bias; j++){
escondidos[j] = 0.0;
for(i = 0; i < nosEntrada + bias; i++){
escondidos[j] += pesosHI[j][i] * entradas[i];
}
}
for(k = 0; k < nosSaida; k++) {
saidas[k] = 0.0;
for(j = 0; j < nosEscondidos + bias; j++) {
if(bias == 1 && j == 0) {
temp = 1;
} else {
temp = funcao.calcFuncao(escondidos[j]);
}
saidas[k] += pesosOH[k][j] * temp;
}
}
}

/**

121
* Inicializa os pesos com valores aleatórios
***/
public void inicializaPesos() {
int i, j, k;
for(j = 0; j < (nosEscondidos + bias); j++) {
for(i = 0; i < (nosEntrada + bias); i++){
pesosHI[j][i] = Math.random();
}
}
for(k = 0; k < nosSaida; k++) {
for(j = 0; j < (nosEscondidos + bias); j++){
pesosOH[k][j] = Math.random();
}
}
}

/**
* Reinicia o treinamento da seguinte forma:<br>
* - define estaTreinada para false<br>
* - executa inicializaPesos
*/
public void reiniciaTreinamento() {
estaTreinada = false;
inicializaPesos();
}
}

122
Classe TreinaRede

/*
* TreinaRede.java
*
* Created on 18 de Junho de 2005, 21:47
*/

package redeNeural;
import funcoesSaida.*;
import java.util.*;

import javax.swing.JProgressBar;

/**
* Treinamento de uma rede neural artificial
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class TreinaRede {

private RedeNeural rna;


private double erroAceitavel;
private int epocasMaximo;
private double fatorAprendizagem;
private int saidasEsperadas[];
private int entradasTreinamento[][];
private int saidasTreinamento[][];
private double fatoresCorrecaoH[];
private double fatoresCorrecaoO[];
private FuncaoSaida funcao;
private double pesosOH[][];
private double pesosHI[][];
private int qtdEpocasAtual;
private ArrayList<Double> errosMaximos;
private double erroMaximo;
private boolean vetorTreinamentoLido;

/**
* Construtor com parâmetros
* @param rede rede a ser treinada
* @param pT padrões de treinamento a serem usados no treinamento
* @param pEpocasMaximo número máximo de épocas a ser treinada a rede
* @param pFatorAprendizagem fator de aprendizagem a ser aplicado no
treinamento
* @param pErroAceitavel maior valor de erro a ser usado como
referência na saída
*/
public TreinaRede(RedeNeural rede, PadroesTreinamento pT, int
pEpocasMaximo, double pFatorAprendizagem, double pErroAceitavel) {
rna = rede;
entradasTreinamento = pT.getPadroesEntrada();
saidasTreinamento = pT.getPadroesSaida();
epocasMaximo = pEpocasMaximo;
fatorAprendizagem = pFatorAprendizagem;
erroAceitavel = pErroAceitavel;
errosMaximos = new ArrayList<Double>();
funcao = rna.getFuncao();

123
pesosHI = rna.getPesosHI();
pesosOH = rna.getPesosOH();
fatoresCorrecaoH = new double[rna.getNosEscondidos() +
rna.getBias()];
fatoresCorrecaoO = new double[rna.getNosSaida()];
saidasEsperadas = new int[rna.getNosSaida()];
vetorTreinamentoLido = true;
}

/**
* Construtor vazio<br>
* Usa os seguintes defaults:<br>
* - rede criada com construtor vazio
* - número máximo de épocas 1000
* - fator de aprendizagem 0.25
* - Erro máximo 0.1
*/
public TreinaRede() {
rna = new RedeNeural();
epocasMaximo = 1000;
fatorAprendizagem = 0.25;
erroAceitavel = 0.1;
errosMaximos = new ArrayList<Double>();
funcao = rna.getFuncao();
pesosHI = rna.getPesosHI();
pesosOH = rna.getPesosOH();
fatoresCorrecaoH = new double[rna.getNosEscondidos() +
rna.getBias()];
fatoresCorrecaoO = new double[rna.getNosSaida()];
saidasEsperadas = new int[rna.getNosSaida()];
vetorTreinamentoLido = false;
}

/**
* Getter dos erros máximos das épocas
* @return Maiores valores de erro obtidos em cada época em um
ArrayList
**/
public ArrayList getErrosMaximos() {
return errosMaximos;
}

/**
* Getter do maior erro obtido
* @return retorna o maior erro obtido como double
*/
public double getErroMaximo() {
return erroMaximo;
}

/**
* getter da quantidade de épocas atual
* @return quantidade de épocas atual como um inteiro
*/
public int getQtdEpocasAtual() {
return qtdEpocasAtual;
}

124
/**
* Setter da rede
**/
public void setRna(RedeNeural rede) {
rna = rede;
funcao = rna.getFuncao();
pesosHI = rna.getPesosHI();
pesosOH = rna.getPesosOH();
fatoresCorrecaoH = new double[rna.getNosEscondidos() +
rna.getBias()];
fatoresCorrecaoO = new double[rna.getNosSaida()];
saidasEsperadas = new int[rna.getNosSaida()];
}

/**
* Treina a Rede Neural
* @return retorna true ou false se conseguiu treinar ou não
**/
public boolean treinar() throws Exception {
int i, j, k, contadorModelo;
boolean estaTreinado = false;
qtdEpocasAtual = 0;
double valorErroAtual;
errosMaximos.clear();
if(!vetorTreinamentoLido) {
throw new Exception("Padrões para treinamento não foram
lidos!");
}
contadorModelo = 0;
while (!estaTreinado && (qtdEpocasAtual < epocasMaximo)) {
valorErroAtual = 0.0;
estaTreinado = true;
for(contadorModelo = 0; contadorModelo <
entradasTreinamento.length; contadorModelo++){
rna.setEntrada(setEntradaSaidaDoPadrao(contadorModelo));
rna.calculeNets();
valorErroAtual += calculeErroGlobal();
calculeFatoresCorrecao();
corrigePesos();
}
if(valorErroAtual > erroAceitavel) {
estaTreinado = false;
}
errosMaximos.add(valorErroAtual);
qtdEpocasAtual++;
}
return estaTreinado;
}

/**
* Treina a Rede Neural
* @param jpb barra de progresso do treinamento
* @return retorna true ou false se conseguiu treinar ou não
**/
public boolean treinar(JProgressBar jpb) throws Exception {
int i, j, k, contadorModelo;
boolean estaTreinado = false;
errosMaximos.clear();

125
qtdEpocasAtual = 0;
double valorErroAtual;
if(!vetorTreinamentoLido) {
throw new Exception("Padrões para treinamento não foram
lidos!");
}
contadorModelo = 0;
jpb.setMaximum(epocasMaximo);
jpb.setString(null);
while (!estaTreinado && (qtdEpocasAtual < epocasMaximo)) {
valorErroAtual = 0.0;
estaTreinado = true;
for(contadorModelo = 0; contadorModelo <
entradasTreinamento.length; contadorModelo++){
rna.setEntrada(setEntradaSaidaDoPadrao(contadorModelo));
rna.calculeNets();
valorErroAtual += calculeErroGlobal();
calculeFatoresCorrecao();
corrigePesos();
}
if(valorErroAtual > erroAceitavel) {
estaTreinado = false;
}
errosMaximos.add(valorErroAtual);
qtdEpocasAtual++;
jpb.setValue(qtdEpocasAtual);
}
return estaTreinado;
}

/**
* Setter dos arrays de valores padrão (entrada e saída)
* @param padrao índice do padrão a ser aplicado nos vetores de entrada
e saída esperada
* @return retorna o vetor de entrada
**/
public int[] setEntradaSaidaDoPadrao(int padrao) {
int i, k;
int bias = rna.getBias();
int entradas[] = new int[rna.getNosEntrada() + bias];
if(bias == 1){
entradas[0] = 1;
}
for(i = bias; i < entradas.length; i++) {
entradas[i] = entradasTreinamento[padrao][i - bias];
}
for(k = 0; k < saidasEsperadas.length; k++) {
saidasEsperadas[k] = saidasTreinamento[padrao][k];
}
return entradas;
}

/**
* Calcula o erro global da época
* @return retorna o valor do erro global como um double
*/
public double calculeErroGlobal() {
double valorErro = 0.0;

126
for(int k = 0; k < rna.getNosSaida(); k++){
valorErro += Math.pow((saidasEsperadas[k] -
funcao.calcFuncao(rna.getValorSaidas(k))),2);
//valorErro += Math.pow(Math.pow((saidasEsperadas[k] -
funcao.calcFuncao(rna.getValorSaidas(k))),2),0.5);
}
return valorErro /= 2.0;
}

/**
* Calcula os fatores de correção
* @param padrao indice que identifica o padrão utilizado no
treinamento
*/
public void calculeFatoresCorrecao(int padrao){
int j, k;
for (k = 0; k < rna.getNosSaida(); k++) {
fatoresCorrecaoO[k] =
funcao.calcDerivada(rna.getValorSaidas(k)) * (saidasTreinamento[padrao][k]
- funcao.calcFuncao(rna.getValorSaidas(k)));
}
for (j = 0; j < (rna.getNosEscondidos() + rna.getBias()); j++) {
fatoresCorrecaoH[j] = 0.0;
for (k = 0; k < rna.getNosSaida(); k++){
fatoresCorrecaoH[j] += fatoresCorrecaoO[k] *
pesosOH[k][j];
}
fatoresCorrecaoH[j] *=
funcao.calcDerivada(rna.getValorEscondidos(j));
}
}

/**
* Calcula os fatores de correção<br>
* Para seu uso, o array saidasEsperadas deve ter sido inicializado com
a saida do treinamento
*/
public void calculeFatoresCorrecao(){
int j, k;
for (k = 0; k < rna.getNosSaida(); k++) {
fatoresCorrecaoO[k] =
funcao.calcDerivada(rna.getValorSaidas(k)) * (saidasEsperadas[k] -
funcao.calcFuncao(rna.getValorSaidas(k)));
}
for (j = 0; j < (rna.getNosEscondidos() + rna.getBias()); j++) {
fatoresCorrecaoH[j] = 0.0;
for (k = 0; k < rna.getNosSaida(); k++){
fatoresCorrecaoH[j] += fatoresCorrecaoO[k] *
pesosOH[k][j];
}
fatoresCorrecaoH[j] *=
funcao.calcDerivada(rna.getValorEscondidos(j));
}
}

/**
* Corrige os pesos entre as conexões

127
* @throws Exception lança exceção se ocorrer erro na redefinição dos
pesos
*/
public void corrigePesos() throws Exception {
int i, j, k;
for (k = 0; k < rna.getNosSaida(); k++){
for (j = 0; j < rna.getNosEscondidos() + rna.getBias(); j++){
pesosOH[k][j] += fatorAprendizagem * fatoresCorrecaoO[k] *
funcao.calcFuncao(rna.getValorEscondidos(j));
}
}
for (j = 0; j < rna.getNosEscondidos() + rna.getBias(); j++){
for (i = 0; i < rna.getNosEntrada() + rna.getBias(); i++){
pesosHI[j][i] += fatorAprendizagem * fatoresCorrecaoH[j] *
rna.getValorEntradas(i);
}
}
try {
rna.setPesosHI(pesosHI);
rna.setPesosOH(pesosOH);
} catch (Exception e) {
throw e;
}
}

/**
* Setter do erro aceitavel
* @param eA valor do erro aceitável do tipo double
*/
public void setErroAceitavell(double eA) {
erroAceitavel = eA;
}

/**
* Getter do erro aceitável
* @return retorna o erro aceitável como double
*/
public double getErroAceitavel() {
return erroAceitavel;
}

/**
* Setter da quantidade máxima de épocas
* @param eM quantidade máxima de épocas do tipo inteiro
*/
public void setEpocasMaximo(int eM) {
epocasMaximo = eM;
}

/**
* Getter da quantidade máxima de épocas
* @return retorna o número máximo de épocas como inteiro
*/
public int getEpocasMaximo() {
return epocasMaximo;
}

/**

128
* Setter do fator de aprendizagem
* @param fA valor do fator de aprendizagem como double
*/
public void setFatorAprendizagem(double fA) {
fatorAprendizagem = fA;
}

/**
* Getter do fator de aprendizagem
* @return retorna o valor do fator de aprendizagem como double
*/
public double getFatorAprendizagem() {
return fatorAprendizagem;
}

/**
* Setter dos padroes de treinamento
* @param pT padroes de treinamento como PadroesTreinamento
*/
public void setPadroesTreinamento(PadroesTreinamento pT) {
entradasTreinamento = pT.getPadroesEntrada();
saidasTreinamento = pT.getPadroesSaida();
vetorTreinamentoLido = true;
}
}

129
Classe PadroesTreinamento

/*
* PadroesTreinamento.java
*
* Created on 19 de Junho de 2005, 16:34
*/

package redeNeural;

import java.io.Serializable;

/**
* Padrões de treinamento para serem usados no treinamento da rede
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class PadroesTreinamento implements Serializable {

private int padroesEntrada[][];


private int padroesSaida[][];

/**
* Construtor vazio<br>
* Inicializa com tamanho 1x1 os arrays de padrões de entrada e saída
*/
public PadroesTreinamento() {
padroesEntrada = new int[1][1];
padroesSaida = new int[1][1];
}

/**
* Construtor com parâmetros<br>
* Inicia os arrays com os arrays passados por parâmetro
* @param pE array com os parâmetros de entrada
* @param pS array com os parâmetros de saída
*/
public PadroesTreinamento(int pE[][], int pS[][]) {
padroesEntrada = pE;
padroesSaida = pS;
}

/**
* Setter dos arrays de padrões de entrada e saída
* @param pE array com os padrões de entrada
* @param pS array com os padrões de saída
*/
public void setPadroesTreinamento(int pE[][], int pS[][]) {
padroesEntrada = pE;
padroesSaida = pS;
}

/**
* Getter dos padrões de entrada
* @return retorna o array de padrões de entrada
*/
public int[][] getPadroesEntrada() {
return padroesEntrada;

130
}

/**
* Getter dos padrões de saída
* @return retorna o array de padrões de saída
*/
public int[][] getPadroesSaida() {
return padroesSaida;
}
}

131
Classe FuncaoSaida

/*
* funcaoSaida.java
*
* Created on 17 de Junho de 2005, 23:39
*/

package funcoesSaida;

/**
* Interface que define a função de saída
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public interface FuncaoSaida {
/**
* Método que deve ser implementado para calcular o valor de saída da
função
* @param valor valor a ser aplicado na função como double
* @return retorna a saída da função como double
*/
public double calcFuncao(double valor);
/**
* Método que deve se implementado para calcular o valor de saída da
derivada da função
* @param valor a ser aplicado na derivada da função como double
* @return retorna a saída da derivada da função como double
*/
public double calcDerivada(double valor);
/**
* Método a ser implementado para informar o nome da função
* @return retorna o nome da função como String
*/
public String getNome();
}

132
Classe FuncaoSigmoidal

/*
* funcaoSigmoidal.java
*
* Created on 17 de Junho de 2005, 23:36
*/

package funcoesSaida;

import java.io.Serializable;

/**
* Implementação da função de saída do tipo sigmoidal
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class FuncaoSigmoidal implements FuncaoSaida, Serializable {

/**
* construtor vazio
*/
public FuncaoSigmoidal() {
}

/**
* Calcula o resultado da função sigmoidal
* @param valor valor a ser aplicado na função do tipo double
* @return retorna o resultado da função com tipo double
*/
public double calcFuncao(double valor) {
return (1.0 / (1.0 + Math.exp(-valor)));
}

/**
* Calcula o resultado da derivada da função sigmoidal
* @param valor valor a ser aplicado na derivada da função como double
* @return retorna o resultado da de derivada da função como double
*/
public double calcDerivada(double valor) {
return ((1.0 / (1.0 + Math.exp(-valor))) * (1.0 - (1.0 / (1.0 +
Math.exp(-valor)))));
}

/**
* Informa o nome da função de saída
* @return retorna o nome da função como String
*/
public String getNome() {
return "Sigmoidal";
}
}

133
Classe FuncaoTangHiperb

/*
* FuncaoTangHiperb.java
*
* Created on 18 de Junho de 2005, 21:27
*/

package funcoesSaida;

import java.io.Serializable;

/**
* Implementação da função de saída do tipo tangente hiperbólica
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class FuncaoTangHiperb implements FuncaoSaida, Serializable {

/**
* construtor vazio
*/
public FuncaoTangHiperb() {
}

/**
* Calcula o resultado da função tangente hiperbólica
* @param valor valor a ser aplicado na função do tipo double
* @return retorna o resultado da função com tipo double
*/
public double calcFuncao(double valor) {
return ((Math.exp(valor) - Math.exp(-valor))/(Math.exp(valor) +
Math.exp(-valor)));
}

/**
* Calcula o resultado da derivada da função tangente hiperbólica
* @param valor valor a ser aplicado na derivada da função como double
* @return retorna o resultado da derivada da função como double
*/
public double calcDerivada(double valor) {
return ( 1.0 - Math.pow(((Math.exp(valor) - Math.exp(-
valor))/(Math.exp(valor) + Math.exp(-valor))), 2.0));
}

/**
* Informa o nome da função de saída
* @return retorna o nome da função como String
*/
public String getNome() {
return "Tangente Hiperbólica";
}
}

134
Classe LeitorPadroes

/*
* LeitorPadroes.java
*
* Created on 19 de Junho de 2005, 16:07
*/

package manipulacaoArquivos;
import redeNeural.*;

/**
* Le arquivo com os padrões de treinamento
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/

public class LeitorPadroes {


private String nomeArquivo;

/**
* Construtor vazio
*/
public LeitorPadroes() {
}

/**
* Construtor com parâmetro
* @param pNomeArquivo nome do arquivo que contém os padrões
*/
public LeitorPadroes(String pNomeArquivo) {
nomeArquivo = pNomeArquivo;
}

/**
* Leitor dos padrões para treinamento
* @return quantidade de registros lidos
* @throws lança exceção de I/O ou erro de leitura no formato do
arquivo
**/
public PadroesTreinamento lerDadosTreinamento() throws Exception {
final int estadoDigito = 1;
final int estadoSeparador = 2;
final int estadoBranco = 3;
int entradasTreinamento[][];
int saidasTreinamento[][];
int ind = 0;
int nEntrada = 0, nSaida = 0, nBias = 0, registros = 0;
int dado, contaLinha = 0, estado, estadoAnterior;
int i, j;
StringBuffer buf;
java.io.DataInputStream arquivoEntrada = new
java.io.DataInputStream(new java.io.BufferedInputStream(new
java.io.FileInputStream(nomeArquivo)));
buf = new StringBuffer();
estadoAnterior = 0;
estado = 0;
while(((dado = arquivoEntrada.read()) != 13) && (dado > 0)) {

135
if(dado == 10) continue;
if("0123456789".indexOf((char)dado) != -1) {
estado = estadoDigito;
} else {
if((char)dado == ';') {
estado = estadoSeparador;
} else {
if((char)dado == ' ') {
estado = estadoBranco;
} else {
estado = 0;
}
}
}
switch(estado) {
case estadoDigito:
buf.append((char)dado);
estadoAnterior = estado;
break;
case estadoSeparador:
switch(ind) {
case 0:
nEntrada = Integer.parseInt(buf.toString());
ind++;
break;
case 1:
nSaida = Integer.parseInt(buf.toString());
ind++;
break;
default:
throw new Exception("Registro: " + (contaLinha
+ 1) + " Separador não esperado!");
}
buf.delete(0, buf.length());
case estadoBranco:
estadoAnterior = estado;
break;
default:
throw new Exception("Registro: " + (contaLinha + 1) + "
Valor lido inválido!");
}
}
contaLinha++;
registros = Integer.parseInt(buf.toString());
if(dado < 0){
throw new Exception("Registro: " + contaLinha + " Final de
arquivo inesperado!");
}
if(ind != 2) {
throw new Exception("Registro: " + contaLinha + " Quantidade
de parametros invalido!");
}
buf.delete(0, buf.length());
entradasTreinamento = new int[registros][nEntrada];
saidasTreinamento = new int[registros][nSaida];
i = 0;
j = 0;
while((dado = arquivoEntrada.read()) > 0) {

136
if(dado == 10) continue;
if(dado == 13){
i = 0;
if (++j > registros) {
throw new Exception("Registro: " + (contaLinha + 1) + "
Quantidade de registros invalido!");
}
contaLinha++;
continue;
}
if("01".indexOf((char)dado) == -1){
throw new Exception("Registro: " + contaLinha + " Valor
lido invalido!");
}
if(i < nEntrada) {
entradasTreinamento[j][i] = dado == 48 ? 0 : 1;
} else {
if(i < (nEntrada + nSaida)){
saidasTreinamento[j][i-nEntrada] = dado == 48 ? 0 : 1;
} else {
throw new Exception("Registro: " + contaLinha + "
tamanho de linha lida invalida!");
}
}
i++;
}
if(j >= registros) {
throw new Exception("Registro: " + (contaLinha + 1) + "
Quantidade de registros invalido!");
}
return new PadroesTreinamento(entradasTreinamento,
saidasTreinamento);
}

/**
* Leitor dos padrões para treinamento
* @param jpb barra de progresso de leitura do arquivo
* @return quantidade de registros lidos
* @throws lança exceção de I/O ou erro de leitura no formato do
arquivo
**/
public PadroesTreinamento lerDadosTreinamento(javax.swing.JProgressBar
jpb) throws Exception {
final int estadoDigito = 1;
final int estadoSeparador = 2;
final int estadoBranco = 3;
int entradasTreinamento[][];
int saidasTreinamento[][];
int ind = 0;
int nEntrada = 0, nSaida = 0, nBias = 0, registros = 0;
int dado, contaLinha = 0, estado, estadoAnterior;
int i, j;
StringBuffer buf;
java.io.DataInputStream arquivoEntrada = new
java.io.DataInputStream(new java.io.BufferedInputStream(new
java.io.FileInputStream(nomeArquivo)));
buf = new StringBuffer();
estadoAnterior = 0;

137
estado = 0;
while(((dado = arquivoEntrada.read()) != 13) && (dado > 0)) {
if(dado == 10) continue;
if("0123456789".indexOf((char)dado) != -1) {
estado = estadoDigito;
} else {
if((char)dado == ';') {
estado = estadoSeparador;
} else {
if((char)dado == ' ') {
estado = estadoBranco;
} else {
estado = 0;
}
}
}
switch(estado) {
case estadoDigito:
buf.append((char)dado);
estadoAnterior = estado;
break;
case estadoSeparador:
switch(ind) {
case 0:
nEntrada = Integer.parseInt(buf.toString());
ind++;
break;
case 1:
nSaida = Integer.parseInt(buf.toString());
ind++;
break;
default:
throw new Exception("Registro: " + (contaLinha
+ 1) + " Separador não esperado!");
}
buf.delete(0, buf.length());
case estadoBranco:
estadoAnterior = estado;
break;
default:
throw new Exception("Registro: " + (contaLinha + 1) + "
Valor lido inválido!");
}
}
contaLinha++;
registros = Integer.parseInt(buf.toString());
jpb.setMaximum(registros);
jpb.setIndeterminate(false);
if(dado < 0){
throw new Exception("Registro: " + contaLinha + " Final de
arquivo inesperado!");
}
if(ind != 2) {
throw new Exception("Registro: " + contaLinha + " Quantidade
de parametros invalido!");
}
buf.delete(0, buf.length());
entradasTreinamento = new int[registros][nEntrada];

138
saidasTreinamento = new int[registros][nSaida];
i = 0;
j = 0;
while((dado = arquivoEntrada.read()) > 0) {
if(dado == 10) continue;
if(dado == 13){
i = 0;
if (++j > registros) {
throw new Exception("Registro: " + (contaLinha + 1) + "
Quantidade de registros invalido!");
}
contaLinha++;
continue;
}
if("01".indexOf((char)dado) == -1){
throw new Exception("Registro: " + contaLinha + " Valor
lido invalido!");
}
if(i < nEntrada) {
entradasTreinamento[j][i] = dado == 48 ? 0 : 1;
} else {
if(i < (nEntrada + nSaida)){
saidasTreinamento[j][i-nEntrada] = dado == 48 ? 0 : 1;
} else {
throw new Exception("Registro: " + contaLinha + "
tamanho de linha lida invalida!");
}
}
i++;
jpb.setValue(j+1);
}
if(j >= registros) {
throw new Exception("Registro: " + (contaLinha + 1) + "
Quantidade de registros invalido!");
}
return new PadroesTreinamento(entradasTreinamento,
saidasTreinamento);
}
}

139
Classe GravadorArquivoPesos

/*
* GravadorArquivoPesos.java
*
* Created on 21 de Junho de 2005, 21:10
*/

package manipulacaoArquivos;

import redeNeural.*;
/**
* Grava arquivo de pesos de uma rede neural artificial
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class GravadorArquivoPesos {
private String nomeArquivo;

/**
* Construtor vazio
*/
public GravadorArquivoPesos() {
}

/**
* Construtor com parâmetros
* @param nArquivo nome do arquivo onde serão gravados os pesos
*/
public GravadorArquivoPesos(String nArquivo) {
nomeArquivo = nArquivo;
}

/**
* Gera o arquivo de pesos
* @param nomeArquivo nome do arquivo onde serão gravados os pesos
* @param rna rede neural da qual ser~ao gravados os pesos
* @return retorna true se conseguiu gravar
* @throws Exception lan'ca exce'c~ao se n~ao conseguir criar ou
escrever no arquivo
*/
public boolean gerarArquivoPesos(String nomeArquivo, RedeNeural rna)
throws Exception {
int i, j, k;
java.io.BufferedWriter arquivo;
try {
arquivo = new java.io.BufferedWriter(new
java.io.FileWriter(nomeArquivo));
} catch (Exception e) {
throw new Exception("Não foi possível criar o arquivo - " +
e.getMessage());
}
try {
arquivo.write("------------------------------------------------
------------------------------------------");
arquivo.newLine();
arquivo.write(" UNIVERSIDADE FEDERAL DE SANTA CATARINA");
arquivo.newLine();

140
arquivo.write(" CENTRO TECNOLÓGICO");
arquivo.newLine();
arquivo.write(" CURSO DE SISTEMAS DE INFORMAÇÃO");
arquivo.newLine();
arquivo.write(" -----------------------------------------------
-----------------------------------------");
arquivo.newLine();
arquivo.write(" Arquivo gerado pelo programa RedeNeural, criado
como parte de um trabalho de TCC, por");
arquivo.newLine();
arquivo.write(" João Carlos Testi Ferreira - Matrícula 0123825-
6");
arquivo.newLine();
arquivo.write(" -----------------------------------------------
-----------------------------------------");
arquivo.newLine();
arquivo.write(" Arquivo com pesos para uma Rede Neural
Artificial do tipo Multi-Layer Perceptron");
arquivo.newLine();
arquivo.write(" Dados da rede Treinada:");
arquivo.newLine();
arquivo.write(" Quantidade de nós de entrada: " +
rna.getNosEntrada());
arquivo.newLine();
arquivo.write(" Quantidade de nós escondidos: " +
rna.getNosEscondidos());
arquivo.newLine();
arquivo.write(" Quantidade de nós de saída: " +
rna.getNosSaida());
arquivo.newLine();
arquivo.write(" Detalhes da rede: ");
arquivo.newLine();
arquivo.write(" 1. Utiliza bias tanto na camada de entrada como
na escondida");
arquivo.newLine();
arquivo.write(" 2. Sua função de saída é " +
rna.getFuncao().getNome());
arquivo.newLine();
arquivo.write(" Informações adicionais:");
arquivo.newLine();
arquivo.write(" Nomenclatura das três camadas: I(entrada),
H(escondida) e O(saída)");
arquivo.newLine();
arquivo.write(" Os pesos estão assim apresentados: PHI[j][i]");
arquivo.newLine();
arquivo.write(" Onde PHI é o peso entre a camada H e I, j é o
índice do nó da camada H e i da camada I.");
arquivo.newLine();
arquivo.write(" De forma análoga temos POH para os pesos entre
a camada O e H");
arquivo.newLine();
arquivo.write("------------------------------------------------
------------------------------------------");
arquivo.newLine();
for(j = 0; j < (rna.getNosEscondidos() + rna.getBias()); j++){
for(i = 0; i < (rna.getNosEntrada() + rna.getBias()); i++){
arquivo.write("PHI[" + j + "][" + i + "] = " +
rna.getValorPesosHI(j, i));

141
arquivo.newLine();
}
}
for(k = 0; k < rna.getNosSaida(); k++){
for(j = 0; j < (rna.getNosEscondidos() + rna.getBias());
j++){
arquivo.write("POH[" + k + "][" + j + "] = " +
rna.getValorPesosOH(k, j));
arquivo.newLine();
}
}
arquivo.write("--------------------------------------( FIM )---
-----------------------------------------");
arquivo.close();
} catch (Exception er) {
throw new Exception("Não foi possível escrever no arquivo - " +
er.getMessage());
}
return true;
}

142
Classe PersistenciaRede

/*
* Created on 25/06/2005
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package manipulacaoArquivos;

import java.io.FileInputStream;

import redeNeural.*;
import funcoesSaida.*;

/**
* Persistência de rede neural artificial em arquivo texto
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class PersistenciaRede {

private String nomeArquivo;


/**
* Construtor vazio
*/
public PersistenciaRede() {
}

/**
* Construtor com parâmetro
* @param nArquivo nome do arquivo onde será gravada a rede
*/
public PersistenciaRede(String nArquivo) {
nomeArquivo = nArquivo;
}

/**
* Cria o arquivo da rede
* @param nomeArquivo nome do arquivo que conterá a rede
* @param rna rede a ser gravada
* @throws Exception Lança exceção se não for possível criar o arquivo
ou escrever nele
*/
/*public void gerarArquivoRede(String nomeArquivo, RedeNeural rna)
throws Exception {
int i, j, k;
java.io.BufferedWriter arquivo;
try {
arquivo = new java.io.BufferedWriter(new
java.io.FileWriter(nomeArquivo));
} catch (Exception e) {
throw new Exception("Não foi possível criar o arquivo - " +
e.getMessage());
}
try {
arquivo.write(rna.getNosEntrada() + ";" +
rna.getNosEscondidos() + ";" + rna.getNosSaida() + ";");

143
arquivo.write(rna.getBias() + ";" + rna.getFuncao().getNome() +
";" + (rna.getEstaTreinada() ? 1 : 0));
arquivo.write(";x");
arquivo.newLine();
for(j = 0; j < rna.getNosEscondidos() + rna.getBias(); j++)
for(i = 0; i < rna.getNosEntrada() + rna.getBias(); i++)
arquivo.write(rna.getValorPesosHI(j, i) + ";");
arquivo.write("x");
arquivo.newLine();
for(k = 0; k < rna.getNosSaida(); k++)
for(j = 0; j < rna.getNosEscondidos() + rna.getBias();
j++)
arquivo.write(rna.getValorPesosOH(k, j) + ";");
arquivo.write("x");
arquivo.newLine();
arquivo.write("-x-");
arquivo.close();
} catch (Exception er) {
throw new Exception("Não foi possível escrever no arquivo - " +
er.getMessage());
}
}*/
public void gerarArquivoRede(String nomeArquivo, RedeNeural rna) throws
Exception {
java.io.FileOutputStream saida;
java.io.ObjectOutputStream os;
try {
saida = new java.io.FileOutputStream(nomeArquivo);
os = new java.io.ObjectOutputStream(saida);
os.writeObject(rna);
os.close();
saida.close();
} catch (Exception er) {
throw new Exception("Não foi possível escrever no arquivo - " +
er.getMessage());
}
}

/**
* Leitor de rede neural artificial
* @param nomeArquivo nome do arquivo que contém a rede
* @return retorna a rede neural lida como RedeNeural
* @throws Exception Lança exceção se não for possível ler o arquivo,
* tiver nome de função inválida, número de campos inválido no
registro,
* não conseguir criar a rede lida.
*/
/*public RedeNeural lerArquivoRede(String nomeArquivo) throws Exception
{
int i, j, k, controle, qtde;
java.io.BufferedReader arquivo;
RedeNeural rna;
String registro;
String[] campos;
try {
arquivo = new java.io.BufferedReader(new
java.io.FileReader(nomeArquivo));
} catch (Exception e) {

144
throw new Exception("Não foi possível ler o arquivo - " +
e.getMessage());
}
rna = new RedeNeural();
try {
registro = arquivo.readLine();
campos = registro.split(";");
controle = 0;
while(!campos[controle].equals("x")) {
switch (controle) {
case 0:
rna.setNosEntrada(Integer.parseInt(campos[controle]));
break;
case 1:
rna.setNosEscondidos(Integer.parseInt(campos[controle]));
break;
case 2:
rna.setNosSaida(Integer.parseInt(campos[controle]));
break;
case 3:
rna.setBias(Integer.parseInt(campos[controle]));
break;
case 4: if(campos[controle].equals("Sigmoidal")) {
rna.setFuncao(new
FuncaoSigmoidal());
} else
if(campos[controle].equals("Tangente Hiperbólica")) {
rna.setFuncao(new
FuncaoTangHiperb());
} else {
throw new
Exception(campos[controle] + ": Função inválida");
}
break;
case 5:
rna.setEstaTreinada((Integer.parseInt(campos[controle]) == 1 ? true :
false));
break;
}
controle++;
if(controle > 5 && (!campos[controle].equals("x"))) {
throw new Exception("Número de campos inválido no
registro\nna primeira linha!");
}
}
if(controle != 6) {
throw new Exception("Número de campos inválido no
registro\nna primeira linha!");
}
registro = arquivo.readLine();
campos = registro.split(";");
qtde = campos.length;
controle = 0;
double phi[][] = new double[rna.getNosEscondidos() +
rna.getBias()][rna.getNosEntrada() + rna.getBias()];
double poh[][] = new
double[rna.getNosSaida()][rna.getNosEscondidos() + rna.getBias()];
for(j = 0; j < rna.getNosEscondidos() + rna.getBias(); j++){

145
for(i = 0; i < rna.getNosEntrada() + rna.getBias(); i++){
if(!campos[controle].equals("x")){
phi[j][i] =
Double.parseDouble(campos[controle++]);
} else {
throw new Exception("Número de campos inválido
no registro\nna segunda linha!");
}
}
}
if(!campos[controle].equals("x")){
throw new Exception("Número de campos inválido no
registro\nna segunda linha!");
}
rna.setPesosHI(phi);
registro = arquivo.readLine();
campos = registro.split(";");
qtde = campos.length;
controle = 0;
for(j = 0; j < rna.getNosSaida(); j++){
for(i = 0; i < rna.getNosEscondidos() + rna.getBias();
i++){
if(!campos[controle].equals("x")){
poh[j][i] =
Double.parseDouble(campos[controle++]);
} else {
throw new Exception("Número de campos inválido
no registro\nna terceira linha!");
}
}
}
if(!campos[controle].equals("x")){
throw new Exception("Número de campos inválido no
registro\nna terceira linha!");
}
rna.setPesosOH(poh);
} catch(Exception e) {
throw new Exception("Não foi possível criar a rede - " +
e.getMessage());
}
return rna;
}*/
public RedeNeural lerArquivoRede(String nomeArquivo) throws Exception {
java.io.FileInputStream entrada;
java.io.ObjectInputStream oi;
redeNeural.RedeNeural rna;
try {
entrada = new java.io.FileInputStream(nomeArquivo);
oi = new java.io.ObjectInputStream(entrada);
rna = (redeNeural.RedeNeural) oi.readObject();
oi.close();
entrada.close();
return rna;
} catch (Exception e) {
e.printStackTrace();
throw new Exception("Não foi possível criar a rede - " +
e.getMessage());
}

146
}
}

147
Classe GeradorCodigo

/**
* GeradorCodigo.java
*
* Created on 26 de Maio de 2005, 18:59
*/

package geradoresCodigo;

import redeNeural.RedeNeural;

/**
* Classe abstrata para geração do arquivo de código fonte de uma rna
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public abstract class GeradorCodigo {
private static final int JAVASCRIPT = 0;
private static final int JAVA = 1;
private static final int CPP = 2;
private static final int OBJ_PASCAL = 3;
private static final int VBSCRIPT = 4;
private static final int VB = 5;

protected java.io.BufferedWriter arquivo;


protected String inicioComentarioBloco, fimComentarioBloco;
protected String inicioComentarioLinha;
protected String extensaoArquivo;

/**
* Construtor vazio
*/
public GeradorCodigo() {
}

/**
* Gera em disco um arquivo vazio com o nome passado como parâmetro
* @param nomeArquivo nome do arquivo a ser criado como String
* @throws Exception Lança exceção se não for possível criar o arquivo
*/
public void gerarArquivoEmDisco(String nomeArquivo) throws Exception {
try {
arquivo = new java.io.BufferedWriter(new
java.io.FileWriter(nomeArquivo + extensaoArquivo));
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}

/**
* Escrever comentário de uma única linha
* @param comentario comentário a ser escrito como String
* @throws Exception Lança exceção se não conseguir escrever no arquivo
*/
public void escrvComentLinha(String comentario) throws Exception {
try {
arquivo.write(inicioComentarioLinha + comentario);

148
arquivo.newLine();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* Inserir caracter(es) de início de comentário de bloco
* @throws Exception Lança exceção se não conseguir escrever no arquivo
*/
public void iniComentBloco() throws Exception {
try {
arquivo.write(inicioComentarioBloco);
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* Escrever uma linha em um bloco de comentário
* @param comentario comentário a ser escrito como String
* @throws Exception Lança exceção se não conseguir escrever no arquivo
*/
public void escrvLnhComentBlco(String comentario) throws Exception{
try {
arquivo.write(comentario);
arquivo.newLine();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}

/**
* Inserir caracter(es) de final de comentário de bloco
* @throws Exception Lança exceção se não conseguir escrever no arquivo
*/
public void finalizarComentarioBloco() throws Exception {
try {
arquivo.write(fimComentarioBloco);
arquivo.newLine();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}

/**
* Método abstrato que escreve a função com os dados da
* rede treinada no arquivo do tipo selecionado
*
*/
public abstract void gerarFuncaoRNAMLP(RedeNeural rna, double limiar)
throws Exception;
}

149
Classe GeradorCodigoJava

/*
* GeradorCodigoJava.java
*
* Created on 26 de Maio de 2005, 19:00
*/

package geradoresCodigo;

import redeNeural.RedeNeural;

/**
* Gera arquivo fonte em linguagem Java
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class GeradorCodigoJava extends GeradorCodigo {

/**
* Construtor vazio
* Gera as variáveis relacionadas aos comentários e extensão de arquivo
*/
public GeradorCodigoJava() {
inicioComentarioBloco = "/*";
fimComentarioBloco = "*/";
inicioComentarioLinha = "//";
extensaoArquivo = ".java";
}

/**
* Implementação da função abstrata
* @param rna Rede neural com a qual será gerado o código fonte
* @param limiar limite entre o valor 0 e 1 da saída
* @throws Exception lança exceção se não conseguir escrever no arquivo
*/
public void gerarFuncaoRNAMLP(RedeNeural rna, double limiar) throws
Exception{
int i, j, k;
int bias = rna.getBias();
int nosEntrada = rna.getNosEntrada();
int nosEscondidos = rna.getNosEscondidos();
int nosSaida = rna.getNosSaida();
double pesosHI[][] = rna.getPesosHI();
double pesosOH[][] = rna.getPesosOH();
try {
arquivo.write("public void RNAMLP(");
String virgula = "";
for(i = 1; i <= nosEntrada; i++){
arquivo.write(virgula);
arquivo.write(" double valor" + i);
virgula = ",";
}
virgula = "";
arquivo.write(" ) {");
//Criação dos arrays
arquivo.newLine();

arquivo.write(" double entrada[] = {");

150
if(bias == 1){
arquivo.write("1.0, ");
}
for(i = 1; i <= nosEntrada; i++){
arquivo.write(virgula);
arquivo.write(" valor" + i);
virgula = ",";
}
virgula = "";
arquivo.write("};");
arquivo.newLine();
arquivo.write(" double escondidos[] = new double [" +
(nosEscondidos + bias) + "];");
arquivo.newLine();
arquivo.write(" double saida[] = new double [" + (nosSaida)
+ "];");
arquivo.newLine();

arquivo.write(" double pesosHI[][] = {");


arquivo.newLine();
for(j = 0; j < (nosEscondidos + bias); j++){
arquivo.write(" {");
virgula = "";
for(i = 0; i < (nosEntrada + bias); i++) {
arquivo.write(virgula);
arquivo.write("" + pesosHI[j][i]);
virgula = ", ";
}
arquivo.write("}, ");
arquivo.newLine();
}

arquivo.write("};");
virgula = "";

arquivo.newLine();
arquivo.write(" double pesosOH[][] = {");
arquivo.newLine();
for(k = 0; k < (nosSaida); k++){
arquivo.write(" {");
virgula = "";
for(j = 0; j < (nosEscondidos + bias); j++){
arquivo.write(virgula);
arquivo.write("" + pesosHI[k][j]);
virgula = ", ";
}
arquivo.write("}, ");
arquivo.newLine();
}
arquivo.write("};");
virgula = "";

//calculo dos netH


arquivo.newLine();
arquivo.write(" for(int j = 0; j < " + (nosEscondidos +
bias) + "; j++) {");
arquivo.newLine();
arquivo.write(" escondidos[j] = 0;");

151
arquivo.newLine();
arquivo.write(" for(i = 0; i < " + (nosEntrada + bias)
+ "; i++) {");
arquivo.newLine();
arquivo.write(" escondidos[j] += pesosHI[j][i] *
entrada[i];" );
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
if(bias == 1){
arquivo.write(" escondidos[0] = 1;");
}
arquivo.newLine();
//aplicação da funcao de saída na camada H
arquivo.write(" for(j = " + bias + "; j < " +
(nosEscondidos + bias) + "; j++){");
arquivo.newLine();
arquivo.write(" escondidos[j] = (1/(1 + exp(-
escondidos[j])));");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
//calculo dos netO
arquivo.write(" for(k = 0; k < " + (nosSaida) + "; k++)
{");
arquivo.newLine();
arquivo.write(" saida[k] = 0;");
arquivo.newLine();
arquivo.write(" for(j = 0; j < " + (nosEscondidos +
bias) + "; j++){");
arquivo.newLine();
arquivo.write(" saida[k] += pesosOH[k][j] *
escondidos[j];");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
//aplicação da funcao de saída na camada O
arquivo.newLine();
arquivo.write(" for(k = 0; k < " + nosSaida + "; k++){");
arquivo.newLine();
arquivo.write(" saida[k] = (1/(1 + exp(-
saida[k])));");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
//aplicacao da funcao de limiar
arquivo.newLine();
arquivo.write(" for(k = 0; k < " + nosSaida + "; k++){");
arquivo.newLine();
arquivo.write(" saida[k] = saida[k] < " + limiar + " ?
0 : 1;");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();

152
arquivo.write(inicioComentarioLinha + " --> O resultado é o
vetor saida");
arquivo.newLine();
arquivo.write("}");
arquivo.close();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}

153
Classe GeraCodigoOP

/*
* GeradorCodigoOP.java
*
* Created on 26 de Maio de 2005, 19:44
*/

package geradoresCodigo;

import redeNeural.RedeNeural;

/**
* Gera arquivo fonte em linguagem Object Pascal
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class GeradorCodigoOP extends GeradorCodigo {

/**
* Construtor vazio
* Gera as variáveis relacionadas aos comentários e extensão de arquivo
*/
public GeradorCodigoOP() {
inicioComentarioBloco = "{";
fimComentarioBloco = "}";
inicioComentarioLinha = "//";
extensaoArquivo = ".pas";
}

/**
* Implementação da função abstrata
* @param rna Rede neural com a qual será gerado o código fonte
* @param limiar limite entre o valor 0 e 1 da saída
* @throws Exception lança exceção se não conseguir escrever no arquivo
*/
public void gerarFuncaoRNAMLP(RedeNeural rna, double limiar) throws
Exception {
int i, j, k;
int bias = rna.getBias();
int nosEntrada = rna.getNosEntrada();
int nosEscondidos = rna.getNosEscondidos();
int nosSaida = rna.getNosSaida();
double pesosHI[][] = rna.getPesosHI();
double pesosOH[][] = rna.getPesosOH();
try {
arquivo.write("procedure RNAMLP(");
String virgula = "";
for(i = 1; i <= nosEntrada; i++){
arquivo.write(virgula);
arquivo.write(" var valor" + i + ": double");
virgula = ";";
}
virgula = "";
arquivo.write(" );");
//Criação dos arrays
arquivo.newLine();
arquivo.write("begin");

154
arquivo.write(" double entrada[] = {");
if(bias == 1){
arquivo.write("1.0, ");
}
for(i = bias; i < (nosEntrada + bias); i++){
arquivo.write(virgula);
arquivo.write(" valor" + i);
virgula = ",";
}
virgula = "";
arquivo.write("};");
arquivo.newLine();
arquivo.write(" double escondidos[] = new double [" +
(nosEscondidos + bias) + "];");
arquivo.newLine();
arquivo.write(" double saida[] = new double [" +
(nosSaida) + "];");
arquivo.newLine();

arquivo.write(" double pesosHI[][] = {");


arquivo.newLine();
for(j = 0; j < (nosEscondidos + bias); j++){
arquivo.write(" {");
virgula = "";
for(i = 0; i < (nosEntrada + bias); i++) {
arquivo.write(virgula);
arquivo.write("" + pesosHI[j][i]);
virgula = ", ";
}
arquivo.write("}, ");
arquivo.newLine();
}

arquivo.write("};");
virgula = "";

arquivo.newLine();
arquivo.write(" double pesosOH[][] = {");
arquivo.newLine();
for(k = 0; k < (nosSaida); k++){
arquivo.write(" {");
virgula = "";
for(j = 0; j < (nosEscondidos + bias); j++){
arquivo.write(virgula);
arquivo.write("" + pesosHI[k][j]);
virgula = ", ";
}
arquivo.write("}, ");
arquivo.newLine();
}
arquivo.write("};");
virgula = "";

//calculo dos netH


arquivo.newLine();

155
arquivo.write(" for(int j = 0; j < " + (nosEscondidos +
bias) + "; j++) {");
arquivo.newLine();
arquivo.write(" escondidos[j] = 0;");
arquivo.newLine();
arquivo.write(" for(i = 0; i < " + (nosEntrada + bias)
+ "; i++) {");
arquivo.newLine();
arquivo.write(" escondidos[j] += pesosHI[j][i] *
entrada[i];" );
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
if(bias == 1){
arquivo.write(" escondidos[0] = 1;");
}
arquivo.newLine();
//aplicação da funcao de saída na camada H
arquivo.write(" for(j = " + bias + "; j < " +
(nosEscondidos + bias) + "; j++){");
arquivo.newLine();
arquivo.write(" escondidos[j] = (1/(1 + exp(-
escondidos[j])));");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
//calculo dos netO
arquivo.write(" for(k = 0; k < " + (nosSaida) + "; k++)
{");
arquivo.newLine();
arquivo.write(" saida[k] = 0;");
arquivo.newLine();
arquivo.write(" for(j = 0; j < " + (nosEscondidos +
bias) + "; j++){");
arquivo.newLine();
arquivo.write(" saida[k] += pesosOH[k][j] *
escondidos[j];");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
//aplicação da funcao de saída na camada O
arquivo.newLine();
arquivo.write(" for(k = 0; k < " + nosSaida + "; k++){");
arquivo.newLine();
arquivo.write(" saida[k] = (1/(1 + exp(-
saida[k])));");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
//aplicacao da funcao de limiar
arquivo.newLine();
arquivo.write(" for(k = 0; k < " + nosSaida + "; k++){");
arquivo.newLine();
arquivo.write(" saida[k] = saida[k] < " + limiar + " ?
0 : 1;");//ver metodo funcao

156
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(inicioComentarioLinha + " --> O resultado é o
vetor saida");
arquivo.newLine();
arquivo.write("}");
arquivo.close();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}

157
Classe GeraCodigoCPP

/*
* GeradorCodigoCPP.java
*
* Created on 26 de Maio de 2005, 19:44
*/

package geradoresCodigo;

import redeNeural.RedeNeural;

/**
* Gera arquivo fonte em linguagem C++
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class GeradorCodigoCPP extends GeradorCodigo {

/**
* Construtor vazio
* Gera as variáveis relacionadas aos comentários e extensão de arquivo
*/
public GeradorCodigoCPP() {
inicioComentarioBloco = "/*";
fimComentarioBloco = "*/";
inicioComentarioLinha = "//";
extensaoArquivo = ".h";
}

/**
* Implementação da função abstrata
* @param rna Rede neural com a qual será gerado o código fonte
* @param limiar limite entre o valor 0 e 1 da saída
* @throws Exception lança exceção se não conseguir escrever no arquivo
*/
public void gerarFuncaoRNAMLP(RedeNeural rna, double limiar) throws
Exception {
int i, j, k;
int bias = rna.getBias();
int nosEntrada = rna.getNosEntrada();
int nosEscondidos = rna.getNosEscondidos();
int nosSaida = rna.getNosSaida();
double pesosHI[][] = rna.getPesosHI();
double pesosOH[][] = rna.getPesosOH();
try {
arquivo.write("void RNAMLP(");
String virgula = "";
for(i = 1; i <= nosEntrada; i++){
arquivo.write(virgula);
arquivo.write(" double valor" + i);
virgula = ",";
}
virgula = "";
arquivo.write(" ) {");
//Criação dos arrays
arquivo.newLine();

158
arquivo.write(" double entrada[] = {");
if(bias == 1){
arquivo.write("1.0, ");
}
for(i = bias; i < (nosEntrada + bias); i++){
arquivo.write(virgula);
arquivo.write(" valor" + i);
virgula = ",";
}
virgula = "";
arquivo.write("};");
arquivo.newLine();
arquivo.write(" double escondidos[" + (nosEscondidos +
bias) + "];");
arquivo.newLine();
arquivo.write(" double saida[" + (nosSaida) + "];");
arquivo.newLine();
arquivo.write(" double pesosHI["+ nosEscondidos +"][" +
nosEntrada + "] = {");
arquivo.newLine();
for(j = 0; j < (nosEscondidos + bias); j++){
arquivo.write(" {");
virgula = "";
for(i = 0; i < (nosEntrada + bias); i++) {
arquivo.write(virgula);
arquivo.write("" + pesosHI[j][i]);
virgula = ", ";
}
arquivo.write("}, ");
arquivo.newLine();
}
arquivo.write("};");
virgula = "";
arquivo.newLine();
arquivo.write(" double pesosOH[" + nosSaida + "][" +
nosEscondidos + "] = {");
arquivo.newLine();
for(k = 0; k < (nosSaida); k++){
arquivo.write(" {");
virgula = "";
for(j = 0; j < (nosEscondidos + bias); j++){
arquivo.write(virgula);
arquivo.write("" + pesosHI[k][j]);
virgula = ", ";
}
arquivo.write("}, ");
arquivo.newLine();
}
arquivo.write("};");
virgula = "";
//calculo dos netH
arquivo.write(" for(int j = 0; j < " + (nosEscondidos +
bias) + "; j++) {");
arquivo.newLine();
arquivo.write(" escondidos[j] = 0;");
arquivo.newLine();
arquivo.write(" for(i = 0; i < " + (nosEntrada + bias)
+ "; i++) {");

159
arquivo.newLine();
arquivo.write(" escondidos[j] += pesosHI[j][i] *
entrada[i];" );
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
if(bias == 1){
arquivo.write(" escondidos[0] = 1;");
}
arquivo.newLine();
//aplicação da funcao de saída na camada H
arquivo.write(" for(j = " + bias + "; j < " +
(nosEscondidos + bias) + "; j++){");
arquivo.newLine();
arquivo.write(" escondidos[j] = (1/(1 + exp(-
escondidos[j])));");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
//calculo dos netO
arquivo.write(" for(k = 0; k < " + (nosSaida) + "; k++)
{");
arquivo.newLine();
arquivo.write(" saida[k] = 0;");
arquivo.newLine();
arquivo.write(" for(j = 0; j < " + (nosEscondidos +
bias) + "; j++){");
arquivo.newLine();
arquivo.write(" saida[k] += pesosOH[k][j] *
escondidos[j];");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
//aplicação da funcao de saída na camada O
arquivo.newLine();
arquivo.write(" for(k = 0; k < " + nosSaida + "; k++){");
arquivo.newLine();
arquivo.write(" saida[k] = (1/(1 + exp(-
saida[k])));");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
//aplicacao da funcao de limiar
arquivo.newLine();
arquivo.write(" for(k = 0; k < " + nosSaida + "; k++){");
arquivo.newLine();
arquivo.write(" saida[k] = saida[k] < " + limiar + " ?
0 : 1;");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(inicioComentarioLinha + " --> O resultado é o
vetor saida");
arquivo.newLine();
arquivo.write("}");

160
arquivo.close();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}

161
Classe GeraCodigoJS

/*
* geradorCodigoJS.java
*
* Created on 26 de Maio de 2005, 19:01
*/

package geradoresCodigo;

import redeNeural.RedeNeural;

/**
* Gera arquivo fonte em linguagem JavaScript
* @author João Carlos Testi Ferreira e Júnior Barbosa Dymow
*/
public class GeradorCodigoJS extends GeradorCodigo {

/**
* Construtor vazio
* Gera as variáveis relacionadas aos comentários e extensão de arquivo
*/
public GeradorCodigoJS() {
inicioComentarioBloco = "/*";
fimComentarioBloco = "*/";
inicioComentarioLinha = "//";
extensaoArquivo = ".js";
}

/**
* Implementação da função abstrata
* @param rna Rede neural com a qual será gerado o código fonte
* @param limiar limite entre o valor 0 e 1 da saída
* @throws Exception lança exceção se não conseguir escrever no arquivo
*/
public void gerarFuncaoRNAMLP(RedeNeural rna, double limiar) throws
Exception{

int i, j, k;
int bias = rna.getBias();
int nosEntrada = rna.getNosEntrada();
int nosEscondidos = rna.getNosEscondidos();
int nosSaida = rna.getNosSaida();
double pesosHI[][] = rna.getPesosHI();
double pesosOH[][] = rna.getPesosOH();
try {
arquivo.write("function RNAMLP(");
String virgula = "";
for(i = 1; i <= nosEntrada; i++){
arquivo.write(virgula);
arquivo.write(" valor" + i);
virgula = ",";
}
virgula = "";
arquivo.write(" ) {");
//Criação dos arrays
arquivo.newLine();

162
arquivo.write(" var entrada = [");
if(bias == 1){
arquivo.write("1, ");
}
for(i = 1; i < nosEntrada + bias; i++){
arquivo.write(virgula);
arquivo.write(" valor" + i);
virgula = ",";
}
virgula = "";
arquivo.write("];");
arquivo.newLine();
arquivo.write(" var escondidos = new Array(" +
(nosEscondidos + bias) + ");");
arquivo.newLine();
arquivo.write(" var saida = new Array(" + (nosSaida) +
");");
arquivo.newLine();
arquivo.write(" var pesosHI = [");
arquivo.newLine();
for(j = 0; j < (nosEscondidos + bias); j++){
arquivo.write("[");
virgula = "";
for(i = 0; i < (nosEntrada + bias); i++) {
arquivo.write(virgula);
arquivo.write("" + pesosHI[j][i]);
virgula = ", ";
}
arquivo.write("], ");
arquivo.newLine();
}
arquivo.write("]");
virgula = "";

arquivo.newLine();
arquivo.write(" var pesosOH = [");
for(k = 0; k < nosSaida; k++){
arquivo.write("[");
virgula = "";
for(j = 0; j < (nosEscondidos + bias); j++) {
arquivo.write(virgula);
arquivo.write("" + pesosOH[k][j]);
virgula = ", ";
}
arquivo.write("], ");
arquivo.newLine();
}
arquivo.write("] ");
arquivo.newLine();

//calculo dos netH


arquivo.write(" for(j = 0; j < " + (nosEscondidos + bias)
+ "; j++) {");
arquivo.newLine();
arquivo.write(" escondidos[j] = 0;");
arquivo.newLine();
arquivo.write(" for(i = 0; i < " + (nosEntrada + bias)
+ "; i++) {");

163
arquivo.newLine();
arquivo.write(" escondidos[j] += pesosHI[j][i] *
entrada[i];" );
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
if(bias == 1){
arquivo.write(" escondidos[0] = 1;");
}
arquivo.newLine();
//aplicação da funcao de saída na camada H
arquivo.write(" for(j = " + bias + "; j < " +
(nosEscondidos + bias) + "; j++){");
arquivo.newLine();
arquivo.write(" escondidos[j] = (1/(1 + Math.exp(-
escondidos[j])));");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
//calculo dos netO
arquivo.write(" for(k = 0; k < " + (nosSaida) + "; k++)
{");
arquivo.newLine();
arquivo.write(" saida[k] = 0;");
arquivo.newLine();
arquivo.write(" for(j = 0; j < " + (nosEscondidos +
bias) + "; j++){");
arquivo.newLine();
arquivo.write(" saida[k] += pesosOH[k][j] *
escondidos[j];");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
//aplicação da funcao de saída na camada O
arquivo.newLine();
arquivo.write(" for(k = 0; k < " + nosSaida + "; k++){");
arquivo.newLine();
arquivo.write(" saida[k] = (1/(1 + Math.exp(-
saida[k])));");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
//aplicacao da funcao de limiar
arquivo.newLine();
arquivo.write(" for(k = 0; k < " + nosSaida + "; k++){");
arquivo.newLine();
arquivo.write(" saida[k] = saida[k] < " + limiar + " ?
0 : 1;");//ver metodo funcao
arquivo.newLine();
arquivo.write(" }");
arquivo.newLine();
arquivo.write(inicioComentarioLinha + " --> O resultado é o
vetor saida");
arquivo.newLine();
arquivo.write("}");

164
arquivo.close();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
}

165
Classe Principal (Interface gráfica da aplicação)

public Principal() {
try {

javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAnd
FeelClassName());
} catch (Exception e) {}
initComponents();
redeSalva = true;
java.awt.Dimension screenSize =
java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-600)/2, (screenSize.height-400)/2, 600,
400);
rna = new redeNeural.RedeNeural();
//this.setSize(600,400);
treinador = new redeNeural.TreinaRede();
lm = (java.awt.CardLayout)painelPrincipal.getLayout();
lm.show(painelPrincipal, "cardInicio");
Treinar.setEnabled(false);
treinamento.setEnabled(false);
this.desabilitaSalvarCodigo();
jLStatus.setText("Selecione um dos itens de menu");
}

/** This method is called from within the constructor to


* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-
BEGIN:initComponents
private void initComponents() {
jPanelMenu = new javax.swing.JPanel();
barraFerramentas = new javax.swing.JToolBar();
jButtonNovo = new javax.swing.JButton();
jButtonAbrir = new javax.swing.JButton();
jButtonSalvar = new javax.swing.JButton();
jButtonConfiguracao = new javax.swing.JButton();
jButtonTreinar = new javax.swing.JButton();
barraStatus = new javax.swing.JPanel();
jLStatus = new javax.swing.JLabel();
painelPrincipal = new javax.swing.JPanel();
jPanelRede = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
jPanelRedeInterno = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
jTFNosEntrada = new javax.swing.JTextField();
jLabel3 = new javax.swing.JLabel();
jTFNosSaida = new javax.swing.JTextField();
jLabel4 = new javax.swing.JLabel();
jTFNosEscondidos = new javax.swing.JTextField();
jComboBox1 = new javax.swing.JComboBox();
jLabel5 = new javax.swing.JLabel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();

166
jButton3 = new javax.swing.JButton();
jButton4 = new javax.swing.JButton();
jButtonConfigurar = new javax.swing.JButton();
jButtonCancelar = new javax.swing.JButton();
jLabel6 = new javax.swing.JLabel();
jRadioButton1 = new javax.swing.JRadioButton();
jRadioButton2 = new javax.swing.JRadioButton();
jButton5 = new javax.swing.JButton();
jPanelTreina = new javax.swing.JPanel();
jLabel7 = new javax.swing.JLabel();
jLabel8 = new javax.swing.JLabel();
jTFErro = new javax.swing.JTextField();
jButton6 = new javax.swing.JButton();
jLabel9 = new javax.swing.JLabel();
jLabel10 = new javax.swing.JLabel();
jTFEpocas = new javax.swing.JTextField();
jTFFator = new javax.swing.JTextField();
jButton7 = new javax.swing.JButton();
jButton8 = new javax.swing.JButton();
jBConfiguraT = new javax.swing.JButton();
jBCancelaT = new javax.swing.JButton();
jPanelVazio = new javax.swing.JPanel();
jPanelRTreina = new javax.swing.JPanel();
jPanelRTreinaSuperior = new javax.swing.JPanel();
jLabel12 = new javax.swing.JLabel();
jLabel13 = new javax.swing.JLabel();
jLabel14 = new javax.swing.JLabel();
jLabel15 = new javax.swing.JLabel();
jLSituacao = new javax.swing.JLabel();
jLErroMax = new javax.swing.JLabel();
jLabel17 = new javax.swing.JLabel();
jLQtdEpocas = new javax.swing.JLabel();
jPanelRTreinaInferior = new javax.swing.JPanel();
barraMenu = new javax.swing.JMenuBar();
menuArquivo = new javax.swing.JMenu();
abrir = new javax.swing.JMenu();
abrirRede = new javax.swing.JMenuItem();
abrirPadroes = new javax.swing.JMenuItem();
Salvar = new javax.swing.JMenu();
salvarRede = new javax.swing.JMenuItem();
salvarPesos = new javax.swing.JMenuItem();
salvarCodigo = new javax.swing.JMenu();
codigoJava = new javax.swing.JMenuItem();
codigoC = new javax.swing.JMenuItem();
codigoOP = new javax.swing.JMenuItem();
codigoJS = new javax.swing.JMenuItem();
jSeparator1 = new javax.swing.JSeparator();
Sair = new javax.swing.JMenuItem();
menuRede = new javax.swing.JMenu();
Treinar = new javax.swing.JMenuItem();
menuConfiguraRede = new javax.swing.JMenu();
rede = new javax.swing.JMenuItem();
treinamento = new javax.swing.JMenuItem();
menuAjuda = new javax.swing.JMenu();
como = new javax.swing.JMenuItem();
sobre = new javax.swing.JMenuItem();

167
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
setTitle("Gerador de Redes Neurais");
setLocationByPlatform(true);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
saindo(evt);
}
});

jPanelMenu.setLayout(new
java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

jPanelMenu.setBorder(new
javax.swing.border.BevelBorder(javax.swing.border.BevelBorder.RAISED));
jPanelMenu.setMinimumSize(new java.awt.Dimension(148, 38));
jPanelMenu.setPreferredSize(new java.awt.Dimension(148, 38));
jButtonNovo.setIcon(new
javax.swing.ImageIcon("C:\\rnaInter\\novo.gif"));
jButtonNovo.setToolTipText("Rede nova");
jButtonNovo.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonNovoActionPerformed(evt);
}
});

barraFerramentas.add(jButtonNovo);

jButtonAbrir.setIcon(new
javax.swing.ImageIcon("C:\\rnaInter\\abrir.gif"));
jButtonAbrir.setToolTipText("Abrir rede");
jButtonAbrir.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonAbrirActionPerformed(evt);
}
});

barraFerramentas.add(jButtonAbrir);

jButtonSalvar.setIcon(new
javax.swing.ImageIcon("C:\\rnaInter\\gravar.jpg"));
jButtonSalvar.setToolTipText("Salvar rede");
jButtonSalvar.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonSalvarActionPerformed(evt);
}
});

barraFerramentas.add(jButtonSalvar);

jButtonConfiguracao.setIcon(new
javax.swing.ImageIcon("C:\\rnaInter\\ferramenta.gif"));
jButtonConfiguracao.setToolTipText("Configurar Treinamento");
jButtonConfiguracao.addActionListener(new
java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {

168
jButtonConfiguracaoActionPerformed(evt);
}
});

barraFerramentas.add(jButtonConfiguracao);

jButtonTreinar.setIcon(new
javax.swing.ImageIcon("C:\\rnaInter\\treinar.gif"));
jButtonTreinar.setToolTipText("Treinar");
jButtonTreinar.setMaximumSize(new java.awt.Dimension(23, 23));
jButtonTreinar.setMinimumSize(new java.awt.Dimension(23, 23));
jButtonTreinar.setPreferredSize(new java.awt.Dimension(23, 23));
jButtonTreinar.addActionListener(new
java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonTreinarActionPerformed(evt);
}
});

barraFerramentas.add(jButtonTreinar);

jPanelMenu.add(barraFerramentas);

getContentPane().add(jPanelMenu, java.awt.BorderLayout.NORTH);

barraStatus.setLayout(new
java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

barraStatus.setBackground(new java.awt.Color(235, 235, 242));


jLStatus.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
barraStatus.add(jLStatus);

getContentPane().add(barraStatus, java.awt.BorderLayout.SOUTH);

painelPrincipal.setLayout(new java.awt.CardLayout());

painelPrincipal.setMinimumSize(new java.awt.Dimension(200, 200));


painelPrincipal.setName("painelRede");
jPanelRede.setLayout(new java.awt.BorderLayout());

jPanelRede.setName("confRede");
jLabel1.setFont(new java.awt.Font("Arial", 1, 12));
jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.setText("Configura\u00e7\u00f5es da Rede");
jPanelRede.add(jLabel1, java.awt.BorderLayout.NORTH);

jPanelRedeInterno.setLayout(null);

jLabel2.setText("Quantidade N\u00f3s de Entrada");


jPanelRedeInterno.add(jLabel2);
jLabel2.setBounds(10, 20, 200, 14);

jTFNosEntrada.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jTFNosEntradaFocusGained(evt);
}
public void focusLost(java.awt.event.FocusEvent evt) {
jTFNosEntradaFocusLost(evt);

169
}
});

jPanelRedeInterno.add(jTFNosEntrada);
jTFNosEntrada.setBounds(220, 20, 40, 19);

jLabel3.setText("Quantidade de N\u00f3s de Sa\u00edda");


jPanelRedeInterno.add(jLabel3);
jLabel3.setBounds(10, 50, 200, 14);

jTFNosSaida.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jTFNosSaidaFocusGained(evt);
}
public void focusLost(java.awt.event.FocusEvent evt) {
jTFNosSaidaFocusLost(evt);
}
});

jPanelRedeInterno.add(jTFNosSaida);
jTFNosSaida.setBounds(220, 50, 40, 19);

jLabel4.setText("Quantidade de N\u00f3s Escondidos");


jPanelRedeInterno.add(jLabel4);
jLabel4.setBounds(10, 80, 200, 14);

jTFNosEscondidos.addFocusListener(new java.awt.event.FocusAdapter()
{
public void focusGained(java.awt.event.FocusEvent evt) {
jTFNosEscondidosFocusGained(evt);
}
public void focusLost(java.awt.event.FocusEvent evt) {
jTFNosEscondidosFocusLost(evt);
}
});

jPanelRedeInterno.add(jTFNosEscondidos);
jTFNosEscondidos.setBounds(220, 80, 40, 19);

jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new
String[] { "Sigmoidal", "Tg hiperbólica" }));
jComboBox1.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jComboBox1FocusGained(evt);
}
});

jPanelRedeInterno.add(jComboBox1);
jComboBox1.setBounds(200, 140, 130, 22);

jLabel5.setText("Fun\u00e7\u00e3o de Ativa\u00e7\u00e3o");
jPanelRedeInterno.add(jLabel5);
jLabel5.setBounds(10, 140, 160, 14);

jButton1.setIcon(new javax.swing.ImageIcon("duvida.gif"));
jButton1.setMaximumSize(new java.awt.Dimension(9, 9));
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {

170
jButton1ActionPerformed(evt);
}
});
jButton1.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jButton1FocusGained(evt);
}
});

jPanelRedeInterno.add(jButton1);
jButton1.setBounds(270, 20, 20, 20);

jButton2.setIcon(new javax.swing.ImageIcon("duvida.gif"));
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
jButton2.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jButton2FocusGained(evt);
}
});

jPanelRedeInterno.add(jButton2);
jButton2.setBounds(270, 50, 20, 20);

jButton3.setIcon(new javax.swing.ImageIcon("duvida.gif"));
jButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton3ActionPerformed(evt);
}
});
jButton3.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jButton3FocusGained(evt);
}
});

jPanelRedeInterno.add(jButton3);
jButton3.setBounds(270, 80, 20, 20);

jButton4.setIcon(new javax.swing.ImageIcon("duvida.gif"));
jButton4.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jButton4FocusGained(evt);
}
});

jPanelRedeInterno.add(jButton4);
jButton4.setBounds(340, 140, 20, 20);

jButtonConfigurar.setText("Configurar");
jButtonConfigurar.addActionListener(new
java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonConfigurarActionPerformed(evt);
}

171
});
jButtonConfigurar.addFocusListener(new
java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jButtonConfigurarFocusGained(evt);
}
});

jPanelRedeInterno.add(jButtonConfigurar);
jButtonConfigurar.setBounds(50, 190, 110, 23);

jButtonCancelar.setText("Cancelar");
jButtonCancelar.addActionListener(new
java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonCancelarActionPerformed(evt);
}
});
jButtonCancelar.addFocusListener(new java.awt.event.FocusAdapter()
{
public void focusGained(java.awt.event.FocusEvent evt) {
jButtonCancelarFocusGained(evt);
}
});

jPanelRedeInterno.add(jButtonCancelar);
jButtonCancelar.setBounds(260, 190, 110, 23);

jLabel6.setText("Usar\u00e1 Bias?");
jPanelRedeInterno.add(jLabel6);
jLabel6.setBounds(10, 110, 190, 14);

jRadioButton1.setSelected(true);
jRadioButton1.setText("Sim");
jRadioButton1.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jRadioButton1FocusGained(evt);
}
});

jPanelRedeInterno.add(jRadioButton1);
jRadioButton1.setBounds(150, 110, 60, 23);

jRadioButton2.setText("N\u00e3o");
jRadioButton2.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jRadioButton2FocusGained(evt);
}
});

jPanelRedeInterno.add(jRadioButton2);
jRadioButton2.setBounds(210, 110, 60, 23);

jButton5.setIcon(new javax.swing.ImageIcon("duvida.gif"));
jButton5.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton5ActionPerformed(evt);
}

172
});
jButton5.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jButton5FocusGained(evt);
}
});

jPanelRedeInterno.add(jButton5);
jButton5.setBounds(270, 110, 20, 20);

jPanelRede.add(jPanelRedeInterno, java.awt.BorderLayout.CENTER);

painelPrincipal.add(jPanelRede, "cardRede");

jPanelTreina.setLayout(null);

jLabel7.setFont(new java.awt.Font("Arial", 1, 12));


jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel7.setText("Configura\u00e7\u00e3o do Treinamento");
jPanelTreina.add(jLabel7);
jLabel7.setBounds(126, 5, 170, 15);

jLabel8.setText("Erro M\u00e1ximo");
jPanelTreina.add(jLabel8);
jLabel8.setBounds(24, 60, 160, 14);

jTFErro.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jTFErroFocusGained(evt);
}
public void focusLost(java.awt.event.FocusEvent evt) {
jTFErroFocusLost(evt);
}
});

jPanelTreina.add(jTFErro);
jTFErro.setBounds(200, 60, 50, 19);

jButton6.setIcon(new javax.swing.ImageIcon("duvida.gif"));
jButton6.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton6ActionPerformed(evt);
}
});

jPanelTreina.add(jButton6);
jButton6.setBounds(260, 60, 20, 20);

jLabel9.setText("N\u00famero de \u00e9pocas M\u00e1ximo");


jPanelTreina.add(jLabel9);
jLabel9.setBounds(20, 100, 160, 14);

jLabel10.setText("Fator de Aprendizagem");
jPanelTreina.add(jLabel10);
jLabel10.setBounds(20, 140, 160, 14);

jTFEpocas.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {

173
jTFEpocasFocusGained(evt);
}
public void focusLost(java.awt.event.FocusEvent evt) {
jTFEpocasFocusLost(evt);
}
});

jPanelTreina.add(jTFEpocas);
jTFEpocas.setBounds(200, 100, 50, 19);

jTFFator.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jTFFatorFocusGained(evt);
}
public void focusLost(java.awt.event.FocusEvent evt) {
jTFFatorFocusLost(evt);
}
});

jPanelTreina.add(jTFFator);
jTFFator.setBounds(200, 140, 50, 19);

jButton7.setIcon(new javax.swing.ImageIcon("duvida.gif"));
jButton7.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton7ActionPerformed(evt);
}
});

jPanelTreina.add(jButton7);
jButton7.setBounds(260, 100, 20, 20);

jButton8.setIcon(new javax.swing.ImageIcon("duvida.gif"));
jButton8.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton8ActionPerformed(evt);
}
});

jPanelTreina.add(jButton8);
jButton8.setBounds(260, 140, 20, 20);

jBConfiguraT.setText("Configurar");
jBConfiguraT.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt) {
jBConfiguraTActionPerformed(evt);
}
});
jBConfiguraT.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jBConfiguraTFocusGained(evt);
}
});

jPanelTreina.add(jBConfiguraT);
jBConfiguraT.setBounds(91, 200, 100, 23);

174
jBCancelaT.setText("Cancelar");
jBCancelaT.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jBCancelaTActionPerformed(evt);
}
});
jBCancelaT.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
jBCancelaTFocusGained(evt);
}
});

jPanelTreina.add(jBCancelaT);
jBCancelaT.setBounds(225, 200, 100, 23);

painelPrincipal.add(jPanelTreina, "cardTreina");

painelPrincipal.add(jPanelVazio, "cardInicio");

jPanelRTreina.setLayout(new
java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 2));

jPanelRTreinaSuperior.setLayout(null);

jLabel12.setFont(new java.awt.Font("Arial", 1, 12));


jLabel12.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel12.setText("Resultado do Treinamento");
jPanelRTreinaSuperior.add(jLabel12);
jLabel12.setBounds(129, 5, 180, 15);

jLabel13.setText("Quantidade de \u00c9pocas:");
jPanelRTreinaSuperior.add(jLabel13);
jLabel13.setBounds(20, 40, 140, 14);

jLabel14.setText("Erro M\u00e1ximo: ");


jPanelRTreinaSuperior.add(jLabel14);
jLabel14.setBounds(20, 70, 150, 14);

jLabel15.setText("Situa\u00e7\u00e3o:");
jPanelRTreinaSuperior.add(jLabel15);
jLabel15.setBounds(20, 100, 130, 14);

jLSituacao.setMaximumSize(new java.awt.Dimension(160, 14));


jLSituacao.setMinimumSize(new java.awt.Dimension(80, 14));
jLSituacao.setPreferredSize(new java.awt.Dimension(80, 14));
jPanelRTreinaSuperior.add(jLSituacao);
jLSituacao.setBounds(160, 100, 80, 14);

jLErroMax.setMaximumSize(new java.awt.Dimension(300, 14));


jLErroMax.setMinimumSize(new java.awt.Dimension(180, 14));
jLErroMax.setPreferredSize(new java.awt.Dimension(180, 14));
jPanelRTreinaSuperior.add(jLErroMax);
jLErroMax.setBounds(170, 70, 180, 14);

jLabel17.setMaximumSize(new java.awt.Dimension(160, 14));


jLabel17.setMinimumSize(new java.awt.Dimension(80, 14));
jLabel17.setPreferredSize(new java.awt.Dimension(80, 14));
jPanelRTreinaSuperior.add(jLabel17);

175
jLabel17.setBounds(180, 100, 80, 14);

jLQtdEpocas.setMaximumSize(new java.awt.Dimension(200, 14));


jLQtdEpocas.setMinimumSize(new java.awt.Dimension(80, 14));
jLQtdEpocas.setPreferredSize(new java.awt.Dimension(80, 14));
jPanelRTreinaSuperior.add(jLQtdEpocas);
jLQtdEpocas.setBounds(170, 40, 40, 14);

jPanelRTreina.add(jPanelRTreinaSuperior);

jPanelRTreina.add(jPanelRTreinaInferior);

painelPrincipal.add(jPanelRTreina, "cardRTreina");

getContentPane().add(painelPrincipal,
java.awt.BorderLayout.CENTER);

menuArquivo.setMnemonic('A');
menuArquivo.setText("Arquivo");
menuArquivo.setToolTipText("Inicie por aqui");
menuArquivo.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
menuArquivoFocusGained(evt);
}
});

abrir.setText("Abrir");
abrirRede.setMnemonic('R');
abrirRede.setText("Configura\u00e7\u00e3o de rede");
abrirRede.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
abrirRedeActionPerformed(evt);
}
});

abrir.add(abrirRede);

abrirPadroes.setMnemonic('A');
abrirPadroes.setText("Arquivo de padr\u00f5es");
abrirPadroes.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt) {
abrirPadroesActionPerformed(evt);
}
});

abrir.add(abrirPadroes);

menuArquivo.add(abrir);

Salvar.setText("Salvar");
salvarRede.setMnemonic('G');
salvarRede.setText("Configura\u00e7\u00e3o de rede");
salvarRede.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
salvarRedeActionPerformed(evt);
}
});

176
Salvar.add(salvarRede);

salvarPesos.setText("Arquivo de Pesos");
salvarPesos.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
salvarPesosActionPerformed(evt);
}
});

Salvar.add(salvarPesos);

salvarCodigo.setText("C\u00f3digo Fonte");
salvarCodigo.setActionCommand("C\u00f3digo Fonte da rede
Treinada");
codigoJava.setText("Fonte em JAVA");
codigoJava.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
codigoJavaActionPerformed(evt);
}
});

salvarCodigo.add(codigoJava);

codigoC.setText("Fonte em C++");
codigoC.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
codigoCActionPerformed(evt);
}
});

salvarCodigo.add(codigoC);

codigoOP.setText("Fonte em Object Pascal");


codigoOP.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
codigoOPActionPerformed(evt);
}
});

salvarCodigo.add(codigoOP);

codigoJS.setText("Fonte em JavaScript");
codigoJS.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
codigoJSActionPerformed(evt);
}
});

salvarCodigo.add(codigoJS);

Salvar.add(salvarCodigo);

menuArquivo.add(Salvar);

menuArquivo.add(jSeparator1);

Sair.setMnemonic('r');

177
Sair.setText("Sair");
Sair.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
SairActionPerformed(evt);
}
});

menuArquivo.add(Sair);

barraMenu.add(menuArquivo);
menuArquivo.getAccessibleContext().setAccessibleParent(barraMenu);

menuRede.setText("Rede");
Treinar.setMnemonic('T');
Treinar.setText("Treinar");
Treinar.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
TreinarActionPerformed(evt);
}
});

menuRede.add(Treinar);

menuConfiguraRede.setText("Configurar");
rede.setText("Rede");
rede.setToolTipText("");
rede.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
redeActionPerformed(evt);
}
});

menuConfiguraRede.add(rede);

treinamento.setText("Aspectos de treinamento");
treinamento.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
treinamentoActionPerformed(evt);
}
});

menuConfiguraRede.add(treinamento);

menuRede.add(menuConfiguraRede);

barraMenu.add(menuRede);

menuAjuda.setMnemonic('j');
menuAjuda.setText("Ajuda");
menuAjuda.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
menuAjudaFocusGained(evt);
}
});

como.setText("Como usar");
menuAjuda.add(como);

178
sobre.setText("Sobre");
menuAjuda.add(sobre);

barraMenu.add(menuAjuda);
menuAjuda.getAccessibleContext().setAccessibleParent(jPanelMenu);

setJMenuBar(barraMenu);
barraMenu.getAccessibleContext().setAccessibleParent(jPanelMenu);

}
// </editor-fold>//GEN-END:initComponents

private void salvarPesosActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_salvarPesosActionPerformed
if (!rna.getEstaTreinada()) {
javax.swing.JOptionPane.showMessageDialog(this, "Não há uma
rede treinada para gerar código!", "Aviso!",
javax.swing.JOptionPane.WARNING_MESSAGE);
return;
}
manipulacaoArquivos.GravadorArquivoPesos gravaPesos;
boolean invalido = true;
gravaPesos = new manipulacaoArquivos.GravadorArquivoPesos();
String nomeArq;
javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
jfc.setApproveButtonMnemonic('S');
jfc.setApproveButtonText("Salvar");
jfc.setDialogTitle("Arquivo de Pesos da Rede");
while(invalido) {
if(jfc.showSaveDialog(this) == jfc.APPROVE_OPTION){
java.io.File file = jfc.getSelectedFile();
nomeArq = file.getName();
if(nomeArq.indexOf('.') > 0) {

if(!nomeArq.substring(nomeArq.indexOf('.')).equals(".js")) {
javax.swing.JOptionPane.showMessageDialog(this,
"Nome de arquivo inválido.\nO nome não deve conter '.'", "Aviso de Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
} else {
invalido = false;
}
} else {
invalido = false;
}
if(!invalido) {
if(nomeArq.indexOf('.') <= 0) {
try {
nomeArq = file.getAbsolutePath().concat(".js");
file = new java.io.File(nomeArq);
} catch (Exception e) {

javax.swing.JOptionPane.showMessageDialog(this,e.getMessage());
}
} else {
nomeArq = file.getAbsolutePath();
file = new java.io.File(nomeArq);
}
int resposta = javax.swing.JOptionPane.YES_OPTION;

179
try {
if(file.exists()) {
resposta =
javax.swing.JOptionPane.showConfirmDialog(this, "Arquivo já existe,
sobrescrever?", "Atenção", javax.swing.JOptionPane.YES_NO_OPTION,
javax.swing.JOptionPane.WARNING_MESSAGE);
}
if(javax.swing.JOptionPane.YES_OPTION != resposta)
{
javax.swing.JOptionPane.showMessageDialog(this,
"O arquivo não foi gravado!");
} else {
nomeArq = nomeArq.substring(0,
nomeArq.length()-3);
gravaPesos.gerarArquivoPesos(nomeArq, rna);
javax.swing.JOptionPane.showMessageDialog(this,
"Arquivo gerado com sucesso!");
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this,
"Não foi possível gravar o arquivo!\nErro: " + e.getMessage());
return;
}
}
} else {
invalido = false;
}
}
}//GEN-LAST:event_salvarPesosActionPerformed

private void jButtonTreinarActionPerformed(java.awt.event.ActionEvent


evt) {//GEN-FIRST:event_jButtonTreinarActionPerformed
TreinarActionPerformed(null);
}//GEN-LAST:event_jButtonTreinarActionPerformed

private void
jButtonConfiguracaoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_jButtonConfiguracaoActionPerformed
treinamentoActionPerformed(null);
}//GEN-LAST:event_jButtonConfiguracaoActionPerformed

private void jButtonSalvarActionPerformed(java.awt.event.ActionEvent


evt) {//GEN-FIRST:event_jButtonSalvarActionPerformed
salvarRedeActionPerformed(null);
}//GEN-LAST:event_jButtonSalvarActionPerformed

private void jButtonAbrirActionPerformed(java.awt.event.ActionEvent


evt) {//GEN-FIRST:event_jButtonAbrirActionPerformed
abrirRedeActionPerformed(null);
}//GEN-LAST:event_jButtonAbrirActionPerformed

private void jButtonNovoActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_jButtonNovoActionPerformed
redeActionPerformed(null);
}//GEN-LAST:event_jButtonNovoActionPerformed

private void codigoJSActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_codigoJSActionPerformed

180
if (!rna.getEstaTreinada()) {
javax.swing.JOptionPane.showMessageDialog(this, "Não há uma
rede treinada para gerar código!", "Aviso!",
javax.swing.JOptionPane.WARNING_MESSAGE);
return;
}
boolean invalido = true;
geraCodigo = new geradoresCodigo.GeradorCodigoJS();
String nomeArq;
String limiar;
limiar = javax.swing.JOptionPane.showInputDialog(this, "Informe o
valor de limiar de saída.\nEste valor será o limite com o\nqual o programa
interpretará uma\nsaída como 0 ou 1.", "0.5");
javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
jfc.setApproveButtonMnemonic('S');
jfc.setApproveButtonText("Salvar");
jfc.setDialogTitle("Código fonte em JavaScript");
while(invalido) {
if(jfc.showSaveDialog(this) == jfc.APPROVE_OPTION){
java.io.File file = jfc.getSelectedFile();
nomeArq = file.getName();
if(nomeArq.indexOf('.') > 0) {

if(!nomeArq.substring(nomeArq.indexOf('.')).equals(".js")) {
javax.swing.JOptionPane.showMessageDialog(this,
"Nome de arquivo inválido.\nO nome não deve conter '.'", "Aviso de Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
} else {
invalido = false;
}
} else {
invalido = false;
}
if(!invalido) {
if(nomeArq.indexOf('.') <= 0) {
try {
nomeArq = file.getAbsolutePath().concat(".js");
file = new java.io.File(nomeArq);
} catch (Exception e) {

javax.swing.JOptionPane.showMessageDialog(this,e.getMessage());
}
} else {
nomeArq = file.getAbsolutePath();
file = new java.io.File(nomeArq);
}
int resposta = javax.swing.JOptionPane.YES_OPTION;
try {
if(file.exists()) {
resposta =
javax.swing.JOptionPane.showConfirmDialog(this, "Arquivo já existe,
sobrescrever?", "Atenção", javax.swing.JOptionPane.YES_NO_OPTION,
javax.swing.JOptionPane.WARNING_MESSAGE);
}
if(javax.swing.JOptionPane.YES_OPTION != resposta)
{
javax.swing.JOptionPane.showMessageDialog(this,
"O arquivo não foi gravado!");

181
} else {
nomeArq = nomeArq.substring(0,
nomeArq.length()-3);
geraCodigo.gerarArquivoEmDisco(nomeArq);
geraCodigo.gerarFuncaoRNAMLP(rna,
Double.parseDouble(limiar));
javax.swing.JOptionPane.showMessageDialog(this,
"Arquivo gerado com sucesso!");
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this,
"Não foi possível gravar o arquivo!\nErro: " + e.getMessage());
return;
}
}
} else {
invalido = false;
}
}
}//GEN-LAST:event_codigoJSActionPerformed

private void codigoOPActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_codigoOPActionPerformed
if (!rna.getEstaTreinada()) {
javax.swing.JOptionPane.showMessageDialog(this, "Não há uma
rede treinada para gerar código!", "Aviso!",
javax.swing.JOptionPane.WARNING_MESSAGE);
return;
}
boolean invalido = true;
geraCodigo = new geradoresCodigo.GeradorCodigoOP();
String nomeArq;
String limiar;
limiar = javax.swing.JOptionPane.showInputDialog(this, "Informe o
valor de limiar de saída.\nEste valor será o limite com o\nqual o programa
interpretará uma\nsaída como 0 ou 1.", "0.5");
javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
jfc.setApproveButtonMnemonic('S');
jfc.setApproveButtonText("Salvar");
jfc.setDialogTitle("Código fonte em Object Pascal");
while(invalido) {
if(jfc.showSaveDialog(this) == jfc.APPROVE_OPTION){
java.io.File file = jfc.getSelectedFile();
nomeArq = file.getName();
if(nomeArq.indexOf('.') > 0) {

if(!nomeArq.substring(nomeArq.indexOf('.')).equals(".pas")) {
javax.swing.JOptionPane.showMessageDialog(this,
"Nome de arquivo inválido.\nO nome não deve conter '.'", "Aviso de Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
} else {
invalido = false;
}
} else {
invalido = false;
}
if(!invalido) {
if(nomeArq.indexOf('.') <= 0) {

182
try {
nomeArq =
file.getAbsolutePath().concat(".pas");
file = new java.io.File(nomeArq);
} catch (Exception e) {

javax.swing.JOptionPane.showMessageDialog(this,e.getMessage());
}
} else {
nomeArq = file.getAbsolutePath();
file = new java.io.File(nomeArq);
}
int resposta = javax.swing.JOptionPane.YES_OPTION;
try {
if(file.exists()) {
resposta =
javax.swing.JOptionPane.showConfirmDialog(this, "Arquivo já existe,
sobrescrever?", "Atenção", javax.swing.JOptionPane.YES_NO_OPTION,
javax.swing.JOptionPane.WARNING_MESSAGE);
}
if(javax.swing.JOptionPane.YES_OPTION != resposta)
{
javax.swing.JOptionPane.showMessageDialog(this,
"O arquivo não foi gravado!");
} else {
nomeArq = nomeArq.substring(0,
nomeArq.length()-4);
geraCodigo.gerarArquivoEmDisco(nomeArq);
geraCodigo.gerarFuncaoRNAMLP(rna,
Double.parseDouble(limiar));
javax.swing.JOptionPane.showMessageDialog(this,
"Arquivo gerado com sucesso!");
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this,
"Não foi possível gravar o arquivo!\nErro: " + e.getMessage());
return;
}
}
} else {
invalido = false;
}
}
}//GEN-LAST:event_codigoOPActionPerformed

private void codigoCActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_codigoCActionPerformed
if (!rna.getEstaTreinada()) {
javax.swing.JOptionPane.showMessageDialog(this, "Não há uma
rede treinada para gerar código!", "Aviso!",
javax.swing.JOptionPane.WARNING_MESSAGE);
return;
}
boolean invalido = true;
geraCodigo = new geradoresCodigo.GeradorCodigoCPP();
String nomeArq;
String limiar;

183
limiar = javax.swing.JOptionPane.showInputDialog(this, "Informe o
valor de limiar de saída.\nEste valor será o limite com o\nqual o programa
interpretará uma\nsaída como 0 ou 1.", "0.5");
javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
jfc.setApproveButtonMnemonic('S');
jfc.setApproveButtonText("Salvar");
jfc.setDialogTitle("Código fonte em C++");
while(invalido) {
if(jfc.showSaveDialog(this) == jfc.APPROVE_OPTION){
java.io.File file = jfc.getSelectedFile();
nomeArq = file.getName();
if(nomeArq.indexOf('.') > 0) {

if(!nomeArq.substring(nomeArq.indexOf('.')).equals(".h")) {
javax.swing.JOptionPane.showMessageDialog(this,
"Nome de arquivo inválido.\nO nome não deve conter '.'", "Aviso de Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
} else {
invalido = false;
}
} else {
invalido = false;
}
if(!invalido) {
if(nomeArq.indexOf('.') <= 0) {
try {
nomeArq = file.getAbsolutePath().concat(".h");
file = new java.io.File(nomeArq);
} catch (Exception e) {

javax.swing.JOptionPane.showMessageDialog(this,e.getMessage());
}
} else {
nomeArq = file.getAbsolutePath();
file = new java.io.File(nomeArq);
}
int resposta = javax.swing.JOptionPane.YES_OPTION;
try {
if(file.exists()) {
resposta =
javax.swing.JOptionPane.showConfirmDialog(this, "Arquivo já existe,
sobrescrever?", "Atenção", javax.swing.JOptionPane.YES_NO_OPTION,
javax.swing.JOptionPane.WARNING_MESSAGE);
}
if(javax.swing.JOptionPane.YES_OPTION != resposta)
{
javax.swing.JOptionPane.showMessageDialog(this,
"O arquivo não foi gravado!");
} else {
nomeArq = nomeArq.substring(0,
nomeArq.length()-2);
geraCodigo.gerarArquivoEmDisco(nomeArq);
geraCodigo.gerarFuncaoRNAMLP(rna,
Double.parseDouble(limiar));
javax.swing.JOptionPane.showMessageDialog(this,
"Arquivo gerado com sucesso!");
}
} catch (Exception e) {

184
javax.swing.JOptionPane.showMessageDialog(this,
"Não foi possível gravar o arquivo!\nErro: " + e.getMessage());
return;
}
}
} else {
invalido = false;
}
}
}//GEN-LAST:event_codigoCActionPerformed

private void codigoJavaActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_codigoJavaActionPerformed
if (!rna.getEstaTreinada()) {
javax.swing.JOptionPane.showMessageDialog(this, "Não há uma
rede treinada para gerar código!", "Aviso!",
javax.swing.JOptionPane.WARNING_MESSAGE);
return;
}
boolean invalido = true;
geraCodigo = new geradoresCodigo.GeradorCodigoJava();
String nomeArq;
String limiar;
limiar = javax.swing.JOptionPane.showInputDialog(this, "Informe o
valor de limiar de saída.\nEste valor será o limite com o\nqual o programa
interpretará uma\nsaída como 0 ou 1.", "0.5");
javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
jfc.setApproveButtonMnemonic('S');
jfc.setApproveButtonText("Salvar");
jfc.setDialogTitle("Código fonte em JAVA");
while(invalido) {
if(jfc.showSaveDialog(this) == jfc.APPROVE_OPTION){
java.io.File file = jfc.getSelectedFile();
nomeArq = file.getName();
if(nomeArq.indexOf('.') > 0) {

if(!nomeArq.substring(nomeArq.indexOf('.')).equals(".java")) {
javax.swing.JOptionPane.showMessageDialog(this,
"Nome de arquivo inválido.\nO nome não deve conter '.'", "Aviso de Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
} else {
invalido = false;
}
} else {
invalido = false;
}
if(!invalido) {
if(nomeArq.indexOf('.') <= 0) {
try {
nomeArq =
file.getAbsolutePath().concat(".java");
file = new java.io.File(nomeArq);
} catch (Exception e) {

javax.swing.JOptionPane.showMessageDialog(this,e.getMessage());
}
} else {
nomeArq = file.getAbsolutePath();

185
file = new java.io.File(nomeArq);
}
int resposta = javax.swing.JOptionPane.YES_OPTION;
try {
if(file.exists()) {
resposta =
javax.swing.JOptionPane.showConfirmDialog(this, "Arquivo já existe,
sobrescrever?", "Atenção", javax.swing.JOptionPane.YES_NO_OPTION,
javax.swing.JOptionPane.WARNING_MESSAGE);
}
if(javax.swing.JOptionPane.YES_OPTION != resposta)
{
javax.swing.JOptionPane.showMessageDialog(this,
"O arquivo não foi gravado!");
} else {
nomeArq = nomeArq.substring(0,
nomeArq.length()-5);
geraCodigo.gerarArquivoEmDisco(nomeArq);
geraCodigo.gerarFuncaoRNAMLP(rna,
Double.parseDouble(limiar));
javax.swing.JOptionPane.showMessageDialog(this,
"Arquivo gerado com sucesso!");
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this,
"Não foi possível gravar o arquivo!\nErro: " + e.getMessage());
return;
}
}
} else {
invalido = false;
}
}
}//GEN-LAST:event_codigoJavaActionPerformed

private void TreinarActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_TreinarActionPerformed
jLStatus.setText("");
janelaProgresso = new Progresso(this, "Treinamento da rede", "Rede
sendo treinada ...", "Fechar", "Treinar");
janelaProgresso.getFrame().setVisible(true);
janelaProgresso.getBarraProgresso().setIndeterminate(true);
Thread processo = new Treino(this, rna, treinador,
janelaProgresso);
janelaProgresso.setProcesso(processo);
jLStatus.setText("");
this.desabilitaSalvarCodigo();
redeSalva = false;
processo.start();
}//GEN-LAST:event_TreinarActionPerformed

private void jBCancelaTFocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jBCancelaTFocusGained
jLStatus.setText("Abandonar a configuração do treinamento");
}//GEN-LAST:event_jBCancelaTFocusGained

private void jBConfiguraTActionPerformed(java.awt.event.ActionEvent


evt) {//GEN-FIRST:event_jBConfiguraTActionPerformed

186
double erro, fator;
int epocas;
if(jTFErro.getText().length() == 0) {
jTFErro.requestFocus();
return;
}
if(jTFEpocas.getText().length() == 0) {
jTFEpocas.requestFocus();
return;
}
if(jTFFator.getText().length() == 0) {
jTFFator.requestFocus();
return;
}
erro = Double.parseDouble(jTFErro.getText());
epocas = Integer.parseInt(jTFEpocas.getText());
fator = Double.parseDouble(jTFFator.getText());
treinador.setErroAceitavell(erro);
treinador.setEpocasMaximo(epocas);
treinador.setFatorAprendizagem(fator);
javax.swing.JOptionPane.showMessageDialog(this, "Treinamento
configurado!", "Resultado", javax.swing.JOptionPane.INFORMATION_MESSAGE);
lm.show(painelPrincipal, "cardInicio");
jLStatus.setText("Selecione um dos ítens de menu");
}//GEN-LAST:event_jBConfiguraTActionPerformed

private void jBConfiguraTFocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jBConfiguraTFocusGained
jLStatus.setText("Configura o treinamento");
}//GEN-LAST:event_jBConfiguraTFocusGained

private void jBCancelaTActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_jBCancelaTActionPerformed
lm.show(painelPrincipal, "cardInicio");
jLStatus.setText("Selecione um dos ítens de menu");
}//GEN-LAST:event_jBCancelaTActionPerformed

private void jButton8ActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_jButton8ActionPerformed
javax.swing.JOptionPane.showMessageDialog(this, "Este campo deve
ser preenchido\ncom valor maior que 0\n e menor que 1. Quanto maior\no
valor, mais rápido será\no treinamento. Entretanto,\nmaior a chance da rede
não\nconseguir ser treinada.\nValores indicados para este\ncampo ficam
entre 0.05 e 0.25.", "Ajuda!",
javax.swing.JOptionPane.INFORMATION_MESSAGE);
}//GEN-LAST:event_jButton8ActionPerformed

private void jButton7ActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_jButton7ActionPerformed
javax.swing.JOptionPane.showMessageDialog(this, "Este campo deve
ser preenchido\ncom o número máximo de épocas\nque a rede deve ser
treinada.\nSe ao final destas épocas\na rede não estiver treinada\no
treinamento encerra informando\nnão ter conseguido treinar.", "Ajuda!",
javax.swing.JOptionPane.INFORMATION_MESSAGE);
}//GEN-LAST:event_jButton7ActionPerformed

private void jButton6ActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_jButton6ActionPerformed

187
javax.swing.JOptionPane.showMessageDialog(this, "Este campo deve
ser preenchido\ncom o valor máximo admissível \nde erro na saída. Os
valores de\nsaída são normalmente 0 ou 1.\nUm erro de 0.1, por
exemplo\nadmitiria como 1 valores entre\n0.9 ou 1.1.", "Ajuda!",
javax.swing.JOptionPane.INFORMATION_MESSAGE);
}//GEN-LAST:event_jButton6ActionPerformed

private void jTFFatorFocusGained(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jTFFatorFocusGained
jLStatus.setText("Informe o o fator de aprendizagem, maior que 0 e
menor que 1.");
}//GEN-LAST:event_jTFFatorFocusGained

private void jTFEpocasFocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jTFEpocasFocusGained
jLStatus.setText("Informe a quantidade máxima de épocas.");
}//GEN-LAST:event_jTFEpocasFocusGained

private void jTFErroFocusGained(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jTFErroFocusGained
jLStatus.setText("Informe o erro máximo aceitável, maior que 0 e
menor que 1.");
}//GEN-LAST:event_jTFErroFocusGained

private void jTFFatorFocusLost(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jTFFatorFocusLost
double fator;
if((jTFFator.getText().length() == 0) ||
(jTFErro.getText().length() == 0) || (jTFEpocas.getText().length() == 0)) {
jBConfiguraT.setEnabled(false);
} else {
jBConfiguraT.setEnabled(true);
}
if (jTFFator.getText().length() != 0) {
try {
fator = Double.parseDouble(jTFFator.getText());
if (fator > 0 && fator < 1) {
treinador.setFatorAprendizagem(fator);
} else {
javax.swing.JOptionPane.showMessageDialog(this, "Valor
inválido!\nEste campo exige um número maior que zero e menor que um.",
"Erro!", javax.swing.JOptionPane.ERROR_MESSAGE);
jTFFator.setText("");
jTFFator.requestFocus(); }
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this,"Valor
inválido!\nEste campo exige um número maior que zero e menor que um.",
"Erro!", javax.swing.JOptionPane.ERROR_MESSAGE);
jTFFator.setText("");
jTFFator.requestFocus();
}
}
}//GEN-LAST:event_jTFFatorFocusLost

private void jTFEpocasFocusLost(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jTFEpocasFocusLost
int epocas;

188
if((jTFFator.getText().length() == 0) ||
(jTFErro.getText().length() == 0) || (jTFEpocas.getText().length() == 0)) {
jBConfiguraT.setEnabled(false);
} else {
jBConfiguraT.setEnabled(true);
}
if (jTFEpocas.getText().length() != 0) {
try {
epocas = Integer.parseInt(jTFEpocas.getText());
if (epocas > 0) {
treinador.setEpocasMaximo(epocas);
} else {
javax.swing.JOptionPane.showMessageDialog(this, "Valor
inválido!\nEste campo exige um número inteiro maior que zero.", "Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
jTFEpocas.setText("");
jTFEpocas.requestFocus();
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this,"Valor
inválido!\nEste campo exige um número inteiro maior que zero.", "Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
jTFEpocas.setText("");
jTFEpocas.requestFocus();
}
}
}//GEN-LAST:event_jTFEpocasFocusLost

private void jTFErroFocusLost(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jTFErroFocusLost
double erro;
if((jTFFator.getText().length() == 0) ||
(jTFErro.getText().length() == 0) || (jTFEpocas.getText().length() == 0)) {
jBConfiguraT.setEnabled(false);
} else {
jBConfiguraT.setEnabled(true);
}
if (jTFErro.getText().length() != 0) {
try {
erro = Double.parseDouble(jTFErro.getText());
if (erro > 0 && erro < 1) {
treinador.setErroAceitavell(erro);
} else {
javax.swing.JOptionPane.showMessageDialog(this, "Valor
inválido!\nEste campo exige um número maior que zero e menor que um.",
"Erro!", javax.swing.JOptionPane.ERROR_MESSAGE);
jTFErro.setText("");
jTFErro.requestFocus();
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this,"Valor
inválido!\nEste campo exige um número maior que zero e menor que um.",
"Erro!", javax.swing.JOptionPane.ERROR_MESSAGE);
jTFErro.setText("");
jTFErro.requestFocus();
}
}
}//GEN-LAST:event_jTFErroFocusLost

189
private void treinamentoActionPerformed(java.awt.event.ActionEvent evt)
{//GEN-FIRST:event_treinamentoActionPerformed
lm.show(painelPrincipal, "cardTreina");
jPanelRedeInterno.setFocusCycleRoot(true);
jTFErro.setText(Double.toString(treinador.getErroAceitavel()));
jTFEpocas.setText(Integer.toString(treinador.getEpocasMaximo()));

jTFFator.setText(Double.toString(treinador.getFatorAprendizagem()));
if((jTFFator.getText().length() == 0) ||
(jTFErro.getText().length() == 0) || (jTFEpocas.getText().length() == 0)) {
jBConfiguraT.setEnabled(false);
}
jLStatus.setText("Configuração do treinamento");
}//GEN-LAST:event_treinamentoActionPerformed

private void redeActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_redeActionPerformed
lm.show(painelPrincipal, "cardRede");
jPanelRedeInterno.setFocusCycleRoot(true);
jLStatus.setText("Configuração da rede");
jTFNosEntrada.setText(Integer.toString(rna.getNosEntrada()));
jTFNosSaida.setText(Integer.toString(rna.getNosSaida()));
jTFNosEscondidos.setText(Integer.toString(rna.getNosEscondidos()));
if(rna.getBias() == 1) {
jRadioButton1.setSelected(true);
} else {
jRadioButton2.setSelected(true);
}
if(rna.getFuncao().getNome().equals("Sigmoidal")) {
jComboBox1.setSelectedIndex(0);
} else {
jComboBox1.setSelectedIndex(1);
}
if((jTFNosEntrada.getText().length() == 0) ||
(jTFNosSaida.getText().length() == 0) ||
(jTFNosEscondidos.getText().length() == 0)) {
jButtonConfigurar.setEnabled(false);
} else {
jButtonConfigurar.setEnabled(true);
}
}//GEN-LAST:event_redeActionPerformed

private void jButtonCancelarActionPerformed(java.awt.event.ActionEvent


evt) {//GEN-FIRST:event_jButtonCancelarActionPerformed
lm.show(painelPrincipal, "cardInicio");
jLStatus.setText("Selecione um dos ítens de menu");
}//GEN-LAST:event_jButtonCancelarActionPerformed

private void menuAjudaFocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_menuAjudaFocusGained
jLStatus.setText("");
}//GEN-LAST:event_menuAjudaFocusGained

private void menuArquivoFocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_menuArquivoFocusGained
jLStatus.setText("");
}//GEN-LAST:event_menuArquivoFocusGained

190
private void jButtonCancelarFocusGained(java.awt.event.FocusEvent evt)
{//GEN-FIRST:event_jButtonCancelarFocusGained
jLStatus.setText("Abandonar a configuração da rede.");
}//GEN-LAST:event_jButtonCancelarFocusGained

private void jButtonConfigurarFocusGained(java.awt.event.FocusEvent


evt) {//GEN-FIRST:event_jButtonConfigurarFocusGained
jLStatus.setText("Configurar a rede.");
}//GEN-LAST:event_jButtonConfigurarFocusGained

private void jButton4FocusGained(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jButton4FocusGained
jLStatus.setText("Ajuda contextual.");
}//GEN-LAST:event_jButton4FocusGained

private void jButton5FocusGained(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jButton5FocusGained
jLStatus.setText("Ajuda contextual.");
}//GEN-LAST:event_jButton5FocusGained

private void jButton3FocusGained(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jButton3FocusGained
jLStatus.setText("Ajuda contextual.");
}//GEN-LAST:event_jButton3FocusGained

private void jButton2FocusGained(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jButton2FocusGained
jLStatus.setText("Ajuda contextual.");
}//GEN-LAST:event_jButton2FocusGained

private void jButton1FocusGained(java.awt.event.FocusEvent evt) {//GEN-


FIRST:event_jButton1FocusGained
jLStatus.setText("Ajuda contextual.");
}//GEN-LAST:event_jButton1FocusGained

private void jComboBox1FocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jComboBox1FocusGained
jLStatus.setText("Selecione a função que será utilizada para
saída.");
}//GEN-LAST:event_jComboBox1FocusGained

private void jRadioButton2FocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jRadioButton2FocusGained
jLStatus.setText("Nesta opção não será utilizado o nó de Bias.");
}//GEN-LAST:event_jRadioButton2FocusGained

private void jRadioButton1FocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jRadioButton1FocusGained
jLStatus.setText("Nesta opção será utilizado um nó a mais como Bias
na entrada e camada escondida.");
}//GEN-LAST:event_jRadioButton1FocusGained

private void jTFNosEscondidosFocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jTFNosEscondidosFocusGained
jLStatus.setText("Este valor pode ser preenchido automaticamente,
basta preencher os demais campos.");
}//GEN-LAST:event_jTFNosEscondidosFocusGained

191
private void jTFNosSaidaFocusGained(java.awt.event.FocusEvent evt)
{//GEN-FIRST:event_jTFNosSaidaFocusGained
jLStatus.setText("Informe um número inteiro maior que zero para Nós
de Saída");
}//GEN-LAST:event_jTFNosSaidaFocusGained

private void jTFNosEntradaFocusGained(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jTFNosEntradaFocusGained
jLStatus.setText("Informe um número inteiro maior que zero para Nós
de Entrada");
}//GEN-LAST:event_jTFNosEntradaFocusGained

private void jButton5ActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_jButton5ActionPerformed
javax.swing.JOptionPane.showMessageDialog(this, "Escolha se deseja
usar um\nnó como Bias. Normalmante\no uso do Bias melhora a\napendizagem da
rede.\nSugerimos escolher Sim.", "Ajuda!",
javax.swing.JOptionPane.INFORMATION_MESSAGE);
}//GEN-LAST:event_jButton5ActionPerformed

private void
jButtonConfigurarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
FIRST:event_jButtonConfigurarActionPerformed
int entrada, saida, escondido, bias;
int esc, sai, ent;
redeSalva = false;
funcoesSaida.FuncaoSaida fa;
if(jTFNosEntrada.getText().length() == 0) {
jTFNosEntrada.requestFocus();
return;
}
if(jTFNosSaida.getText().length() == 0) {
jTFNosSaida.requestFocus();
return;
}
try {
ent = Integer.parseInt(jTFNosEntrada.getText());
sai = Integer.parseInt(jTFNosSaida.getText());
esc = (ent + sai)/2;
if (Integer.parseInt(jTFNosEscondidos.getText()) != esc) {
if(javax.swing.JOptionPane.showConfirmDialog(this, "O campo
Nós Escondidos está \npreenchido com valor diferente\ndo sugerido (" + esc
+ ").\nRecomendamos aceitar o valor\nsugerido. Clique em Yes para\nalterá-
lo ou No para mantê-lo!", "Ajuda!", javax.swing.JOptionPane.YES_NO_OPTION)
== javax.swing.JOptionPane.OK_OPTION) {
jTFNosEscondidos.setText(Integer.toString(esc));
}
}
} catch (Exception e) {}
if(jTFNosEscondidos.getText().length() == 0) {
jTFNosEscondidos.requestFocus();
return;
}
if(jComboBox1.getSelectedIndex() < 0) {
jComboBox1.requestFocus();
return;
}

192
entrada = Integer.parseInt(jTFNosEntrada.getText());
saida = Integer.parseInt(jTFNosSaida.getText());
escondido = Integer.parseInt(jTFNosEscondidos.getText());
bias = jRadioButton1.isSelected() ? 1 : 0;
if(jComboBox1.getSelectedIndex() == 0){
fa = new funcoesSaida.FuncaoSigmoidal();
} else {
fa = new funcoesSaida.FuncaoTangHiperb();
}
rna.setFuncao(fa);
try {
rna.setNosEntrada(entrada);
rna.setNosEscondidos(escondido);
rna.setNosSaida(saida);
rna.setBias(bias);
treinador.setRna(rna);
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this, "Erro na
configuração da rede!\n" + e.getMessage(), "Aviso de Erro",
javax.swing.JOptionPane.ERROR_MESSAGE);
leuPadroes = false;
Treinar.setEnabled(false);
treinamento.setEnabled(false);
return;
}
javax.swing.JOptionPane.showMessageDialog(this, "Rede
configurada!", "Resultado", javax.swing.JOptionPane.INFORMATION_MESSAGE);
lm.show(painelPrincipal, "cardInicio");
Treinar.setEnabled(leuPadroes);
treinamento.setEnabled(leuPadroes);
jLStatus.setText("Selecione um dos Itens de menu");
}//GEN-LAST:event_jButtonConfigurarActionPerformed

private void jTFNosEscondidosFocusLost(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jTFNosEscondidosFocusLost
int esc;
try {
esc = Integer.parseInt(jTFNosEscondidos.getText());
if(esc < 1) {
javax.swing.JOptionPane.showMessageDialog(this, "Valor
inválido!\nEste campo exige um número inteiro maior que zero.", "Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
jTFNosEscondidos.setText("");
jTFNosEscondidos.requestFocus();
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this, "Valor
inválido!\nEste campo exige um número inteiro maior que zero.", "Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
jTFNosEscondidos.setText("");
jTFNosEscondidos.requestFocus();
}
if((jTFNosEntrada.getText().length() == 0) ||
(jTFNosSaida.getText().length() == 0) ||
(jTFNosEscondidos.getText().length() == 0)) {
jButtonConfigurar.setEnabled(false);
} else {
jButtonConfigurar.setEnabled(true);

193
}
}//GEN-LAST:event_jTFNosEscondidosFocusLost

private void jTFNosSaidaFocusLost(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jTFNosSaidaFocusLost
int ent, sai;
try {
sai = Integer.parseInt(jTFNosSaida.getText());
if(sai < 1) {
javax.swing.JOptionPane.showMessageDialog(this, "Valor
inválido!\nEste campo exige um número inteiro maior que zero.", "Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
jTFNosSaida.setText("");
jTFNosSaida.requestFocus();
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this, "Valor
inválido!\nEste campo exige um número inteiro maior que zero.", "Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
jTFNosSaida.setText("");
jTFNosSaida.requestFocus();
}
ent = Integer.parseInt(jTFNosEntrada.getText());
sai = Integer.parseInt(jTFNosSaida.getText());
if(jTFNosEntrada.getText().length()>0 &&
jTFNosSaida.getText().length()>0 && jTFNosEscondidos.getText().length() ==
0) {
jTFNosEscondidos.setText(Integer.toString((ent + sai)/2));
}
if((jTFNosEntrada.getText().length() == 0) ||
(jTFNosSaida.getText().length() == 0) ||
(jTFNosEscondidos.getText().length() == 0)) {
jButtonConfigurar.setEnabled(false);
} else {
jButtonConfigurar.setEnabled(true);
}
}//GEN-LAST:event_jTFNosSaidaFocusLost

private void jTFNosEntradaFocusLost(java.awt.event.FocusEvent evt)


{//GEN-FIRST:event_jTFNosEntradaFocusLost
int ent, sai, esc;
try {
ent = Integer.parseInt(jTFNosEntrada.getText());
if(ent < 1) {
javax.swing.JOptionPane.showMessageDialog(this, "Valor
inválido!\nEste campo exige um número inteiro maior que zero.", "Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
jTFNosEntrada.setText("");
jTFNosEntrada.requestFocus();
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this, "Valor
inválido!\nEste campo exige um número inteiro maior que zero.", "Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
jTFNosEntrada.setText("");
jTFNosEntrada.requestFocus();
}
ent = Integer.parseInt(jTFNosEntrada.getText());

194
sai = Integer.parseInt(jTFNosSaida.getText());
if(jTFNosEntrada.getText().length()>0 &&
jTFNosSaida.getText().length()>0 && jTFNosEscondidos.getText().length() ==
0) {
jTFNosEscondidos.setText(Integer.toString((ent + sai)/2));
}
if((jTFNosEntrada.getText().length() == 0) ||
(jTFNosSaida.getText().length() == 0) ||
(jTFNosEscondidos.getText().length() == 0)) {
jButtonConfigurar.setEnabled(false);
} else {
jButtonConfigurar.setEnabled(true);
}
}//GEN-LAST:event_jTFNosEntradaFocusLost

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_jButton3ActionPerformed
javax.swing.JOptionPane.showMessageDialog(this, "Este campo deve
ser preenchido \ncom a quantidade de nós \nintermediários que a rede
terá.\nO melhor valor para este campo\ndepende de muitos
fatores.\nSugerimos aceitar o valor\nindicado pelo programa", "juda!",
javax.swing.JOptionPane.INFORMATION_MESSAGE);
}//GEN-LAST:event_jButton3ActionPerformed

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_jButton2ActionPerformed
javax.swing.JOptionPane.showMessageDialog(this, "Este campo deve
ser preenchido \ncom a quantidade de saídas que \na rede terá.\nSaídas são,
portanto, os dados que\nobteremos como resultado de um\ndado problema.",
"Ajuda!", javax.swing.JOptionPane.INFORMATION_MESSAGE);
}//GEN-LAST:event_jButton2ActionPerformed

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_jButton1ActionPerformed
javax.swing.JOptionPane.showMessageDialog(this, "Este campo deve
ser preenchido \ncom a quantidade de entradas que \na rede terá.\nEntradas
são, portanto, os dados \nconhecidos de um dado problema.", "Ajuda!",
javax.swing.JOptionPane.INFORMATION_MESSAGE);
}//GEN-LAST:event_jButton1ActionPerformed

private void salvarRedeActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_salvarRedeActionPerformed
javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
jfc.setApproveButtonMnemonic('S');
jfc.setApproveButtonText("Salvar");
jfc.setDialogTitle("Arquivo com os dados da rede");
if(jfc.showSaveDialog(this) == jfc.APPROVE_OPTION){
java.io.File file = jfc.getSelectedFile();
int resposta = javax.swing.JOptionPane.YES_OPTION;
manipulacaoArquivos.PersistenciaRede gravador = new
manipulacaoArquivos.PersistenciaRede();
try {
if(file.exists()) {
resposta =
javax.swing.JOptionPane.showConfirmDialog(this, "Arquivo já existe,
sobrescrever?", "Atenção", javax.swing.JOptionPane.YES_NO_OPTION,
javax.swing.JOptionPane.WARNING_MESSAGE);
}

195
if(javax.swing.JOptionPane.YES_OPTION != resposta) {
javax.swing.JOptionPane.showMessageDialog(this, "O
arquivo não foi gravado!");
} else {
gravador.gerarArquivoRede(file.getAbsolutePath(), rna);

javax.swing.JOptionPane.showMessageDialog(this,"Configurações gravadas com


sucesso!");
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this, "Não foi
possível gravar o arquivo!\nErro: " + e.getMessage());
}
redeSalva = true;
}
}//GEN-LAST:event_salvarRedeActionPerformed

private void saindo(java.awt.event.WindowEvent evt) {//GEN-


FIRST:event_saindo
this.trataSaida();
System.exit(0);
}//GEN-LAST:event_saindo

private void SairActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_SairActionPerformed
this.trataSaida();
System.exit(0);
}//GEN-LAST:event_SairActionPerformed

private void abrirPadroesActionPerformed(java.awt.event.ActionEvent


evt) {//GEN-FIRST:event_abrirPadroesActionPerformed
String nomeArquivo;
LeArquivo leitor;
boolean compativel = false;
javax.swing.JFileChooser jFC = new javax.swing.JFileChooser();
jFC.setApproveButtonMnemonic('A');
jFC.setApproveButtonText("Abrir");
jFC.setDialogTitle("Arquivo com os padrões para treinamento");
if(jFC.showOpenDialog(this) == jFC.APPROVE_OPTION){
nomeArquivo = jFC.getSelectedFile().getPath();
janelaProgresso = new Progresso(this, "Leitura do arquivo de
padrões", "Arquivo sendo lido ...", "Fechar", "Ler");
janelaProgresso.getFrame().setVisible(true);
janelaProgresso.getBarraProgresso().setIndeterminate(true);
jLStatus.setText("Arquivo sendo lido ...");
leitor = new LeArquivo(this, rna, treinador, janelaProgresso,
nomeArquivo);
janelaProgresso.setProcesso(leitor);
leitor.start();
}
}//GEN-LAST:event_abrirPadroesActionPerformed

private void abrirRedeActionPerformed(java.awt.event.ActionEvent evt)


{//GEN-FIRST:event_abrirRedeActionPerformed
String nomeArquivo;
javax.swing.JFileChooser jFC = new javax.swing.JFileChooser();
jFC.setApproveButtonMnemonic('A');
jFC.setApproveButtonText("Abrir");

196
jFC.setDialogTitle("Arquivo com os dados para criação da rede");
if(jFC.showOpenDialog(this) == jFC.APPROVE_OPTION){
nomeArquivo = jFC.getSelectedFile().getPath();
manipulacaoArquivos.PersistenciaRede leitor = new
manipulacaoArquivos.PersistenciaRede();
try {
rna = leitor.lerArquivoRede(nomeArquivo);
javax.swing.JOptionPane.showMessageDialog(this, "Arquivo de
configurações lido com sucesso!", "Aviso!",
javax.swing.JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(this, "Erro na
leitura do arquivo: " + e.getMessage(), "Aviso de Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
}//GEN-LAST:event_abrirRedeActionPerformed

public void resultadoTreino() {


jLStatus.setText("Selecione um dos ítens de menu");
lm.show(painelPrincipal, "cardRTreina");

jLQtdEpocas.setText(Integer.toString(treinador.getQtdEpocasAtual()));
jLErroMax.setText(Double.toString(treinador.getErroMaximo()));
jLSituacao.setText(rna.getEstaTreinada() ? "Treinou" : "Não
Treinou");
ArrayList <Double> ae = treinador.getErrosMaximos();
int qt = ae.size();
int ad;
int qtd;
if(qt > 10){
ad = qt / 10;
qtd = qt / ad;
} else {
qtd = qt;
ad = 1;
}
String cat1 = "Erros";
String cat2 = "Limite";
DefaultCategoryDataset ds = new DefaultCategoryDataset();
int i;
for(i = 0; i < qt; i+=ad) {
ds.setValue(ae.get(i), cat1, ""+i);
ds.setValue(treinador.getErroAceitavel(), cat2, ""+i);
}
ds.setValue(ae.get(qt-1), cat1, ""+qt);
ds.setValue(treinador.getErroAceitavel(), cat2, ""+qt);
JFreeChart graf = ChartFactory.createLineChart("Gráfico de Evolução
do Treinamento", "Épocas", "Erro", ds, PlotOrientation.VERTICAL, true,
false, false);
jPanelRTreinaInferior.removeAll();
jPanelRTreinaInferior.add(new ChartPanel(graf));
}

public void completaLeitura() {


leuPadroes = true;
Treinar.setEnabled(true);
treinamento.setEnabled(true);

197
jLStatus.setText("Selecione um dos itens de menu");
}

private void trataSaida() {


//javax.swing.JOptionPane.showMessageDialog(this, "Confirma a
saída?");
}

public void habilitaTreinar() {


Treinar.setEnabled(true);
}

public void desabilitaTreinar() {


Treinar.setEnabled(false);
}

public void desabilitaSalvarCodigo() {


salvarCodigo.setEnabled(false);
}

public void habilitaSalvarCodigo() {


salvarCodigo.setEnabled(true);
}

public void adequaSalvarCodigo() {


salvarCodigo.setEnabled(rna.getEstaTreinada());
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Principal().setVisible(true);
}
});
}

// Variables declaration - do not modify//GEN-BEGIN:variables


private javax.swing.JMenuItem Sair;
private javax.swing.JMenu Salvar;
private javax.swing.JMenuItem Treinar;
private javax.swing.JMenu abrir;
private javax.swing.JMenuItem abrirPadroes;
private javax.swing.JMenuItem abrirRede;
private javax.swing.JToolBar barraFerramentas;
private javax.swing.JMenuBar barraMenu;
private javax.swing.JPanel barraStatus;
private javax.swing.JMenuItem codigoC;
private javax.swing.JMenuItem codigoJS;
private javax.swing.JMenuItem codigoJava;
private javax.swing.JMenuItem codigoOP;
private javax.swing.JMenuItem como;
private javax.swing.JButton jBCancelaT;
private javax.swing.JButton jBConfiguraT;
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;

198
private javax.swing.JButton jButton4;
private javax.swing.JButton jButton5;
private javax.swing.JButton jButton6;
private javax.swing.JButton jButton7;
private javax.swing.JButton jButton8;
private javax.swing.JButton jButtonAbrir;
private javax.swing.JButton jButtonCancelar;
private javax.swing.JButton jButtonConfiguracao;
private javax.swing.JButton jButtonConfigurar;
private javax.swing.JButton jButtonNovo;
private javax.swing.JButton jButtonSalvar;
private javax.swing.JButton jButtonTreinar;
private javax.swing.JComboBox jComboBox1;
private javax.swing.JLabel jLErroMax;
private javax.swing.JLabel jLQtdEpocas;
private javax.swing.JLabel jLSituacao;
private javax.swing.JLabel jLStatus;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel10;
private javax.swing.JLabel jLabel12;
private javax.swing.JLabel jLabel13;
private javax.swing.JLabel jLabel14;
private javax.swing.JLabel jLabel15;
private javax.swing.JLabel jLabel17;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JLabel jLabel9;
private javax.swing.JPanel jPanelMenu;
private javax.swing.JPanel jPanelRTreina;
private javax.swing.JPanel jPanelRTreinaInferior;
private javax.swing.JPanel jPanelRTreinaSuperior;
private javax.swing.JPanel jPanelRede;
private javax.swing.JPanel jPanelRedeInterno;
private javax.swing.JPanel jPanelTreina;
private javax.swing.JPanel jPanelVazio;
private javax.swing.JRadioButton jRadioButton1;
private javax.swing.JRadioButton jRadioButton2;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JTextField jTFEpocas;
private javax.swing.JTextField jTFErro;
private javax.swing.JTextField jTFFator;
private javax.swing.JTextField jTFNosEntrada;
private javax.swing.JTextField jTFNosEscondidos;
private javax.swing.JTextField jTFNosSaida;
private javax.swing.JMenu menuAjuda;
private javax.swing.JMenu menuArquivo;
private javax.swing.JMenu menuConfiguraRede;
private javax.swing.JMenu menuRede;
private javax.swing.JPanel painelPrincipal;
private javax.swing.JMenuItem rede;
private javax.swing.JMenu salvarCodigo;
private javax.swing.JMenuItem salvarPesos;
private javax.swing.JMenuItem salvarRede;

199
private javax.swing.JMenuItem sobre;
private javax.swing.JMenuItem treinamento;
// End of variables declaration//GEN-END:variables
public redeNeural.RedeNeural rna;
public redeNeural.TreinaRede treinador;
public java.awt.CardLayout lm;
public boolean leuPadroes = false;
geradoresCodigo.GeradorCodigo geraCodigo;
public Progresso janelaProgresso;
public boolean redeSalva;
}

class Progresso extends javax.swing.JFrame {


private Principal principal;
private javax.swing.JLabel mensagem;
private javax.swing.JProgressBar barraProgresso;
private javax.swing.JPanel setorNorte;
private javax.swing.JPanel setorSul;
private javax.swing.JPanel setorCentro;
private javax.swing.JButton botao;
private Thread processoAtivo;
private String origem;
public Progresso(Principal princ, String titulo, String msg, String
rotuloBotao, String or) {
principal = princ;
origem = or;
java.awt.Dimension screenSize =
java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-280)/2, (screenSize.height-120)/2, 280,
120);
this.setTitle(titulo);
this.setSize(280, 120);
this.setLayout(new java.awt.BorderLayout());
setorNorte = new javax.swing.JPanel();
setorSul = new javax.swing.JPanel();
setorCentro = new javax.swing.JPanel();
mensagem = new javax.swing.JLabel(msg);
botao = new javax.swing.JButton(rotuloBotao);
barraProgresso = new javax.swing.JProgressBar();
barraProgresso.setBounds(5, 5, 15, 50);
this.add(setorNorte, java.awt.BorderLayout.NORTH);
this.add(setorCentro, java.awt.BorderLayout.CENTER);
this.add(setorSul, java.awt.BorderLayout.SOUTH);
setorNorte.add(mensagem);
setorCentro.add(barraProgresso);
setorSul.add(botao);
botao.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
botaoActionPerformed(evt);
}
});
}
public void setRotuloBotao(String rb) {
botao.setText(rb);
}
public void setMensagem(String msg) {
mensagem.setText(msg);
}

200
public void setProcesso(Thread processo) {
processoAtivo = processo;
}
public javax.swing.JProgressBar getBarraProgresso() {
return barraProgresso;
}
public javax.swing.JFrame getFrame() {
return this;
}
public void botaoActionPerformed(java.awt.event.ActionEvent evt) {
if(botao.getText() == "Cancelar") {
processoAtivo.stop();
}
if(botao.getText() == "Fechar") {
if(origem.equals("Ler")) {
principal.completaLeitura();
}
}
if(botao.getText() == "Resultado") {
principal.resultadoTreino();
}
this.dispose();
}
}

class Treino extends Thread {


private redeNeural.TreinaRede treinador;
private redeNeural.RedeNeural rna;
private Progresso jpro;
private Principal principal;
public Treino(Principal princ, redeNeural.RedeNeural r,
redeNeural.TreinaRede tr, Progresso pr) {
rna = r;
treinador = tr;
jpro = pr;
principal = princ;
}
public void run() {
try {
principal.desabilitaSalvarCodigo();

rna.setEstaTreinada(treinador.treinar(jpro.getBarraProgresso()));
jpro.setRotuloBotao("Cancelar");
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(null, "Erro no
treinamento!\n" + e.getMessage(), "Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
jpro.setRotuloBotao("Fechar");
return;
}
if(rna.getEstaTreinada()) {
jpro.setRotuloBotao("Resultado");
jpro.getBarraProgresso().setIndeterminate(false);
jpro.getBarraProgresso().setValue(treinador.getEpocasMaximo());
jpro.setMensagem("Rede treinada com sucesso!");
principal.habilitaSalvarCodigo();
} else if (treinador.getEpocasMaximo() <=
treinador.getQtdEpocasAtual()) {

201
jpro.getBarraProgresso().setIndeterminate(false);
jpro.setMensagem("Não foi possível treinar a rede!");
jpro.setRotuloBotao("Fechar");
}
}
}

class LeArquivo extends Thread {


redeNeural.PadroesTreinamento pt;
manipulacaoArquivos.LeitorPadroes leitor;
redeNeural.RedeNeural rna;
redeNeural.TreinaRede treinador;
Progresso jp;
Principal principal;
boolean compativel = false;

public LeArquivo(Principal pr, redeNeural.RedeNeural r,


redeNeural.TreinaRede tr, Progresso janela, String nomeArquivo) {
leitor = new manipulacaoArquivos.LeitorPadroes(nomeArquivo);
rna = r;
treinador = tr;
jp = janela;
principal = pr;
}

public void run() {


try {
principal.desabilitaTreinar();
jp.getBarraProgresso().setStringPainted(true);
pt = leitor.lerDadosTreinamento(jp.getBarraProgresso());
if(pt.getPadroesEntrada()[0].length == rna.getNosEntrada()) {
if(pt.getPadroesSaida()[0].length == rna.getNosSaida()) {
treinador.setPadroesTreinamento(pt);
compativel = true;
jp.setMensagem("Arquivo lido com sucesso");
jp.setRotuloBotao("Fechar");
}
}
if(!compativel) {
jp.setMensagem("Erro na leitura do arquivo");
jp.setRotuloBotao("Fechar");
javax.swing.JOptionPane.showMessageDialog(null, "Arquivo de
padrões incompatível com a rede configurada. ", "Aviso de Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
} else {
principal.completaLeitura();
}
} catch (Exception e) {
javax.swing.JOptionPane.showMessageDialog(null, "Erro na
leitura do arquivo: " + e.getMessage(), "Aviso de Erro!",
javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
}

202
203