Machine Learning com TensorFlow Deixe um comentário

Para aqueles que acompanharam a primeira parte, bom vê-los novamente! Pra quem tá chegando agora, recomendo buscar ler a primeira parte do artigo sobre este tema! Foram apresentados conteúdos essenciais que trabalharemos um pouco mais neste artigo, além de finalmente começarmos a aplicar tudo que estávamos desenvolvendo.
Retomando de onde paramos, o modelo que buscaremos treinar é o da curva senoidal (explicamos tudo na primeira parte deste artigo! Você poderir conferir no seguinte link), portanto vamos aos trabalhos! Primeiramente, devemos importar as bibliotecas e dependências que usaremos:

# TensorFlow is an open source machine learning library
!pip install tensorflow==2.0
import tensorflow as tf
# NumPy is a math library
import numpy as np
# Matplotlib is a graphing library
import matplotlib.pyplot as plt
# math is Python's math library
import math

Perceba que estamos dando apelidos para cada uma de nossas dependências. tf é apelido de TensorFlow, np para numpy e plt para a matplotlib, logo sempre que um método for chamado utilizando qualquer um destes apelidos, você já saberá a qual biblioteca ele pertence. Também é importante notar que os códigos aqui mostrados são feitos para rodar no próprio prompt da máquina, portanto não vá criando um programa com todos os códigos reunidos, precisamos nos comunicar diretamente com o prompt para que algumas instalações de dependências sejam realizadas, caso deseje inserir tudo em um programa só, estude que pedaços do código devem ser executados em prompt (instalações e afins) e quais parcelas podem ser inseridas em algum interpretador sem que haja perda de informação. Caso tudo ocorra como deveria, a seguinte mensagem será apresentada:

Successfully installed tensorboard-2.0.0 tensorflow-2.0.0 tensorflow-estimator-2.0.0

Como comentado anteriormente, os algoritmos de deep learning aprendem a prever modelos com base em dados. No nosso modelo atual, estamos selecionando um valor qualquer x e prevendo sua função seno em y. Para isso, obviamente necessitamos de certos dados para o modelo.
É certo que para uma aplicação real, nossos dados seriam todos captados através de sensores, porém para o nosso programinha simples, vamos nos contentar em gerá-los de forma aleatória. Vamos gerar 1.000 dados totalmente aleatórios que representarão pontos na curva senoidal.
Da matemática, sabemos que o período de uma onda senoidal é 2ℼ, portanto o que visamos para o nosso programa é que todos os mil pontos de dados gerados estejam contidos no intervalo de 0 até 2ℼ, para que consigamos prever o resultado de cada um desses senos.

O seguinte código atingirá nosso objetivo:

# We'll generate this many sample datapoints
SAMPLES = 1000

# Set a 'seed' value, so we get the same random numbers each time we run this
# notebook. Any number can be used here.
SEED = 1337
np.random.seed(SEED)
tf.random.set_seed(SEED)

# Generate a uniformly distributed set of random numbers in the range from
# 0 to 2π, which covers a complete sine wave oscillation
x_values = np.random.uniform(low=0, high=2*math.pi, size=SAMPLES)

# Shuffle the values to guarantee they're not in order
np.random.shuffle(x_values)

# Calculate the corresponding sine values
y_values = np.sin(x_values)

# Plot our data. The 'b.' argument tells the library to print blue dots.
plt.plot(x_values, y_values, 'b.')
plt.show()

Estamos utilizando alguns comandos provenientes da biblioteca NumPy, uma biblioteca extremamente importante para as aplicações em Machine Learning, já que facilita muito algumas operações e comandos matemáticos. Note o uso da expressão ‘np.random.shuffle()’ para gerarmos nossos dados, o método random retorna um array de números aleatórios dentro de um determinado intervalo (assim como dito anteriormente que seria necessário) e o shuffle simplesmente embaralha todos nossos dados em uma ordem 100% aleatória, isso é importante pois se alimentarmos o modelo com dados ordenados obtemos previsões menos precisas. Outro caso de uso de métodos no NumPy seria o trecho ‘np.sin()’, que utilizamos para calcular os senos de cada valor, mas o interessante é que o NumPy faz isso para todos os dados de uma vez só, ou seja, inserimos o array citado anteriormente e obtemos um array como resposta do método.
O último trecho de código faz uso da biblioteca matplotlib, e plota gráficos importantes para analisarmos nossos dados. O uso desta dependência é de muita importância nas aplicações de Deep Learning, já que podemos plotar e observar nossos dados, esta última sendo um pedaço essencial para as aplicações.
Bom, com tudo sendo executado de forma correta, você estará diante de um gráfico. Talvez parcialmente completo ou talvez com algumas parcelas generosas da curva estando sumidas, mas calma que tá tudo certo, meu pequeno gafanhoto! Este gráfico representa todos os nossos dados gerados! E lembra que comentamos que geramos 1.000 dados aleatórios entre 0 e 2π? Pois é, não podemos garantir que estes 1.000 dados vão cobrir todos os pontos visíveis da curva seno de 0 à 2π, eles são aleatórios! Beleza, então talvez você esteja pensando, agora só falta alimentar nosso modelo e pronto, né?! Calminha aí, se fosse assim, tava tudo muito fácil.

Curva senoidal - TensorFlow
Curva Senoidal – TensorFlow

Uma das grandes vantagens da rede de Deep Learning é sua habilidade incrível de captar padrões até nos dados mais bagunçados. Essa tal “bagunça” é o que chamamos de distúrbio ou perturbação (em alguns lugares também conhecida como noise). É graças a esse olho aguçado que os algoritmos conseguem fazer previsões até nos piores dados do mundo real! Sabendo de tudo isso, vamos dar uma apimentada nos nossos dados com um pouquinho de perturbação:

# Add a small random number to each y value
y_values += 0.1 * np.random.randn(*y_values.shape)

# Plot our data
plt.plot(x_values, y_values, 'b.')
plt.show()

O que estamos fazendo aqui é simples, pegamos os nossos dados e os somamos com pequenos outros números aleatórios e distintos, fugindo mais ainda do padrão ordenado tão temido pelos modelos. Depois apenas utilizamos os métodos da matplotlib para gerar o gráfico novamente. Parece pouca coisa mas o efeito é gigantesco! Rode seu código e repare que você estará diante de um gráfico muito mais legal de brincar e treinar em nosso modelo!

Curva senoidal com Perturbações- TensorFlow
Curva Senoidal com Perturbações- TensorFlow

O que temos em mãos é uma série de dados muito mais parecidos com aqueles capturados no mundo real, dados cheios de perturbações e incertezas.
Talvez você se lembre quando iniciamos nossa conversa neste assunto que costumamos dividir os dados em 3 partes: treinamento, validação e teste. Normalmente, para avaliarmos o modelo que treinamos, comparamos as previsões obtidas com dados do mundo-real, que sabemos estar correto, afinal validamos o modelo como positivo no caso das informações serem semelhantes. Esta avaliação ocorre durante o treinamento (chamamos esta etapa da avaliação como validação) e após os treinos estarem completos (etapa de teste). Para garantirmos que teremos dados o suficiente para a avaliação, vamos separar uma parcela dos dados que construímos antes de começarmos a treinar o modelo de fato. Um bom número de proporção já conhecido na indústria é o de 20% para validação, 20% para teste e os 60% restantes para o treino em si. O código a seguir executa essas divisões e faz o desenho com cores diferentes para auxiliar:

# We'll use 60% of our data for training and 20% for testing. The remaining 20%
# will be used for validation. Calculate the indices of each section.
TRAIN_SPLIT =  int(0.6 * SAMPLES)
TEST_SPLIT = int(0.2 * SAMPLES + TRAIN_SPLIT)
# Use np.split to chop our data into three parts.
# The second argument to np.split is an array of indices where the data will be
# split. We provide two indices, so the data will be divided into three chunks.
x_train, x_validate, x_test = np.split(x_values, [TRAIN_SPLIT, TEST_SPLIT])
y_train, y_validate, y_test = np.split(y_values, [TRAIN_SPLIT, TEST_SPLIT])
# Double check that our splits add up correctly
assert (x_train.size + x_validate.size + x_test.size) ==  SAMPLES
# Plot the data in each partition in different colors:
plt.plot(x_train, y_train, 'b.', label='Train')
plt.plot(x_validate, y_validate, 'y.', label='Validate')
plt.plot(x_test, y_test, 'r.', label='Test')
plt.legend()
plt.show()

Perceba o uso do método ‘split()’ da biblioteca NumPy, é ele quem particiona nossos dados. Ele opera recebendo um array de dados e outro de índices, picotando então estes dados em pequenas outras partes, assim como passado pelos índices.
Beleza! Agora se você rodar tudo que fizemos agora você finalmente terá em mãos os nossos dados fresquinhos e prontos para alimentarmos o nosso modelo.

Dados Particionados na Curva Senoidal - TensorFlow
Dados Particionados na Curva Senoidal – TensorFlow

Tá, você pode estar achando isso tudo uma grande baboseira e querer correr logo pra parte onde vemos as previsões ocorrendo e o modelo atuando, mas o tratamento de dados é uma parte essencial do processo, talvez seja a parte mais importante! Dados desconexos e mal tratados geram previsões falhas e imprecisas, mesmo com o modelo mais completo e o algoritmo mais friamente construído, se o alimentarmos com “lixo virtual”, de nada servirá toda a estrutura da rede.

Eu sei que você está ansioso para finalizarmos logo tudo e vermos o resultado final, mas infelizmente nosso tempo aqui acabou por enquanto. Em breve ensinaremos a construir o modelo, realizar os testes e enfim upar tudo isso no hardware! Até lá, estude e mantenha o foco, nos vemos em breve!


Esse conteúdo é resultado da parceria da MakerHero com a Cheetah E-Racing. Curtiu o conteúdo? Então deixe seu comentário abaixo! E não esqueça de acompanhar a Cheetah E-Racing nas redes sociais.

Faça seu comentário

Acesse sua conta e participe