Primeira vez aqui? Seja bem vindo e cheque o FAQ!
x

Como aproximar a função seno usando redes neurais com função de base radial?

+1 voto
372 visitas

1 Resposta

0 votos
respondida Jul 8, 2016 por Marcleiton Morais (21 pontos)  

As redes neurais do tipo RBF foram desenvolvidas baseadas na teoria de aproximação de funções. Essa teoria trata o problema genérico de aproximar uma função contínua e multivariada y(x) por uma função de aproximação f(w,x) dado um número fixo de parâmetros w (x e w são vetores reais de dimensões m e h, respectivamente). Sendo assim, existem dois aspectos importantes do modelo a serem definidos: a função f(⋅) e os parâmetros w. Escolhida uma função f(⋅) específica, o problema se reduz à determinação do conjunto de parâmetros w que fornece a melhor aproximação possível de y(⋅) para o conjunto de exemplos (dados). Em que y(X) é uma função contínua definida sobre o conjunto X, e f(w,X) é uma função de aproximação que depende continuamente de w ∈ P e X, tal que o problema de aproximação resume-se a determinar os parâmetros w* tais que: d[f(w*,X), y(X)] < d[f(w,X), y(X)], ∀ w ∈ P, onde d(⋅,⋅) é uma métrica de distância que permite avaliar a qualidade da aproximação. Sendo assim, o problema de aprendizagem corresponde a coletar os dados de entrada e seus correspondentes valores de saída desejada e aplicá-los no processo de definição dos parâmetros w do modelo de aproximação.
A presente implementação considera Redes Neurais com Funções de Ativação de Base Radial. A escolha dessa abordagem decorre de três fatores principais: essas funções sempre apresentam uma única camada intermediária; os neurônios de saída são sempre lineares; e os neurônios da camada intermediária têm apenas funções de base radial como função de ativação, ao invés de funções sigmoidais ou outras. A conseqüência do uso de funções de ativação de base radial está na forma como as entradas são processadas pelos neurônios da camada intermediária. Ao invés da ativação interna de cada neurônio da camada intermediária se dar pelo emprego do produto escalar entre o vetor de entradas e o vetor de pesos, como no caso do perceptron, ela é obtida a partir de uma norma ponderada da diferença entre ambos os vetores.
Considera-se uma função de base radial gaussiana para f( ) e, a partir de uma camada de saída linear, o método de aprendizagem adotado para os pesos, responsáveis pela combinação linear das ativações da camada intermediária, emprega a técnica pseudo-inversão (CHEN at al., 1991). Nesse caso, como o algoritmo se ocupa apenas com o ajuste dos pesos da camada de saída da rede RBF (modelo linear nos parâmetros), o critério para fixação dos centros, considerando um número fixo e previamente especificado de centros, é a escolha aleatória de um subconjunto de padrões de entrada como centros.

import numpy as np
from scipy import *
from scipy.linalg import norm, pinv
from matplotlib import pyplot as plt

class RBF:
    def __init__(self, indim, numCenters, outdim):
        self.indim = indim
        self.outdim = outdim
        self.numCenters = numCenters
        self.centers = [random.uniform(-1, 1, indim) for i in xrange(numCenters)]
        self.beta = 10
        self.W = random.random((self.numCenters, self.outdim))

    def _basisfunc(self, c, d):
        assert len(d) == self.indim
        return exp(-self.beta * norm(c-d)**2)

    def _calcAct(self, X):
        # Ativação das RBFs
        G = zeros((X.shape[0], self.numCenters), float)
        for ci, c in enumerate(self.centers):
            for xi, x in enumerate(X):
                G[xi,ci] = self._basisfunc(c, x)
        return G

    def train(self, X, Y): #X: matriz de dimensão n x indim #y: vetor coluna de dimensão n x 1
        # escolher vetores de centro aleatório do conjunto de treinamento
        rnd_idx = random.permutation(X.shape[0])[:self.numCenters]
        self.centers = [X[i,:] for i in rnd_idx]
        # calculate activations of RBFs
        G = self._calcAct(X)
        # matriz de pesos (pseudo-inversa)
        self.W = dot(pinv(G), Y)

    def test(self, X): #X: matriz de dimensão n x indim
        G = self._calcAct(X)
        Y = dot(G, self.W)
        return Y

if __name__ == '__main__':
    n = 100
    x = mgrid[0:2*np.pi:complex(0,n)].reshape(n, 1)
    y = np.sin(x)
    # regressão RBF
    rbf = RBF(1, 20, 1)
    rbf.train(x, y)
    z = rbf.test(x)
    # função seno
    plt.figure(figsize=(10, 6))
    plt.plot(x, y, 'k-')
    # modelo aprendido
    plt.plot(x, z, 'ro', linewidth=2)
    for c in rbf.centers:
        # predição RBF
        cx = arange(c-0.7, c+0.7, 0.01)
        cy = [rbf._basisfunc(array([cx_]), array([c])) for cx_ in cx]
        plt.plot(cx, cy, '-', color='white', linewidth=0.2)
    plt.xlim(0, 6.3)
    plt.show()

A imagem será apresentada aqui.

Referências:
Simon O. Haykin - Neural Networks and Learning Machines-Prentice Hall (2008) - 3rd Edition
Markus Svensen and Christopher M. Bishop - Pattern Recognition and Machine Learning (Information Science and Statistics)-Springer Science+Business Media, LLC (2006)
CHEN, S., COWAN, C.F.N. & GRANT, P.M. “Orthogonal Least Squares Algorithm for Radial Basis Function Networks”, IEEE Transactions on Neural Networks, 2(2): 302-309, 1991.

...