<jupyter_start><jupyter_text>Importando as bibliotecas necessarias<jupyter_code>import sys
assert sys.version_info >= (3, 5) 

import sklearn
assert sklearn.__version__ >= "0.20"

import tensorflow as tf
from tensorflow import keras
assert tf.__version__ >= "2.0"

import numpy as np
import os 

# para fazer a saída do notebook estável através de diferentes runs
np.random.seed(42)
tf.random.set_seed(42)

import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc('axes', labelsize=14)
mpl.rc('xtick', labelsize=12)
mpl.rc('ytick', labelsize=12)
%matplotlib inline<jupyter_output><empty_output><jupyter_text>Sobre o dataset MNIST<jupyter_code># Importa o dataset mnist do openml por nome, id, etc..
# 'data', 'target', 'feature_names', 'DESCR', 'details', 'categories', 'url'
# data = array com uma linha por instância e uma coluna por feature (70,000 digitos)
# target = array com os labels (70,000 labels). Labels são strings
# Imagens de 28x28, 784 features, um pixel por feature de 0 (branco) até 255 (preto)
from sklearn.datasets import fetch_openml
mnist = fetch_openml('mnist_784')
x, y, z = mnist["data"], mnist["target"], mnist["feature_names"]
a, b, c, d = mnist["DESCR"], mnist["details"], mnist["categories"], mnist["url"]
x.shape
x[0]
plt.imshow(x[0].reshape(28,28), cmap="binary")
plt.axis("off")
plt.show()
# targets
y.shape
# targets
y[0]
# feature names
z
# description
a
# details
b
# categories
c
# url
d<jupyter_output><empty_output><jupyter_text>Sobre o split do dataset MNIST em treinamento, validação e teste<jupyter_code># carrega 60,000 imagens de 28x28 de 10 dígitos para treinamento e 10,000 imagens para teste
# para treinamento são 30,000 padrões SD-3 e 30,000 padrões SD-1
# para testes são 5,000 SD-3 e 5,000 SD-1
# SD-3 foi escrito por funcionários do Census Bureau e está em sequência
# SD-1 foi escrito por estudantes e não fora de ordem
(X_train_full, y_train_full), (X_test, y_test) = keras.datasets.mnist.load_data()
plt.imshow(X_train_full[0].reshape(28,28), cmap="binary")
plt.axis("off")
plt.show()
y_train_full[0]
plt.imshow(X_test[0].reshape(28,28), cmap="binary")
plt.axis("off")
plt.show()
y_test[0]
# é boa prática separar parte do dataset de treinamento para validação. O dataset de validação deve ter por 
# objetivo ajudar o desenvolvedor a validar o melhor modelo. Após escolha do melhor modelo, usa-se o dataset
# de treinamento para treinar o modelo e depois o dataset de teste para testar
X_train, X_valid = X_train_full[:-5000], X_train_full[-5000:]
# dataset de treinamento com com 55,000 imagens
plt.imshow(X_train[1].reshape(28,28), cmap="binary")
plt.axis("off")
plt.show()
# dataset de treinamento com 55,000 imagens
plt.imshow(X_valid[0].reshape(28,28), cmap="binary")
plt.axis("off")
plt.show()
y_train, y_valid = y_train_full[:-5000], y_train_full[-5000:]
y_train[0]
y_valid[0]<jupyter_output><empty_output><jupyter_text>Sobre convolução<jupyter_code>import numpy as np
from sklearn.datasets import load_sample_image

# carregando imagens para teste
china = load_sample_image("china.jpg") / 255
flower = load_sample_image("flower.jpg") / 255
images = np.array([china, flower])
batch_size, height, width, channels = images.shape 
images.shape 
plt.imshow(images[0])
plt.axis("off")
plt.show()
plt.imshow(images[1])
plt.axis("off")
plt.show()
# criando filtros: receptive field 7x7, para 3 canais e 2 imagens
filters = np.zeros(shape=(7, 7, channels, 2), dtype=np.float32)
filters
filters[:, 3, :, 0] = 1  # filtro vertical
filters
filters[3, :, :, 1] = 1  # horizontal line
filters
# tf chama uma fç de rede neural convolucional que recebe as imagens (china e flower)
# e aplica os filtros, o stride e o padding
outputs = tf.nn.conv2d(images, filters, strides=1, padding="SAME") 
# plot 1st image's 2nd feature map 
plt.imshow(outputs[0, :, :, 1], cmap="gray")
def crop(images):
    return images[150:220, 130:250]
