<jupyter_start><jupyter_text>Atividade 5 - Redes Neurais MLPNesta atividade iremos trabalhar com o problema de classificação de dígitos em imagens, utilizando o conhecido conjunto de dados MNIST.O conjunto de dados é formado por imagens preto e branco de 28x28 pixels que representam dígitos escritos à mão, de 0 à 9. Cada pixel possui um valor entre 0 (totalmente preto) e 255 (totalmente branco). O desafio é treinar um modelo para reconhecer corretamente cada dígito representado. Ou seja, é um problema de classificação multi-classe de 10 classes (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). O conjunto já é previamente dividido em treino e teste.Dado esse problema, faça o que se pede:1. Treine e avalie (no conjunto de teste) um classificador baseline com uma MLP de uma camada. Defina a quantidade de neurônios na camada oculta e argumente o motivo da sua escolha. Utilize métricas de desempenho para classificação multiclasse de sua escolha.2. Crie uma arquitetura de MLP realizando a otimização de hiperparâmetros, usando uma técnica da sua escolha (grid search, random search). Os hiperparâmetros que serão otimizados são de sua escolha, mas devem conter o número de camadas e o número de neurônios em cada camada. Teste o melhor modelo encontrado no conjunto de teste e compare com o baseline.OBS¹: A forma mais simples de extração de atributos de imagens é considerar cada pixel como um atributo. Para isso, basta transformar a matriz de cada imagem em um vetor unidimensional. Outras técnicas de extração de atributos baseadas em PDI (processamento digital de imagens) podem ser utilizadas.OBS²: A MLP pode ser utilizada com a implementação do scikit-learn ou do keras.<jupyter_code>from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
#loading
(X_train_val, y_train_val), (X_test, y_test) = mnist.load_data()
X_train, X_val, y_train, y_val = train_test_split(X_train_val, y_train_val, test_size=0.2)

#shape of dataset
print('X_train_val: ' + str(X_train_val.shape))
print('Y_train_val: ' + str(y_train_val.shape))
print('X_test:  '  + str(X_test.shape))
print('Y_test:  '  + str(y_test.shape))
print('x_train: ' + str(X_train.shape))
print('x_val: ' + str(X_val.shape))
print('y_train: ' + str(y_train.shape))
print('y_val: ' + str(y_val.shape))
#plotting
for i in range(9):  
    plt.subplot(330 + 1 + i)
    plt.imshow(X_train[i], cmap=plt.get_cmap('gray'))
    plt.show()
#features = X_train.reshape(-1)
#features
#X_train
image_size = X_train_val.shape[1]
input_size = image_size*image_size
X_train_val = np.reshape(X_train_val,[-1,input_size])
X_test = np.reshape(X_test,[-1,input_size])
X_val = np.reshape(X_val,[-1,input_size])
X_train = np.reshape(X_train,[-1,input_size])

#Já sabemos que cada pixel tem seu código de cor único e também sabemos que ele tem um valor máximo de 255. 
#É importante converter todos os valores de 0 a 255 de cada pixel para um intervalo de valores de 0 a 1. 
#A maneira mais simples é dividir o valor de cada pixel por 255 para obter os valores no intervalo de 0 a 1.
#Normalização
X_train_val = X_train_val / 255
X_test = X_test / 255
X_val = X_val/255
X_train=X_train/255<jupyter_output><empty_output><jupyter_text>Parte1: Modelo Baseline --- MLP<jupyter_code>from sklearn.neural_network import MLPClassifier
from sklearn.metrics import accuracy_score, classification_report
model_baseline = MLPClassifier(hidden_layer_sizes=(200,))
model_baseline.fit(X_train_val,y_train_val)
#Defini em 200 neurônios para a camada oculta pelo fato de a rede base apresentar um bom resultado e percebi também, que colocando acima de 200 neurônios, aumenta ainda mais o custo computacional e o modelo não melhora quase nada.
y_pred = model_baseline.predict(X_test)
print(f'A acurácia do baseline foi: {accuracy_score(y_test,y_pred)*100}%')
acuracia_baseline = accuracy_score(y_test,y_pred)*100
#from sklearn.metrics import recall_score, precision_score, f1_score
#AUC_base = accuracy_score(y_test,y_pred)*100
#Recall_base = recall_score(y_test,y_pred,average=None)*100
#Precision_base = precision_score(y_test,y_pred,average=None)*100
#F1_base = f1_score(y_test,y_pred,average=None)*100'''
print(classification_report(y_test,y_pred))
#Matriz de Confusão
from sklearn import metrics
import seaborn as sns
cm_base = metrics.confusion_matrix(y_test,y_pred)
sns.heatmap(cm_base, annot=True, fmt = 'd')<jupyter_output><empty_output><jupyter_text>Parte 2: Construção de Mellhor Arquitetura(Hiperparâmetros) -- MLP  Possibilidade 1<jupyter_code>from sklearn.model_selection import RandomizedSearchCV
import warnings
warnings.filterwarnings("ignore")
model2 = MLPClassifier()
model2.get_params().keys()
from scipy.stats import uniform 
param = dict(
    alpha = [10**uniform.rvs(loc=-5, scale=4)],
    activation=['relu','logistic','tanh'],
    tol = [0.01,0.001,0.0001],
    hidden_layer_sizes=[(200),(200,100),(800,500),(250,350,450)],
    max_iter= [50, 100, 300, 600]
)
random_search = RandomizedSearchCV(model2, param, random_state=42)
random_search.fit(X_train_val,y_train_val.ravel())
random_search.best_estimator_
y_pred2 = random_search.predict(X_val).reshape(-1,1)
print(f'A acurácia da possibilidade 1 foi: {accuracy_score(y_val,y_pred2)*100}%')
print(classification_report(y_val,y_pred2))
#Matriz de Confusão
from sklearn import metrics
import seaborn as sns
cm = metrics.confusion_matrix(y_val,y_pred2)
sns.heatmap(cm, annot=True, fmt = 'd')<jupyter_output><empty_output><jupyter_text>Possibilidade 2<jupyter_code>import warnings
warnings.filterwarnings("ignore")
#O solucionador para otimização de peso.
# ‘Lbfgs’ é um otimizador na família de métodos quase Newton.
#'Sgd' refere-se à descida do gradiente estocástico.
#‘Adam’ refere-se a um otimizador baseado em gradiente estocástico proposto por Kingma, Diederik e <NAME>

