Redes Neurais | Teoria

A metalinguagem de um post sobre a abstração de como raciocinamos (ou a porta de entrada para o modelo de aprendizado de máquina mais em alta nos dias de hoje).

Caio Deberaldini
Turing Talks
9 min readSep 22, 2019

--

Escrito por Caio Deberaldini, Camila Lobianco e Paulo Sestini.

Foto por Filip Bunkens em Unsplash.

1. Introdução

O ser humano possui uma elevada capacidade de apreensão de padrões. Isso é o que forma nossa capacidade de dedução. Se nós estivermos em um supermercado e vermos na sessão das frutas um objeto pequeno, vermelho e com pequenos pontinhos pretos, saberemos que é um morango porque, desde que existimos, vimos morangos o suficiente para saber que essas características são o padrão que define esse objeto.

Isso não é muito diferente do que um corretor de imóveis faz. Depois de alguns anos vendo um conjunto de casas e descobrindo que uma casa com característica X e Y vale um valor Z, ele é capaz de deduzir o valor de um imóvel. Não obstante, esse é um processo demorado, o qual demanda anos para alguém que trabalha nesse ramo adquirir esta “habilidade” .

Com a ascensão dos computadores, pela primeira vez foi possível a ideia de automatizar o reconhecimento de padrões. Isso em função de sua capacidade de fazer contas com uma alta velocidade. Então os cientistas começaram a pensar em uma forma de traduzir esses padrões em cálculos e permitir que o computador fizesse o trabalho bruto por eles. É nesse contexto que surgem as redes neurais.

Mas enfim, o que são redes neurais? Em síntese, elas são algoritmos de reconhecimento. Ou seja, sua função principal é a de receber um conjunto de dados, achar padrões dentre eles e definir o que aquele padrão significa. Ou seja, vamos supor uma rede neural que consiga ler letra cursiva e devolva o que está escrito para o usuário. O cientista de dados, nesse caso, pegaria cada pixel do input e o transformaria em uma matriz de valores. A rede neural descobriria padrões dentro dessa matriz que diriam se ali está escrito um “A” ou um “B”. Da mesma forma no exemplo do corretor de imóveis: ela veria que se a casa tem 2 quartos ela tem um valor e se tem 1, tem outro valor diferente.

2. Por que redes neurais?

As redes neurais possuem uma estrutura complexa e dinâmica, o que as permite modelar uma ampla gama de problemas e se ajustar a situações.

Quando precisamos resolver algum problema, se olharmos ao nosso redor podemos ver que, possivelmente, a natureza já resolveu problema similar por conta própria, através da evolução. Desse modo, podemos tentar copiar o que já surgiu de forma natural. Assim, quando se trata de encontrar uma solução que seja capaz de reconhecer padrões, nós olhamos para a criação da natureza especializada nisto: o cérebro.

3. Modelando uma rede neural

A unidade básica de uma rede neural é análoga às do cérebro: os neurônios.

Um neurônio é uma célula que conduz sinal elétrico em apenas um sentido. Ele é composto pelo seu corpo celular, onde está o núcleo, pelo axônio, que conduz o sinal, e os dendritos, que conectam o neurônio a outros neurônios.

Para o neurônio conduzir um sinal, esse deve receber um sinal de entrada com um valor mínimo de intensidade. Recebido o sinal, há a propagação de corrente elétrica através do axônio, chegando no corpo celular e passando para outros neurônios.

O neurônio de uma rede neural será criado de maneira análoga. Esse receberá sinais, que passarão por uma função de ativação e darão origem ao sinal de saída do neurônio. Porém, permitiremos que cada sinal tenha uma importância diferente para o neurônio, um peso, que dirá o quanto cada sinal contribui para o sinal final.

Com o neurônio criado, criamos a rede conectando vários neurônios. Dessa forma, passamos para a rede um conjunto de sinais inicial e utilizamos as saídas de alguns neurônios como entradas para outros.

4. A matemática por trás do modelo

Após essa introdução sobre como as redes neurais foram idealizadas — com base em modelos biológicos, assim como muitos algoritmos de Machine Learning — , passaremos para a parte mais interessante das redes neurais: a matemática por trás do modelo.

O modelo de redes neurais funciona por meio de camadas que, ao se comunicarem, produzem equações cada vez mais complexas — proporcionalmente à profundidade da rede - com o intuito de predizer melhor. Tomando como paralelo o uso da Regressão Linear para o caso da predição de valores contínuos para um determinado label, vimos que conseguíamos, para determinados datasets, obter uma acurácia relativamente elevada, ajustando os exemplos por uma (simples) reta. Extrapolando o raciocínio, se tivermos funções de ordens maiores e mais complexas, podemos obter um ajuste ainda melhor, ou a delimitação de uma fronteira mais bem definida para a classificação dos nossos objetos em análise (queremos usar nossa rede neural para classificarmos, não é mesmo?). Bom, até aqui, nada muito difícil de assimilar, porém, conhecendo a cara de uma rede neural entenderemos melhor esse processo, assim como os termos que a definem — representada pela figura abaixo:

Arquitetura de uma rede neural. Fonte: “Coursera Machine Learning — Stanford University”, Andrew Ng.

Termos básicos:

Em uma rede neural, temos três categorias de layers (camadas) por onde os dados fluem:

  • A 1ª delas chama-se Input Layer e o seu nome já é bastante explicativo (nossos dados têm que entrar por algum lugar, certo?);
  • A última camada, analogamente, é bastante autoexplicativa e recebe o nome de Output Layer (aos que tiveram Mecânica dos Fluidos ou Eletromagnetismo, o Teorema da Continuidade está ai pra provar que tudo o que entra, também sai);
  • E, por fim, deixamos a camada intermediária pro final pois ela merece uma melhor atenção. Na ilustração da figura acima, é representada a Hidden Layer como uma camada única, porém, em muitas aplicações de Machine Learning nós trabalhamos com arquiteturas com mais camadas intermediárias. São nessas camadas onde, entrando uma combinação linear dos valores da camada anterior, será aplicada a função de ativação no neurônio e, assim, será gerado um novo valor para aquele neurônio. Tudo bem, se você achou essa explicação complicada, não se preocupe. Ficará tudo mais claro com as explicações e as ilustrações que se seguirão.

Assim como o nome sugere, a combinação linear dos valores da camada anterior, passada como entrada para cada um dos neurônios da camada seguinte, é uma função linear em que seus parâmetros serão os valores da camada anterior e a combinação deles será feita pela matriz de pesos entre as camadas.

Ativação dos neurônios. Fonte: “Coursera Machine Learning — Stanford University”, Andrew Ng.

Como ilustrado na figura acima, cada neurônio da Hidden Layerrepresentado por aᵢ⁽ʲ⁾recebe o retorno da função de ativação — representada pela função g, aplicada à uma função linear, a qual, por sua vez, é a combinação linear dos neurônios da camada anterior. Assim, se nossa Hidden Layer tiver mais camadas (ao invés de apenas uma), aplicamos a mesma ideia, usando-se os valores das camadas anteriores, obtidos por esse processo, para calcular os valores das próximas camadas. Dada uma camada j+1, aplicamos esse processo com os valores dos neurônios da camada j (simples, não?).

Entretanto, em uma função linear temos o termo chamado de coeficiente linear (termo “solto” na função, que não depende dos parâmetros de entrada). No nosso caso, estes coeficientes seriam todos os valores da primeira coluna da matriz de pesos — todo θ(i, j, 0), onde j refere-se a camada anterior a camada que estamos analisando, i refere-se ao neurônio que estamos calculando o valor, na camada em análise e, por fim, 0 refere-se ao neurônio de número 0 da camada anterior. Mas, na prática, nos só temos os parâmetros de entrada, representados pelo vetor {x(1), …, x(n)}, onde n é o nosso número de features. Assim, para que os nossos dados estejam de acordo com o nosso modelo, para cada camada subsequente que desejamos calcular o valor de seus neurônios, devemos introduzir uma unidade de viés (bias unit) na camada anterior, a fim de que a combinação linear esteja correta.

