Baixe o app para aproveitar ainda mais
Prévia do material em texto
Multilayer Perceptron (MLP) Aluno: João Correia Costa Redes neurais Multilayer Perceptron (MLP) são comprovadamente capazes de resolver problemas de classificação e previsão em bases de dados multidimensionais. Utilizando as classes MLPRegressor e MLPClassifier da biblioteca python sklearn, foram implementadas redes neurais de arquitetura variada, baseadas no algoritmo Backpropagation. O objetivo do exercício é classificar as intâncias da base de dados Statlog, e predizer o valor do atributo MEDV da base Boston Housing. A fim de avaliar o desempenho de cada modelo, foram realizados treinamentos repetidos, com variação de parâmetros. Os erros e acurácias médias obtidos foram plotados em gráficos para análise geral do desempenho. Código - Previsão e Classificação Boston Housing A primeira base de dados a ser analisada é o Boston Housing. Foram inicializadas redes neurais MLP com duas camadas escondidas, com 10i neurônios em cada uma, onde i é o index que representa a configuração da camada. Por tanto, para i=1, a rede apresenta 10 neurônios em cada camada. Foram implementadas 30 configurações, i variando de 1 a 30. O treinamento foi repetido 5 vezes com coeficiente de aprendizado alpha igual a 0.0001 e tolerância de 10e-6. Variamos a função de ativação (logistic, relu, identity, tanh) built-in sklearn, e plotamos os gráficos de desempenho abaixo. Os dados de treinamento representam 70% das amostras, sendo o restante dados de teste. Foi efetuada uma normalização dos dados através da classe StandardScaler, facilitando a convergência do modelo. ok Menor erro quadrático médio: ----------------------------------------------------------------- 18.836600931944524 +/- 0.5862605238870229 i=15 ok Menor erro quadrático médio: ----------------------------------------------------------------- 13.110946578964883 +/- 0.5348334517542644 i=26 ok Menor erro quadrático médio: ----------------------------------------------------------------- 13.129410642163034 +/- 0.8805185804292263 i=27 ok Menor erro quadrático médio: ----------------------------------------------------------------- 29.860623354411306 +/- 0.1248449768655211 i=19 Observou-se uma queda progressiva do erro quadrático médio para todas as funções, excetuando a identidade, à medida que o número de unidades na camada escondida aumenta. Os melhores desempenhos foram obtidos pelas funções de ativação Tangente Hiperbólica e 'Relu' com erros, respectivamente, iguais a 13.11 +/- 0.53 e 13.12 +/- 0.88 . A função identidade apresentou o pior desempenho, com erro quadático médio insensível a variação no número de neurônios na camada escondida. Statlog O dataset Statlog é binário, com 270 instâncias e 20 atributos para cada uma delas. Foram implementadas redes de arquitetura variada, semelhantes as do Boston Housing, e o treinamento foi repetido 5 vezes para cada uma. Os dados foram normalizados através da classe StandardScaler. O objeto python para classificação foi o MLPClassifier built-in sklearn. Variamos as funções de ativação (logistic, relu, identity, tanh) e plotamos os gráficos de desempenho abaixo. Os dados foram divididos entre amostras de teste e de treinamento seguindo a mesma proporção do Boston Housing (train-70%, test-30%) Maior Acurácia média: ----------------------------------------------------------------- 0.5407407407407407 +/- 0.13250773199998755 i=26 Maior Acurácia média: ----------------------------------------------------------------- 0.7999999999999999 +/- 0.016096796062228785 i=5 Maior Acurácia média: ----------------------------------------------------------------- 0.7925925925925925 +/- 0.013524013765559641 i=3 Maior Acurácia média: ----------------------------------------------------------------- 0.8049382716049382 +/- 0.016096796062228778 i=15 Os desempenhos do modelo para as funções tangente hiperbólica, Sigmoidal Unipolar e identidade foram muito semelhantes, em torno de 80% para os dados de teste após a estabilização da curva. Observa-se uma leve tendência ao overfitting para valores de configuração i acima de 15 neurônios. In [98]: # Bibliotecas Padrão from sklearn.neural_network import MLPRegressor, MLPClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error, accuracy_score from sklearn.preprocessing import StandardScaler from sklearn.tree import DecisionTreeRegressor from sklearn.pipeline import make_pipeline from sklearn import datasets import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sbn import random import statistics In [99]: class Stats: def __init__(self): self.error_test = [] self.error_train = [] self.acrs_test = [] self.acrs_train = [] self.stdvs_test = [] self.stdvs_train = [] self.arch_params = None self.alphas = None self.size = 0 self.x_train, self.x_test, self.y_test, self.y_train = None, None, None, None self.classifier = None def get_stats(self, params, alpha, times, activation, classifier): error_test, error_train, acr_test, acr_train = [], [], [], [] for i in range(times): if not classifier: # Inicializando a rede MLP mlp = MLPRegressor(hidden_layer_sizes=params, tol=1e-2, max_iter=3000, random_state mlp.fit(self.x_train, self.y_train) yp_train = mlp.predict(self.x_train) yp_test = mlp.predict(self.x_test) error_test.append(mean_squared_error(self.y_test, yp_test)) error_train.append(mean_squared_error(self.y_train, yp_train)) if classifier: # Inicializando a rede MLP mlp = MLPClassifier(hidden_layer_sizes=params, tol=1e-2, max_iter=3000, random_state mlp.fit(self.x_train, self.y_train) yp_train = mlp.predict(self.x_train) yp_test = mlp.predict(self.x_test) acr_test.append(accuracy_score(self.y_test, yp_test)) acr_train.append(accuracy_score(self.y_train, yp_train)) if not classifier: self.error_test.append(self.mean(error_test)) self.error_train.append(self.mean(error_train) ) self.stdvs_test.append(self.stdv(error_test)) self.stdvs_train.append(self.stdv(error_train)) error_test, error_train = [], [] if classifier: self.acrs_test.append(self.mean(acr_test)) self.acrs_train.append(self.mean(acr_train) ) self.stdvs_test.append(self.stdv(acr_test)) self.stdvs_train.append(self.stdv(acr_train)) acr_test, acr_train = [], [] def train_for(self, x_train, y_train, x_test, y_test, arch_params, alphas, times, # inicilaizando dados de treinamento self.classifier = classifier self.y_test, self.y_train = y_test, y_train sc = StandardScaler() # fit to the train data sc.fit(x_train) self.x_train = sc.transform(x_train) self.x_test = sc.transform(x_test) for params, alpha in zip(arch_params, alphas): self.size += 1 self.get_stats(params, alpha, times, activation, classifier) def stdv(self, acrs): return statistics.stdev(acrs) def mean(self, acrs): return statistics.mean(acrs) def view(self, title): if not self.classifier: self.error_test = np.array(self.error_test) self.error_train = np.array(self.error_train) if self.classifier: self.acrs_test = np.array(self.acrs_test)self.acrs_train = np.array(self.acrs_train) self.stdvs_test = np.array(self.stdvs_test) self.stdvs_train = np.array(self.stdvs_train) ax = range(self.size) sbn.axes_style() sbn.set_style("darkgrid", {"axes.facecolor": ".9"}) fig = plt.figure() if not self.classifier: plt.errorbar(ax, self.error_test, yerr = self.stdvs_test, ls = "None", col plt.plot(ax, self.error_test, marker = "h", color = (0.6, 0, 0), label="Te plt.errorbar(ax, self.error_train, yerr = self.stdvs_train, ls = "None", c plt.plot(ax, self.error_train, marker = "h", color = (0, 0, 0.6), label="T print("ok") plt.title(f"{title}", fontsize=16) plt.xlabel("Configuração da camada intermediária", fontsize=16) plt.ylabel("Erros Médios", fontsize=16) plt.legend(fontsize = 16) if self.classifier: plt.errorbar(ax, self.acrs_test, yerr = self.stdvs_test, ls = "None", colo plt.plot(ax, self.acrs_test, marker = "h", color = (0.6, 0, 0), label="Tes plt.errorbar(ax, self.acrs_train, yerr = self.stdvs_train, ls = "None", co plt.plot(ax, self.acrs_train, marker = "h", color = (0, 0, 0.6), label="Tr plt.title(f"{title}", fontsize=16) plt.xlabel("Configuração da camada intermediária", fontsize=16) plt.ylabel("Acurácias Médios", fontsize=16) plt.legend(fontsize = 16) fig.set_size_inches(14.5, 8.5, forward=True) #fig.subplots_adjust(left=0.0, bottom=0.1, right=1.0, top=0.9, wspace=0.2, hsp fig plt.show() In [100… # Inicializando dados Boston Housing db = datasets.load_boston() df_x = db.data df_y = db.target # Inicializando os dados x_train, x_test, y_train, y_test = train_test_split(df_x, df_y, test_size=0.3, random_ In [101… sts = Stats() sts.train_for(x_train, y_train, x_test, y_test, arch_params=[(10*i, 10*i,) for i in ra sts.view("Erros Médios para o Boston Housing (activation='logistic')") i = np.argmin(sts.error_test) print("Menor erro quadrático médio:") print("-"*65) print(f"{np.min(sts.error_test)} +/- {sts.stdvs_test[i]}\t\t i={i}") In [102… sts = Stats() sts.train_for(x_train, y_train, x_test, y_test, arch_params=[(10*i, 10*i,) for i in ra sts.view("Erros Médios para o Boston Housing (activation='tanh')") i = np.argmin(sts.error_test) print("Menor erro quadrático médio:") print("-"*65) print(f"{np.min(sts.error_test)} +/- {sts.stdvs_test[i]}\t\t i={i}") In [103… sts = Stats() sts.train_for(x_train, y_train, x_test, y_test, arch_params=[(10*i, 10*i,) for i in ra sts.view("Erros Médios para o Boston Housing (activation='relu')") i = np.argmin(sts.error_test) print("Menor erro quadrático médio:") print("-"*65) print(f"{np.min(sts.error_test)} +/- {sts.stdvs_test[i]}\t\t i={i}") In [104… sts = Stats() sts.train_for(x_train, y_train, x_test, y_test, arch_params=[(10*i, 10*i,) for i in ra sts.view("Erros Médios para o Boston Housing (activation='identity')") i = np.argmin(sts.error_test) print("Menor erro quadrático médio:") print("-"*65) print(f"{np.min(sts.error_test)} +/- {sts.stdvs_test[i]}\t\t i={i}") In [74]: # Inicializando os dados Statlog with open("heart.dat") as file: data = [] for line in file.readlines(): data.append(line.split()) data = np.array(data, 'float') df_y = data[:, -1] df_x = data[:, :-1] # Inicializando os dados x_train, x_test, y_train, y_test = train_test_split(df_x, df_y, test_size=0.3, random_ In [93]: sts = Stats() sts.train_for(x_train, y_train, x_test, y_test, arch_params=[(10*i, 10*i,) for i in ra sts.view("Acurácias Médias para o Statlog (activation='logistic')") i = np.argmax(sts.acrs_test) print("Maior Acurácia média:") print("-"*65) print(f"{np.max(sts.acrs_test)} +/- {sts.stdvs_test[i]}\t\t i={i}") In [94]: sts = Stats() sts.train_for(x_train, y_train, x_test, y_test, arch_params=[(10*i, 10*i,) for i in ra sts.view("Acurácias Médias para o Statlog (activation='tanh')") i = np.argmax(sts.acrs_test) print("Maior Acurácia média:") print("-"*65) print(f"{np.max(sts.acrs_test)} +/- {sts.stdvs_test[i]}\t\t i={i}") In [95]: sts = Stats() sts.train_for(x_train, y_train, x_test, y_test, arch_params=[(10*i, 10*i,) for i in ra sts.view("Acurácias Médias para o Statlog (activation='identity')") i = np.argmax(sts.acrs_test) print("Maior Acurácia média:") print("-"*65) print(f"{np.max(sts.acrs_test)} +/- {sts.stdvs_test[i]}\t\t i={i}") In [96]: sts = Stats() sts.train_for(x_train, y_train, x_test, y_test, arch_params=[(10*i, 10*i,) for i in ra sts.view("Acurácias Médias para o Statlog (activation='relu')") i = np.argmax(sts.acrs_test) print("Maior Acurácia média:") print("-"*65) print(f"{np.max(sts.acrs_test)} +/- {sts.stdvs_test[i]}\t\t i={i}")
Compartilhar