Abrir menu principal
Question book.svg
Este artigo ou secção não cita fontes confiáveis e independentes (desde maio de 2010). Ajude a inserir referências.
O conteúdo não verificável pode ser removido.—Encontre fontes: Google (notícias, livros e acadêmico)

O perceptron é um tipo de rede neural artificial inventada em 1957 por Frank Rosenblatt no Cornell Aeronautical Laboratory. Ele pode ser visto como o tipo mais simples de rede neural feedforward: um classificador linear.

Índice

DefiniçãoEditar

O perceptron é um classificador binário que mapeia sua entrada   (um vetor de valor real) para um valor de saída   (uma valor binário simples) através da matriz.

 

Onde   é um vetor de peso real e   é o produto escalar (que computa uma soma com pesos) e   é o viés (do inglês "bias"), um termo constante que não depende de qualquer valor de entrada.


Implementação em PythonEditar

'''
	Este projeto esta disponivel no GiHub de Marcos castro de Sousa
	Implementação da rede neural Perceptron
	w = w + N * (d(k) - y) * x(k)
'''

import random, copy

class Perceptron:

	def __init__(self, amostras, saidas, taxa_aprendizado=0.1, epocas=1000, limiar=-1):

		self.amostras = amostras # todas as amostras
		self.saidas = saidas # saídas respectivas de cada amostra
		self.taxa_aprendizado = taxa_aprendizado # taxa de aprendizado (entre 0 e 1)
		self.epocas = epocas # número de épocas
		self.limiar = limiar # limiar
		self.num_amostras = len(amostras) # quantidade de amostras
		self.num_amostra = len(amostras[0]) # quantidade de elementos por amostra
		self.pesos = [] # vetor de pesos


	# função para treinar a rede
	def treinar(self):
		
		# adiciona -1 para cada uma das amostras
		for amostra in self.amostras:
			amostra.insert(0, -1)

		# inicia o vetor de pesos com valores aleatórios
		for i in range(self.num_amostra):
			self.pesos.append(random.random())

		# insere o limiar no vetor de pesos
		self.pesos.insert(0, self.limiar)

		# inicia o contador de epocas
		num_epocas = 0

		while True:

			erro = False # o erro inicialmente inexiste

			# para todas as amostras de treinamento
			for i in range(self.num_amostras):

				u = 0

				'''
					realiza o somatório, o limite (self.amostra + 1)
					é porque foi inserido o -1 para cada amostra
				'''
				for j in range(self.num_amostra + 1):
					u += self.pesos[j] * self.amostras[i][j]

				# obtém a saída da rede utilizando a função de ativação
				y = self.sinal(u)

				# verifica se a saída da rede é diferente da saída desejada
				if y != self.saidas[i]:

					# calcula o erro: subtração entre a saída desejada e a saída da rede
					erro_aux = self.saidas[i] - y

					# faz o ajuste dos pesos para cada elemento da amostra
					for j in range(self.num_amostra + 1):
						self.pesos[j] = self.pesos[j] + self.taxa_aprendizado * erro_aux * self.amostras[i][j]

					erro = True # ainda existe erro

			# incrementa o número de épocas
			num_epocas += 1

			# critério de parada é pelo número de épocas ou se não existir erro
			if num_epocas > self.epocas or not erro:
				break


	# função utilizada para testar a rede
	# recebe uma amostra a ser classificada e os nomes das classes
	# utiliza a função sinal, se é -1 então é classe1, senão é classe2
	def testar(self, amostra, classe1, classe2):

		# insere o -1
		amostra.insert(0, -1)

		# utiliza o vetor de pesos que foi ajustado na fase de treinamento
		u = 0
		for i in range(self.num_amostra + 1):
			u += self.pesos[i] * amostra[i]

		# calcula a saída da rede
		y = self.sinal(u)

		# verifica a qual classe pertence
		if y == -1:
			print('A amostra pertence a classe %s' % classe1)
		else:
			print('A amostra pertence a classe %s' % classe2)


	# função de ativação: degrau bipolar (sinal)
	def sinal(self, u):
		return 1 if u >= 0 else -1


print('\nA ou B?\n')

# amostras: um total de 4 amostras
amostras = [[0.1, 0.4, 0.7], [0.3, 0.7, 0.2], 
				[0.6, 0.9, 0.8], [0.5, 0.7, 0.1]]

# saídas desejadas de cada amostra
saidas = [1, -1, -1, 1]

# conjunto de amostras de testes
testes = copy.deepcopy(amostras)

# cria uma rede Perceptron
rede = Perceptron(amostras=amostras, saidas=saidas,	
						taxa_aprendizado=0.1, epocas=1000)

