Rede Neural Recorrente (RNN) com Keras

Heitor Victor

2019-09-09

Este arquivo contém um breve tutorial de como utilizar RNN para treinar um modelo para predizer o número presente em uma imagem. Para treinar o modelo será utilizada a base de dados digit.recognizer que pode ser encontrada no site de disputas em DS Kaggle atráves do link https://www.kaggle.com/c/digit-recognizer/leaderboard.

Carregando pacotes e criando as matrizes de dados

Inicialmente vamos carregar os pacotes tidyverse e keras. Fixemos também as dimensões da matriz de dados tal como o número de classes da variável resposta.

Para visualizar uma imagem podemos selecionar uma linha do data.frame, e fazer algumas transformações na matriz que irá gerar cada imagem para que o número fique “em pé”. O resultado é visto abaixo:

Podemos também ver vários digitos ao mesmo tempo e em escala de cinza. A função a seguir nos dá esta possibilidade:

## 
## Removing label column...
## Removing Flag column...

Agora, vamos criar as matrizes de treino e teste. Isto é necessário pois nos modelos de redes neurais precisamos explicitar as matrizes utilizadas no cálculo de cada modelo. É basicamente a mesma coisa de uma regressão, porém, no R para estimar modelos de regressão existem funções internas que nos ajudam nesta parte.

Treinando modelo

Antes de iniciar o processo de estimação, verifique se o tensorflowestá instalado em sua máquina. Ele será utilizado pelo keras. Para instalar o tensorflow utilize: tensorflow::install_tensorflow().

Agora vamos começar criar o objeto para treinamento do modelo. Primeiro defina o método de modelagem a ser utilizado. O keras foi construído de maneira bem intuítiva e se encaixa com a metodologia tidy. Portanto, podemos utilizar o operador %>%.

Agora, definir os hiperparâmetros do modelo.

Os modelos de RN são estimados por meio de camadas. O comando layer_dense define estas camadas. A seguir a descrição dizendo para que cada parâmetro serve:

  1. units: Serve para informarmos o número de parâmetros.

  2. activation: Define qual será a função de ativação. Em redes neurais a função de ativação é o meio que utiliza-se para estimar os parâmetros de cada camada. Relacionando com regressão, a função de ativação equivale ao método de estimação dos parâmetros, por exemplo, quadrados mínimos.

  3. input_shape: Informa o número das colunas da matriz X que serão utilizadas.

  4. layer_drop: Este argumento faz com que sejam abandonadas algumas linhas da matriz de treinamento. É útil para não gerar overfitting.

Note o número de parâmetros é 10 e a função de ativação é a softmax. Este números de parâmetros da última camada representa o número de colunas a serem estimadas. É muito parecido com regressão multivariada. Ainda, note que as semelhanças não são atoa, já que o que estamos fazendo é estimar um modelo em que a variável resposta segue uma distribuição multinomial.

Quanto à função de ativação softmax, está serve para gerar estimativas no intervalo (0,1), tal como a função logística. A função softmax é dada por:

\[ \sigma(z)_j = \frac{e^{z_j}}{\sum^K_{k = 1} e^{z_j}} \text{ onde } j = 1,2,...,K. \]

Não menos importante, a função relu é amplamente utilizada nas camadas ocultas (antes da última), pois ela é não-linear e de fácil utilização pois só recebe valores positivos e é igual a reta afim para tais valores. Esta função de ativação é bastante útil pois facilita a computação, contudo, esta também apresenta alguns problemas de estimação com descidas de gradientes que tendem à zero devido à problemas de máquina (leia-se métodos númericos).

\[ f(x) = máx(0,x) \]

O próximo passo é definir a função de perda, o método de estimação e a métrica de performance. Para tal utilize compile. Para a função de perda vamos utilizar a entropia cruzada para variáveis categoricas. Quanto ao método de otimização para estimar os parâmetros, utilizaremos o método RMSProp. Por fim, a métrica de performance será a acúracia.

Agora vamos treinar o modelo. Veja que estamos salvando o processo a seguir em um objeto. Este objeto irá guardar a trajetória de estimação do modelo para que possamos ver a função de perda e a acúracia. Função de perda é o que será minimizado, geralmente minimiza-se a acúracia.

Para treinar sua rede, utilize fit. Nessa função acrescente a matriz de treino e o vetor resposta (neste caso matriz), como também o número de validações cruzadas (epochs) e o tamanho de cada validação cruzada (batch_size). Além disso, podemos definir aleatóriamente uma parte da nossa matriz de treinamento para fazer as validações cruzadas por meio do argumento validation_split. Todas esta preocupação com overfitting é muito importante pois estamos trabalhando com um imenso número de parâmetros.

Testando o modelo

Após treinamento, podemos agora ver a acúracia de nosso modelo na base de testes. basta utilizar a função evaluate dando como argumentos a matriz de teste e a matriz de respostas.

## $loss
## [1] 0.09737537
## 
## $acc
## [1] 0.9745722

Vamos agora fazer o mesmo que a função evaluate faz só que manualmente =). Basta ter as matrizes de pesos de cada camada e fazer as operações matriciais.

## [1] "list"
## [1] 6
## [1] 784 256
##      [,1] [,2] [,3] [,4]  [,5] [,6] [,7] [,8] [,9]   [,10]
## [1,]    0    0    0    0 6e-05    0    0    0    0 0.99994

Note que o output são probabilidades para cada digito. O digito (cada coluna é um digito) com a maior probabilidade será escolhido para a predição. Para nosso exemplo o digito da base de teste foi o 9 (coluna 10). O modelo estimou uma prob. de 99.9999% de ser este digito. Acertamos em cheio !