def buildClassifier(self, data, test=None): self.clases = list(data.getClases()) self.nClases = len(self.clases) self.columnas = list(data.getColumnasList()) self.nColumnas = len(self.columnas) if data.getNumeroInstances() >= 100000: self.activo_control_fin = True particionado = DivisionPorcentual() particionado.setPorcentajeTrain(0.8) particion = particionado.generaParticionesProporcional(data) data = particion.getTrain() self.conjuntoValidacion = particion.getTest() self.nInstaces = data.getNumeroInstances() #creamos las neuronas de entrada self.capaEntrada = [1 for x in range(0, self.nColumnas + 1)] #self.capaEntrada = map((lambda x: 1), range(0, self.nColumnas + 1)) #inicializamos los pesos de manera aleatoria #por cada neurona de la capa oculta for indNeurona in range(0, self.neuronasCapaOculta): #por cada neurona de la capa de entrada self.pesosCapaOculta.append([]) self.pesosCapaOculta[indNeurona] = map( (lambda x: (random.random() - 0.5)), range(0, self.nColumnas + 1)) #inicializamos los pesos de la capa de salida for indNeurona in range(0, self.nClases): self.pesosCapaSalida.append([]) self.pesosCapaSalida[indNeurona] = map( (lambda x: (random.random() - 0.5)), range(0, self.neuronasCapaOculta + 1)) #self.NguyenWidrow() #generamos todos los vectores objetivos vectoresObjetivos = {} for instancia in data.getListInstances(): vectoresObjetivos[instancia] = self.generaVectorObjetivoSalida( instancia) instancias = data.getListInstances() cuadratico_epoca_anterior = float("inf") # Cabecera para el fichero if self.debug: self.debugFile.write("Época\t") if test is not None: self.debugFile.write("Error de test\t") self.debugFile.write("Error train\tArray de pesos\n") cuadratico_anterior = 1000 #paso1 for epoca in range(0, self.nEpocas): cuadratico_epoca = 0 #print epoca #paso2 por cada instancia en train for instancia in instancias: #***********inicio de Feedforward********************************** #paso 3, valores de entrada for indNeurona in range(1, self.nColumnas + 1): self.capaEntrada[indNeurona] = instancia.getElementAtPos( indNeurona - 1) #paso 4, salida neuronas capa oculta, vector Z #z0 siempre es 1 salidaCapaOculta = [1] #por cada neurona realizamos una salida for indNeurona in range(0, self.neuronasCapaOculta): suma = 0 for indNeuronaEntr in range(0, self.nColumnas + 1): suma += ( self.pesosCapaOculta[indNeurona][indNeuronaEntr] * self.capaEntrada[indNeuronaEntr]) #aplicamos la sigmoidal a la suma, esto nos da la salida de la neurona if self.bipolar == False: #f1 if suma > 400: salidaCapaOculta.append(1.0) elif suma < -400: salidaCapaOculta.append(0.0) else: salidaCapaOculta.append(1.0 / (1.0 + math.exp(-suma))) else: #f2 if suma > 400: salidaCapaOculta.append(1.0) elif suma < -400: salidaCapaOculta.append(-1.0) else: salidaCapaOculta.append((2.0 / (1.0 + math.exp(-suma))) - 1.0) #paso 5, calculamos las respuestas de las neuronas de la capa de salida, vector Y salidaFinal = [] for indNeurona in range(0, self.nClases): suma = 0 for indNeuronaOculta in range(0, self.neuronasCapaOculta + 1): suma += ( self.pesosCapaSalida[indNeurona][indNeuronaOculta] * salidaCapaOculta[indNeuronaOculta]) #aplicamos la sigmoidal a la suma, esto nos da la salida de la neurona if self.bipolar == False: #f1 if suma > 400: salidaFinal.append(1.0) elif suma < -400: salidaFinal.append(0.0) else: salidaFinal.append(1.0 / (1.0 + math.exp(-suma))) else: #f2 if suma > 400: salidaFinal.append(1.0) elif suma < -400: salidaFinal.append(-1.0) else: salidaFinal.append((2.0 / (1.0 + math.exp(-suma))) - 1.0) #***********fin de Feedforward ********************************** #calculo del error cuadratico medio cuadratico_instancia = reduce( add, map((lambda x, y: (x - y)**2), vectoresObjetivos[instancia], salidaFinal)) cuadratico_epoca += cuadratico_instancia #***********inicio Retropropagación del error ******************* #paso 6 if self.bipolar == False: #Tk - Yk * f1`(Yin) deltaMinusculaK = map( (lambda x, y: (x - y) * (y * (1.0 - y))), vectoresObjetivos[instancia], salidaFinal) else: #Tk - Yk * f2`(Yin) deltaMinusculaK = map((lambda x, y: (x - y) * (0.5 * ( (1.0 + y) * (1.0 - y)))), vectoresObjetivos[instancia], salidaFinal) deltaMayusculaJK = [] for indNeuronaSalida in range(0, self.nClases): #calculamos delta mayuscula deltaMayusculaJK.append([]) aux = deltaMinusculaK[indNeuronaSalida] * self.alpha deltaMayusculaJK[indNeuronaSalida] = map( (lambda x: aux * x), salidaCapaOculta) #paso 7 deltaMinInj = [0 for x in range(0, self.neuronasCapaOculta)] for indNeurona in range(0, self.nClases): for indNeuronaOculta in range(1, self.neuronasCapaOculta + 1): deltaMinInj[ indNeuronaOculta - 1] += self.pesosCapaSalida[indNeurona][ indNeuronaOculta] * deltaMinusculaK[indNeurona] deltaMinusculaJ = [] if self.bipolar == False: #f`1 deltaMinusculaJ = map((lambda x, y: x * (y * (1.0 - y))), deltaMinInj, salidaCapaOculta[1:]) else: #f`2 deltaMinusculaJ = map((lambda x, y: x * (0.5 * ((1.0 + y) * (1.0 - y)))), deltaMinInj, salidaCapaOculta[1:]) deltaMayusculaIJ = [] for indNeuronaOculta in range(0, self.neuronasCapaOculta): deltaMayusculaIJ.append([]) aux = self.alpha * deltaMinusculaJ[indNeuronaOculta] deltaMayusculaIJ[indNeuronaOculta] = map( (lambda x: aux * x), self.capaEntrada) #paso 8 #Actualizar pesos y sesgos for indiceClase in range(0, self.nClases): self.pesosCapaSalida[indiceClase] = map( add, self.pesosCapaSalida[indiceClase], deltaMayusculaJK[indiceClase]) for indiceNOculta in range(0, self.neuronasCapaOculta): self.pesosCapaOculta[indiceNOculta] = map( add, self.pesosCapaOculta[indiceNOculta], deltaMayusculaIJ[indiceNOculta]) #comprobar condicion de finalizacion #fin de bucle de instancias cuadratico_epoca = cuadratico_epoca / float( self.nInstaces * self.nClases) if self.debug == True: if test is None: self.debugFile.write( str(epoca) + '\t' + str(self.getErrorFromInstances(data)) + '\t') else: self.debugFile.write( str(epoca) + '\t' + str(self.getErrorFromInstances(test)) + '\t' + str(self.getErrorFromInstances(data)) + '\t') #for indiceNOculta in range(0, self.neuronasCapaOculta): # map(lambda x: self.debugFile.write(str(x) + '\t'), self.pesosCapaOculta[indiceNOculta]) #for indiceClase in range(0, self.nClases): # map(lambda x: self.debugFile.write(str(x) + '\t'), self.pesosCapaSalida[indiceClase]) self.debugFile.write('\n') difErrCuadratico = abs( (cuadratico_epoca - self.errorCuadraticoMedio_old) / self.errorCuadraticoMedio_old) #print difErrCuadratico if difErrCuadratico < 0.00000001: return self.errorCuadraticoMedio_old = cuadratico_epoca if self.activo_control_fin == True and epoca % 50 == 0: error = self.getECMFromInstances(self.conjuntoValidacion) print self.lastError print error #error = self.getErrorFromInstances(self.conjuntoValidacion) if self.lastError < error: break else: #print str(epoca)+ '\t' + str(error) self.lastError = error
print 'Error medio: ' + str(procentajeError) for clase in instances.getClases(): sumaAux = float(erroresPorClase[clase] + aciertosPorClase[clase]) print '\t' + clase + ': ' + str( erroresPorClase[clase]) + ' aciertos: ' + str( aciertosPorClase[clase]) + ' porcentaje: ' + str( erroresPorClase[clase] / sumaAux) """pruebas unitarias""" if __name__ == '__main__': lector = LectorNeuro() instances = lector.leerFichero('../data/nand.txt') porcentajeParticionado = 1.0 particionado = DivisionPorcentual() particionado.setPortcentajeTrain(porcentajeParticionado) particion = particionado.generaParticionesProporcional(instances) print "Adaline" clasificador = Adaline() clasificador.setDebug(True) clasificador.buildClassifier(particion.getTrain()) print "Error TRAIN:" calculaError(clasificador, particion.getTrain()) if porcentajeParticionado != 1.0: print "Error TEST:" calculaError(clasificador, particion.getTest()) print "Perceptron" clasificador = Perceptron()