# treina a rede
rede.treinar()

# testando a rede
for teste in testes:
	rede.testar(teste, 'A', 'B')

Implementação em C#Editar

  1  
  2 using System;
  3 using System.Linq;
  4 
  5 namespace perceptron
  6 {
  7     public class Perceptron
  8     {
  9         static readonly double[] w = new double[3];
 10         private readonly int[,] _matrizAprendizado = new int[4, 3];
 11         private double _net;
 12 
 13         Perceptron()
 14         {
 15              //tabela AND
 16             _matrizAprendizado[0, 0] = 0;
 17             _matrizAprendizado[0, 1] = 0;
 18             _matrizAprendizado[0, 2] = 0;
 19 
 20             _matrizAprendizado[1, 0] = 0;
 21             _matrizAprendizado[1, 1] = 1;
 22             _matrizAprendizado[1, 2] = 0;
 23 
 24             _matrizAprendizado[2, 0] = 1;
 25             _matrizAprendizado[2, 1] = 0;
 26             _matrizAprendizado[2, 2] = 0;
 27 
 28             _matrizAprendizado[3, 0] = 1;
 29             _matrizAprendizado[3, 1] = 1;
 30             _matrizAprendizado[3, 2] = 1;
 31 
 32             w[0] = 0;
 33             w[1] = 0;
 34             w[2] = 0;
 35         }
 36 
 37         public static void Main(string[] args)
 38         {
 39             //pesos antes do treinamento
 40             w.ToList().ForEach(x => Console.WriteLine(x + ","));
 41 
 42             Console.WriteLine("\n");
 43 
 44             //efetua-se o treinamento da rede
 45             new Perceptron().Treinar();
 46 
 47             Console.WriteLine("\n");
 48 
 49             //pesos ajustados após treinamento
 50             w.ToList().ForEach(x => Console.WriteLine(x + ","));
 51 
 52             //dados de entrada para rede treinada, 0 e 0 resulta em 0 (tabela and) -1 corresponde ao BIAS
 53 
 54             int[] amostra1 = { 0, 1, -1 }; // 0 e 1 -> 0 Classe B
 55             int[] amostra2 = { 1, 0, -1 }; // 1 e 0 -> 0 Classe B
 56             int[] amostra3 = { 0, 0, -1 }; // 0 e 0 -> 0 Classe B
 57             int[] amostra4 = { 1, 1, -1 }; // 1 e 1 -> 1 Classe A
 58 
 59 
 60             ClassificarAmostra(amostra1);
 61             ClassificarAmostra(amostra2);
 62             ClassificarAmostra(amostra3);
 63             ClassificarAmostra(amostra4);
 64 
 65             Console.ReadKey();
 66         }
 67 
 68         public static void ClassificarAmostra(int[] amostra)
 69         {
 70             //pesos encontrados após o treinamento
 71             int[] pesos = { 2, 1, 3 };
 72 
 73             //aplicação da separação dos dados linearmente após aprendizado
 74             var u = amostra.Select((t, k) => pesos[k] * t).Sum();
 75 
 76             var y = LimiarAtivacao(u);
 77 
 78             Console.WriteLine(y > 0 ? "Amostra da classe A >= 0" : "HelloWorld < 0");
 79         }
 80 
 81         private static int LimiarAtivacao(double u)
 82         {
 83             return (u >= 0) ? 1 : 0;
 84         }
 85 
 86         int Executar(int x1, int x2)
 87         {
 88             _net = (x1 * w[0]) + (x2 * w[1]) + ((-1) * w[2]);
 89 
 90             return (_net >= 0) ? 1 : 0;
 91         }
 92 
 93         public void Treinar()
 94         {
 95             var treinou = true;
 96 
 97             for (var i = 0; i < _matrizAprendizado.GetLength(0); i++)
 98             {
 99                 var saida = Executar(_matrizAprendizado[i, 0], _matrizAprendizado[i, 1]);
100 
101                 if (saida != _matrizAprendizado[i, 2])
102                 {
103                     CorrigirPeso(i, saida);
104 
105                     treinou = false;
106                 }
107             }
108 
109             if (!treinou)
110                 Treinar();
111         }
112 
113         void CorrigirPeso(int i, int saida)
114         {
115             w[0] = w[0] + (1 * (_matrizAprendizado[i, 2] - saida) * _matrizAprendizado[i, 0]);
116             w[1] = w[1] + (1 * (_matrizAprendizado[i, 2] - saida) * _matrizAprendizado[i, 1]);
117             w[2] = w[2] + (1 * (_matrizAprendizado[i, 2] - saida) * (-1));
118         }
119     }
120 }

