Chapter 10 Modelos Neurais


10.1 Veja uma Rede Neural em Funcionamento

Vamos entrar em http://playground.tensorflow.org/ e ver um rede neural em funcionamento.

knitr::include_url("http://playground.tensorflow.org/")

10.2 Neurônio simples

Um neurônio artificial nada mais é do que um artefato de software que faz uma combinação linear das entradas e aplica um função de ativação como a função \(sign\), \(tanh\) ou \(relu\) para produzir uma saída.

\[ f(X) = sign( w_0 + w_1 x_1 + ... + w_n x_n ) \]

O treinamento do neurônio é feito ajustando-se os pesos \(w_n\) de acordo com o erro de predição obtido para se estimar a saída \(f(X) \cong y\).

\[ \min_{W} \sum || f(X)- y || \]

10.3 Redes neurais

Um único neurônio entretanto tem uma capacidade limitada de aprendizado. Por exemplo, ele não consegue aprender a função XOR.

Função \(XOR(X) \rightarrow y\):

  X     y
 0 0    0
 0 1    1
 1 0    1
 1 0    0

Pois um único neurônio somente tem capacidade para fazer a separação de conjuntos linearmente separáveis.

Para resolver essa limitação podemos então trabalhar com múltiplos neurônios em camadas. As saídas dos neurônios de uma camada são então empregadas como entradas para a camada seguinte. As camadas entre a camada inicial de neurônios (de entrada) e a camada final (de saída) constitui as camadas ocultas da rede.

O treinamento da rede segue o mesmo princípio, embora mais complexo, ajustando os pesos \(w_n\) de acordo com o erro de predição obtido para se estimar a saída \(f(X) \cong y\).

\[ \min_{W} \sum || f(X)- y || \]

Chamamos esse aprendizado de backpropagation ou retropropagação.

10.4 Teorema da Aproximação Universal

Pode-se demonstrar (George Cybenko, 1989 e Kurt Hornik, 1991) que redes neurais de múltiplas camadas são aproximadores universais de funções o quê dá uma grande capacidade para os modelos neurais.

10.5 Deeplearning

Modelos deeplearning são baseados em modelos neurais exatamente como vimos, mas incluem a ideia de que um maior número de camadas fornece uma capacidade maior de representação dos dados. Embora as redes deeplearning não difiram essencialmente do modelo neural tradicional várias arquiteturas de rede (redes convolucionais, recorrentes etc.) foram desenvolvidas nos últimos anos aproveitando uma maior capacidade computacional antes não disponível.

Em geral as bibliotecas deeplearning, para buscar eficiência no treinamento e execução de redes profundas (até dezenas e centenas de camadas com milhares de neurônios) , implementam uma série de recursos como a representação dos dados por tensores, execução em árvore de cálculos e uso de gpu. Algumas das bibliotecas mais empregadas são TensorFlow/Keras, CNTK, PyTorch.

Para R empregaremos H2O como biblioteca de deeplearning.

nota: No momento que escrevemos este texto a integração do Python com bibliotecas Deeplearning parece mais facilitado que em R.

10.6 Modelos Neurais são sempre melhores que quaisquer outros modelos?

Não. Modelos neurais tem uma grande capacidade e os modelos deeplearning permitiram a solução de vários problemas que antes não podíamos resolver com modelos mais tradicionais. Carros autonômos, tradução automática de texto e speech, reconhecimento de imagens e pessoas são algumas de suas aplicações. Mas para muitos outros problemas a busca de um modelo para os dados depende essencialmente do dado em questão que, para alguns, modelos como uma árvore de decisão (random forest) ou outros modelos tradicionais ainda podem trazer uma resposta melhor. Além disso as redes neurais, por apresentarem um grande número de parâmetros (hyperprameters), nem sempre são fáceis de treinar.

10.7 Um Modelo Neural Simples em R

Modelos neurais podem ser empregados para implementar modelos Supervisionados e não Supervisionados, podemos usar para Classificação, Regressão não Linear, Clusterização e muitas outras tarefas. Aqui vamos nos ater a modelos Supervisionados para Classificação. Aqui empregamos a biblioteca neuralnet para classificação.

