<jupyter_start><jupyter_text><jupyter_code># Tensorflow
# Keras
# <NAME>

# Glossário de Python

# Exibir informações
print("Hello, world!")

# Declarar uma variável
numero = 20
print(numero, type(numero))

# Trabalhar com listas e exibir tipo das informações
lista = [10, 20, 30]
print(lista, type(lista))

# Pegar elementos da lista
elemento_da_lista = lista[0]
print(elemento_da_lista, type(elemento_da_lista))

# Mudar elementos da lista
lista[1] = 99
print(lista, type(lista), type(lista[1]))

# Quantidade de elementos da lista
quantidade_elementos = len(lista)
print("Quantidade de elementos", quantidade_elementos, type(quantidade_elementos))

# Tupla
tupla = (51, 62, 79)
print(tupla, type(tupla))

tupla2 = 99, 11, 13
print(tupla2, type(tupla2))

tupla3 = 10, 5
print(tupla3, type(tupla3))

# Acessando elementos da tupla
elemento_da_tupla = tupla[0]
print(elemento_da_tupla, type(elemento_da_tupla))

# Tupla vs Lista?
# Tuplas não podem ser modificadas
# TypeError: 'tuple' object does not support item assignment
# tupla[0] = 30

# Atalho para comentar: Ctrl + /

tupla4 = 9, 6, 3, 2
print(tupla4, type(tupla4))

"""
tupla4_em_lista = list(tupla4)
tupla4_em_lista[0] = 99
tupla4_lista_em_tupla_novamente = tuple(tupla4_em_lista)
print(tupla4_lista_em_tupla_novamente, type(tupla4_lista_em_tupla_novamente))
"""

# Comentários de uma linha
"""
Comentários
de
várias
linhas
"""
nome = "<NAME>"

contador = 0
# Nova célula

print(nome)

contador = contador + 1
print(f"Esse nome foi exibido {contador} vez(es)!")
# Importar Tensorflow, Keras e todas as ferramentas/bibliotecas que precisamos!

from tensorflow import keras # Importa a biblioteca Keras

from keras.datasets import mnist # Base de Dados MNIST - 60k imagens treino, 10k imagens teste

from tensorflow.python.keras import Sequential # Arquitetura da nossa rede neural
from tensorflow.python.keras.layers import Dense, Dropout # Neurônio (base da rede) e Regularizador (evita overfitting)
from tensorflow.compat.v1.keras.optimizers import RMSprop # Otimizador (back propagation)
(x_treino, y_treino), (x_teste, y_teste) = mnist.load_data()

# X_Treino -> 60k imagens, 28x28 pixels
# Y_Treino -> 60k labels, contendo o número que está desenhado na imagem

# X_Teste -> 10k imagens, 28x28 pixels
# Y_Teste -> 10k labels, contendo o número que está desenhado na imagem
# Após importar os dados, é importante dar uma analisada para ver o que temos no dataset
# e como ele está estruturado

print("Quantidade de imagens para treino:", len(x_treino))

print("Quantidade de imagens para teste:", len(x_teste))

print("Tipo de x_treino:", type(x_treino))

primeira_imagem = x_treino[0]

representacao_primeira_imagem = y_treino[0]

print("O que a imagem 0 de treino representa?", representacao_primeira_imagem)

print("Formato da primeira imagem:", primeira_imagem.shape, type(primeira_imagem))

print(primeira_imagem)
import matplotlib.pyplot as plt

indice = 12000

print("A imagem representa:", y_treino[indice])

plt.imshow(x_treino[indice], cmap=plt.cm.binary)
# Fluxo para construção da rede neural

# - Organizar a camada de entrada (input)
# - Organizar a camada de saída (output)
# - Estruturar a nossa rede neural
# - Treinar o modelo
# - Fazer as previsões
# Achatando a matriz de pixels e transformando em uma única lista

quantidade_treino = len(x_treino) # 60000
quantidade_teste = len(x_teste) # 10000

resolucao_imagem = x_treino[0].shape # (28, 28)
resolucao_total = resolucao_imagem[0] * resolucao_imagem[1] # 28 * 28 = 784

x_treino = x_treino.reshape(quantidade_treino, resolucao_total)

x_teste = x_teste.reshape(quantidade_teste, resolucao_total)
print("Quantidade de itens em x_treino[0]:", len(x_treino[0]))

# Como será que ficou x_treino[0]?
print(x_treino[0])
# Normalização de dados

# 255 vire 1
# 127 vire 0.5
# 0 vire 0
# E assim por diante

# Posso pegar o meu valor que eu quero transformar e dividir pelo valor máximo do meu intervalo
# Exemplo, se eu dividir 255 por 255, tenho 1
# Exemplo, se eu dividir 127 por 255, tenho ~0.5
# Exemplo, se eu dividir 0 por 255, tenho 0

"""
# Explicando o porque da conversão de tipos

primeira_imagem = x_treino[0]
primeiro_pixel = primeira_imagem[0] # uint8

# Quando eu divido uint8 por algum número, recebemos um float64
# Porém, o tensorflow precisa de float32 para trabalhar
# Portanto, precisamos converter o tipo antes de dividí-lo

print(primeiro_pixel, type(primeiro_pixel / 255)) # float64

# Fim da explicação
"""
# Normalização de dados

