Advertisement
renard162

Rede perceptron

Nov 29th, 2020
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.18 KB | None | 0 0
  1. import numpy as np
  2. from sklearn.model_selection import train_test_split
  3. from sklearn import datasets
  4. import matplotlib.pyplot as plt
  5.  
  6. # Só para mostrar uma barrinha durante o processo de treino, para poder
  7. # monitorar a etapa do processo, pois a geração de gráfico em tempo
  8. # real (plt.ion()) é bem chatinha no que diz respeito a desempenho.
  9. from tqdm import tqdm
  10.  
  11.  
  12.  
  13.  
  14. #Classe do Perceptron
  15. class Perceptron:
  16. # Definindo o numero de iterações e a taxa de aprendizado
  17.     def __init__(self, learning_rate=0.01, n_iters=1000):
  18.         self.lr = learning_rate
  19.         self.n_iters = n_iters
  20.         self.activation_func = self._unit_step_func
  21.         self.weights = None
  22.         self.bias = None
  23.        
  24.         #Aqui você define o tempo de delay (em segundos) entre cada render do
  25.         #plot. Veja que, independente do hardware, implementar um render em
  26.         #tempo real sempre reduz o desempenho do seu algoritmo, pois é
  27.         #necerssário forçar um delay entre as iterações.
  28.         self.delay = 1e-5
  29.    
  30.    
  31.     #Adicionei o argumento optativo de plotar o gráfico do treinamento em
  32.     #tempo real. Por padrão ele é True, forçando o plot do treinamento em
  33.     #tempo real, mas se chamar esse metodo com
  34.     #"obj.fit(x_train, y_train, plot_train=False)", o algoritmo irá rodar
  35.     #como você fez inicialmente. Fiz essa implementação só para que você
  36.     #pudesse comparar desempenho com maior facilidade.
  37.     def fit(self, X, y, plot_train: bool=True):
  38.         n_samples, n_features = X.shape
  39.         # inicializando os parametros
  40.         self.weights = np.zeros(n_features)
  41.         self.bias = 0
  42.         y_ = np.array([1 if i > 0 else 0 for i in y])
  43.        
  44.         if plot_train:
  45.             #Aqui gerou-se o gráfico inicial, veja que o gráfico iterativo não
  46.             #funciona com o render "inline", portanto use outro render, caso
  47.             #esteja usando ipython/jupyter ("%matplotlib qt", por exemplo)
  48.             self._x_init = np.amin(X[:,0])
  49.             self._x_end = np.amax(X[:,0])
  50.            
  51.             y_init = 0
  52.             y_end = 0
  53.            
  54.             plt.ion() #Liga o modo de gráfico iterativo
  55.             self.fig = plt.figure()
  56.             plt.scatter(X[:,0], X[:,1], marker='o', c=y)
  57.            
  58.             self.plt_ax = self.fig.add_subplot(1, 1, 1)
  59.             self.plt_ax.grid(True)
  60.             self.plt_line = self.plt_ax.plot([self._x_init, self._x_end],
  61.                                              [y_init, y_end], 'k')
  62.             plt.draw() #Desenha a linha do plot
  63.             self.fig.show()
  64.            
  65.             #Pausa necessária para que o render não trave,
  66.             #dependendo da máquina talvez seja necessário aumentar esse tempo.
  67.             #Subir ele até "1e-3" no máximo usualmente resolve os problemas
  68.             #caso estes existam.
  69.             plt.pause(self.delay)
  70.            
  71.         #Veja que o "tqdm" foi aplicado no "iterator", mas, como citei no
  72.         #import, é só estético, se quiser tirar a barrinha, pode
  73.         #tirar o "tqdm".
  74.         for _ in tqdm(range(self.n_iters)):
  75.             for idx, x_i in enumerate(X):
  76.                 linear_output = np.dot(x_i, self.weights) + self.bias
  77.                 y_predicted = self.activation_func(linear_output)
  78.                 # Perceptron update rule
  79.                 update = self.lr * (y_[idx] - y_predicted)
  80.                 self.weights += update * x_i
  81.                 self.bias += update
  82.  
  83.             if plot_train:
  84.                 #Chama o método para atualizar o plot a cada iteração.
  85.                 self._update_train_plot()
  86.              
  87.                
  88.     def predict(self, X):
  89.         linear_output = np.dot(X, self.weights) + self.bias
  90.         y_predicted = self.activation_func(linear_output)
  91.         return y_predicted
  92.    
  93.    
  94.     def _unit_step_func(self, x):
  95.         return np.where(x>=0, 1, 0)
  96.    
  97.    
  98.     def _update_train_plot(self):
  99.         y_init = (-self.weights[0] * self._x_init - self.bias) \
  100.                     / self.weights[1]
  101.         y_end = (-self.weights[0] * self._x_end - self.bias) \
  102.                     / self.weights[1]
  103.                    
  104.         #Essas duas linhas (pop e remove) são responsáveis por apagar a
  105.         #linha antiga do plot.
  106.         self.plt_line = self.plt_line.pop(0)
  107.         self.plt_line.remove()
  108.        
  109.         #Cria a nova linha
  110.         self.plt_line = self.plt_ax.plot([self._x_init, self._x_end],
  111.                                          [y_init, y_end], 'k')
  112.        
  113.         #Assim como no plot inicial, desenha a nova linha e espera um tempo
  114.         #para que o novo plot seja renderizado.
  115.         plt.draw()
  116.         plt.pause(self.delay)
  117.        
  118.  
  119.  
  120.  
  121. def accuracy(y_true, y_pred):
  122.     accuracy = np.sum(y_true == y_pred) / len(y_true)
  123.     return accuracy
  124.  
  125.  
  126.  
  127.  
  128. # Gerando duas classes de dados que são linearmente separaveis
  129. X, y = datasets.make_blobs(n_samples=150,n_features=2,centers=2,cluster_std=1.05,random_state=2)
  130. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)
  131. p = Perceptron(learning_rate=0.01, n_iters=1000)
  132. p.fit(X_train, y_train, plot_train=True)
  133. predictions = p.predict(X_test)
  134. print("Perceptron classification accuracy", accuracy(y_test, predictions))
  135. fig = plt.figure()
  136. ax = fig.add_subplot(1,1,1)
  137. plt.scatter(X_train[:,0], X_train[:,1],marker='o',c=y_train)
  138. x0_1 = np.amin(X_train[:,0])
  139. x0_2 = np.amax(X_train[:,0])
  140. x1_1 = (-p.weights[0] * x0_1 - p.bias) / p.weights[1]
  141. x1_2 = (-p.weights[0] * x0_2 - p.bias) / p.weights[1]
  142. ax.plot([x0_1, x0_2],[x1_1, x1_2], 'k')
  143. ymin = np.amin(X_train[:,1])
  144. ymax = np.amax(X_train[:,1])
  145. ax.set_ylim([ymin-3,ymax+3])
  146. plt.show()
  147.  
  148.  
  149. #Este seu problema converge muito rapidamente pois seus conjuntos já estão
  150. #bem agrupados, assim, não é possível acompanhar a linha se movendo em tempo
  151. #real. Se quiser verificar este efeito, aumente o tempo de delay
  152. #na propriedade self.delay. Se você colocar 1 segundo, verá nitidamente o
  153. #avanço do treinamento mas as iteraçãoes demorarão MUITO, talvez sendo
  154. #necessário interromper o prcesso. Tenta usar outro conjunto de dados,
  155. #menos organizados, para testar.
  156.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement