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.