# Conversão para tipos

x_treino = x_treino.astype('float32')
x_teste = x_teste.astype('float32')

x_treino /= 255 # Divide todos os 60000 valores de x_treino por 255 e armazena esse resultado em x_treino
x_teste /= 255 # Divide todos os 10000 valores de x_teste por 255 e armazena esse resultado em x_teste
# Como está o pixel 350 da primeira imagem de x_treino?
print(x_treino[0][350], type(x_treino[0][350]))

# Como está x_treino[0] agora?
print(x_treino[0])
# Preparação da camada de saída

# Quais são as possibilidades de saída? Números de 0 a 9
# Atualmente, nas labels, temos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
# Transformaremos para o formato da camada de saída: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# Sendo que cada número possui valor 1 na posição que corresponde a esse número
# Exemplo:
# Número 5 [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
# Número 9 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
# Número 0 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

print("Primeiro elemento:", y_treino[0], type(y_treino[0]))

valores_unicos = set(y_treino)

print("Valores únicos:", valores_unicos)

quantidade_valores_unicos = len(valores_unicos) # 10

# Transformação de valores inteiros em valores categóricos

print("y_treino[0] antes:", y_treino[0])

y_treino = keras.utils.to_categorical(y_treino, quantidade_valores_unicos)
y_teste = keras.utils.to_categorical(y_teste, quantidade_valores_unicos)

print("y_treino[0] depois:", y_treino[0])
# Prever os resultados é transformar os valores categórios em um número equivalente
# Exemplo:
# [0         1     2        3     4     5       6     7        8     9 ]
# [0.11.     0.    0.22.    0.    0.    0.9.    0.    0.36.    0.    0.]
# Significa que a rede está prevendo que a aquela imagem (matriz de pixels) representa um número 5
# Criando o modelo da rede neural

model = Sequential()

# Primeira hidden layer
# 30 neurônios
# Função de ativação
# Como estamos na primeira hidden layer, precisamos definir o input shape

model.add(Dense(30, activation='relu', input_shape=(resolucao_total,)))

# Adicionamos um regularizador, que ajuda a evitar o overfitting
# Overfitting = quando a rede aprender a resolver aquela base específica, mas não
# abstrai o problema de forma suficiente para resolver imagens que ela não conhece

model.add(Dropout(0.2))

# Segunda hidden layer
# 20 neurônios
# Função de ativação: ReLU

model.add(Dense(20, activation='relu'))

# Mais um regularizador depois da segunda hidden layer

model.add(Dropout(0.2))

# Finalizamos com a camada de saída (output)
model.add(Dense(quantidade_valores_unicos, activation='softmax'))

# Exibimos o resumo do modelo criado

model.summary()
# Compila e treina o modelo
# Definimos a função de erro
# Definimos o otimizador
# Definimos a métrica de aprendizado

model.compile(loss='categorical_crossentropy',
              optimizer=RMSprop(),
              metrics=['accuracy'])

# Treinamos o modelo

# Imagens em treino, labels em treino
# batch_size = Tamanho do batch (recomendado potência de 2)
# epochs = Quantas épocas irei treinar
# verbose = Exibe o treinamento
# Imagens em teste, labels em teste

history = model.fit(x_treino, y_treino,
                    batch_size=128,
                    epochs=10,
                    verbose=1,
                    validation_data=(x_teste, y_teste))
# Fazendo novas previsões

indice = 0

print("Valor categórico em y_teste[indice]:", y_teste[indice])

# Preparo a imagem para fazer a previsão
imagem = x_teste[indice].reshape((1, resolucao_total))

print()

# Faço a previsão
prediction = model.predict(imagem)
print("Previsão:", prediction)

# Traduzindo a previsão em algo mais legível
import numpy as np
prediction_class = np.argmax(prediction, axis=-1)
print("Previsão ajustada:", prediction_class)

print()

# Carregar os dados originais novamente para exibir como imagem
(x_treino_img, y_treino_img), (x_teste_img, y_teste_img) = mnist.load_data()
plt.imshow(x_teste_img[indice], cmap=plt.cm.binary)<jupyter_output>Valor categórico em y_teste[indice]: [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]

Previsão: [[6.97158686e-09 2.83256663e-09 1.04885485e-05 7.20429962e-05
  1.91713156e-11 4.31662693e-06 2.08266071e-09 9.99912858e-01
  1.43410190e-08 3.74770622e-07]]
Previsão ajustada: [7]
{'fraction_non_alphanumeric': 0.09822866344605476, 'fraction_numerical': 0.049689440993788817, 'mean_word_length': 4.627831715210356, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '418222', 'license': 'MIT', 'n_tokens_mistral': 3672, 'n_tokens_neox': 3382, 'n_words': 985, 'path': 'Ocean_DeepLearning_13_08_2021.ipynb', 'repo_name': 'paulosalvatore/Ocean_DeepLearning_13_08_2021', 'size': '8710'}