import numpy as np
import scipy as sc
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles
#Crear Dataset
n = 500 #numero de registros en los datos
p = 2 #numero de caracteristicas que tienen los datos
#hacer un circulo con los datos y caracteristicas separado con un factor de 0.5 y 0.05 de ruido
X, Y = make_circles(n_samples = n, factor = 0.5, noise = 0.05)
Y = Y[:, np.newaxis]
#visualizar (X[...])... donde X => es el eje en el plano
#indice '0' en el vector Y visible en azul claro
plt.scatter(X[Y[:, 0] == 0, 0], X[Y[:, 0] == 0, 1], c="skyblue") #p=1
#indice '1' en el vector Y visible en salmon
plt.scatter(X[Y[:, 0] == 1, 0], X[Y[:, 0] == 1, 1], c="salmon") #p=2
plt.axis("equal")
plt.show()
class neural_layer(): #crear una clase capa neuronal
#inicia un constructor de numero de conexiones, numero de neuronas y funcion de activacion
def __init__(self,n_conn, n_neur, act_f):
self.act_f = act_f #la act_f = al mismo parametro de act_f
self.b = np.random.rand(1, n_neur)*2 -1 #vector aleatorio con numero 0 como valor medio -1 a 1
self.b = np.random.rand(n_conn, n_neur)*2 -1 #matriz con numero de conexiones necesarias al numero de neuronas
#Funciones de activacion
sigm = (lambda x: 1/(1 + np.e**(-x)), #para un parametro de entrada x, sigm vale:
lambda x: x * (1 - x)) #derivada de sigm
_x = np.linspace(-5, 5, 100) #variable que crea 100 valores de forma lineal de entre -5 y 5
relu = lambda x: np.maximum(0,x) #valor maximo entre 0 y X
plt.plot(_x, sigm[0](_x)) #vista de la grafica con [0]= sigmoide con [1]= derivada
def create_nn(topology, act_f):
nn = []
for l, layer in enumerate(topology[:-1]):
nn.append(neural_layer(topology[l], topology[l+1], act_f))
return nn
topology = [p, 4, 8, 1] #numero de neuronas por capa
neural_net = create_nn(topology, sigm)
l2_cost = lambda Yp, Yr: (np.mean(Yp - Yr)**2), #error cuadratico medio de Yp = valor predicho e Yr = valor real
lambda Yp, Yr: (Yp - Yr)) #derivada del ECM
def train(neural_net, X, Y, l2_cost, lr=0.5, train=True): #funcion de entrenamiento / lr= ratio de aprendizaje
out =[(None, X)] # vectores de suma ponderada y valor de activacion
#Forward pass
for l, layer in enumerate (neural_net):
Z = out[-1][1] @ neural_net[1].W + neural_net[1].b #suma ponderada
a = neural_net[1].act_f[0](z) #activacion de la salida de la capa X
out.append((z,a))
print(l2cost[0](out[-1][1], Y)) #imprime el error
if train: #Si la variable Train es False nunca se ejecuta
#Backward pass (propagacion de error al inicio)
deltas = []
for l in reversed(range(0, len(neural_net)): #añades vectores del final hacia el principio
z = out[l+1][0]
a = out[l+1][1]
if l = len(neural_net) - 1:
#calcular delta ultima capa.
deltas.insert(0,l2_cost[1](a, Y) * neural_net[l].act_f[1](a))
else:
#calcular delta respecto a capa previa.
deltas.insert(0, deltas[0] @ _W.Transpose * neural_net[1].act_f[1](a))
_W = neural_net[l].W #guardado temporal
#Gradient descent
neural_net[l].b = neural_net[l].b - np.mean(deltas[0], axis=0, keepdims=True) * lr #algoritmo de bayas
neural_net[l].W = neural_net[l].W - output[1][1].Transpose @ deltas[0] * lr
return out[-1][1]
train(neural_net, X, Y, l2_cost, 0.5)
NN_exe.py
import time
from IPython.display import clear_output
neural_n = create_nn(topology, sigm)
loss = []
for l in range(2500):
#Entrenamiento de la red neuronal:
pY = train(neural_n, X, Y, l2_cost, lr=0.05)
if i % 25 == 0;
loss.append(l2_cost[0](pY, Y))
res = 50 #resolucion de la pantalla
_x0 = np.linspace(-1.5, 1.5, res)
_x1 = np.linspace(-1.5, 1.5, res)
_Y = np.zeros((res, res))
for l0, x0 in enumerate(_x0):
for l1, x1 in enumerate(_x1):
_Y[l0, l1] = train(neural_n, np.array([[x0, x1]]), Y, l2_cost, train = False)[0][0]
plt.pcolormesh(_x0, _x1, _Y, cmap= "coolware")
plt.axis("equal")
plt.scatter[X[Y[:,0] == 0, 0], X[Y[:,0] == 0, 1], c="skyblue")
plt.scatter[X[Y[:,0] == 1, 0], X[Y[:,0] == 1, 1], c="salmon")
clear_output(wait=True)
plt.show()
plt.plot(range(len(loss)), loss)
plt.show()
time.sleep(0.5)
No hay comentarios:
Publicar un comentario