Redes neurais convolucionais
Nós usamos uma composição de operações não lineares, chamadas camadas, para aprender uma representação do que estamos estudando.
O número de camadas é o que dá a “profundidade”.
Hoje em dia temos modelos com centenas de camadas.
Nome alternativo (menos apelativo): aprendizado de representação em camadas.
Para trabalhar com redes neurais, é necessário saber fazer multiplicações de matrizes e cálculo de derivadas (gradientes).
Conhecimentos em probabilidade e estatística ajudam a entender de onde as funções vêm e como lidar com os hiperparâmetros.
Vamos ver cada parte separadamente.
Definimos o modelo de regressão linear da seguinte forma:
\[\hat{y_i} = w x_i + b\]
Poderíamos escrever
\[\hat{y_i} = f(x_i)\]
em que:
\[f(x) = w x + b\]
Chamamos \(f\) de ‘layer’ (camada) na terminologia de redes neurais.
Uma ‘layer’ é uma transformação dos dados que é parametrizada por pesos.
‘Aprender’, então, significa encontrar os melhores pesos para cada camada.
No exemplo:
\[f(x) = w x + b\]
Os pesos são \(w\) e \(b\).
Essas camadas são os ‘tijolos’ do Deep Learning, que podem ter diversas ‘camadas’.
A camada do exemplo é chamada de ‘Densa’ ou ‘Linear’.
Um modelo pode possuir uma ou mais dessas camadas.
Mede quanto o modelo está perto do que queremos que ele fique.
No nosso caso, mede o quanto a previsão dada por \(wx + b\) está perto de \(y\), o verdadeiro valor daquele imóvel.
Uma função de perda bastante usada é o MSE: Erro quadrático médio:
\[L(\hat{y}) = \frac{1}{n}\sum_{i=1}^{n} (y_i - \hat{y_i})^2\]
\[L(w, b) = \frac{1}{n} \sum_{i=1}^{n} (y_i - wx_i - b)^2\]
Queremos encontrar o valor mínimo da curva.
A partir de um ponto, consigo traçar uma reta tangente a esse ponto. O que fazer?
\(b\) e \(m\) representam \(b\) e \(w\) no nosso exemplo. O eixo ‘Error’ representa o valor da função de perda.
Conseguimos visualizar a descida até o mínimo da função de perda pelo método do gradiente.
Na direita a reta ajustada para os dados.
Em vez de calcular a média da derivada em todos os exemplos da base de dados, calculamos em apenas uma amostra. Essa amostra é chamada de mini-batch.
Cada vez que atravessamos a base inteira dessa forma chamamos de ‘epoch’.
É possível atualizar os pesos sem precisar fazer contas na base inteira. Mais rápido.
Como estimamos o passo com apenas uma amostra, os passos podem ser ruins.
Na prática, parece que o fato dos passos serem ruins perto do mínimo é bom, pois isso faz um certo tipo de regularização. Não se sabe explicar esse comportamento muito bem ainda. Fonte
Existem outras variações do SGD, cada tentando resolver um problema diferente.
Esse artigo é um ótimo resumo de todas as versões que existem.
Não existe um que é sempre melhor do que os outros.
Além do SGD, os mais usados são SGD com momentum, adam e rmsprop.
Usamos a função de ativação \(\sigma(z) = max\{0, z\}\).
A ideia do ReLu é ser fácil de otimizar, porque é muito parecido com simplesmente não ter ativação (ativação linear).
As derivadas são altas quando a unidade é importante, isto é, quando o output é alto.
Ver capítulo 6.3.1 do Deep Learning Book para outras extensões.
\[\sigma(z) = \frac{1}{1 + e^{-z}}\]
Antes da introdução do ReLu, a maioria das redes neurais usava esse tipo de ativação.
A derivada da sigmoid fica saturada quando o input é muito negativo ou muito positivo.
\[\sigma(z) = \frac{1}{1 + e^{-z}}\]
Não se recomenda usá-la como função de ativação em hidden layers
Ver capítulo 6.2.3 do Deep Learning Book.
Em problemas de classficação, não queremos que \(\hat{y}\) seja qualquer valor, e sim a probabilidade de \(y\) ser de uma determinada classe.
Temos então 2 pontos:
Queremos que \(\hat{y}\) seja um número entre 0 e 1.
Como queremos que o output \(\hat{y}\) seja uma probabilidade, não queremos minimizar o MSE e sim uma outra função de perda. Como o sigmoid satura muito rápido, precisamos de uma função de perda que lide com isso.
Para resolver esse problema basta usar uma função de ativação na última camada que transforme o intervalo \(]-\infty, \infty[\) no intervalo \([0,1]\).
Uma função famosa por isso, e que já conhecemos é a função sigmoid.
Em geral usamos a função de perda que chamamos de ‘cross entropy’.
Essa função é dada por:
\[L(\hat{y}) = \sum_{i = 1}^{n} \left[ y_i \times \log \hat{y_i} + (1-y) \times \log(1 - \hat{y_i}) \right]\] Isso fica mais claro quando lemos o seguinte código:
Isso equivale a estimativa de máxima verossimilhança quando assumimos que \(y\) tem distribuição \(\text{Bernoulli}(\hat{y})\).
banana | maçã | laranja |
---|---|---|
0 | 1 | 0 |
1 | 0 | 0 |
0 | 0 | 1 |
O número de colunas igual ao número de categorias possíveis.
O número de linhas é o número de observações da base.
Os valores são 0 quando a observação não é daquela categoria e 1 quando é da categoria.
Queremos que o nosso modelo retorne uma matriz de probabilidades, por exemplo:
banana | maçã | laranja |
---|---|---|
0.2 | 0.7 | 0.1 |
0.6 | 0.1 | 0.3 |
0.1 | 0.3 | 0.6 |
Seja \(x = (x_1, x_2, ... x_k)\) então:
\[\sigma(x)_i = \frac{e^{x_i}}{\sum_{i = 1}^{n}{e^{x_i}}}\]
MLPs são modelos de redes neurais simples
A natureza da resposta leva a diferentes funções de perda
Para regressão, usualmente utilizamos o erro quadrático médio. Para logística, usamos a crossentropy
Podemos trabalhar com respostas unidimensionais ou multidimensionais.
Cada valor representa a intensidade de cinza.
Imagens coloridas são representadas como um array de 3 dimensões.
É como se fosse um ‘empilhado’ de 3 matrizes.
Cada elemento é a intensidade de cada cor daquele píxel.
A principal diferença com relação à MLP é que a as camadas ‘densas’ aprendem padrões globais dos inputs, enquanto convoluções aprendem padrões locais dos inputs.
Por exemplo, considere a matriz de pesos 3x3
\[W = \left[\begin{array}{rrr}-1&-1&-1\\0&0&0\\1&1&1\end{array}\right]\]
E a janela 3x3 a partir do ponto \((12,16)\) da matriz \(X\)
\[X_{12,16} = \left[\begin{array}{rrr} 0.98 & 0.53 & 0.79 \\ 0.97 & 0.99 & 1.00 \\ 0.98 & 1.00 & 1.00 \end{array}\right]\]
A convolução de \(X\) por \(W\) no ponto \((12,16)\) é dada por
\[\begin{aligned} (X_{12,16} *w )_{12,16} &= w_{1,1}x_{11,15} + w_{1,2}x_{11,16} + w_{1,3}x_{11,17} + \\ &+ w_{2,1}x_{12,15} + w_{2,2}x_{12,16} + w_{2,3}x_{12,17} + \\ &+ w_{3,1}x_{13,15} + w_{3,2}x_{13,16} + w_{3,3}x_{13,17} \end{aligned}\]
Ou seja, é uma multiplicação ponto a ponto.
Definimos uma matriz de pesos (em cinza na representação ao lado)
Andamos com essa matriz de pesos para cada parte da imagem (em azul ao lado).
Esses pesos são multiplicados e depois somados para gerar uma nova ‘imagem’ (em verde).
No padding, no strides | Arbitrary padding, no strides | Half padding, no strides | Full padding, no strides |
No padding, strides | Padding, strides | Padding, strides (odd) |
Primeiro temos um kernel (matriz de parâmetros p/ cada canal):
Em seguida somamos os outputs de cada canal:
Serve para reduzir a dimensão da imagem. Parece com o que fazemos na convolução, mas em vez disso calculamos o máximo dos valores de cada janela.
Mesclamos algumas camadas de convolução e max pooling, diminuindo a altura e largura das imagens e aumentando a profundidade.
Depois transformamos em uma matriz e fazemos um modelo de classificação logístico usual.
Técnica de regularização bastante utilizada em deep learning.
Consiste em aleatóriamente zerar alguns outputs.
É parametrizado por uma probabilidade \(p\) de zerar alguns parâmetros.
redes neurais convolucionais CNN’s trocam a função de “multiplicação de matriz” pela função de convolução.
CNN’s são úteis para trabalhar com imagens, pois lidam com a dependência local dos dados.
CNN’s podem ser utilizadas para lidar com problemas de regressão e classificação, unidimensionais e multidimensionais.
Dropout é uma técnica de regularização muito útil no contexto de redes neurais.
2024