Ajuste a una curva

Una de las aplicaciones de las redes neuronales es el ajuste de datos. Para ver cómo lo hace, comenzamos creando un conjunto de datos cualquiera. Por ejemplo, nos valdría una curva hecha como se ve en el siguiente código.

In [34]:
import neurolab as nl
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

x = np.arange(0.0, 10.0, 0.1)
secuencia = np.sin(x-1)*0.5+0.1*np.sin(5*x) # Nuestra secuencia de valores

Visualizamos la gráfica mediante algunos comandos de matplotlib.

In [35]:
plt.plot(x, secuencia)
plt.xlabel('x')
plt.ylabel('valores')
plt.title('Secuencia de valores')
plt.grid(True)
plt.show()

longitud_muestra = 10 #Elegido arbitrariamente

muestras_vector = []
etiquetas_vector = []
for i in range(len(secuencia)-longitud_muestra):
    muestras_vector.append(secuencia[i:i+longitud_muestra])
    etiquetas_vector.append([secuencia[i+longitud_muestra]])
    
    
    
print(muestras_vector[0])
print(etiquetas_vector[0])
print("----------------------")
print(muestras_vector[1])
print(etiquetas_vector[1])
print("----------------------")
print(muestras_vector[2])
print(etiquetas_vector[2])
[-0.42073549 -0.3437209  -0.27453095 -0.22235934 -0.19139149 -0.17986555
 -0.18059717 -0.18283843 -0.17501491 -0.14766972]
[-0.095892427466313851]
----------------------
[-0.3437209  -0.27453095 -0.22235934 -0.19139149 -0.17986555 -0.18059717
 -0.18283843 -0.17501491 -0.14766972 -0.09589243]
[-0.020637324233625076]
----------------------
[-0.27453095 -0.22235934 -0.19139149 -0.17986555 -0.18059717 -0.18283843
 -0.17501491 -0.14766972 -0.09589243 -0.02063732]
[0.071393115577638194]
In [36]:
intervalos = [[-1.0, 1.0] for i in range(longitud_muestra)] #intervalos de valores de entrada

Definimos la red con dos capas

In [37]:
red = nl.net.newff(intervalos,[5, 1],[nl.trans.TanSig(), nl.trans.TanSig()])

Comenzamos el entrenamiento

In [38]:
error = red.train(muestras_vector, etiquetas_vector, epochs=500, show=10, goal=0.00001)
Epoch: 10; Error: 0.21056641987598726;
Epoch: 20; Error: 0.006045792463275607;
Epoch: 30; Error: 0.0033590703769475825;
Epoch: 40; Error: 0.0027710455315455807;
Epoch: 50; Error: 0.0023032365342399116;
Epoch: 60; Error: 0.0016314473499659907;
Epoch: 70; Error: 0.0010873869442072394;
Epoch: 80; Error: 0.0009372892134709175;
Epoch: 90; Error: 0.0007268539239480462;
Epoch: 100; Error: 0.0006850195277679092;
Epoch: 110; Error: 0.0005747287195340788;
Epoch: 120; Error: 0.0004923201583505406;
Epoch: 130; Error: 0.00036852232235014607;
Epoch: 140; Error: 0.00031170323297122356;
Epoch: 150; Error: 0.00018678641433063513;
Epoch: 160; Error: 0.0001064524753286356;
Epoch: 170; Error: 7.582038156038366e-05;
Epoch: 180; Error: 5.4905751730586515e-05;
Epoch: 190; Error: 4.740340114179835e-05;
Epoch: 200; Error: 3.97611003155857e-05;
Epoch: 210; Error: 3.75054997878484e-05;
Epoch: 220; Error: 3.247651664245096e-05;
Epoch: 230; Error: 3.1373549775457384e-05;
Epoch: 240; Error: 2.6729000207620865e-05;
Epoch: 250; Error: 2.5998424161077278e-05;
Epoch: 260; Error: 2.4137750765100962e-05;
Epoch: 270; Error: 2.233075895987741e-05;
Epoch: 280; Error: 2.191030654614588e-05;
Epoch: 290; Error: 2.1816395746126363e-05;
Epoch: 300; Error: 2.046721649493522e-05;
Epoch: 310; Error: 1.835307994470229e-05;
Epoch: 320; Error: 1.7815706113091173e-05;
Epoch: 330; Error: 1.648223151375313e-05;
Epoch: 340; Error: 1.5520749576040147e-05;
Epoch: 350; Error: 1.5377481488021032e-05;
Epoch: 360; Error: 1.4716358761652784e-05;
Epoch: 370; Error: 1.3919558498628514e-05;
Epoch: 380; Error: 1.3639875261922763e-05;
Epoch: 390; Error: 1.2962727923461024e-05;
Epoch: 400; Error: 1.1053210017046635e-05;
The goal of learning is reached

Veremos ahora qué tal se ajusta nuestra red a los datos originales

In [39]:
resultados = []

for i in range(longitud_muestra):
    resultados.append(muestras_vector[0][i])
        
for i in range(len(secuencia)-longitud_muestra):
    resultados.append(red.sim([resultados[i:i+longitud_muestra]])[0][0])

etiquetas_vector = ([[0]]*longitud_muestra) + etiquetas_vector

plt.plot(resultados, 'r-', etiquetas_vector, 'g-')
plt.xlabel('Longitud de muestra')
plt.ylabel('Valores')
plt.title('Resultados')
plt.grid(True)
plt.show()

Tareas prácticas

  1. Repite el entrenamiento con diferentes hiperparámetros:
    • Distinto número de iteraciones.
    • Distinto número de neuronas.
    • Distinto número de muestras de entrada.
  2. Comprueba el rendimiento de la red frente a un conjunto de muestras no utilizadas para el entrenemiento.
  3. Crea otra curva e intenta ajustarla mediante la red. Mentén los valores de la función en el intervalo [-1,1].
In [ ]: