3. Elaine Cecília Gatto
Apostila de Perceptron e Multilayer Perceptron
Elaborada com base nas aulas da disciplina de
Introdução a Redes Neurais Artificiais minis-
trada pelo Professor Doutor Ricardo Cerri e
também nos cursos Online do Professor Dou-
tor Jones Granatyr
Universidade Federal de São Carlos
Departamento de Computação
Programa de Pós-Graduação em Ciência da Computação
São Carlos/SP
Junho de 2018
4. Resumo
A ideia desta apostila surgiu da minha necessidade em aprender de forma mais aprofundada
os conceitos matemáticos envolvidos com o Perceptron e o Multilayer Perceptron. Tive
dificuldades no entendimento básico dessas duas Redes Neurais Artificiais (RNAs) e
também a Linguagem R, que são fundamentais para o entendimento e implementação
das outras RNAs. Devido a essa minha dificuldade, fiz alguns cursos online na UDEMY,
ministrados pelo Professor Doutor Jones, os quais me ajudaram a entender muito melhor
o funcionamento das Redes Neurais e, a partir das minhas anotações feitas em caderno,
tanto das aulas do Professor Doutor Ricardo, quanto desses cursos online, decidi por a
prova o que eu tinha aprendido, organizando meu pensamento, de forma que pudesse
me auto-orientar posteriormente e, até mesmo compartilhar isto com outras pessoas que
tenham também dificuldades como eu tive. Esta apostila é o resultado desses estudos
e apresenta a resolução matemática passo a passo, minuciosamente, sem deixar de fora
nenhum detalhe, é uma verdadeira entrega mastigada e quase digerida do conhecimento,
que me ajudou e espero que ajude outras pessoas. O Capítulo 2 apresenta o Perceptron,
unidade básica de processamento de toda rede neural, e o Capítulo 1 apresenta o Multilayer
Perceptron, que é uma RNA mais complexa e permite aplicação de Deep Learning. A
Teoria não é abordada aqui pois há muito material disponível na Internet (livros, artigos,
etc.), assim sugiro que utilize esta apostila como material de apoio ao seu material teórico.
Dúvidas podem ser encaminhadas ao meu e-mail: elainececiliagatto@gmail.com. Muito
Obrigada e bons estudos.
Palavras-chaves: Redes Neurais Artificiais, Perceptron, Multilayer Perceptron.
9. Lista de abreviaturas e siglas
RNAs Redes Neurais Artificiais
MLP Multi Layer Perceptron
CE Camada de Entrada
CO Camada Oculta
CS Camada de Saída
CE → CO Camada de Entrada PARA a Camada Oculta
CO → CS Camada Oculta PARA a Camada de Saída
CS → CO Camada de Saída PARA a Camada Oculta
CO → CE Camada Oculta PARA a Camada de Entrada
10.
11. Lista de símbolos
i i-ésimo elemento da linha da matriz
j j-ésimo elemento da coluna da matriz
n Número total de entradas
m Momentum
η Taxa de Aprendizagem
k Neurônio
ksi Neurônios da CS
koi Neurônios da CO
x Matriz de Entrada
xeo Matriz de Entrada da CE → CO
xos Matriz de Entrada da CO → CS
w Matriz de Pesos
weo Matriz de Pesos da CE → CO
wos Matriz de Pesos da CO → CS
v Potencial de Ativação
veo Potencial de Ativação da CE → CO
vos Potencial de Ativação da CO → CS
f(v) Função de Ativação
f(veo) Função de Ativação da CE → CO
f(vos) Função de Ativação da CO → CS
y Saída do Neurônio
yeo Saída do Neurônio da CE → CO
yos Saída do Neurônio da CO → CS
12. erro Erro Simples
mediaE Média do Erro Simples
erroQ Erro Quadrático
mediaEQ Média do Erro Quadrático
Delta
s Delta da CS
o Delta da CO
d Derivada da Função de Ativação
ds Derivada da Função de Ativação da CS
do Derivada da Função de Ativação da CO
17. 15
1 Perceptron
1.1 Conceitos
Criador: Rosenbalt
Ano: 1958
Arquitetura: Uma camada de entrada com n atributos e uma camada de saída com
apenas um neurônio. Não há camada oculta.
Tipo de RNA: O Perceptron é uma RNA do Tipo FeedForward.
Paradigma de Aprendizado: O Perceptron é uma RNA que emprega o Aprendizado
Supervisionado.
Algoritmo de Treinamento: O Perceptron faz uso do Algoritmo de Correção e Erro
para o Treinamento.
Modo de Treinamento: Batch ou Online
Tipo de Função de Ativação: Degrau, Sinal, etc.
Tipo de Separação das Classes: Hiperplanos
Problemas que resolve: Linearmente Separáveis e Classificação.
Vantagens: O perceptron pode ser utilizado para resolver diversos problemas que sejam
linearmente separáveis.
Desvantagens: O perceptron não consegue solucionar problemas não linearmente separá-
veis.
Representação Gráfica e Tabular: Apresentada na Figura 1
1.2 Exemplo
Considere os seguintes dados de entrada apresentados na Tabela 1:
Tabela 1 – Dados de Entrada
Exemplo x1 x2 x3 Bias Classe
E1 0 0 1 -1 -1
E2 1 1 0 -1 1
Considere também o seguinte vetor de pesos indicado pela Tabela 2:
18. 16 Capítulo 1. Perceptron
Figura 1 – Representação Gráfica e Tabular do Perceptron
Fonte: Elaborado pela autora
Tabela 2 – Vetor de Pesos Inicial
1 2 3 b
w 0.4 -0.5 0.6 0.5
Calcule o Perceptron considerando os seguintes parâmetros:
• Potencial de Ativação: v = n
i=1(xi ∗ wi)
• Função de Ativação Sinal:
f(v) =
−1, se v ≤ 0
1, se v > 0
• Saída: y = f(v)
• Erro Simples: Erro = Desejado − Obtido
• Erro Quadrático: ErroQ = ErroQ + (Erro ∗ Erro)
• Média do Erro: MediaE = ErroQ/N.o
deLinhas
• Taxa de Aprendizagem: η = 0.4
19. 1.2. Exemplo 17
Figura 2 – Perceptron Exemplo
Fonte: Elaborado pela autora
Figura 3 – 1.a
Época + 1.o
Exemplo
Fonte: Elaborado pela autora
• Atualização dos pesos:
NãoCalculaNovosPesos, se Erro = 0
winovo = wiatual + (η ∗ Erro ∗ xi), se Erro = 0
• Critério de Parada:
Finaliza, se MediaE = 0
Repete, se MediaE = 0
A Representação Gráfica deste Perceptron é apresentada na Figura 2 e a Figura 3
mostra o seu estado atual, com os respectivos valores iniciais de entrada e pesos de E1,
para o início do cálculo.
A. Primeira Época
21. 1.2. Exemplo 19
Figura 4 – 1.a
Época + 2.o
Exemplo
Fonte: Elaborado pela autora
Fim do Cálculo para o Primeiro Exemplo. Novo Vetor de Pesos:
Tabela 3 – Pesos Atualizados: 1.a
Época + 1.o
Exemplo
1 2 3 b
w 0.4 -0.5 -0.2 1.3
A.2 Segundo Exemplo (E2)
A Figura 4 apresenta o estado atual do Perceptron com os novos valores de pesos
e já com os valores de entrada do Segundo Exemplo. Note que os pesos que estão em
vermelho são aqueles que sofreram atualizações no processo de execução do Primeiro
Exemplo.
1.o
Passo: Calcular o Potencial de Ativação
v = (x1 ∗ w1) + (x2 ∗ w2) + (x3 ∗ w3) + (bias ∗ wb)
v = (1 ∗ 0.4) + (0 ∗ (−0.5)) + (0 ∗ (−0.2)) + (−1 ∗ 1.3)
v = (0.4 + 0 + 0 − 1.3) = −0.9
2.o
Passo: Calcular a Função de Ativação
−0.9 > 0 = F
−0.9 = 0 = F
−0.9 < 0 = V
f(v) = f(−0.9) = −1
3.o
Passo: Calcular a Saída
y = f(v) = −1
22. 20 Capítulo 1. Perceptron
4.o
Passo: Calcular o Erro
Erro = Desejado − Obtido = ClasseE2 − y = 1 − (−1) = 2
5.o
Passo: Calcular o Erro Quadrático
ErroQ = ErroQ + (Erro ∗ Erro) = 4 + (2 ∗ 2) = 4 + (4) = 8
6.o
Passo: Calcular a Média do Erro
MediaE = ErroQ/2 = 8/2 = 4
7.o
Passo: Calcular Novos Pesos
w1novo = w1atual + (η ∗ Erro ∗ x1)
w1novo = 0.4 + (0.4 ∗ 2 ∗ 1) = 0.4 + (0.4) = 1.2
w2novo = w2atual + (η ∗ Erro ∗ x2)
w2novo = −0.5 + (0.4 ∗ 2 ∗ 0) = −0.5 + (0) = −0.5
w3novo = w3atual + (η ∗ Erro ∗ x3)
w3novo = −0.2 + (0.4 ∗ 2 ∗ 0) = −0.2 + (0) = −0.2
wbnovo = wbatual + (η ∗ Erro ∗ xb)
wbnovo = 1.3 + (0.4 ∗ 2 ∗ (−1)) = 1.3 + (−0.8) = 0.5
Fim do Cálculo para o Segundo Exemplo. Novo Vetor de Pesos:
Tabela 4 – Pesos Atualizados: 1.a
Época + 2.o
Exemplo
1 2 3 b
w 1.2 -0.5 -0.2 0.5
8.o
Passo: Critério de Parada
MediaE = 0 => 4 = 0 => F
Fim da Primeira Época. A execução do Algoritmo continua. Agora será repetido
todo o cálculo, para os exemplos 1 e 2. A Figura 5 apresenta o estado atual do Perceptron
com os novos valores dos pesos e os valores de entrada de E1. Observe que os pesos que
foram alterados estão na cor vermelha!
23. 1.2. Exemplo 21
Figura 5 – 2.a
Época + 1.o
Exemplo
Fonte: Elaborado pela autora
B. Segunda Época
B.1. Primeiro Exemplo (E1)
1.o
Passo: Calcular o Potencial de Ativação
v = (x1 ∗ w1) + (x2 ∗ w2) + (x3 ∗ w3) + (bias ∗ wb)
v = (0 ∗ 1.2) + (0 ∗ (−0.5)) + (1 ∗ (−0.2)) + (−1 ∗ 0.5)
v = (0 + 0 + −0.2 + (−0.5)) = −0.7
2.o
Passo: Calcular a Função de Ativação
−0.7 > 0 = F
−0.7 ≤ 0 = V
f(v) = f(−0.7) = −1
3.o
Passo: Calcular a Saída
y = f(v) = −1
4.o
Passo: Calcular o Erro
Erro = Desejado − Obtido = ClasseE1 − y = −1 − (−1) = −1 + 1 = 0
5.o
Passo: Calcular o Erro Quadrático
ErroQ = ErroQ + (Erro ∗ Erro) = 0 + (0 ∗ 0) = 0 + (0) = 0
6.o
Passo: Calcular a Média do Erro
MediaE = ErroQ/2 = 0/2 = 0
24. 22 Capítulo 1. Perceptron
Como o Erro é igual a 0 não é necessário calcular novos pesos! Fim do cálculo para
o primeiro exemplo. A Figura 6 apresenta o estado atual do Perceptron com os respectivos
valores de E2 e pesos.
Figura 6 – 2.a
Época + 2.o
Exemplo
Fonte: Elaborado pela autora
B. Segundo Exemplo (E2)
1.o
Passo: Calcular o Potencial de Ativação
v = (x1 ∗ w1) + (x2 ∗ w2) + (x3 ∗ w3) + (bias ∗ wb)
v = (1 ∗ 1.2) + (0 ∗ (−0.5)) + (0 ∗ (−0.2)) + (−1 ∗ 0.5)
v = (1.2 + 0 + 0 + (−0.5)) = 0.7
2.o
Passo: Calcular a Função de Ativação
0.7 > 0 = V
0.7 ≤ 0 = F
f(v) = f(0.7) = 1
3.o
Passo: Calcular a Saída
y = f(v) = 1
4.o
Passo: Calcular o Erro
Erro = Desejado − Obtido = ClasseE2 − y = 1 − 1 = 0
5.o
Passo: Calcular o Erro Quadrático
ErroQ = ErroQ + (Erro ∗ Erro) = 0 + (0 ∗ 0) = 0 + (0) = 0
25. 1.3. Algoritmo 23
6.o
Passo: Calcular a Média do Erro
MediaE = ErroQ/2 = 0/2 = 0
Como o Erro é igual a 0 não é necessário calcular novos pesos, portanto, fim do
cálculo para o segundo exemplo, fim da segunda época, fim do algoritmo e fim do Exemplo.
1.3 Algoritmo
Nesta seção são apresentadas uma versão do Algoritmo do Perceptron em pseudo-
código (Algoritmo 1) e em linguagem R (Listing 1.1, Listing 1.2 e Listing 1.3) de forma
que traduzam os cálculos feitos manualmente na seção 1.2. É importante enfatizar que
na seção 1.2 foi demonstrado passo a passo a execução dos cálculos para o Treinamento
da RNA. Depois disto, a RNA já pode ser usada para teste, isto é, já está pronta para
classificar novos dados, é o que será demonstrado agora. É importante frisar que em Algo-
ritmo 1 DADOS é uma matriz, PESOS e EXEMPLO são vetores! Desejado é a célula da
matriz de entrada que contém a Classe daquele exemplo em particular. Este é o algoritmo
em Pseudocódigo, isto significa que você pode pegar este algoritmo e transportá-lo para
qualquer linguagem e ele funcionará, talvez sejam necessários ajustes por conta da sintaxe
da linguagem, mas a lógica é esta. O código fonte de é um arquivo de script R chamado
Perceptron e o código fonte em é outro script chamado TreinaTestaPerceptron.
Listing 1.1 – Perceptron.R
setwd("caminho da sua pasta")
# TREINO
perceptron2.treino <− function(dados,pesos){
n <− 0.4
erro <− 1
epocas <− 0
nRowsD <− nrow(dados)
tamP <− length(pesos)
while(erro == 1){
cat("nn##############################")
epocas <− epocas + 1
cat("nÉPOCA =", epocas)
erro <− 0
erroQ <− 0
mediaErro <− 0
for(i in 1:nRowsD){
cat("nn")
26. 24 Capítulo 1. Perceptron
Algorithm 1 Perceptron em Pseudocódigo
1: function treinaPerceptron(dados, pesos)
2: n ← 0
3: erro ← 1
4: epocas ← 0
5: tam ← dimensaoV etorPesos
6: nRowsD ← quantidadeTotalDeLinhasDaMatrizDados
7: while (erro == 0) do
8: epocas ← epocas + 1
9: erroQ ← 0
10: mediaE ← 0
11: for i ← 1 to nrows do do
12: v ← 0
13: for j ← 1 to tam do do
14: v ← v + dados[i, j] ∗ pesos[j]
15: end for
16: y ← funcaoSinal(v)
17: erro ← desejado − y
18: erroQ ← erroQ + (erro ∗ erro)
19: if (desejado = y) then
20: erro ← 1
21: for j ← 1 to tam do do
22: pesos[j] ← pesos[j] + (n ∗ (desejado − y) ∗ dados[i, j])
23: end for
24: end if
25: end for
26: mediaE ← erroQ/nRowsD
27: end while
28: return pesos
29: end function
30: function testaPerceptron(exemplo, pesos)
31: v ← 0
32: for i ← 1 to tamanhoDoExemplo do do
33: v ← v + (exemplo[i] ∗ pesos[i])
34: end for
35: y ← funcaoSinal(v)
36: return y
37: end function
27. 1.3. Algoritmo 25
cat("nEXEMPLO = ", i)
v <− 0
for(j in 1:tamP){
v <− v + dados[i,j]∗pesos[j]
}
y <− sign(v)
erro <− dados[i,4] − y
erroQ <− erroQ + (erro) ∗ (erro)
cat("n Erro Quadrático = ", erroQ)
if (dados[i ,4] != y){
erro <− 1
for(j in 1:length(pesos)){
pesos[j ] <− pesos[j] + (n∗(dados[i,4]−y)∗
dados[i,j ])
}
}
}
mediaErro <− mediaErro/nrow(dados)
cat("nnMédia do Erro Quadrático = ", mediaErro)
}
cat("nnFinalizado com ",epocas," épocasnn")
return(pesos)
}
# TESTE
perceptron2 <− function(exemplo,pesos){
cat("nn=====================================")
cat("nTESTE!")
v <− 0
for(i in 1:length(exemplo)){
v <− v + exemplo[i]∗pesos[i]
}
y <− sign(v)
cat("nn")
return(y)
}
Listing 1.2 – TreinaTestaPerceptron.R
setwd("caminho da sua pasta")
28. 26 Capítulo 1. Perceptron
source(’Perceptron.R’)
# Conjunto de dados artificial
x1 <− c (4,2,5,3,1.5,2.5,4,5,1.5,3,5,4)
x2 <− c (5,4.5,4.5,4,3,3,3,3,1.5,2,1.5,1)
bias <− c (1,1,1,1,1,1,1,1,1,1,1,1)
classe <− c(1,−1,1,1,−1,−1,1,1,−1,−1,1,−1)
dados <− data.frame(x1,x2,bias,classe)
dados
# i = linha
# j = coluna
dados[1,4]
dados[2,4]
dados[3,4]
dados[4,4]
nrow(dados)
ncol(dados)
# Pesos iniciais gerados aleatoriamente
pesos <− runif(3,−1,1)
pesos <− t(pesos)
length(pesos)
novos.pesos <− perceptron2.treino(dados,pesos)
# Plot dos dados
cores <− dados$classe
cores[cores==−1] <− 2
plot(x1,x2,col=cores,pch=ifelse(dados$classe>0,"+","−"),cex=2,lwd=2)
# Hiperplano
intercept <− − novos.pesos[3] / novos.pesos[2]
slope <− − novos.pesos[1] / novos.pesos[2]
abline(intercept ,slope,col="green")
# Classifica novos dados
perceptron2(c(2,2,1) ,novos.pesos)
perceptron2(c(4,4,1) ,novos.pesos)
29. 1.3. Algoritmo 27
Na Listing 1.2 o Algoritmo termina o treinamento após 12 épocas. Com essas
mesmas listagens de códigos fontes é possível fazer o treinamento e teste, de forma
adaptada, do banco de dados Iris, conforme apresenta a Listing 1.3
Listing 1.3 – PerceptronIris.R
setwd("caminho da sua pasta")
source(’Perceptron.R’)
# Definindo o uso do banco de dados iris
data( iris )
# dimensão (linhas x colunas)
dim(iris)
# nomes das colunas
names(iris)
# sumário das classes
summary(iris$Species)
# Vê como os atributos separam os dados
pairs( iris [,1:4], col=iris$Species)
# Pega Sepal Width e Petal Width
x <− cbind(iris$Sepal.Width,iris$Petal.Width)
x
# Rouula Setosa como positivo e o resto como negativo
y <− ifelse( iris$Species == "setosa", +1, −1)
y
# Bias
bias <− rep(1,nrow(x))
bias
x <− cbind(x,bias)
x
# Classes
30. 28 Capítulo 1. Perceptron
x <− cbind(x,y)
x
# Pesos iniciais gerados aleatoriamente
pesos <− runif(3,−1,1)
pesos
pesos <− t(pesos)
pesos
# Treina o perceptron
pesos. iris <− perceptron2.treino(x,pesos)
# Plota os dados
plot(x,cex=0.2)
points(subset(x,y==1),col="black",pch="+",cex=2)
points(subset(x,y==−1),col="red",pch="−",cex=2)
# Hiperplano
intercept <− − pesos.iris[3] / pesos. iris [2]
slope <− − pesos.iris[1] / pesos. iris [2]
abline(intercept ,slope,col="green")
# Classifica novos dados
perceptron2(c (2.5,0.3,1) ,pesos. iris )
perceptron2(c (2.5,0.5,1) ,pesos. iris )
A função de ativação utilizada no Exemplo demonstrado em 1.2 pode ser substi-
tuída por outras, conforme o problema a ser resolvido. Apenas a título de curiosidade,
reimplemente os códigos aqui apresentados para resolver os problemas das portas lógicas
AND, OR, NAND, NOR e NOT. Faça também a resolução manual para conferir os
resultados, os pesos podem começar com 0.0 (ou 0.5) e a taxa de aprendizagem como 1 ou
0.5. Boa Sorte.
31. 29
2 Multilayer Perceptron
2.1 Conceitos
Criadores: Rumelhart, Hinton e Williams
Ano: Década de 80
Arquitetura: Uma camada de entrada (CE) com n atributos, uma ou mais camadas
ocultas (CO) com um ou mais neurônios em cada uma delas e, por fim, uma camada de
saída (CS) com um ou mais neurônios, conforme o problema a ser modelado.
Tipo de R.N.A.: Recorrente ou Retroalimentação
Paradigma de Aprendizado: Supervisionado
Algoritmo de Treinamento: BackPropagation (Gradiente Descendente)
Modo de Treinamento: Batch ou Online
Tipo de Função de Ativação: Sigmoidal, Tangente Hiperbólica, etc.
Tipo de Separação das Classes: Hiperplanos
Problemas que resolve: Não Linearmente Separáveis, Classificação e Regressão
Representação Gráfica: A Figura 7 apresenta um exemplo de Arquitetura de RNA,
com uma camada de entrada com vários atributos de entrada, duas camadas escondidas
com vários neurônios cada, e uma camada de saída também com vários neurônios.
2.2 Exemplo
A porta lógica XOR será utilizada como exemplo para demonstração de resolução
passo a passo do MLP. A Figura 8 apresenta a arquitetura definida para a resolução deste
problema. A Rede Neural é composta por uma camada de entrada (CE) com três entradas
(Bias, x1 e x2), uma camada oculta (CO) com quatro neurônios (Bias, k1, k2 e k3) e
uma camada de saída (CS) com apenas um neurônio (ky). A Tabela 5 apresenta a Porta
Lógica XOR que tem a saída igual a 1 quando as entradas são diferentes e a saída igual a 0
quando as entradas são iguais. Conforme o desenvolvimento do exercicio vai ocorrendo, as
tabelas e imagens serão apresentadas com seu estado atual para facilitar o entendimento.
Considere os seguintes parâmetros para o MLP especificamente para o problema
XOR. Praticamente todas as equações são utilizadas aqui para o MLP em geral, apenas
enfatizei algumas coisas relativas ao XOR para facilitar o entendimento.
32. 30 Capítulo 2. MLP
Figura 7 – Representação Gráfica do MLP
Figura 8 – Arquitetura do MLP para o XOR
Tabela 5 – Porta Lógica XOR
x1 x2 S
0 0 0
0 1 1
1 0 1
1 1 0
33. 2.2. Exemplo 31
A Equação 2.1 é usada para calcular o potencial de ativação, onde xi1 = bias
vij = (xij ∗ wij) + (xij ∗ wij) + ... + (xnn ∗ wnn) (2.1)
A Equação 2.2 é usada para calcular a função de ativação
f(vij) =
1
1 + e−vij
(2.2)
A Equação 2.3 é usada para calcular a saída
yij = f(vij) (2.3)
A Equação 2.4 é usada para calcular o erro simples, onde xi4 = classe
erroi = xi4 − yij (2.4)
A Equação 2.5 é usada para calcular a média do erro simples
mediaE =
(erro1 + erro2 + ... + erron)
n
(2.5)
A Equação 2.6 é usada para calcular o erro quadrático
erroQi = erroQi + (erroi ∗ erroi) (2.6)
A Equação 2.7 é usada para calcular a média do erro quadrático
mediaEQ =
(erroQ1 + erroQ2 + ... + erroQn)
n
(2.7)
A Equação 2.8 é usada para calcular a derivada da função de ativação
dij = (yij ∗ (1 − yij)) (2.8)
A Equação 2.9 é usada para calcular o delta da camada de saída
sij = erroi ∗ dij (2.9)
A Equação 2.10 é usada para calcular o delta da camada oculta
oij = dij ∗ wsij ∗ sij (2.10)
A Equação 2.11 e a Equação 2.12 são usadas para calcular novos pesos da camada
de saída para a camada oculta
kij = (yij ∗ sij) + (yij ∗ sij) + ... + ynn ∗ snn) (2.11)
34. 32 Capítulo 2. MLP
wijNovo = (wijAtual ∗ m) + (kij ∗ η) (2.12)
A Equação 2.13 e a Equação 2.14 são usadas para calcular novos pesos da camada
oculta para a camada de entrada
xij = (xij ∗ oij) + (xij ∗ oij) + ... + (xnn ∗ onn) (2.13)
wijNovo = (wijAtual ∗ m) + (xij ∗ η) (2.14)
O momentum é igual a 1 (m = 1) e a taxa de aprendizado é igual a 0.3 (η = 0.3)
A. Cálculo da CE → CO
A.1. Primeiro Exemplo
Dados de Entrada: xeo
Bias x1 x2
E1 1 0 0
E2 1 0 1
E3 1 1 0
E4 1 1 1
Pesos da CE → CO: weo
K1 K2 K3
Bias 0.896 -0.424 0.258
X1 -0.422 -0.740 -0.577
X2 -0.082 -0.961 -0.469
1.o
Passo: Calcular o Potencial de Ativação
veo11 = (xeo11 ∗ weo11) + (xeo12 ∗ weo21) + (xeo13 ∗ weo31)
= (1 ∗ 0.896) + (0 ∗ (−0.424)) + (0 ∗ 0.358) = (0.896 + 0 + 0) = 0.896
veo12 = (xeo11 ∗ weo12) + (xeo12 ∗ weo22) + (xeo13 ∗ weo32) =
= (1 ∗ (−0.422)) + (0 ∗ (−0.740)) + (0 ∗ (−0.577)) = (−0.422 + 0 + 0) = −0.422
veo13 = (xeo11 ∗ weo13) + (xeo12 ∗ weo23) + (xeo13 ∗ weo33)
= (1 ∗ (−0.082)) + (0 ∗ (−0.961)) + (0 ∗ (−0.469)) = (−0.082 + 0 + 0) = −0.082
2.o
Passo: Calcular a Função de Ativação
f(veo11) = f(0.986) =
1
1 + e−veo11
=
1
1 + e−0.986
=
1
1 + 0.373
=
1
1.373
= 0.7283
f(veo12) = f(−0.422) =
1
1 + e−veo12
=
1
1 + e−(−0.422)
=
1
1 + 1.5250
=
1
2.5250
= 0.3960
f(veo13) = f(−0.082) =
1
1 + e−veo13
=
1
1 + e−(−0.082)
=
1
1 + 1.0854
=
1
2.0854
= 0.4795
37. 2.2. Exemplo 35
1.o
Passo: Calcular o Potencial de Ativação
veo41 = (xeo41 ∗ weo11) + (xeo42 ∗ weo21) + (xeo43 ∗ weo31)
= (1 ∗ 0.896) + (1 ∗ (−0.424)) + (1 ∗ 0.358)
= (0.896 + (−0.424) + 0.358) = 0.83
veo42 = (xeo41 ∗ weo12) + (xeo42 ∗ weo22) + (xeo43 ∗ weo32)
= (1 ∗ (−0.422)) + (1 ∗ (−0.740)) + (1 ∗ (−0.577))
= (−0.422 + (−0.740) + (−0.577)) = −1.739
veo43 = (xeo41 ∗ weo13) + (xeo42 ∗ weo23) + (xeo43 ∗ weo33)
= (1 ∗ (−0.082)) + (1 ∗ (−0.961)) + (1 ∗ (−0.469))
= (−0.082 + (−0.961) + (−0.469))) = −1.512
2.o
Passo: Calcular a Função de Ativação
f(veo41) = f(0.83) =
1
1 + e−veo41
=
1
1 + e−0.83
=
1
1 + 0.4360
=
1
1.4360
= 0.696
f(veo42) = f(−1.739) =
1
1 + e−veo42
=
1
1 + e−(−1.739)
=
1
1 + 5.6916
=
1
6.6916
= 0.1756
f(veo43) = f(−1.512) =
1
1 + e−veo43
=
1
1 + e−(−1.512)
=
1
1 + 4.5357
=
1
5.5357
= 0.1806
3.o
Passo: Calcular a Saída
yeo41 = f(veo41) = 0.696
yeo42 = f(veo42) = 0.1756
yeo43 = f(veo43) = 0.1806
Fim do Cálculo da CE → CO. A Tabela 6 mostra os resultados obtidos para o
Potencial de Ativação veo e a Tabela 7 para a Função de Ativação que é consequentemente
a saída yeo = f(veo). A Figura 9 apresenta os estados do MLP após o cálculo de cada
exemplo.
38. 36 Capítulo 2. MLP
Figura 9 – MLP XOR CE → CO
(a) E1 (b) E2
(c) E3 (d) E4
Tabela 6 – Matriz Potencial de Ativação
CE → CO: veo
veo1 veo2 veo3
E1 0.896 -0.422 -0.082
E2 1.254 -0.999 -0.551
E3 0.742 -1.162 -1.043
E4 0.830 -1.739 -1.512
Tabela 7 – Matriz Função de Ativação
CE → CO: yeo = f(veo)
yeo1 yeo2 yeo3
E1 0.7283 0.3960 0.4795
E2 0.7780 0.2665 0.3656
E3 0.6774 0.2383 0.2605
E4 0.6960 0.1756 0.1806
B. Cálculo da CO → CS
A Matriz de Entrada agora é a Matriz apresentada na Tabela 7 porém adicionada
do Bias, conforme mostra a Tabela 8 e a Tabela 9 apresenta os pesos para o cálculo da
CO → CS.
50. 48 Capítulo 2. MLP
Tabela 20 – Pesos da CE → CO atualizados
weo
K1 K2 K3
Bias 0.884918 -0.41938 0.351597
X1 -0.43127 -0.73427 -0.57187
X2 -0.09091 -0.1222 -0.4176
H. Critério de Parada
Enquanto o Erro Quadrático for maior que duas vezes o limiar, normalmente 1e-3,
então continua a executar o algoritmo até alcançar valores de pesos estáveis.
FIM DO ALGORITMO
I. Resumo
1. Cálculo da CE → CO
a) Potencial de Ativação
b) Função de Ativação
c) Saída
2. Cálculo da CO → CS
a) Potencial de Ativação
b) Função de Ativação
c) Saída
3. Cálculo do Erro
a) Erro Simples
b) Média do Erro Simples
c) Erro Quadrático
d) Média do Erro Quadrático
4. Cálculo da CS
a) Derivada da Função de Ativação da CO → CS
b) Cálculo do s
5. Cálculo da CO
51. 2.2. Exemplo 49
a) Derivada da Função de Ativação da CE → CO
b) Cálculo do o
6. Cálculo da CS → CO
a) Calcular novas entradas
b) Calcular novos pesos
7. Cálculo da CO → CE
a) Calcular novas entradas
b) Calcular novos pesos
8. Critério de Parada
VERSÃO MATRICIAL
CE → CO:
Entradas Pesos
BIAS X2 ... XN K1 K2 ... KN
E1 xeo11 xeo12 ... xeo1n BIAS weo11 weo12 ... weo1n
E2 xeo21 xeo22 ... xeo2n X2 weo21 weo22 ... weo2n
... ... ... ... ... ... ... ... ... ...
EN xeon1 xeon2 ... xeonn
*
XN weon1 weon2 ... weonn
=
Potencial de Ativação
K1 K2 ... KN
E1 veo11 veo12 ... veo1n
E2 veo21 veo22 ... veo2n
... ... ... ... ...
EN veon1 veon2 ... veonn
Potencial de Ativação Função de Ativação
K1 K2 ... KN K1 K2 ... KN
E1 veo11 veo12 ... veo1n E1 f(veo11) f(veo12) ... f(veo1n)
E2 veo21 veo22 ... veo2n E2 f(veo21) f(veo22) ... f(veo2n)
... ... ... ... ... ... ... ... ... ...
EN veon1 veon2 ... veonn
=
EN f(veon1) f(veon2) ... f(veonn)
=
Saída dos Neurônios
K1 K2 ... KN
E1 yeo11 yeo12 ... yeo1n
E2 yeo21 yeo22 ... yeo2n
... ... ... ... ...
EN yeon1 yeon2 ... yeonn
55. 2.3. Algoritmo 53
Pesos Novas Entradas
K1 K2 ... KN BIAS E1 ... EN
BIAS xeo11 xeo11 ... xeo1n E1 xoe11 xoe11 ... xoe1n
K1 xeo21 xeo21 ... xeo2n E2 xoe21 xoe21 ... xoe2n
... ... ... ... ... ... ... ... ... ...
EN xeon1 xeon1 ... xeonn
* m +
EN xoen1 xoen1 ... xoenn
* n =
Novos Pesos
K1 K2 ... K3
BIAS weo11 weo11 ... weo1n
K1 weo21 weo21 ... weo2n
... ... ... ... ...
KN weon1 weon1 ... weonn
2.3 Algoritmo
Esta seção apresentará a implementação em R. Os comentários já explicam o código.
Vale ressaltar que o algoritmo demorará um tempo para executar, normalmente esses
algoritmos são assim mesmo, portanto, tenha paciência. A Listing 2.1 mostra como treinar
MLP, a Listing 2.2 como testar e, a Listing 2.3 como classificar novos dados. O arquivo
datasetTreino.txt contém os valores da porta lógica XOR para 22
variáveis e, o arquivo
datasetTeste.txt contém os valores da porta lógica XOR para 23
variáveis.
Listing 2.1 – MultilayerPerceptron.R
setwd("local da sua pasta")
# ESTE ALGORITMO FUNCIONA PARA APENAS UMA SAÍDA AO FINAL DA
REDE
# Funcao de ativacao
mlp.funcao.ativacao = function(v){
y = 1 / (1 + exp(−v))
return(y)
}
# Derivada da funcao de ativacao
mlp.derivada.funcao.ativacao = function(y){
d = y ∗ (1 − y)
return(d)
}
# Arquitetura
56. 54 Capítulo 2. MLP
# numero de neuronios na entrada
# numero de neuronios na escondida
# numero de neuronios na saida
# funcao ativação
# derivada da funcao ativacao
mlp.arquitetura = function(num.entrada, num.oculta, num.saida, funcao.ativacao,
derivada.funcao.ativacao){
# Propriedades da rede
arq = list ()
arq$num.entrada = num.entrada
arq$num.oculta = num.oculta
arq$num.saida = num.saida
arq$funcao.ativacao = mlp.funcao.ativacao
arq$derivada.funcao.ativacao = mlp.derivada.funcao.ativacao
# Definindo o Bias
bias = 1
# Pesos conectando a Camada de Entrada com a Camada Oculta.
num.pesos.entrada.oculta = (num.entrada + bias) ∗ num.oculta
# Gerando os pesos de forma aleatória
# O número de linhas éo número de neurônios na Camada Oculta
# O número de colunas éo número de entradas na Camada de Entrada mais o
Bias
arq$oculta = matrix(runif(min=−0.5,max=0.5, num.pesos.entrada.oculta),
nrow = num.oculta, ncol = num.entrada + bias)
# Número de Pesos conectando a Camada Oculta com a Camada de Saída
num.pesos.oculta.saida = (num.oculta + bias) ∗ num.saida
# Gerando os pesos de forma aleatória
# O número de linhas éo número de neurônios na Camada de Saída
# O número de colunas éo número de neurônios na Camada Oculta mais o
Bias
arq$saida = matrix(runif(min=−0.5,max=0.5,num.pesos.oculta.saida), nrow =
num.saida, ncol = num.oculta + bias)
57. 2.3. Algoritmo 55
return(arq)
}
# Fase de Propagacao − FEEDFOWARD
# arq é a arquitetura da rede configurada
# exemplo éo exemplo do conjunto de dados a ser processado
# %∗% operador do R para multiplicar matrizes
mlp.propagacao = function(arq, exemplo){
# 1. CE −> CO
# 1.a. Potencial de Ativação
v.entrada.oculta = arq$oculta %∗% as.numeric(c(exemplo, 1))
# 1.b Função de Ativação e 1.c. Saída
y.entrada.oculta = arq$funcao.ativacao(v.entrada.oculta)
# 2. CO −> CS
# 2.a Potencial de Ativação
v.oculta.saida = arq$saida %∗% c(y.entrada.oculta, 1)
# 2.b Função de Ativação e 2.c Saída
y.oculta.saida = arq$funcao.ativacao(v.oculta.saida)
# Resultados
resultados = list ()
resultados$v.entrada.oculta = v.entrada.oculta
resultados$y.entrada.oculta = y.entrada.oculta
resultados$v.oculta.saida = v.oculta.saida
resultados$y.oculta.saida = y.oculta.saida
return(resultados)
}
# Fase de Retropropagação − BACKPROPAGATION
mlp.retropropagacao = function(arq, dados, n, limiar){
# Condição de Parada
erroQuadratico <− (2 ∗ limiar)
58. 56 Capítulo 2. MLP
# Conta quantas vezes executou o algoritmo
epocas <− 0
# Treina a RNA enquanto o erroQuadratico for menor que o limiar
while(erroQuadratico > limiar){
erroQuadratico <− 0
# Treina para todos os exemplos
for(i in 1:nrow(dados)){
# Pegando um exemplo de entrada
x.entrada <− dados[i, 1:arq$num.entrada]
# Classe do exemplo
x.saida = dados[i, ncol(dados)]
# Calcula o FEED FORWARD
resultado <− mlp.propagacao(arq, x.entrada)
# Saída do Neurônio
y <− resultado$y.oculta.saida
# 3. Calculando o Erro
# 3.a. Calculando o Erro Simples
erro <− x.saida − y
# 3.c. Calculando o Erro Quadrático
erroQuadratico = erroQuadratico + (erro ∗ erro)
# 4. Cálculo da Camada de Saída
# 4.a. e 4.b
delta.saida <− erro ∗ arq$derivada.funcao.ativacao(y)
# 5. Cálculo da Camada Oculta
# 5.a. e 5.b
pesos.saida <− arq$saida[,1:arq$num.oculta]
delta.oculta <− as.numeric(arq$derivada.funcao.ativacao(
resultado$y.entrada.oculta)) ∗ (delta.saida %∗% pesos.
59. 2.3. Algoritmo 57
saida)
# 6. Cálculo da Camada de Saída para a Camada Oculta
# 6.a e 6.b
arq$saida <− arq$saida + n ∗ (delta.saida %∗% c(resultado$y.
entrada.oculta,1))
# 7. Cálculo da Camada Camada Oculta para a Camada de
Entrada
# 7.a e 7.b
arq$oculta <− arq$oculta + n ∗ (t(delta.oculta) %∗% as.
numeric(c(x.entrada,1)))
}
# 3.b
mediaE <− erro / nrow(dados)
# Critério de parada
erroQuadratico <− erroQuadratico / nrow(dados)
cat("Erro Quadratico Medio = ",erroQuadratico, "n")
# contador
epocas <− epocas + 1
}
retorno = list ()
retorno$arq = arq
retorno$epocas = epocas
return(retorno)
}
Listing 2.2 – TreinaMLP.R
setwd("caminho da sua pasta")
source(’mlp.R’)
# Lendo os dados do XOR
treino = read.table(’dataset_treino.txt’)
treino
60. 58 Capítulo 2. MLP
# Configurando a Arquitetura da Rede
mlp.arq <− mlp.arquitetura(2,3,1, funcao.ativacao, derivada.funcao.ativacao)
mlp.arq
modelo <− mlp.retropropagacao(mlp.arq, treino, 0.3, 1e−2)
modelo
Listing 2.3 – TestaMLP.R
setwd("caminho da sua pasta")
source(’mlp.R’)
# Testa com novos dados
teste = read.table(’dataset_teste.txt’)
teste
mlp.arq <− mlp.arquitetura(3,4,1, funcao.ativacao, derivada.funcao.ativacao)
mlp.arq
modelo <− mlp.retropropagacao(mlp.arq, teste, 0.3, 1e−2)
modelo
A Figura 11 apresenta uma arquitetura sugerida para o problema da base de dados
IRIS. A base de dados Iris tem 4 atributos de entrada, 150 exemplos (150 linhas) e três
atributos de saída (virginica, setosa, versicolor), assim, a arquitetura sugere 5 entradas,
sendo 4 para o IRIS (x1, x2, x3 e x4) e 1 para o BIAS, 4 neurônios na camada oculta,
sendo 3 normais e 1 para o BIAS, e obrigatoriamente três neurônios na saída. O código
MLP apresentado anteriormente não funcionará para problemas que precisem de mais de
um neurônio na saída, assim, será necessário modificá-lo, ou adicionando mais neurônios
na implementação, ou fazendo uma codificação diferenciada no único neurônio de saída. O
ideal é que as saídas sejam correspondentes ao problema a ser resolvido. Depois de fazer as
modificações necessárias no código, você deve dividir a sua base de dados IRIS em teste e
treino, e isso pode ser feito de várias formas. A Listing 2.4 apresenta uma forma, dividindo
o conjunto em vários conjuntos diferentes, e a Listing 2.5 mostra outra forma, dividindo a
base em oitenta porcento para treino e o restante para teste.
Listing 2.4 – TestaMLP.R
Dados <− iris
Dados
61. 2.3. Algoritmo 59
Figura 11 – Arquitetura sugerida MLP-IRIS
Dados[,1:4] <− scale(Dados[,1:4])
Dados
Dados <− Dados[sample(nrow(Dados)),]
Dados
treino <− createDataPartition(Dados$Species, p=.8, list = FALSE, times = 1)
treino
ncol(treino)
nrow(treino)
irisTreino <− Dados[treino,]
irisTreino
ncol( irisTreino )
nrow(irisTreino)
irisTeste <− Dados[−treino,]
irisTeste
ncol( irisTeste )
nrow(irisTeste)
62. 60 Capítulo 2. MLP
Arquitetura <− Arquitetura(4,3,3,fa,dfa)
Arquitetura
treina <− BackPropagation(Arquitetura, irisTreino, 0.5, 1e−2)
treina
testa <− BackPropagation(Arquitetura, irisTeste, 0.5, 1e−2)
testa
Listing 2.5 – TestaMLP.R
#Lê o dataset iris
dados = iris
#Normaliza os dados
dados[,1:4]=scale(dados [,1:4])
#Randomiza os dados
dados=dados[sample(nrow(dados)),]
#Cria os k−folds com k = 10
num.folds = 10
folds <− createFolds(dados$Species, k = num.folds)
Arquitetura <− Arquitetura(4,3,3,fa,dfa)
Arquitetura
#Classifica os k folds
for(i in 1:num.folds){
treino = dados[unlist(folds [ setdiff (c(1:10) , i)]) ,]
teste = dados[folds[[ i ]],]
mlp.algoritmo = BackPropagation(Arquitetura, treino, 0.5, 1e−2)
cat(paste("Treinou MLP Fold",i,"n",sep=" "))
teste . reais = c(teste. reais , teste [, ncol(teste)])
}