model3_1 = MLPClassifier(solver='sgd', hidden_layer_sizes=(300,300), alpha = 1e-5, max_iter=150)
model3_1.fit(X_train, y_train)   
y_pred3_1 = model3_1.predict(X_val)

model3_2 = MLPClassifier(solver='lbfgs', hidden_layer_sizes=(200,200), alpha = 1e-5, max_iter=150)
model3_2.fit(X_train, y_train)   
y_pred3_2 = model3_2.predict(X_val)
print(f'Acurácia sgd: {accuracy_score(y_val,y_pred3_1)*100}%')
print(f'Acurácia lbfgs: {accuracy_score(y_val,y_pred3_2)*100}%')
print('sgd')
print(classification_report(y_val,y_pred3_1))
print('lbfgs')
print(classification_report(y_val,y_pred3_2))
#Matriz de Confusão
from sklearn import metrics
import seaborn as sns
cm_3_1 = metrics.confusion_matrix(y_val,y_pred3_1)
print('Matriz de Confusão sgd')
sns.heatmap(cm_3_1, annot=True, fmt = 'd')
#Matriz de Confusão
from sklearn import metrics
import seaborn as sns
cm_3_2 = metrics.confusion_matrix(y_val,y_pred3_2)
print('Matriz de Confusão lbfgs')
sns.heatmap(cm_3_2, annot=True, fmt = 'd')<jupyter_output>Matriz de Confusão lbfgs<jupyter_text>Melhor Modelo Analisando as métricas de resultados, o do random foi o melhor modelo  Aplicando os dados de testes<jupyter_code>model_best = MLPClassifier(activation='tanh', alpha=3.190021451766908e-05,
              hidden_layer_sizes=(200, 100), max_iter=50)
model_best.fit(X_train_val,y_train_val)
y_pred_best = model_best.predict(X_test)
print(f'A acurácia do melhor modelo foi: {accuracy_score(y_test,y_pred_best)*100}%')
acuracia_best = accuracy_score(y_test,y_pred_best)*100
print(classification_report(y_test,y_pred_best))
#Matriz de Confusão
from sklearn import metrics
import seaborn as sns
cm_best = metrics.confusion_matrix(y_test,y_pred_best)
sns.heatmap(cm_best, annot=True, fmt = 'd')<jupyter_output><empty_output><jupyter_text>Comparação Baseline com Modelo Escolhido<jupyter_code>import pandas as pd
#Criando um dataframe para apresentar os resultados
# Ainda vou colocar o terceiro
modelo1 = pd.Series({'Modelos': 'Modelo 1(Baseline)', 'Acurácia': acuracia_baseline})
modelo2 = pd.Series({'Modelos': 'Modelo 2(Random)', 'Acurácia': acuracia_best})


df_resultados = pd.DataFrame([modelo1,modelo2])
df_resultados
print('           Modelo Baseline --- Métricas de Resultado            ')
print(classification_report(y_test,y_pred))
print("\n")
print('           Modelo RandomSearchCV --- Métricas de Resultado            ')
print(classification_report(y_test,y_pred_best))
print("\n")
print('Baseline')
sns.heatmap(cm_base, annot=True, fmt = 'd')
print('Random')
sns.heatmap(cm_best, annot=True, fmt = 'd')<jupyter_output>Random
{'fraction_non_alphanumeric': 0.09991693366559867, 'fraction_numerical': 0.03156520707250504, 'mean_word_length': 6.491555555555555, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 24, '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': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '419768', 'license': 'MIT', 'n_tokens_mistral': 3344, 'n_tokens_neox': 3131, 'n_words': 812, 'path': 'Atividade 5/Atividade 5 - Redes Neurais MLP.ipynb', 'repo_name': 'Ruann-01/Python_IA', 'size': '8429'}