plt.imshow(crop(outputs[0, :, :, 1]), cmap = "gray")<jupyter_output><empty_output><jupyter_text>Software para o Projeto Final de Programacao  Split do dataset MNIST<jupyter_code># carregar dataset mnist, e fazer split em dataset de treinamento e validacao
(X_train_full, y_train_full), (X_test, y_test) = keras.datasets.mnist.load_data()
X_train, X_valid = X_train_full[:-5000], X_train_full[-5000:]
y_train, y_valid = y_train_full[:-5000], y_train_full[-5000:]

# metricas necessarias a camada de batch normalization
X_mean = X_train.mean(axis=0, keepdims=True)
X_std = X_train.std(axis=0, keepdims=True) + 1e-7
X_train = (X_train - X_mean) / X_std # quantidade de desvios padrão da média
X_valid = (X_valid - X_mean) / X_std
X_test = (X_test - X_mean) / X_std

# newaxis é utilizado para aumentar a dimensão de um array
X_train = X_train[..., np.newaxis]
X_valid = X_valid[..., np.newaxis]
X_test = X_test[..., np.newaxis]<jupyter_output><empty_output><jupyter_text>Criando a arquitetura ResNet-34<jupyter_code># Funcao partial permite derivar uma função com "x" parâmetros para uma função com menos parâmetros 
# e fixa os valores definidos para a função mais limitada.
from functools import partial
# ResNet-34 é uma rede com 34 camadas (34 contanto apenas as camadas convolucionais e as camadas totalmente
# conectadas) contendo 3 residual units que geram 64 feature maps, 4 RUs que geram 128 maps, 
# 6 RUs com 256 maps e 3 RUs com 512 maps.

# definindo a estrutura da camada convolucional
DefaultConv2D = partial(keras.layers.Conv2D, kernel_size=3, strides=1,
                        padding="SAME", use_bias=False)

# definindo a classe ResUnit
class ResidualUnit(keras.layers.Layer):
    def __init__(self, filters, strides=1, activation="relu", **kwargs):
        super().__init__(**kwargs)
        self.activation = keras.activations.get(activation)
        self.main_layers = [
            DefaultConv2D(filters, strides=strides), # Conv, 128 filtros, 3x3, stride 2, S
            keras.layers.BatchNormalization(),       # Batch normalization + RELU
            self.activation,
            DefaultConv2D(filters),                  # Conv, 128 filtros, 3x3, stride 1, S
            keras.layers.BatchNormalization()]       # Batch normalization
        self.skip_layers = []
        if strides > 1:
            self.skip_layers = [
                DefaultConv2D(filters, kernel_size=1, strides=strides), # Conv, 128 filtros, 1x1, stride 2, S
                keras.layers.BatchNormalization()]

# No metodo call(), fazemos com que as entradas atravessem as camadas principais e as camadas skip,
# para depois adicionarmos as saídas das camadas principais e skip à função de ativação.

    def call(self, inputs):
        Z = inputs
        for layer in self.main_layers:
            Z = layer(Z)
        skip_Z = inputs
        for layer in self.skip_layers:
            skip_Z = layer(skip_Z)
        return self.activation(Z + skip_Z)
# criacao da arquitetura 
model = keras.models.Sequential()
model.add(DefaultConv2D(64, kernel_size=7, strides=2,
                        input_shape=[28, 28, 1]))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Activation("relu"))