library("neuralnet")
## Warning: package 'neuralnet' was built under R version 3.5.3
# install.packages('ISLR')
library(ISLR)
## Warning: package 'ISLR' was built under R version 3.5.3
RNGversion('3.5.0')
set.seed(1984)

data = College
head(data)
##                              Private Apps Accept Enroll Top10perc Top25perc
## Abilene Christian University     Yes 1660   1232    721        23        52
## Adelphi University               Yes 2186   1924    512        16        29
## Adrian College                   Yes 1428   1097    336        22        50
## Agnes Scott College              Yes  417    349    137        60        89
## Alaska Pacific University        Yes  193    146     55        16        44
## Albertson College                Yes  587    479    158        38        62
##                              F.Undergrad P.Undergrad Outstate Room.Board Books
## Abilene Christian University        2885         537     7440       3300   450
## Adelphi University                  2683        1227    12280       6450   750
## Adrian College                      1036          99    11250       3750   400
## Agnes Scott College                  510          63    12960       5450   450
## Alaska Pacific University            249         869     7560       4120   800
## Albertson College                    678          41    13500       3335   500
##                              Personal PhD Terminal S.F.Ratio perc.alumni Expend
## Abilene Christian University     2200  70       78      18.1          12   7041
## Adelphi University               1500  29       30      12.2          16  10527
## Adrian College                   1165  53       66      12.9          30   8735
## Agnes Scott College               875  92       97       7.7          37  19016
## Alaska Pacific University        1500  76       72      11.9           2  10922
## Albertson College                 675  67       73       9.4          11   9727
##                              Grad.Rate
## Abilene Christian University        60
## Adelphi University                  56
## Adrian College                      54
## Agnes Scott College                 59
## Alaska Pacific University           15
## Albertson College                   55
data_scaled = data
data_scaled[,2:18] = scale(data[,2:18]) 

L = sample(1:nrow(data),round(nrow(data)/3))
train = as.data.frame(data_scaled[-L,])
test = as.data.frame(data_scaled[L,])

# n = names(train)
# f <- as.formula(paste("Private ~", paste(n[!n %in% "Private"], collapse = " + ")))

f <- "Private ~ ."
net = neuralnet(f,data=train,hidden=c(5,3),linear.output=F)
plot(net)

predicted_data = predict(net,test[,2:18])
predicted_data = max.col(predicted_data)

predicted_data = levels(data$Private)[predicted_data]

cm = table(predicted_data,test$Private)
print(cm)
##               
## predicted_data  No Yes
##            No   59  16
##            Yes   5 179
cat('Accuracy : ', sum(diag(cm))/sum(cm)* 100, '%')
## Accuracy :  91.89189 %

10.8 Um modelo DeepLearning com H2O

Aqui um modelo de Deeplearning empregando a biblioteca H2o.

RNGversion('3.5.0')
set.seed(1984)

# install.packages('h2o)
library(h2o)
## Warning: package 'h2o' was built under R version 3.5.3
## 
## ----------------------------------------------------------------------
## 
## Your next step is to start H2O:
##     > h2o.init()
## 
## For H2O package documentation, ask for help:
##     > ??h2o
## 
## After starting H2O, you can use the Web UI at http://localhost:54321
## For more information visit http://docs.h2o.ai
## 
## ----------------------------------------------------------------------
## 
## Attaching package: 'h2o'
## The following objects are masked from 'package:stats':
## 
##     cor, sd, var
## The following objects are masked from 'package:base':
## 
##     %*%, %in%, &&, ||, apply, as.factor, as.numeric, colnames,
##     colnames<-, ifelse, is.character, is.factor, is.numeric, log,
##     log10, log1p, log2, round, signif, trunc
# install.packages('bit64')
# library(bit64) # for speed data.table

h2o.init()
## 
## H2O is not running yet, starting it now...
## Warning in .h2o.startJar(ip = ip, port = port, name = name, nthreads = nthreads, : You have a 32-bit version of Java. H2O works best with 64-bit Java.
## Please download the latest Java SE JDK from the following URL:
## https://www.oracle.com/technetwork/java/javase/downloads/index.html
## 
## Note:  In case of errors look at the following log files:
##     C:\Users\rdeol\AppData\Local\Temp\Rtmp6X33kK\file64dc73bb45ae/h2o_rdeol_started_from_r.out
##     C:\Users\rdeol\AppData\Local\Temp\Rtmp6X33kK\file64dc7d476dab/h2o_rdeol_started_from_r.err
## 
## 
## Starting H2O JVM and connecting: ... Connection successful!
## 
## R is connected to the H2O cluster: 
##     H2O cluster uptime:         13 seconds 499 milliseconds 
##     H2O cluster timezone:       America/Sao_Paulo 
##     H2O data parsing timezone:  UTC 
##     H2O cluster version:        3.30.0.1 
##     H2O cluster version age:    7 months and 12 days !!! 
##     H2O cluster name:           H2O_started_from_R_rdeol_rlj378 
##     H2O cluster total nodes:    1 
##     H2O cluster total memory:   0.97 GB 
##     H2O cluster total cores:    0 
##     H2O cluster allowed cores:  0 
##     H2O cluster healthy:        TRUE 
##     H2O Connection ip:          localhost 
##     H2O Connection port:        54321 
##     H2O Connection proxy:       NA 
##     H2O Internal Security:      FALSE 
##     H2O API Extensions:         Amazon S3, Algos, AutoML, Core V3, TargetEncoder, Core V4 
##     R Version:                  R version 3.5.2 (2018-12-20)
## Warning in h2o.clusterInfo(): 
## Your H2O cluster version is too old (7 months and 12 days)!
## Please download and install the latest version from http://h2o.ai/download/
# c1=h2o.init(max_mem_size = "2G", 
#            nthreads = 2, 
#            ip = "localhost", 
#            port = 54321)

head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
model =  h2o.deeplearning(1:4,5,                         # input X,y
                          as.h2o(iris),                  # df input
                          epochs=100,                    # train limit
                          hidden=c(4,16,4))              # network
## 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |======================================================================| 100%
## 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |======================================================================| 100%
summary(model)
## Model Details:
## ==============
## 
## H2OMultinomialModel: deeplearning
## Model Key:  DeepLearning_model_R_1605535249587_1 
## Status of Neuron Layers: predicting Species, 3-class classification, multinomial distribution, CrossEntropy loss, 183 weights/biases, 6,6 KB, 15.000 training samples, mini-batch size 1
##   layer units      type dropout       l1       l2 mean_rate rate_rms momentum
## 1     1     4     Input  0.00 %       NA       NA        NA       NA       NA
## 2     2     4 Rectifier  0.00 % 0.000000 0.000000  0.000854 0.000387 0.000000
## 3     3    16 Rectifier  0.00 % 0.000000 0.000000  0.004740 0.005966 0.000000
## 4     4     4 Rectifier  0.00 % 0.000000 0.000000  0.252567 0.431084 0.000000
## 5     5     3   Softmax      NA 0.000000 0.000000  0.343126 0.454181 0.000000
##   mean_weight weight_rms mean_bias bias_rms
## 1          NA         NA        NA       NA
## 2    0.029201   0.611542  0.520232 0.088882
## 3    0.009212   0.385829  1.033779 0.062302
## 4   -0.039279   0.386829  0.981728 0.034980
## 5   -0.683528   1.977224  1.578711 2.693363
## 
## H2OMultinomialMetrics: deeplearning
## ** Reported on training data. **
## ** Metrics reported on full training frame **
## 
## Training Set Metrics: 
## =====================
## 
## Extract training frame with `h2o.getFrame("iris_sid_8fd5_1")`
## MSE: (Extract with `h2o.mse`) 0.02359127
## RMSE: (Extract with `h2o.rmse`) 0.1535945
## Logloss: (Extract with `h2o.logloss`) 0.07889532
## Mean Per-Class Error: 0.04
## Confusion Matrix: Extract with `h2o.confusionMatrix(<model>,train = TRUE)`)
## =========================================================================
## Confusion Matrix: Row labels: Actual class; Column labels: Predicted class
##            setosa versicolor virginica  Error      Rate
## setosa         50          0         0 0.0000 =  0 / 50
## versicolor      0         45         5 0.1000 =  5 / 50
## virginica       0          1        49 0.0200 =  1 / 50
## Totals         50         46        54 0.0400 = 6 / 150
## 
## Hit Ratio Table: Extract with `h2o.hit_ratio_table(<model>,train = TRUE)`
## =======================================================================
## Top-3 Hit Ratios: 
##   k hit_ratio
## 1 1  0.960000
## 2 2  1.000000
## 3 3  1.000000
## 
## 
## 
## 
## 
## Scoring History: 
##             timestamp   duration training_speed    epochs iterations
## 1 2020-11-16 12:01:32  0.000 sec             NA   0.00000          0
## 2 2020-11-16 12:01:32  0.212 sec  28301 obs/sec  10.00000          1
## 3 2020-11-16 12:01:32  0.261 sec 153061 obs/sec 100.00000         10
##        samples training_rmse training_logloss training_r2
## 1     0.000000            NA               NA          NA
## 2  1500.000000       0.37973          0.44927     0.78371
## 3 15000.000000       0.15359          0.07890     0.96461
##   training_classification_error
## 1                            NA
## 2                       0.14667
## 3                       0.04000
## 
## Variable Importances: (Extract with `h2o.varimp`) 
## =================================================
## 
## Variable Importances: 
##       variable relative_importance scaled_importance percentage
## 1  Petal.Width            1.000000          1.000000   0.342631
## 2 Petal.Length            0.847247          0.847247   0.290294
## 3  Sepal.Width            0.676052          0.676052   0.231637
## 4 Sepal.Length            0.395288          0.395288   0.135438
h2o.scoreHistory(model)  #  see training_classification_error = 100 - acc
## Scoring History: 
##             timestamp   duration training_speed    epochs iterations
## 1 2020-11-16 12:01:32  0.000 sec             NA   0.00000          0
## 2 2020-11-16 12:01:32  0.212 sec  28301 obs/sec  10.00000          1
## 3 2020-11-16 12:01:32  0.261 sec 153061 obs/sec 100.00000         10
##        samples training_rmse training_logloss training_r2
## 1     0.000000            NA               NA          NA
## 2  1500.000000       0.37973          0.44927     0.78371
## 3 15000.000000       0.15359          0.07890     0.96461
##   training_classification_error
## 1                            NA
## 2                       0.14667
## 3                       0.04000
plot(model)

