A Magia das Redes Neurais Artificiais

Imagine conseguir uma maneira de treinar o computador para:

1) Com um Conjunto de Dados de Entrada e seus Resultados(Saídas) conhecidos
2) Estimar com boa precisão as Saídas(Resultados) para um novo Conjunto de Dados de Entrada

Imaginou? Pois é exatamente isto que as Redes Neurais Artificiais possibilitam para você. Leia este artigo até o final quando farei um Exemplo Prático em vídeo que você poderá replicar em seu computador. Ok?

Rede Neural Como Caixa-Preta

A Rede Neural Artificial é como uma Caixa-Preta, não sabemos detalhes de como funciona internamente, mas sabemos que ao colocarmos valores de Entrada obteremos os valores de Saída corretos. (clique aqui para uma prova visual de como as Redes Neurais Artificiais se ajustam a qualquer função matemática contínua)

Redes Neurais Artificiais

As Redes Neurais Artificiais fazem parte do conjunto de técnicas de IA(Inteligência Artificial) para que o computador/máquina/robô/carro/etc tome decisões, muitas vezes com resultados melhores que os especialistas humanos. As Redes Neurais Artificiais são fundamentais para o sucesso da Indústria 4.0!

Descobrindo as Redes Neurais Artificiais

Meu primeiro contato com Redes Neurais foi em 1996 quando uma empresa Metal-Mecânica, para a qual já havíamos prestado serviços de Automação, nos desafiou a identificar os números marcados manualmente com punções em peças metálicas.

O desafio era grande, pois não conhecíamos ninguém que já tivesse feito algo semelhante.

Bom … me debrucei sobre o problema até chegar às Redes Neurais Artificiais. Felizmente a Internet em 1996 já era acessível no Brasil e achei fantástico que o algoritmo da Rede Neural Artificial pudesse se ajustar para “entender” o problema.

Lembro que na época programei tudo em Turbo Pascal usando Orientação a Objetos. Deu bastante trabalho!

Infelizmente o trabalho não foi aplicado na empresa porque ficou evidente para nós que, se queríamos alguma chance de sucesso, era necessário controlar melhor as condições de marcação das peças e também da tomada das fotografias.

Isto ficou impraticável para a empresa, portanto continuaram dependendo de um operador para ler os números marcados sem obedecer a regras rígidas de marcação dos números e tomada das fotos/imagens.

Uma Experiência Para Ser Lembrada

Como não consegui o resultado prático que eu esperava para a Indústria, deixei de lado as Redes Neurais Artificiais, mas nunca esqueci seu potencial.

Pois veja, final de 2017, quando estava reciclando meus conhecimentos de BIG DATA, Data Analytics e áreas correlatas, fiquei novamente em contato com Redes Neurais Artificiais.

Nestes cursos consolidei meus conhecimentos sobre a Linguagem R, que é uma Linguagem Estatística com grandes recursos em IA, e particularmente aprendi um pacote chamado H2O que torna muito simples aplicar Redes Neurais Artificiais em casos reais.

Com poucas linhas de programação você consegue treinar a Rede Neural Artificial e predizer valores para um novo Conjunto de Dados de Entrada.

O Neurônio Artificial

Nas Redes Neurais Artificiais um único neurônio artificial procura imitar o neurônio humano, recebendo e transmitindo informações.

Neurônio Artificial

Clique aqui se quiser saber mais sobre os fundamentos do método de Redes Neurais Artificiais.

Um único neurônio pode resolver problemas muito simples, como por exemplo a tabela verdade do operador lógico OU.

Unindo-se vários destes neurônios, em várias camadas de neurônios, é possível resolver problemas bastante complexos e não-lineares.

Neurônio Artificial - Múltiplas Camadas

Aplicando as Redes Neurais Artificiais na Engenharia

O caso que explicarei neste artigo é bem conhecido dos Engenheiros. Trata-se da Viga/Eixo/Cilindro em Balanço com Carga Concentrada na Extremidade.

cantilever-beam-01

(Obs.: fiz o meu melhor no começo deste artigo apenas com TEXTOS e IMAGENS, mas no final do artigo você encontrará um VÍDEO explicando detalhadamente como replicar este estudo com Redes Neurais Artificiais.)

Para o caso acima sabemos que a deflexão(flecha) máxima na extremidade, onde aplica-se a carga concentrada, segue a equação Flecha = (P x L^3) / (3 x E x I), onde I é o momento de inércia de área, que para a circunferência vale I = 3,14159 x D^4 / 64.

Cálculo da Viga

I do Círculo

Coloquei estas equações em uma Planilha Excel e gerei 100.000 linhas com valores aleatórios para P(carga) e L(comprimento do eixo). P variando de 0 a 30 N(Newtons) e L variando entre 1000 e 1500 mm.

Neste caso considerei fixos o diâmetro do eixo, valendo 20 mm e o E(módulo de elasticidade do material do eixo) valendo 210.000 N/mm^2 (210 GPa) (aço com baixo teor de carbono).

Cálculo da Flecha do Cilindro

Veja na figura acima que criei a coluna “Flecha Ajustada” que nada mais é do que o arredondamento dos valores de Flecha, assim obtive valores de Flecha inteiros variando de 0 a 20 mm (21 valores discretos).

Preparando o Arquivo de Dados de Entrada

A partir disto gerei um arquivo CSV contendo apenas as duas variáveis independentes (explanatórias) P e L e a variável dependente Flecha.

Arquivo CSV gerado

Perceba que editei o arquivo CSV para alterar os nomes das 3 colunas que ficaram simplesmente P, L e Fl. Isto facilitará nosso trabalho futuro com a Linguagem R. Também substitui as vírgulas por pontos.

Após isto, já com o arquivo de dados preparado, fui para o R (Linguagem R) para fazer o treinamento da Rede Neural Artificial de forma que para qualquer par de entradas de P e L eu obtivesse a Flecha correta.

Lembrando que P varia entre 0 e 30 N e que L varia de 1000 a 1500 mm. As flechas de saída esperadas devem ser números inteiros entre 0 e 20 mm.

Uma vez que você instale o software gratuito R poderá seguir os passos mostrados abaixo.

Redes Neurais Artificiais com a Linguagem R

No console do R copie e cole esta linha de código, caso ainda não tenha instalado o pacote “h2o” também gratuito:

install.packages(“h2o”) # instala o Pacote “h2o”. Escolher o repositório de RJ ou SP.

Após instalar você deve carregar o pacote “h2o”:

library(h2o) # carrega o Pacote “h2o”

Logo após instalado e carregado você deve inicializar o Pacote:

h2o.init() # inicializa o Pacote “h2o”

Inicialização do R

IMPORTANTE! Algumas vezes o “h2o” não trabalha com a última versão de JAVA, assim você terá que verificar se o seu computador tem uma versão de JAVA homologada para trabalhar com o “h2o”. Tive que ajustar isto em meu notebook!

O próximo passo é carregar o arquivo com os dados de entrada. Baixe aqui o arquivo CSV que será carregado:

dados = h2o.importFile(file.choose())

Em seguida ao carregamento do arquivo com 100.000 linhas você deve separar o Conjunto de Dados em dois conjuntos com 70% e 30% dos dados (Treino[70K linhas] e Teste[30K linhas):

dados.split = h2o.splitFrame(dados, ratios = 0.7)

A linha acima cria um vetor com dois conjuntos, um com aproximadamente 70% dos dados e o segundo com o restante, totalizando 100% (100.000 linhas).

As duas linhas abaixo criam as conjuntos de treino e teste, que serão utilizados em nosso modelo de Rede Neural Artificial:

treino = dados.split[[1]]
teste = dados.split[[2]]

Crie cópias destas duas variáveis no formato de dados nativo do R:

treinoR = as.data.frame(treino)
testeR = as.data.frame(teste)

Veja a seguir os tipos das variáveis criadas:

class(treino) # retorna o tipo “H2OFrame” que são frames distribuídos específicos do pacote “h2o”
class(treinoR) # retorna o tipo “data.frame” nativo do R

Classe R

A seguir veja as dimensões de treino:

dim(treino) # aproximadamente 70.000 linhas e exatamente 3 colunas (P, L e Fl)

Conhecendo Melhor os Dados

O próximo passo mostra o cabeçalho dos dados em treino:

head(treino)

Você poderá ver também os dados de rodapé(cauda) em treino:

tail(treino)

Se quiser poderá verificar os nomes das 3 Colunas copiando e colando no R este código:

colnames(treino)

Dim e Head

Se quiser olhar o Gráfico de Dispersão da variável de saída Fl digite:

plot(treinoR$Fl) # gráfico de dispersão de Fl (coluna Fl)

Dispersão

plot(treinoR$Fl[1:1000]) # gráfico de dispersão dos primeiros 1000 valores de Fl (coluna Fl)

Dispersão2

Olhando os dois gráficos acima você notará que as categorias 18, 19 e 20 tem poucos elementos, enquanto as primeiras categorias, principalmente de 0 a 10, são bastante densas. Isto terá grande impacto no treinamento da Rede Neural Artificial como mostrarei a seguir.

Para um Histograma de Fl entre:

hist(treinoR$Fl) # Histograma da variável Fl(flecha do eixo/cilindro/viga) no Conjunto TreinoR

Hist01

hist(treinoR$Fl[10000:11000], 21) # histograma dos valores de Fl entre 10000 e 11000

Hist02

É evidente que as primeiras categorias são densas e que as últimas são raras, principalmente as categorias 18, 19 e 20.

Um gráfico BoxPlot ajuda muito a entender os dados. Veja: (explico melhor o que é o BoxPlot em um vídeo ao final deste artigo)

boxplot(treinoR$P, treinoR$Fl, names=c(“P”,”Fl”)) # boxplot das variáveis P e Fl # mostra os valores mínimo e máximo de Fl e P no Conjunto treino, além de mediana(segundo quartil), primeiro e terceiro quartil, e ainda mostra os outliers, que são valores que não parecem pertencer ao conjunto de valores do conjunto

BP01

Observe que os dois pontos 19 e 20 em Fl foram considerados outliers.

Resumos e Outliers

Você pode ver os resumos estatísticos das variáveis P e L:

summary(treinoR$P)
summary(treinoR$Fl)

Summary01

Confirma assim que, enquanto os dados em P são uniformemente distribuídos, os dados em Fl são mais densos para as primeiras categorias e mais esparsos para as últimas categorias, sendo a categoria 20 a menos densa de todas.

Outliers são valores que não seguem o padrão do restante dos dados. É sempre recomendável verificar os dados quanto a existência de outliers:

boxplot.stats(treinoR$Fl)$out

Out01

Veja que os elementos das categorias 19 e 20 foram considerados outliers.

Você pode fazer o mesmo para a variável L(comprimento do eixo). Rode as linhas a seguir:

boxplot(treinoR$L, horizontal = T)
summary(treinoR$L)

L01

plot(treinoR$L)

L02

plot(treinoR$L[1:1000])

L03

hist(treinoR$L)

L04

Agora para a variável P(força):

boxplot(treinoR$P, horizontal = T)
summary(treinoR$P)
plot(treinoR$P)
plot(treinoR$P[1:1000])
hist(treinoR$P)

Veja o resumo do conjunto de treino até o momento:

summary(treino)

A coluna Fl ainda contém números, por isto os dados estatísticos aparecem, como mediana, média entre outros.

Agora você fará uma modificação que transformará os números da Coluna Fl em variáveis Categóricas, ou seja, os números 0, 1, 2 até 20 serão transformados nas categorias “0”, “1”, “2” até “20”:

treino$Fl = as.factor(treino$Fl) # treino[,3] = as.factor(treino[,3]) # coluna da Flecha(Fl) # Transforma Número em variável Categórica
summary(treino)

SumTre02

Veja que agora o R mostrou as quantidades encontradas nas categorias de “1” a “6” ao invés de estatísticas sobre a coluna Fl.

Verifique as Correlações entre as 3 variáveis:

cor(treino) # correlação entre P e L
cor(treinoR) # correlação entre P, L e Fl

Cor01

Apenas cor(treinoR) mostra as correlações com Fl, porque neste caso a coluna Fl ainda contém números no conjunto treinoR enquanto no conjunto de dados treino a coluna Fl contém variáveis categóricas (NaN = Not a Number).

Se quiser faça as mesmas análises para o conjunto teste.

Treinando a Rede Neural

Agora você já pode treinar a Rede Neural (levou menos de 1 minuto em meu notebook):

modelo = h2o.deeplearning(y = “Fl”, training_frame=treino, validation_frame=teste, activation=”Tanh”, hidden=c(20,30), epochs=40, score_training_samples = 0)

É possível verificar a evolução do treinamento da Rede Neural Artificial para ambos conjuntos de treino e teste:

plot(modelo)

PlotM01

Você também pode observar a performance do modelo:

h2o.performance(modelo)

Perf02

Observe que o erro do modelo aparece no canto direito inferior da imagem. O erro é de 3,12%, pois errou 2187 vezes em 70046 tentativas de predizer os valores de Fl do conjunto treino.

Destaco que rodando outras vezes este mesmo modelo de Rede Neural Artificial, em condições idênticas portanto, obtive algumas vezes erros menores que 2%. Isto acontece porque a Rede Neural Artificial realiza muitas iterações para convergir o modelo e usa valores aleatórios para inicializar seus parâmetros.

print([email protected]$model_summary)

Sm01

Veja que esta Rede Neural Artificial é 2 x 20 x 30 x 21, ou seja, são duas unidades na camada de entrada (P e L), 20 neurônios na primeira camada escondida, 30 neurônios na segunda camada escondida e 21 neurônios na camada de saída que dizem respeito as 21 categorias de 0 a 20.

Aqui um resumo completo do modelo:

summary(modelo)

Sm02

Para o conjunto teste acima o erro foi de 3,18%.

Veja a importância de cada variável para os resultados:

h2o.varimp_plot(modelo)
h2o.varimp(modelo)

VI01

Os parâmetros do modelo podem ser visualizados em :

[email protected]

MP01

Você também consegue comparar os valores PREVISTOS com os CORRETOS no modelo:

h2o.confusionMatrix(modelo) # na vertical a esquerda, de 0 a 20, estão os valores CORRETOS e no topo, também de 0 a 20, estão os valores PREVISTOS

CM01

Esta “matriz de confusão” pode ser obtida para o conjunto teste também:

cmteste = h2o.confusionMatrix(modelo, teste)
head(cmteste, 20)

CM02

Avaliando os Erros do Modelo

É fácil perceber que quando o modelo erra a previsão ele escolhe um dos dois vizinhos, em outras palavras, observando a categoria “4”. É evidente que quando o modelo erra a predição ele diz que o resultado é a categoria “3” ou “5” que são os vizinhos da categoria “4”. Sendo assim a estimativa da Rede Neural Artificial ainda continua coerente com a realidade.

Neste exemplo ele errou 57 vezes em 2684 tentativas de prever a categoria “4”, ou seja, previu corretamente 2627 vezes, e, quando errou, previu a classe “3” 4 vezes e a classe “5” 53 vezes.

Os valores de rodapé mostram o mesmo tipo de erro(vizinhos do valor correto):

tail(cmteste, 20)

CM03

Destaco que o modelo errou todas as predições para as categorias 18, 19 e 20, tanto para o conjunto de teste acima quanto para o conjunto de dados de treino. Isto mostra que esta Rede Neural Artificial precisa de mais amostras das categorias 18, 19 e 20.

Veja! A categoria 20 apareceu apenas 78 vezes em um conjunto treino de 70046 elementos. Isto representa em torno de 0,1% das vezes, por conta disto suas 78 instâncias foram entendidas como outliers. O ideal é que aparecesse em torno de 3300 vezes que é próximo a 70046 / 21 (100% / 21 Categorias = 4,8% / categoria).

Agora você pode criar um conjunto com a predição de todos os valores Fl de saída baseados nos valores de entrada (P e L) do conjunto teste:

pred = h2o.predict(modelo, teste)
pred

Pred01

Analisando os Resultados Previstos pelo Modelo

Nesta tabela você vê as predições de “p0” a “p20”. Nota que, por exemplo, se você consulta a linha 1 e verifica que o valor previsto é “2” notará que o maior valor estará em Linha 1 x Coluna “p2”, valor próximo de 1 geralmente (0,9999985 neste exemplo), os outros “ps” na mesma linha tem valores menores e por isto não determinaram o valor previsto.

Veja que a Rede Neural toma a decisão, mas não tem 100% de certeza da decisão que toma, neste sentido é muito parecida com os humanos na tomada de decisão. Escolhemos intuitivamente a situação com a maior probabilidade de ser a correta.

Pronto! Agora você tem condições de calcular os valores de flecha(Fl) usando o modelo da Rede Neural ao invés da equação da Viga. PS: note que devido aos poucos valores no conjunto treino para as classes “18”, “19” e “20” a Rede Neural funciona bem para estimar valores das classes de 0 a 17 apenas.

Predições com o Modelo

Uso prático: 1) Calcular a Flecha na extremidade da viga dados P = 12,34 N e L = 1236,45 mm.

Para isto crie um segundo conjunto de teste para não alterar o original:

teste2 = teste

Após insira os valores de P e L na primeira linha do conjunto teste:

teste2[1,1] = 12.34
teste2[1,2] = 1236.45

Agora basta fazer a predição:

pred1 = h2o.predict(modelo, teste2[1,1:3])
pred1

t2-04

A categoria prevista foi “5”, pois “p5” possui o maior valor, ou seja, é o neurônio mais ativado dos 21 neurônios da camada de saída da Rede Neural Artificial. Pela equação Flecha = (P x L^3) / (3 x E x I) o valor também é 5 mm.

2) Agora calcule Fl para P = 8,97 N e L = 1145,78 mm. Também mostre o conjunto teste2 antes e depois de inserir os novos P e L na linha 2 do conjunto.

teste2
teste2[2,1] = 8.97
teste2[2,2] = 1145.78
pred2 = h2o.predict(modelo, teste2[2,1:3])
pred2
teste2

t2-05

Desta vez a Rede Neural Artificial previu a categoria “3”, cujo “p0” possui o valor de 0.9999952, que é maior que todos os outros valores de “ps”. Pela equação da Viga o valor da deflexão também é 3 mm.

Como mensagem final gostaria de destacar que as Redes Neurais Artificais densas permitem o deeplearning e são usadas cada vez mais por Facebook, Google e outros grandes players.

Um prova disto é que o Facebook reconhece as pessoas nas fotos que você publica. Para descobrir quem são as pessoas nas fotos o facebook utiliza Redes Neurais Artificiais densas (deeplearning) em reconhecimento facial neste caso.

(Assista ao (vídeo a seguir e conheça em detalhes como replicar este estudo com Redes Neurais Artificiais.)

PS: baixe aqui o novo arquivo CSV com 110.000 linhas.

Um abraço!

Nilo Guimarães

Inscreva-se no 3º Congresso Nacional Online de Engenharia Mecânica e Automação! (de 06 a 10/08/2018)