Uma leve explicação sobre Redes Neurais e a matemática por trás dela.

Adriel Cabral
8 min readAug 17, 2020

--

Introdução

Redes Neurais são sistemas de computação com nós interconectados que funcionam como os neurônios do cérebro humano. Usando algoritmos, elas podem reconhecer padrões escondidos e correlações em dados brutos, agrupá-los e classificá-los, e — com o tempo — aprender e melhorar continuamente.

Elas são aplicadas em diversos tópicos, como : visão computacional, processamento de linguagem natural e otimização, ou seja, é uma ferramenta que possui uma grande abrangência em seu uso.

Vamos começar com o exemplo de um neurônio biológico(figura 1) e posteriormente de um neurônio artificial (NA) (figura 3).

Neurônio Biológico

Figura 1: Partes de um neurônio biológico

Os estímulos se propagam sempre no mesmo sentido: são recebidos pelos dendritos, seguem pelo corpo celular, percorrem o axônio e, da extremidade desse, são passados à célula seguinte (dendrito — corpo celular — axônio). A figura abaixo ilustra a transmissão desses impulsos nervosos

Figura 2: Impulsos Nervosos

O Neurônio artificial (NA) funciona de forma similar, uma informação chega, é processada e por fim é retornado um valor, o resultado.

Neurônio Artificial

Figura 3: Perceptron

O NA é chamado de Perceptron, com apenas ele, é possível construir a “Rede” mais simples possível, porém, infelizmente, ela é muito limitada para resolver problemas. Todo o Perceptron possui pesos, uma função de ativação e um bias associado. Esse exemplo possui apenas 3 pesos, todavia isso muda dependendo da quantidade de entradas.

1.As entradas podem ser resultados de outros neurônios, assim são formadas as Redes Neurais

2.O bias sempre vai ter o valor 1 e um peso, visto que é considerado uma entrada.

3.Os pesos são iniciados de maneira aleatória, normalmente entre -1 e 1.

Matemática do “impulso nervoso”

Nesse processo, os valores de entrada são multiplicados pelos seus respectivos pesos (conexões) e depois são somados (soma ponderada), após isso, a soma será usada em uma função de ativação retornando a nossa resposta !.

Na figura 3 as entradas são 1(bias), 2 e 4 e os pesos 0.3, 0.4 e 0.2, respectivamente, multiplicamos os pesos pelas entradas e depois somamos, o resultado é 1.9. Por fim, utilizamos esse valor, 1.9, em uma função de ativação (que nesse caso é a step function) e teremos o resultado, 1.

Rede Neural (RN)

Figura 4: Multilayer Perceptron

A partir do Perceptron, podemos formar RNs, apenas precisamos agrupar os neurônios em camadas e depois ligá-los com os pesos, esse tipo de rede é bastante conhecida como Multilayer Perceptron.

1.Não confunda essas 2 bolinhas da camada de entrada com neurônios !, é apenas uma forma ilustrativa para os valores de entrada.

2.Nesse exemplo não está incluso os bias, mas, se tivesse, seriam 3 ( 1 para cada camada intermediária e 1 para a de saída).

Feedforward

Todo esse processo matemático explicado anteriormente acontece para todos os neurônios da nossa RN e é chamado de feedforward , seriam os “impulsos nervosos”, sempre tomando esse sentido, da esquerda para a direita.

O processo de “aprendizagem” da RN

Até agora, apenas vimos como funciona a propagação das informações da nossa Rede e quais são os seus componentes (entradas, camadas, pesos, função de ativação e bias).

O processo de aprendizagem consiste em encontrar o melhor conjunto de pesos que generalizem os nossos dados, mas como fazer isso ?

Usaremos um otimizador bastante conhecido para RNs, o Gradiente descendente, juntamente com o backpropagation e uma função de perda para fazermos a atualização dos nossos pesos e encontrar o melhor conjunto.

Função de perda

Essa função é utilizada para sabermos como o nosso algoritmo esta se saindo nas predições e como devemos atualizar os nossos pesos, ou seja, ela é de suma importância para o aprendizado da rede.

Existem vários tipos de funções de perda e cada uma é melhor em determinados problemas e situações.

Gradiente descendente

Se você esta usando uma função que indica o erro de cada previsão de sua rede, qual o valor que você mais deseja que ela retorne ? o mínimo, é claro. Então é ai que entra o nosso otimizador.

O gradiente é um vetor contendo todas as derivadas parciais de suas variáveis e ele indica em que sentido e direção devemos ir para ter o maior valor resultante da função. Tendo isso em vista, cada derivada parcial indica em que direção e sentido aquela determinada variável deve seguir para aumentarmos a resultante.

Figura 5: Símbolo do Gradiente de uma função
Figura 6: Símbolo da derivada parcial

Mas, se precisamos chegar ao menor valor da função de perda, como ele vai nos ajudar ? É simples, apenas indo para o sentido e direção contrários ao gradiente, isto é, apenas seguir o valor negativo das derivadas parciais, que no nosso caso são as parciais dos pesos.

Figura 7: Usando o gradiente para encontrar o valor mínimo da função

Nesse gráfico, os eixos X e Y seriam 2 pesos da nossa rede e Z o nosso erro.

A cada treinamento, os valores dos pesos são atualizados e o erro diminui seguindo essa “descida”, ganhando assim outro nome , descida do gradiente.

Figura 8: fórmula da atualização dos pesos

O alfa se chama taxa de aprendizagem e serve pra controlar o quanto atualizaremos os pesos. Dessa forma, você pode interpretar como sendo o tamanho dos “passos” até chegar no valor mínimo.

1.O valor da taxa de aprendizagem é escolhido pela pessoa, porém é normal começar com valores pequenos.

Vamos colocar em prática utilizando um Perceptron e a tabela AND.

Figura 9: tabela AND

Os valores de entrada serão os elementos da coluna 1 e 2 e o resultado esperado será a ultima coluna, por exemplo, daremos os números 0 e 0 como entrada e esperamos que a rede retorne 0.

Elementos do nosso Perceptron

Função de ativação

Existem várias funções de ativação e cada uma é empregada em determinadas situações e camadas, por exemplo, a função sigmoide é muito usada na ultima camada e quando temos um problema de classificação binária, pois ela retorna valores de 0 a 1, o que se encaixa perfeitamente em nosso problema.

Figura 10: gráfico da função sigmoide

Função de perda

Figura 11: função de perda ( mean squared error )

Utilizaremos a função chamada de mean squared error ( erro quadrático médio) em que “n” é a quantidade de exemplos que a rede irá utilizar antes de atualizar os pesos. Ela é muito utilizada para problemas de regressão, situações em que precisamos predizer um valor numérico.

1.Nos atualizaremos os pesos a cada exemplo, ou seja, o valor de “n” será 1. Esse método é chamado de Descida do Gradiente Estocástica.

Cálculo das parciais

Para fazer os cálculos necessários você precisa ter noção sobre : derivadas, derivadas parciais e regra da cadeia (as 2 primeiras são um pouco óbvias).

Figura 12: ilustração do nosso perceptron

Como “n” é igual a 1, então a nossa função de perda ficará assim: (y — ý)², em que “y” e é resposta da rede e “ý” é a resposta correta.

1.Tenha em mente que Y = g(x1 * w1 + x2 * w2 + w3)

Veja que precisamos aplicar a regra da cadeia, pois existem 2 funções : a principal ,( )², e a secundária, y — ý.

Figura 13: regra da cadeia

Aplicando a regra da cadeia:

Lembre-se que estamos calculando a derivada parcial em relação a um peso, logo o ý’ irá sair , pois é considerado uma constante.

Teremos que aplicar a regra da cadeia novamente, porém na função g(x).

Derivando em relação ao peso w1:

Pronto, encontramos a parcial do peso w1.

As derivadas dos outros pesos ficarão assim:

São as derivadas parciais dos pesos w2 e w3, respectivamente.

Antes de colocar a “mão na massa”, vamos deixar essas contas com um melhor visual utilizando a regra delta. Se você olhar com um pouco de atenção ,perceberá que o seguinte termo se repete.

Chamaremos esse termo de Delta, então ficará assim:

Criando o algoritmo

Começaremos importando a biblioteca numpy, pois ajudará na manipulação de matrizes e na criação da nossa base de dados:

Base de Dados

Nossa base de dados possui 4 linhas e 3 colunas. As duas primeiras colunas são nossas entradas e a ultima é o resultado esperado que a rede retorne.

Pesos

Iniciaremos os pesos de forma aleatória entre -1 e 1.

Função de ativação

Figura 14: derivada da função sigmoide

Treinamento

Na descida do gradiente estocástica é recomendado que você embaralhe os seus dados a cada atualização de peso, pois evita que sua rede sofra algum viés, por exemplo, “se acostumar” com a sequência dos dados.

Impulso e backpropagation

A parte da atualização se chama backpropagation, pois é como se estivéssemos fazendo uma retro propagação calculando o nosso erro e atualizando os pesos.

1.Utilizei erro = y — ý para não calcularmos novamente no Delta.

2.O valor que escolhi para a taxa de aprendizagem foi 0.5.

Código do “treinamento” completo:

--

--

Adriel Cabral
Adriel Cabral

Written by Adriel Cabral

Sou estudante de Ciência da Computação da UFPB e tenho um grande interesse pela área de Machine Learning e Data Science.

Responses (1)