6.8 Função Deviance
\[ \begin{aligned} D(y,\hat\mu(x)) &= \sum_{i=1}^n 2\left[y_i\log\frac{y_i}{\hat\mu_i(x_i)} + (1-y_i)\log\left(\frac{1-y_i}{1-\hat\mu_i(x_i)}\right)\right] = \\ &= 2 D_{KL}\left(y||\hat\mu(x)\right), \end{aligned} \]
onde \(D_{KL}(p||q) = \sum_i p_i\log\frac{p_i}{q_i}\) é a divergência de Kullback-Leibler.
Agora, veja um modelo de deep learning:
Faz uma combinação linear inputs \(x\), adiciona um viés (bias) e depois aplica uma função de ativação não linear. No nosso caso, adiciona um parâmetro multiplicando \(x\) e um viés fixo, fazendo
\[ f(x) = w x + \text{bias} \]
A função de ativação é uma sigmoide, dada por
\[ \sigma(x) = \frac{1}{1 + e^{-x}} \]
Notou alguma similaridade?
6.8.1 Função de custo: categorical cross-entropy
\[ \begin{aligned} H(p, q) &= H(p) + D_{KL}(p||q) \\ &= -\sum_x p(x)\log(q(x)) \end{aligned} \]
No nosso caso, isso é equivalente a uma constante mais a função deviance.
Para ajustar os parâmetros, existem diversos algoritmos de otimização. Um dos mais utilizados é o de descida de gradiente estocástico.
6.8.2 Exemplot
logistic <- function(x) 1 / (1 + exp(-x))
n <- 100000
set.seed(19910401)
dados <- tibble(
x = runif(n, -2, 2),
y = rbinom(n, 1, prob = logistic(-1 + 2 * x))
)
dados
Ajustando uma regressão logística no R
modelo <- glm(y ~ x, data = dados, family = 'binomial')
broom::tidy(modelo)
Ajustando um deep learning com o keras
library(keras)
input_keras <- layer_input(shape = 1, name = "modelo_keras")
output_keras <- input_keras %>%
layer_dense(units = 1, name = "camada_unica") %>%
layer_activation("sigmoid",
input_shape = 1,
name = "link_logistic")
# Constrói a nossa hipótese f(x) (da E[y] = f(x))
modelo_keras <- keras_model(input_keras, output_keras)
A especificação do modelo é dada por
summary(modelo_keras)
#> ___________________________________________________________________________
#> Layer (type) Output Shape Param #
#> ===========================================================================
#> modelo_keras (InputLayer) (None, 1) 0
#> ___________________________________________________________________________
#> camada_unica (Dense) (None, 1) 2
#> ___________________________________________________________________________
#> link_logistic (Activation) (None, 1) 0
#> ===========================================================================
#> Total params: 2
#> Trainable params: 2
#> Non-trainable params: 0
#> ___________________________________________________________________________
Agora, especificamos a função de perda e a forma de otimizar
modelo_keras %>%
compile(
loss = 'binary_crossentropy',
optimizer = "sgd"
)
modelo_keras %>%
fit(x = dados$x, y = dados$y, epochs = 3)
modelo_keras %>%
get_layer("camada_unica") %>%
get_weights()
#> [[1]]
#> [,1]
#> [1,] 2.00727
#>
#> [[2]]
#> [1] -1.017746
Algumas dúvidas que podem surgir para você nesse momento:
- Se é a mesma coisa, por que ele está ganhando tanta popularidade?
- Devo estudar deep learning ou posso continuar fazendo regressão logística?