Relatório da Aula Prática sobre Redes Neurais Artificiais Instituto de Informática UFRGS Carlos Eduardo Ramisch Cartão: 134657 INF01017 Redes Neurais e Sistemas Fuzzy Porto Alegre, 16 de outubro de 2006. 1. Introdução O objetivo dessa aula prática é a familiarização e a implementação dos conceitos vistos em aula teórica, tais como o modelo de neurônio artificial, o perceptron, as redes alimentadas adiante e o algoritmo de backpropagation. Para esse propósito, será feito uso do toolkit do MATLAB para a implementação de Redes Neurais Artificiais. Esse toolkit facilita o trabalho, eliminando detalhes de implementação que seriam bastante custosos se feitos em outro ambiente. 2. Funções de Ativação A primeira tarefa consiste apenas em verificar as diferentes funções de ativação utilizadas nos modelos de neurônio artificial. Para isso, o MATLAB fornece uma série de funções que são usualmente utilizadas com esse propósito. Entre as funções testadas estão a tangente hiperbólica, a função logística e a função limiar. Nas imagens abaixo, pode-se verificar a plotagem das funções na imagem 2.1: (a) Função tangente hiperbólica; (b) Função logística; (c) Função limiar; (d) Função limiar simétrica em relação a 0. (a) (b)
(c) (d) Imagem 2.1 Plotagem das funções de ativação. 3. Perceptron Para criar e treinar perceptrons, foram usadas as funções do matlab newp, que cria um perceptron e define o domínio das entradas, adapt, que realiza a adaptação de pesos de acordo com o algoritmo de treinamento do perceptron, e sim, que simula a propagação da entrada do perceptron. O trecho de código abaixo simula um perceptron que aprende a função OR: 1. net = newp([-2 2; -2 2],1); 2. P = [0 0; 0 1; 1 0; 1 1]'; 3. T = [0 1 1 1]; 4. figure; 5. plotpv(p,t); 6. linehandle=plotpc(net.iw{1},net.b{1}); 7. hold on 8. for cont=1:6, 9. net = adapt(net,p,t); 10. linehandle=plotpc(net.iw{1},net.b{1}, linehandle); 11. drawnow; 12. pause; 13. Y = sim(net,p) 14. end; 15. hold off Nesse trecho de código, as entradas são representadas pelo vetor P e os valores desejados pelo vetor T. O algoritmo itera 6 vezes sobre o perceptron, adaptando os pesos sinápticos e então exibindo os resultados. A maior parte do código não tem importância, sendo apenas para apresentar a informação de forma gráfica. Na linha 1, criamos um novo perceptron, definindo o domínio da entrada como [-2, 2]. A linha 9 é responsável por adaptar os pesos das sinapses, e na linha 9, o vetor Y recebe o resultado da propagação das entradas no perceptron. Os resultados das últimas 4 iterações podem ser vistos na imagem 3.1, em ordem cronológica.
(a) (b) (c) Imagem 3.1 Resultado do treinamento iterativo do perceptron para a função OR. 4. Rede Alimentada Adiante para Aprendizado da Função XOR A fim de aprender uma função não linearmente separável, instancia-se uma rede de mais de uma camada. Essa rede, conhecida como Multi Layer Perceptron, é formada por neurônios conectados para frente apenas, isto é, não existem ciclos. Além disso, uma camada só é conectada com a próxima e com a anterior, não podendo haver pulos sobre alguma camada. No Matlab, a função newff cria uma rede com camadas. Noc aso da função XOR que desejamos implementar, colocaremos apenas duas camadas, a ouculta e a de saída. Na camada oculta, colocaremos dois neurônios e, na de saída, apenas um, correspondente à saída da função XOR. O código executado pode ser visto abaixo: 1. net = newff([-2, 2; -2, 2],[2, 1]); 2. P = [0 0; 0 1; 1 0; 1 1]'; 3. T = [0 1 1 0]; 4. net = train( net, P, T ); 5. simulation = sim(net,p) 6. weights1 = net.iw{1} 7. weights2 = net.lw{2} 8. bias1 = net.b{1} 9. bias2 = net.b{2} (d)
Na linha 1, criamos os neurônios da rede. Como no exemplo anterior, P guarda as entradas e T a saída desejada da rede. Na linha 4, o algoritmo backpropagation é usado para ajustar os pesos da rede, que são exibidos nas próximas linhas. Considerando que a rede é formada por dois neurônios, 1 e 2, na camada oculta, e um neurônio, 3, na camada de saída (de acordo com a imagem 4.1), os valores dos pesos encontrados foram: w 10 = b 1 = 2.1863 w 11 = -4.4069 w 12 = 4.1282 w 20 = b 2 = 0.5798 w 21 = 1.8838 w 22 = -1.8601 w 30 = b 3 = 5.3592 w 31 = -3.4961 w 32 = -3.7321 Quando simulados, os valores encobntreados pela rede foram aproximadamente os mesmos que a função original, demonstrando que o aprendizado se deu corretamente: simulation = [ 0.0000 0.9999 0.9999 0.0000 ] w 11 w 12 w 10 w 31 w 30 w 22 w 21 w 20 w 32 Imagem 4.1 Esquemático da Rede Neural que simula a função XOR. 5. Rede Alimentada Adiante para Aprendizado da Função Seno Para aprender a função seno, foi utilizada a mesma metodologia do exemplo da seção anterior, com a diferença das entradas e saídas do sistema. O mapeamento da rede é de uma dimensão de entrada para uma dimensão de saída, diferentemente do modelo anterior. O esquemático, porém, é muito semelhante ao da imagem 4.1, seguindo a mesma lógica. O código do Matlab usado para a simulação é exibido abaixo: 1. net = newff([-3, 3],[2, 1]); 2. P = [-2, -1.75, -1.5, -1.25, -1, -0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]; 3. T = [sin(-2), sin(-1.75), sin(-1.5), sin(-1.25), sin(-1), sin(-0.75), sin(-0.5), sin(-0.25), sin(0), sin(0.25), sin(0.5), sin(0.75), sin(1), sin(1.25), sin(1.5), sin(1.75), sin(2)]; 4. net = train( net, P, T ); 5. simulation = sim(net,p) 6. weights1 = net.iw{1} 7. weights2 = net.lw{2}
8. bias1 = net.b{1} 9. bias2 = net.b{2} A diferença está nos vetores de treinamento P e T, que agora modelam o comportamento discretizado da função seno. O resultado da simulação, bem como os pesos encontrados para a rede são mostrados abaixo. Uma vez que a simulação tem um resultado bastante próximo da saída desejada, consideramos de maneira subjetiva que a rede foi treinada com sucesso.: w 10 = b 1 = 1.2103 w 11 = -1.2613 w 20 = b 2 = -1.2103 w 21 = -1.2613 w 30 = b 3 = 3.6783e-007 w 31 = -1.2108 w 32 = -1.2108 T = -0.9093-0.9840-0.9975-0.9490-0.8415-0.6816-0.4794-0.2474 0 0.2474 0.4794 0.6816 0.8415 0.9490 0.9975 0.9840 0.9093 simulation = -0.9783-0.9721-0.9582-0.9255-0.8498-0.6993-0.4768-0.2328-0.0000 0.2328 0.4768 0.6993 0.8498 0.9255 0.9582 0.9721 0.9783