test1 = apply(iris[iris$Species == 'setosa',1:4], 2, mean) 
test2 = apply(iris[iris$Species == 'virginica',1:4], 2, mean) 
test3 = apply(iris[iris$Species == 'versicolor',1:4], 2, mean) 
test = rbind(test1,test2,test3)

newdata = h2o.predict(model, 
                      as.h2o(test))
## 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |======================================================================| 100%
## 
  |                                                                            
  |                                                                      |   0%
  |                                                                            
  |======================================================================| 100%
pred = as.data.frame(newdata$predict) # Formal class H2O... need to be converted

print(pred)
##      predict
## 1     setosa
## 2  virginica
## 3 versicolor

10.9 Exercício

Empregue o template de uso do pacote neuralnet para o data set college e implemente o modelo para o conjunto iris. Lembre-se de empregar

RNGversion('3.5.0')
set.seed(1984)

Empregue as mesmas configurações da rede no modelo e não faça o rescale dos dados.

10.10 Exercício

Empregue o template de uso do pacote H2o para o data set iris e implemente o modelo para o conjunto fraud.

O dataset fraud encontra-se em:

(http://meusite.mackenzie.br/rogerio/ML/qconlondon2016_sample_data.csv', header=TRUE)

Você deve alterar o modelo para contemplar os conjuntos de treinamento (2/3) e teste (1/3) como temos empregado. Também, não empregue o atributo fraud$charge_time no modelo (veja que todas as operações são no mesmo horário).

Altere o modelo certificando-se dos seguintes parâmetros:

epochs=500, 

classification_stop=0.4,

hidden=c(4,16,4)

Lembre-se de empregar


RNGversion('3.5.0')
set.seed(1984)

Veja que mesmo com o seed o treinamento da rede (que gera grupos de treinamento e teste internamente para treinar o modelo) pode apresentar resultados diferentes a cada execução. Respeite portanto os parâmetros dados e as recomendações nas questões sobre execuções sucessivas.