model.add(keras.layers.MaxPool2D(pool_size=3, strides=2, padding="SAME"))
prev_filters = 64
for filters in [64] * 3 + [128] * 4 + [256] * 6 + [512] * 3:
    strides = 1 if filters == prev_filters else 2
    model.add(ResidualUnit(filters, strides=strides))   # adiciona a RU como se fosse uma unica camada
    prev_filters = filters
model.add(keras.layers.GlobalAvgPool2D())               # calcula a média de cada feature map
model.add(keras.layers.Flatten())           # camada de pre-processamento para converter cada entrada em um array 1D
model.add(keras.layers.Dense(10, activation="softmax")) # camada totalmente conectada com função de ativação softmax
# resumo do modelo criado 
model.summary()<jupyter_output>Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_36 (Conv2D)           (None, 14, 14, 64)        3136      
_________________________________________________________________
batch_normalization_36 (Batc (None, 14, 14, 64)        256       
_________________________________________________________________
activation_1 (Activation)    (None, 14, 14, 64)        0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 7, 7, 64)          0         
_________________________________________________________________
residual_unit_16 (ResidualUn (None, 7, 7, 64)          74240     
_________________________________________________________________
residual_unit_17 (ResidualUn (None, 7, 7, 64)          74240     
______________________________________________________[...]<jupyter_text>Etapa de treinamento<jupyter_code># configura o modelo com os loss e a métrica de acuracia
# X_train = input data; y_train = target data; epochs = numero de iterações; 
# validation_data = dados aonde serão avaliados o loss e a acurácia, ao final de cada epoch

model.compile(loss="sparse_categorical_crossentropy", optimizer="nadam", metrics=["accuracy"])
history = model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))<jupyter_output>Epoch 1/10
1719/1719 [==============================] - 3994s 2s/step - loss: 0.2039 - accuracy: 0.9447 - val_loss: 0.0926 - val_accuracy: 0.9738
Epoch 2/10
1719/1719 [==============================] - 3975s 2s/step - loss: 0.0930 - accuracy: 0.9747 - val_loss: 0.0725 - val_accuracy: 0.9814
Epoch 3/10
1719/1719 [==============================] - 3958s 2s/step - loss: 0.0650 - accuracy: 0.9819 - val_loss: 0.0552 - val_accuracy: 0.9832
Epoch 4/10
1719/1719 [==============================] - 3934s 2s/step - loss: 0.0577 - accuracy: 0.9836 - val_loss: 0.0322 - val_accuracy: 0.9922
Epoch 5/10
1719/1719 [==============================] - 3953s 2s/step - loss: 0.0447 - accuracy: 0.9873 - val_loss: 0.0737 - val_accuracy: 0.9782
Epoch 6/10
1719/1719 [==============================] - 3959s 2s/step - loss: 0.0515 - accuracy: 0.9863 - val_loss: 0.0375 - val_accuracy: 0.9910
Epoch 7/10
1719/1719 [==============================] - 3952s 2s/step - loss: 0.0337 - accuracy: 0.9903 - val_loss: 0.0453 -[...]<jupyter_text>Avaliacao do modelo usando as 10,000 imagens do dataset de teste<jupyter_code>score = model.evaluate(X_test, y_test)<jupyter_output>313/313 [==============================] - 22s 70ms/step - loss: 1140.7450 - accuracy: 0.9862<jupyter_text>Teste usando 10 imagens do dataset de teste<jupyter_code># imaginemos uma nova entrada
X_new = X_test[:10] 
X_new.shape
plt.imshow(X_new[0].reshape(28,28))
plt.imshow(X_new[1].reshape(28,28))
plt.imshow(X_new[2].reshape(28,28))
plt.imshow(X_new[3].reshape(28,28))
plt.imshow(X_new[4].reshape(28,28))
plt.imshow(X_new[5].reshape(28,28))
plt.imshow(X_new[6].reshape(28,28))
plt.imshow(X_new[7].reshape(28,28))
plt.imshow(X_new[8].reshape(28,28))
plt.imshow(X_new[9].reshape(28,28))
y_pred = np.argmax(model.predict(X_new), axis=-1)
y_pred
np.round(model.predict(X_new))
y_pred
y_pred.shape
y_pred[0]
y_pred[1]
y_pred[2]<jupyter_output><empty_output><jupyter_text>Resultado do modelo com 10 imagens de teste<jupyter_code>score = model.evaluate(X_new, np.array([7, 2, 1, 0, 4, 1, 4, 9, 5, 9]))<jupyter_output>1/1 [==============================] - 0s 2ms/step - loss: 0.0044 - accuracy: 1.0000<jupyter_text>Nova imagem de teste gerada pelo usuario<jupyter_code>from tensorflow.keras.preprocessing import image
num0 = image.load_img('Imagem_n0_crop.png', color_mode="grayscale", target_size=(28,28))
num1 = image.load_img('Imagem_n1_crop.png', color_mode="grayscale", target_size=(28,28))
num2 = image.load_img('Imagem_n2_crop.png', color_mode="grayscale", target_size=(28,28))
num3 = image.load_img('Imagem_n3_crop.png', color_mode="grayscale", target_size=(28,28))
num4 = image.load_img('Imagem_n4_crop.png', color_mode="grayscale", target_size=(28,28))
num5 = image.load_img('Imagem_n5_crop.png', color_mode="grayscale", target_size=(28,28))
num6 = image.load_img('Imagem_n6_crop.png', color_mode="grayscale", target_size=(28,28))
num7 = image.load_img('Imagem_n7_crop.png', color_mode="grayscale", target_size=(28,28))
num8 = image.load_img('Imagem_n8_crop.png', color_mode="grayscale", target_size=(28,28))
num9 = image.load_img('Imagem_n9_crop.png', color_mode="grayscale", target_size=(28,28))
from tensorflow.keras.preprocessing.image import img_to_array
num0_array = img_to_array(num0) / 255
num1_array = img_to_array(num1) / 255
num2_array = img_to_array(num2) / 255
num3_array = img_to_array(num3) / 255
num4_array = img_to_array(num4) / 255
num5_array = img_to_array(num5) / 255
num6_array = img_to_array(num6) / 255
num7_array = img_to_array(num7) / 255
num8_array = img_to_array(num8) / 255
num9_array = img_to_array(num9) / 255
plt.imshow(num0_array.reshape(28,28))
plt.imshow(num1_array.reshape(28,28))
plt.imshow(num2_array.reshape(28,28))
plt.imshow(num3_array.reshape(28,28))
plt.imshow(num4_array.reshape(28,28))
plt.imshow(num5_array.reshape(28,28))
plt.imshow(num6_array.reshape(28,28))
plt.imshow(num7_array.reshape(28,28))
plt.imshow(num8_array.reshape(28,28))
plt.imshow(num9_array.reshape(28,28))
digitos_10 = np.array([num0_array,num1_array,num2_array,num3_array,num4_array,num5_array,
                    num6_array,num7_array,num8_array,num9_array])
digitos_10.shape
digitos_10_pred = np.argmax(model.predict(digitos_10), axis=-1)<jupyter_output><empty_output><jupyter_text>4 digitos foram previstos de maneira correta, foram eles: 1, 5, 8 e 9. Provavelmente a distribuicao das imagens geradas para este novo teste nao eh a mesma que a utilizada no dataset MNIST.<jupyter_code>digitos_10_pred
score_digitos = model.evaluate(digitos_10, np.array([0,1,2,3,4,5,6,7,8,9]))<jupyter_output>1/1 [==============================] - 0s 1ms/step - loss: 2.6219 - accuracy: 0.4000
{'fraction_non_alphanumeric': 0.14423145954483452, 'fraction_numerical': 0.06640821308062315, 'mean_word_length': 5.038144776766363, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '623344', 'license': 'MIT', 'n_tokens_mistral': 5700, 'n_tokens_neox': 5029, 'n_words': 1201, 'path': 'PFP_GGoehringer.ipynb', 'repo_name': 'ggoehringer/PFP_GG', 'size': '13929'}