Implementação em RubyEditar

  1   #
  2  # Classe PERCEPTRON responsável para aprendizado e resolução da tabela AND
  3  #
  4 
  5 class Perceptron 
  6 
  7   def initialize
  8     # pesos sinápticos [0] entrada 1, [1] entrada 2, [3]BIAS
  9     @w   = []
 10 
 11     # variável responsável pelo somatório(rede).
 12     @net = 0
 13 
 14     # variavél responsável pelo número máximo de épocas
 15     @epocasMax = 30
 16 
 17     # variável responsável pela contagem das épocas durante o treinamento
 18     @count      = 0
 19 
 20     # declara o vetor da matriz de aprendizado
 21     @matriz_aprendizado = []
 22 
 23     self.inicia_matriz
 24   end
 25 
 26   def inicia_matriz
 27     # Primeiro valor
 28     @matriz_aprendizado[0]    = []
 29     @matriz_aprendizado[0][0] = 0; # entrada 1
 30     @matriz_aprendizado[0][1] = 0; # entrada 2
 31     @matriz_aprendizado[0][2] = 0; # valor esperado
 32 
 33     # Segundo Valor
 34     @matriz_aprendizado[1]    = []
 35     @matriz_aprendizado[1][0] = 0; # entrada 1
 36     @matriz_aprendizado[1][1] = 1; # entrada 2
 37     @matriz_aprendizado[1][2] = 0; # valor esperado
 38 
 39     # terceiro valor
 40     @matriz_aprendizado[2]    = []
 41     @matriz_aprendizado[2][0] = 1; # entrada 1
 42     @matriz_aprendizado[2][1] = 0; # entrada 2
 43     @matriz_aprendizado[2][2] = 0; # valor esperado
 44 
 45     # quarto valor
 46     @matriz_aprendizado[3]    = []
 47     @matriz_aprendizado[3][0] = 1; # entrada 1
 48     @matriz_aprendizado[3][1] = 1; # entrada 2
 49     @matriz_aprendizado[3][2] = 1; # valor esperado
 50     
 51     # inicialização dos pesos sinápticos
 52 
 53     # Peso sináptico para primeira entrada.
 54     @w[0] = 0;
 55     # Peso sináptico para segunda entrada.
 56     @w[1] = 0;
 57     # Peso sináptico para o BIAS
 58     @w[2] = 0;
 59   end
 60 
 61   # Método responsávelpelo somatório e a função de ativação.
 62   def executar(x1, x2)
 63     # Somatório (NET)
 64     @net = (x1 * @w[0]) + (x2 * @w[1]) + ((-1) * @w[2]);
 65 
 66     # Função de Ativação
 67     return 1 if (@net >= 0) 
 68 
 69     return 0;
 70   end
 71 
 72   # Método para treinamento da rede
 73   def treinar() 
 74     # variavel utilizada responsável pelo controlede treinamento recebefalso
 75     treinou = true;
 76     
 77     # varável responsável para receber o valor da saída (y)
 78     saida   = nil;
 79 
 80     # laço usado para fazer todas as entradas
 81     @matriz_aprendizado.length.times do |i|
 82       
 83       # A saída recebe o resultado da rede que no caso é 1 ou 0
 84       saida = self.executar(@matriz_aprendizado[i][0], @matriz_aprendizado[i][1]);
 85      
 86       if (saida != @matriz_aprendizado[i][2]) 
 87         # Caso a saída seja diferente do valor esperado
 88         
 89         # os pesos sinápticos serão corrigidos
 90         self.corrigirPeso(i, saida);
 91 
 92         # a variavél responsável pelo controlede treinamento recebe falso
 93         treinou = false;
 94       end
 95     end
 96 
 97     # acrescenta uma época
 98     @count+=1;
 99 
100     # teste se houve algum erro duranteo treinamento e o número de epocas
101     #é menor qe o definido
102     if(not treinou and (@count < @epocasMax))
103       # chamada recursiva do método
104       self.treinar();
105     end
106   end    # fim do método para treinamento
107 
108   # Método para a correção de pesos
109   def corrigirPeso(i, saida) 
110     @w[0] = @w[0] + (1 * (@matriz_aprendizado[i][2] - saida) * @matriz_aprendizado[i][0]);
111     @w[1] = @w[1] + (1 * (@matriz_aprendizado[i][2] - saida) * @matriz_aprendizado[i][1]);
112     @w[2] = @w[2] + (1 * (@matriz_aprendizado[i][2] - saida) * (-1));
113   end
114 end

Implementação em JavaEditar

  1  
  2  /*
  3  * Classe PERCEPTRON responsável para aprendizado e resolução da tabela AND
  4  */
  5 
  6 public class Perceptron {
  7 
  8     // pesos sinápticos [0] entrada 1, [1] entrada 2, [3]BIAS
  9     private double[] w = new double[3];
 10 
 11     // variável responsável pelo somatório(rede).
 12     private double NET = 0;
 13 
 14     // variavél responsável pelo número máximo de épocas
 15     private final int epocasMax = 30;
 16 
 17     // variável responsável pela contagem das épocas durante o treinamento
 18     private int count = 0;
 19 
 20     // declara o vetor da matriz de aprendizado
 21     private int[][] matrizAprendizado = new int[4][3];
 22 
 23     // MÉTODO DE RETORNO DO CONTADOR
 24     public int getCount(){
 25 
 26       return this.count;
 27 
 28     }
 29  // metodo de inicialização inicia o vetor da matriz de aprendizado
 30   Perceptron() {
 31 
 32     // Primeiro valor
 33     this.matrizAprendizado[0][0] = 0; // entrada 1
 34     this.matrizAprendizado[0][1] = 0; // entrada 2
 35     this.matrizAprendizado[0][2] = 0; // valor esperado
 36 
 37     // Segundo Valor
 38     this.matrizAprendizado[1][0] = 0; // entrada 1
 39     this.matrizAprendizado[1][1] = 1; // entrada 2
 40     this.matrizAprendizado[1][2] = 0; // valor esperado
 41 
 42     // terceiro valor
 43     this.matrizAprendizado[2][0] = 1; // entrada 1
 44     this.matrizAprendizado[2][1] = 0; // entrada 2
 45     this.matrizAprendizado[2][2] = 0; // valor esperado
 46 
 47     // quarto valor
 48     this.matrizAprendizado[3][0] = 1; // entrada 1
 49     this.matrizAprendizado[3][1] = 1; // entrada 2
 50     this.matrizAprendizado[3][2] = 1; // valor esperado
 51     
 52     // inicialização dos pesos sinápticos
 53 
 54     // Peso sináptico para primeira entrada.
 55     w[0] = 0;
 56     // Peso sináptico para segunda entrada.
 57     w[1] = 0;
 58     // Peso sináptico para o BIAS
 59     w[2]= 0;
 60        
 61 }
 62 
 63   // Método responsávelpelo somatório e a função de ativação.
 64     int executar(int x1, int x2) {
 65 
 66         // Somatório (NET)
 67         NET = (x1 * w[0]) + (x2 * w[1]) + ((-1) * w[2]);
 68 
 69         // Função de Ativação
 70         if (NET >= 0) {
 71             return 1;
 72         }
 73         return 0;
 74     }
 75 
 76     // Método para treinamento da rede
 77     public void treinar() {
 78 
 79         // variavel utilizada responsável pelo controlede treinamento recebefalso
 80         boolean treinou= true;
 81         // varável responsável para receber o valor da saída (y)
 82         int saida;
 83 
 84         // laço usado para fazer todas as entradas
 85         for (int i = 0; i < matrizAprendizado.length; i++) {
 86             // A saída recebe o resultado da rede que no caso é 1 ou 0
 87             saida = executar(matrizAprendizado[i][0], matrizAprendizado[i][1]);
 88             
 89            
 90             if (saida != matrizAprendizado[i][2]) {
 91                 // Caso a saída seja diferente do valor esperado
 92                 
 93                 // os pesos sinápticos serão corrigidos
 94                 corrigirPeso(i, saida);
 95                 // a variavél responsável pelo controlede treinamento recebe falso
 96                 treinou = false;
 97 
 98             }
 99         }
100         // acrescenta uma época
101         this.count++;
102 
103         // teste se houve algum erro duranteo treinamento e o número de epocas
104         //é menor qe o definido
105         if((treinou == false) && (this.count < this.epocasMax)) {
106             // chamada recursiva do método
107             treinar();
108 
109         }
110 
111     }    // fim do método para treinamento
112 
113     // Método para a correção de pesos
114     void corrigirPeso(int i, int saida) {
115 
116         w[0] = w[0] + (1 * (matrizAprendizado[i][2] - saida) * matrizAprendizado[i][0]);
117         w[1] = w[1] + (1 * (matrizAprendizado[i][2] - saida) * matrizAprendizado[i][1]);
118         w[2] = w[2] + (1 * (matrizAprendizado[i][2] - saida) * (-1));
119 }}