Contextualizando a origem das redes neurais artificiais
Para entendermos melhor as redes neurais artificiais, precisamos olhar para o passado. Em 1943, os pesquisadores McCulloch e Pitts propuseram o primeiro modelo matemático simplificado de neurônio. Esse modelo consiste, resumidamente, em entradas e saídas binárias, e as conexões entre neurônios são baseadas na lógica booleana: AND (E), OR (OU) e NOT (NÃO). Logo após essa primeira proposta matemática, no final dos anos 1950, Frank Rosenblatt apresentou o primeiro neurônio artificial conhecido como Perceptron (Perceptron), que é, basicamente, um precursor das redes neurais que usamos hoje.
A inspiração para essas propostas de neurônios e redes neurais é o nosso cérebro. O cérebro humano é composto por uma rede neural formada por diferentes neurônios. Temos um neurônio conectado a milhões de outros neurônios, e essa rede é formada por bilhões de células que se comunicam entre si a partir de estímulos.
Relacionando o neurônio biológico às redes neurais artificiais
À esquerda, observamos uma imagem de um neurônio do nosso cérebro. Ele é formado pelo corpo celular, onde a informação — isto é, o sinal recebido — é processada. No corpo celular, há ramificações chamadas dendritos, que funcionam como antenas e recebem sinais químicos de outros neurônios, nosso canal de comunicação. Depois de processada, a informação percorre um grande ramo, o axônio, até suas terminações. O axônio é uma estrutura transmissora responsável por levar o impulso adiante. Quando o corpo celular decide que a informação é relevante, dispara um impulso para que outro neurônio a receba. De forma simplificada, esse sinal é transmitido para o espaço entre um neurônio e outro, a sinapse. É por meio do fortalecimento ou enfraquecimento das sinapses que o nosso cérebro aprende. A partir dessa mecânica e dessa fisiologia impressionantes do nosso cérebro, surgiram as redes neurais artificiais.
Vamos fazer uma analogia: uma rede neural de várias camadas é, basicamente, uma abstração matemática do nosso cérebro. Cada um desses nós equivale a um neurônio. É nesse ponto que ocorre o processamento: o nó matemático realiza o cálculo somatório do que é recebido. Nós vamos entrar em mais detalhes no próximo slide. As ramificações representam as conexões entre neurônios, isto é, a passagem da informação de um nó para outro. O sinal que percorre o neurônio biológico humano é equivalente, nessa analogia, às operações matemáticas que conduzem o fluxo de informação até chegar ao nó de saída, com o qual nós obtemos uma resposta.
Definindo entradas, pesos e vieses no neurônio artificial
Como todo esse fluxo — o impulso, o sinal transmitido, o dado que é processado e gera uma resposta — é representado por operações matemáticas, temos dois elementos fundamentais na rede neural: os pesos e os vieses.
Para exemplificar o funcionamento de um neurônio, consideramos primeiro um neurônio isolado e, em seguida, uma rede neural completa, com vários neurônios conectados. Vamos observar os primeiros nós da rede: eles representam as entradas. Suponhamos que estamos analisando fraudes. Cada fraude tem um conjunto de características: horário em que ocorreu, tipo de transação (débito ou crédito), valor, local da ocorrência, se ocorreu em outro país ou fora do local onde a pessoa mora, e o tipo de estabelecimento. Cada uma dessas informações é uma variável X, um nó de entrada da rede.
A partir disso, precisamos atribuir um nível de importância para cada uma dessas entradas. O que seria mais crítico? O que teria maior peso para caracterizar a fraude? Vamos supor que seja a distância entre o local onde a pessoa mora e o local da ocorrência, além do horário. Atribuímos pesos para mensurar esse nível de importância de cada variável, dado o nosso problema. Em seguida, pegamos cada valor de entrada e multiplicamos pelo seu respectivo peso.
Onde entra o viés? Depois de multiplicarmos cada uma das entradas pelo seu peso (seu grau de importância), somamos um viés. Esse viés é um ajuste no nosso valor base. Matematicamente, o viés desloca o resultado da nossa função, o que permite que a rede seja mais flexível aos nossos dados.
Aplicando a função de ativação e interpretando a saída
Basicamente, a fórmula aplicada a essa primeira entrada seria W vezes x (peso vezes a entrada), mais o viés. Em seguida, o neurônio faz um somatório dessa informação, e esse somatório passa pela função de ativação. A função de ativação é um limiar que decide se esse impulso, isto é, essa informação, deve ativar o neurônio ou não.
Como podemos ver, a combinação inicial de entrada, pesos e viés é uma função linear. A função de ativação adiciona a não linearidade, porque sabemos que nossos dados e problemas do mundo real, em sua maior parte, não são lineares. Ao final dessa aplicação, obtemos a saída. Por exemplo, ao entrarmos com dados de fraude, multiplicarmos pelo peso de importância, realizarmos o somatório e aplicarmos a função de ativação, obtemos a probabilidade de a transação ser ou não uma fraude.
Esse é um exemplo de um neurônio artificial simples, um Perceptron (perceptron), que veremos com mais detalhes nas próximas aulas e que também desenvolveremos em código com o PyTorch (PyTorch).
Compreendendo a arquitetura de uma rede neural profunda
Agora que entendemos um neurônio de forma isolada, precisamos compreender como ele funciona em conjunto, como na rede com vários neurônios conectados. O primeiro ponto é entender a arquitetura dessa rede neural. Vamos considerar o exemplo de uma rede neural com três camadas. Portanto, trata-se de uma rede neural profunda, com múltiplas camadas.
A primeira etapa dessa arquitetura é a camada de entrada, que corresponde aos nossos x. Essa camada de entrada é onde os dados brutos entram. Podemos estar trabalhando com transações; poderíamos estar entrando com imagens e seus pixels (pontos da imagem); ou com texto previamente tratado em formato numérico. É aqui que os dados entram.
A próxima é a camada oculta, onde o processamento principal acontece. Elas são chamadas de ocultas porque não visualizamos diretamente sua saída; seu output (saída) não é explícito. Agora, nós iremos mostrar em detalhes que o PyTorch (PyTorch) permite visualizar essas informações e acompanhar o processamento interno.
O ponto crucial é que, em cada neurônio, multiplicamos o valor pelo peso, somamos o viés e repassamos o resultado ao próximo neurônio. Es assim que cada neurônio gera seu resultado e o encaminha adiante.
Consolidando a decisão e preparando a prática com PyTorch
Por fim, temos a camada de saída, onde a decisão final do modelo acontece: se é fraude ou não é; se a imagem é de um cachorro ou de um gato; qual é a probabilidade de ocorrer churn (evasão) ou não; ou, em recomendação de produtos, qual produto tem maior probabilidade de compra. É aqui que a decisão atua e obtemos o resultado final da rede neural.
Aqui entra a grande ideia do Deep (profundo) dentro do aprendizado profundo: utilizamos cada vez mais camadas ocultas, e cada camada recebe uma representação diferente da anterior, extraindo o dado de maneira progressivamente mais refinada. Recebemos na primeira camada entradas mais brutas, fazemos um primeiro refinamento e assim por diante, até chegarmos a uma informação bem mais simples — por exemplo, 0/1: a probabilidade de ser fraude ou não; a imagem de cachorro ou gato. Assim, conseguimos identificar um processo muito mais complexo, com padrões mais complexos, quase um aprendizado hierárquico.
Agora que entendemos os componentes principais das redes neurais, vamos praticar: examinar nossos dados de transações, verificar quais informações de fraude temos e conhecer o núcleo do PyTorch (PyTorch), os tensores, que são onde a informação será armazenada e que sustentarão a rede neural que criaremos. Vamos lá!