Bias Unit:

Como pode ser visto na ilustração da arquitetura de uma rede neural (um pouquinho acima neste post), tanto na camada de entrada (Input), quanto nas camadas escondidas (Hidden), nós adicionamos uma unidade de viés. Assim, tomando essa arquitetura como exemplo (camada escondida única), para o cálculo do valor dos neurônios da camada escondida, devemos adicionar um valor x(0) = 1 na camada de entrada. Dessa forma, ao multiplicar o peso correspondente pela unidade de viés, ficaremos com o peso “isolado” (nosso coeficiente linear da função linear) na combinação linear. Generalizando: para toda camada j+1, adicionamos uma unidade de viés à camada j, ou seja, inserimos a(0, j) = 1.

Função de Ativação:

Para finalizar o aprendizado sobre o fluxo dos dados e como eles são manipulados na nossa rede neural, precisamos retomar uma ideia passada no início desta seção sobre a matemática por trás dessa maravilha de modelo: criar funções mais complexas, conforme vamos nos aprofundando na nossa rede, com o objetivo de obtermos um modelo mais preciso e que consiga classificar melhor o nosso target.

Existem diversas funções de ativação (Sigmóide, ReLU, Softmax, Tangente Hiperbólica, entre outras). Falaremos e utilizaremos, nos posts sobre redes neurais, a função sigmóide.

Função Sigmóide

A motivação para utilizarmos esta função de ativação é conseguir manter o valor da combinação linear entre 0 e 1. Como queremos classificar um alvo (ou múltiplos alvos), devemos ter saídas binárias — tumor benigno × tumor maligno, gato × não_gato, etc. A seguir, são apresentadas a cara da função sigmóide e como ela se comporta:

Função sigmóide
Gráfico da função sigmóide

Perfeito, além de tornarmos as nossas equações mais complexas, tendo em vista a não-linearidade da função sigmóide e por aplicarmos ela em cada neurônio, conseguimos manter os nossos valores entre 0 e 1. Mas, afinal de contas, porque precisamos disso? Lembrando-se de posts passados sobre modelos de predição, em especial aqueles voltados à classificação, sabemos que, no final de todo processo, obteremos a probabilidade condicional de o objeto em análise pertencer a determinada classe, dado que entramos com os valores correspondentes a suas features. Assim, escolhendo um valor arbitrário de probabilidade como sendo a fronteira entre o seu objeto não pertencer ou pertencer àquela classe, conseguimos classificá-lo! Por exemplo, vamos supor que, após treinarmos nossa rede neural, tentaremos classificar se determinada lata de cerveja pertence a marca A ou não. Podemos colocar um threshold em 0.5, de tal forma que, caso, ao final da rede neural, nossa probabilidade for 0.78, podemos afirmar que, como essa probabilidade é maior do que a nossa fronteira de decisão, então aquela lata pertence a marca A, ou seja, discretizamos nosso resultado — 0, não pertence; 1, pertence.

5. Conclusão

Sabemos que este post, ainda que destrinchadas as partes necessárias, é bastante carregado e pouco prático. Porém, o conteúdo aqui apresentado não só introduz você, caro leitor, ao incrível mundo das redes neurais, como também te prepara para, no próximo post, entender como funcionam os algoritmos de treinamento de uma rede neural e como implementá-los. Esperamos que tenham gostado e nos vemos no próximo post!

Curtiu? Então não deixe de criar sua conta no Medium e seguir a gente para continuar aprendendo mais modelos e outros assuntos de IA. Dê uma olhada em nossos outros posts e acompanhe o Grupo Turing no Facebook e no LinkedIn, temos várias oportunidades em IA por lá também.

Até!

--

--