Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- import os
- import random
- #import keras
- import scipy
- import math
- class MLP(object):
- def __init__(self, layers_size, learning_rate, **args):
- '''
- learning_rate Constante de aprendizaje
- layers_size Dimension de los datos de entrada y salida y de las capas intermedias.
- ejemplos layers_size
- [100, 50, 10] 100 neuronas de entrada, 50 de capa oculta 1 y 10 de salida
- [100, 50, 20, 10] 100 neuronas de entrada, 50 de capa oculta 1, 50 de capa oculta 2 y 10 de salida
- [100, 50, 20, 50, 10] etc.
- '''
- matrizSalidas = []
- matrizEntradas = []
- matrizPesos = []
- random.randint(0, 2)
- for i in range(0, len(layers_size)):
- if (i != 0):
- matrizEntradas.append(np.ones((layers_size[i], layers_size[i - 1] + 1)))
- matrizPesos.append(np.ones((layers_size[i], layers_size[i - 1] + 1)))
- else:
- matrizEntradas.append(np.ones((layers_size[i], 1)))
- matrizPesos.append(np.ones((layers_size[i], 1)))
- matrizSalidas.append(np.ones((layers_size[i], 1)))
- for i in range(0, len(layers_size)):
- for l in range(0, matrizPesos[i].shape[0]):
- for j in range(0, matrizPesos[i].shape[1]):
- matrizPesos[i][l, j] = (random.randint(0, 2) - 1)
- self.learning_rate = learning_rate
- self.__dict__.update(args)
- # TODO
- self.layers_size = layers_size
- self.matricesEntrada = matrizEntradas
- self.matricesSalidas = matrizSalidas
- self.matricesPesos = matrizPesos
- def fit(self, X_train, y_train, X_Test, y_test):
- '''
- Recibe los datos de entrada X y los datos de salida esperados y para entrenar el modelo de red neuronal.
- X Matriz bidimiensional con forma (u,v) donde u es el número de tuplas y v el número de variables
- y Vector unidimensional con longitud u que contiene las salidas esperadas para cada una de las tuplas de X
- No devuelve nada
- '''
- # TODO
- if(X_Test == None):
- for i in range(150):
- actual = self.mse(X_train, y_train)
- self.backpropagation(X_train, y_train, actual)
- #print(actual)
- actual = self.mse(X_train, y_train)
- self.backpropagation(X_train, y_train, actual)
- anterior = 1000000000
- actual = self.mse(X_train, y_train)
- while(anterior > actual):
- print(actual)
- actual = anterior
- self.backpropagation(X_train, y_train, actual)
- actual = self.mse(X_train, y_train)
- def backpropagation(self, X, y, mse):
- '''
- Recibe los datos de entrada X y los datos de salida esperados y para realizar una actualización en batch
- de los valores thetas
- X Matriz bidimiensional con forma (u,v) donde u es el número de tuplas y v el número de variables
- y Vector unidimensional con longitud u que contiene las salidas esperadas para cada una de las tuplas de X
- No devuelve nada
- '''
- # TODO
- error = self.matricesSalidas
- for l in reversed(range(len(self.matricesSalidas))):
- if (l==len(self.matricesSalidas)-1):
- for i in range(0, self.matricesSalidas[l].shape[1]):
- error[l][i, 0] = (y[i]-self.matricesSalidas[l][i, 0])*(self.matricesSalidas[l][i, 0])*(1-self.matricesSalidas[l][i, 0])
- else:
- for i in range(0, self.matricesSalidas[l].shape[1]-1):
- error[l][i, 0] = self.matricesSalidas[l][i, 0]
- error[l][i,0] = error[l][i,0]* (1-self.matricesSalidas[l][i, 0])
- mult = np.multiply(error[l+1],self.matricesPesos[l+1])
- error[l][i,0] = error[l][i,0]*(np.sum(mult, axis=1))[i]
- for l in range(0, len(error)):
- for i in range(0, self.matricesEntrada[l].shape[1]-1):
- for j in range(0, self.matricesEntrada[l].shape[0]-1):
- suma = self.learning_rate*error[l][i-1,0]
- suma = suma*self.matricesEntrada[l][j, i]
- self.matricesPesos[l][j,i]=self.matricesPesos[l][j,i]+suma
- def sigmoid(self, x):
- return 1/(1+math.exp(-x))
- def sigmoidDeriv(self, x):
- return sigmoid(x) * (1 - sigmoid(x))
- def predict(self, X):
- '''
- Recibe los datos de entrada X para estimar la salida estimada y_ segun el modelo entrenado
- X Matriz bidimiensional con forma (u,v) donde u es el número de tuplas y v el número de variables
- y Vector unidimensional con longitud u que contiene las salidas esperadas para cada una de las tuplas de X
- Devuelve un vector unidimensional y_ de longitud u el cual contiene el conjunto de salidas estimadas para X
- '''
- # TODO
- y=[]
- # for i in range(0, len(X)):
- # self.matricesSalidas[0]= np.matrix(X[i]).T
- for i in range(0, len(X)):
- self.matricesSalidas[0][i, 0] = X[i]
- #aqui ponemos la primera posicion del array de matrices de salidas lo igualamos a las entradas
- for p in range(0):
- for l in range(1, len(self.matricesEntrada)):
- for i in range(0, self.matricesEntrada[l].shape[0]-1):
- for j in range(0, self.matricesEntrada[l].shape[1]-1):
- self.matricesEntrada[l][i, j] = self.matricesSalidas[l - 1][j, 0]
- nuevoArray=np.sum(np.multiply(self.matricesEntrada[l],self.matricesPesos[l]), axis=1)
- for i in range(0,len(nuevoArray)-1):
- self.matricesSalidas[l][i,0] = self.sigmoid(nuevoArray[i])
- #self.matricesSalidas[l] = keras.activations.sigmoid(
- # np.sum(np.multiply(self.matricesEntrada[l], self.matricesPesos[l]), axis=0))
- # for i in range(1, self.matricesSalidas[-1].shape[1]):
- # np.concatenate(y, self.matricesSalidas[-1])
- y.append(self.matricesSalidas[-1])
- return y
- def mse(self, X, y):
- '''
- Recibe los datos de entrada X y los datos de salida esperados y para obtener el error cuadratico medio
- del modelo entrenado
- X Matriz bidimiensional con forma (u,v) donde u es el número de tuplas y v el número de variables
- y Vector unidimensional con longitud u que contiene las salidas esperadas para cada una de las tuplas de X
- Devuelve el error cuadratico medio (float)
- '''
- # TODO
- '''
- pred = self.predict(X)
- numeroTuplas = len(X)
- suma = 0
- for i in range(numeroTuplas):
- suma = suma + ((pred[i] - y[i] ** 2))
- errorCuadraticoMedio = float(1 / float(numeroTuplas)) * suma
- return errorCuadraticoMedio
- '''
- hipotesis = self.predict(X)
- ErrorCuadraticoMedio = 0
- #Recorremos las columnas de nuestro array hipotesis
- for i in (range (len(hipotesis))):
- #.item en lugar de [i] nos evita bastantes errores
- #Aplicamos la fórmula del error cuadrático medio de la diapositiva 6 del tema 3 de regresión
- ErrorCuadraticoMedio = ErrorCuadraticoMedio + ((hipotesis[i] - y[i])**2)
- #Devolvemos el sumatorio entre el número de tuplas
- mse = ErrorCuadraticoMedio/X.shape[0]
- return np.sum(mse)
- if __name__ == '__main__':
- from sklearn import datasets
- # X = np.matrix([[0,0], [0,1], [1,0], [1,1]])
- # y = np.matrix([[0], [1], [1], [0]])
- # j = MLP([2,2,1], 0.5)
- # j.fit(X, y, None, None)
- # print(j.mse(X, y))
- X, y = datasets.load_iris(return_X_y=True)
- np.random.permutation(list(zip(X,y)))
- puntoCorte = int(len(X) * 0.7)
- X_Train = X[:puntoCorte]
- X_Test = X[puntoCorte:]
- y_Train = y[:puntoCorte]
- y_Test = y[puntoCorte:]
- zip(*(X,y))
- redIris = MLP([4, 4, 4, 3], 0.9)
- redIris.fit(X_Train, y_Train, X_Test, y_Test)
- print(redIris.mse(X,y))
- # j = MLP([2, 2, 1], 0.5)
- # print("SalidaXor")
- #print(j.predict([0, 1]))
- #j.backpropagation([0, 1], [1], 0.5)
- #print(j.predict([0, 0]))
- #redIris = MLP([X.shape[1], 50, 20, 3])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement