jan
7
Fuja do C(++): Python como uma linguagem para o desenvolvimento de Redes Neurais
Filed Under programação | Leave a Comment
Há muito tempo tem-se falado de Python e suas aplicações, no entando nas Universidades Federais do Brasil a linguagem “default” para desenvimento e estudo de algoritmos de redes neurais é o C ou C++, nesta palestra, apresentada na PyConBrasil 3 (SOCIESC-Joinville-SC) demonstrei o uso de Python para algumas aplicações de desenvolvimento de sistemas inteligentes e mostrei o inicio do desenvolvimento do Framework PYNN, que se propõe a ter foco acadêmico e auxiliar o desenvolvimento de novos algoritmos de redes neurais, e não apenas implementar os algoritmos existentes. Read more
dez
20
No primeiro artigo desta série vimos como um padrão pode ser classificado usando redes neurais [1], só que na natureza existem padrões que não podem ser separados apenas com um hiperplano (ex. XOR), para esses problemas usamos uma rede MLP, que significa que temos vários neurônios agrupados tentando calcular dois ou mais hiperplanos para separar os padrões em classes.
Uma rede MLP se parece com algo do tipo:

Para implementar uma rede MLP em Python podemos usar o programa abaixo, ainda sem otimizações, mas que em breve estarei orientando todo ele a objeto para ficar mais claro.
# -*- coding: utf-8 -*- # # nn.py - Neural Networks in Python # v0.1 at 2007-03-20 # # Changelog # 2004-03-24 - implement momentum factor # 2004-03-25 - implement a quadratic medium error import random from numpy import exp class mlp: """ This is a Multi-Layer Perceptron class with Backpropagation algoritm implemented. Allan Garcia allan.garcia@gmail.com """ def __init__(self, iterations=None, architecture=None, trainning_examples=None, weights=None): """ This function initializes all properties of this class. """ self.learnning_factor = 0.5 self.momentum_factor = 0.0 self.n = 0 self.bias = 1 self.sum_error = 0 self.error_tolerated = 0.1 self.weights = {} self.answers = {} self.gradients = {} self.current_examples = [] self.current_d = [] self.current_x = [] self.num = random.Random() if iterations != None: self.iterations = iterations else: self.iterations = 5000 if architecture != None: self.architecture = architecture else: self.architecture = (2,1) if trainning_examples != None: self.trainning_examples = trainning_examples else: self.trainning_examples = [] self.init_example() if weights != None: self.weights = weights else: self.weights = {} self.init_weights() #FIXME: Implement a sanity check to verify the size of examples vectors. def init_weights(self): """ This procedure initializes all weights of the network, obeying its architecture. """ before_architecture_layer = 0 for j in range(len(self.architecture)): if j == 0: for i in range(self.architecture[j]): weight = [] for l in range(len(self.trainning_examples[0][0]) + 1): # +1 for bias weight.insert(l, self.num.uniform(-1,1)) self.weights[i,j] = weight else: for i in range(self.architecture[j]): weight = [] for l in range(before_architecture_layer + 1): # +1 for bias weight.insert(l, self.num.uniform(-1,1)) self.weights[i,j] = weight before_architecture_layer = self.architecture[j] def init_example(self): """ If no trainning examples are provided, the XOR problem is implemented. """ sets = [([0,0],[0]), ([1,1],[0]), ([1,0],[1]), ([0,1],[1])] self.trainning_examples = list(sets) def prepare_examples(self): """ This procedure implements the sorting os next iteration sets of examples. """ self.current_examples = list(self.trainning_examples) random.shuffle(self.current_examples) def elect_example(self): """ This procedure puts in evidence the next example pair. """ self.current_x, self.current_d = self.current_examples.pop() def activation(self, v): """ This function is the activation function of the perceptron. """ y = (1 / (1 + exp(-v))) return y def dactivation(self, v): """ This function is the derivated of activation function above. """ y = v * (1 - v) return y def perceptron(self, i, j, x): """ This function is the linear combination implementation of the perceptron. """ weight = self.weights[i,j] v = 0 for i in xrange(len(x)): v += x[i] * weight[i] v += weight[len(weight)-1] * self.bias return v def error(self): """ This calculates the error. """ erro = [] last_col = len(self.architecture)-1 for l in xrange(self.architecture[last_col]): erro.insert(l, self.current_d[l] - self.answers[l,last_col]) lsum = 0.0 for l in xrange(len(erro)): lsum += (erro[l] ** 2) self.sum_error += lsum / 2 return erro def medium_error(self): """ This gives a quadratic medium error """ s = self.sum_error / self.n return s def propagation(self, x): """ This propagates the perceptron and calculates all answers. """ for j in xrange(len(self.architecture)): if j == 0: for i in xrange(self.architecture[j]): self.answers[i,j] = self.activation(self.perceptron(i, j, x)) else: x = [] for i in xrange(self.architecture[j-1]): x.insert(i, self.answers[i,j-1]) for i in xrange(self.architecture[j]): self.answers[i,j] = self.activation(self.perceptron(i, j, x)) def retropropagation(self, e): """ This procedure implements the retropropagation algoritm. """ for j in xrange(len(self.architecture)).__reversed__(): last_col = len(self.architecture)-1 if j == last_col: for i in xrange(self.architecture[j]): self.gradients[i,j] = e[i] * self.dactivation(self.answers[i,j]) else: for i in xrange(self.architecture[j]): tgradients = 0.0 next_col = j + 1 for l in xrange(self.architecture[next_col]): tgradients += self.gradients[l,next_col] * self.weights[l,next_col][i] self.gradients[i,j] = self.dactivation(self.answers[i,j]) * tgradients next_oldweights = dict(self.weights) for j in xrange(len(self.architecture)): for i in xrange(self.architecture[j]): weights = self.weights[i,j] newweights = [] if j == 0: for l in xrange(len(self.current_x)): delta = self.learnning_factor * self.gradients[i,j] * self.current_x[l] if self.n > 1: delta += self.momentum_factor * self.oldweights[i,j][l] newweights.insert(l, weights[l] + delta) last_weight = len(weights) - 1 delta = self.learnning_factor * self.gradients[i,j] * self.bias if self.n > 1: delta += self.momentum_factor * self.oldweights[i,j][last_weight] newweights.insert(last_weight, weights[last_weight] + delta) self.weights[i,j] = newweights else: for l in xrange(self.architecture[j-1]): delta = self.learnning_factor * self.gradients[i,j] * self.answers[l,j-1] if self.n > 1: delta += self.momentum_factor * self.oldweights[i,j][l] newweights.insert(l, weights[l] + delta) last_weight = self.architecture[j-1] delta = self.learnning_factor * self.gradients[i,j] * self.bias if self.n > 1: delta += self.momentum_factor * self.oldweights[i,j][last_weight] newweights.insert(last_weight, weights[last_weight] + delta) self.weights[i,j] = newweights self.oldweights = dict(next_oldweights) def trainning(self): """ This procedure do the trainning of the perceptron network. """ while self.n < self.iterations: self.n = self.n + 1 self.prepare_examples() while self.current_examples != []: self.elect_example() self.propagation(self.current_x) e = self.error() self.retropropagation(e) if self.medium_error() < self.error_tolerated: break print 'Medium Error:', self.medium_error() def execute(self, x): """ This procedure uses the neural network for a result giving. """ self.propagation(x) last_col = len(self.architecture)-1 output = [] for i in xrange(self.architecture[last_col]): output.insert(i, self.answers[i,last_col]) return output def output(self): pass
Execute o programa acima usando:
from mlp import mlp examples_xor = [([0,0],[0]),([1,1],[0]),([1,0],[1]),([0,1],[1])] nn = mlp(iterations=5000, architecture=(2,1), trainning_examples=examples_xor) nn.learnning_factor = 0.5 nn.momentum_factor = 0.0 nn.trainning() nn.execute([0,0]) nn.execute([1,1]) nn.execute([0,1]) nn.execute([1,0])
Você irá pereber que a porta lógica XOR estará implementada, tente executar este treino usando um Perceptron comum e veja a diferença no resultado.
dez
11
Desenvolvimento de sistemas e consultoria
Filed Under programação | 2 Comments
Caríssimos,
O site da minha empresa acaba de ser reformulado, a ADG Soluções é especializada em desenvolvimento de sistemas personalizados usando tecnologia WEB e consultoria em todas as aplicações da tecnologia Linux. Para acessar entre no endereço:
http://www.adgsolucoes.com.br/
Obrigado pela sua visita,
Allan Garcia
out
11
Este artigo será dividido em várias partes, vou falar sobre as Redes Neurais propriamente ditas e como implementar alguns algorítmos usando Python, nesta primeira parte vamos ver o básico e a medida que os artigos forem sendo publicados ver coisas mais avançadas.
Perceba que o objetivo é demonstrar as implementações em Python e não ver teoria aprofundada de Redes Neurais, para isso recomendo o livro do Haykin.
Apresentando as Redes Neurais
O que são? - “São sistemas de processamento de sinais ou de informações, compostos por um grande número de processadores elementares chamados neurônios artificiais, operando de forma paralela e distribuída, de modo a resolver um determinado problema físico/computacional.”
Esquema! - (X1, X2, …, Xn) dot (W1, W2, …, Wn) — F(x) — Y
Isso significa que uma Rede Neural, de um neurônio apenas, é um combinador linear que passa por uma função de ativação e dá um resultado Y, o mais interessante é que podemos programá-la para que ela dê o resultado que você deseje! Com isso podemos fazer, dentre outras coisas, aproximadores de funções, associadores, classificação de padrões, predição futura, controle de sistemas, filtragem de sinais, compressão de dados, datamining, etc.
Redes Neurais podem ser de vários tipos, nesta parte básica vamos ver as mais simples, as Redes Neurais supervisionadas, que são treinadas (ou programadas) usando um conjunto de exemplos conhecidos, com atributos e respostas, e desta forma a Rede Neural “se acostuma” em dar os resultados desejados e passa a responder de acordo.
Programar uma Rede Neural é ajustar os valores do vetor W, de todos os neurônios, para que determinada entrada X, quando processada, resulte num valor Y desejado.
Um algoritmo simples
Este descreve apenas o funcionamento de um neurônio .
# -*- coding: utf8 -*- from numpy import array, sign class Neuron: def __init__(self, example, factor=0.1): self._bias = -1.0 self._factor = factor x, self._d = example self._x = array([self._bias]+x) self._w = array([0.0]*(len(self._x))) self._y = None self.train(example) def train(self, example): x, self._d = example self._x = array([self._bias]+x) self._y = self._sign(self._sum()) if self._y != self._d: self._adjust_w() def execute(self, x): self._x = array([self._bias]+x) self._y = self._sign(self._sum()) return self._y def _error(self): return self._d - self._y def _sum(self): return (self._x*self._w).sum() def _sign(self, v): if sign(v) < 0: y = 0 else: y = sign(v) return y def _adjust_w(self): self._w += self._factor * self._x * self._error()
E para executar o perceptron, que é o que irá apresentar os exemplos ao neurônio, temos:
# -*- coding: utf8 -*- from Neuron import Neuron from random import randint class Perceptron: def __init__(self, examples, max_epochs=100): self._examples = examples self._this_epoch_examples = list(self._examples) self._max_epochs = max_epochs self._epoch = 0 self._neuron = Neuron(self._rand_example()) self.train() def train(self): while self._epoch <= self._max_epochs: self._this_epoch_examples = list(self._examples) for i in range(len(self._this_epoch_examples)): self._neuron.train(self._rand_example()) print "Epoch: %d" % self._epoch self._epoch += 1 def execute(self, x): return self._neuron.execute(x) def _rand_example(self): lenght = len(self._this_epoch_examples) i = randint(0,lenght-1) return self._this_epoch_examples.pop(i)
Execute as classes acima usando
# -*- coding: utf8 -*- from Perceptron import Perceptron # AND examples_and = [ [[1,1],1], [[1,0],0], [[0,1],0], [[0,0],0] ] nn = Perceptron(examples_and) nn.execute([1,0])
Analise o objeto criado, seus métodos e pesos, verifique que com o método “execute” você poderá testar se as respostas estão sendo dadas corretamente.
Aguarde a parte 2 deste artigo para mais detalhes…