Crear una red neuronal básica usando TensorFlow, Keras y SKLearn
En esta ocasión, vamos a programar a una red neuronal usando librerías de diferenciación automática, las cuales extraen muchos conceptos y nos permiten diseñar RN más complejas sin tener que calcular distintas derivadas cada vez que modifiquemos nuestra arquitectura.
Para esto existen librerías de diferenciación automática cómo Tensorflow y Pythorch y a continuación implementaremos la misma red neuronal anterior, solucionando el problema de la clasificación binaria per a un nivel más alto.
En estas librerías podemos representar el flujo de nuestros datos como grafos. Veamos el código de la RN usando tensorflow 1.x:
%tensorflow_version 1.x
import tensorflow as tf
from matplotlib import animation
from IPython.core.display import display, HTML
# Definimos los puntos de entrada de la red, para la matriz X e Y.
iX = tf.placeholder('float', shape=[None, X.shape[1]])
iY = tf.placeholder('float', shape=[None])
lr = 0.01 # learning rate
nn = [2, 16, 8, 1] # número de neuronas por capa.
# Capa 1
W1 = tf.Variable(tf.random_normal([nn[0], nn[1]]), name='Weights_1')
b1 = tf.Variable(tf.random_normal([nn[1]]), name='bias_1')
l1 = tf.nn.relu(tf.add(tf.matmul(iX, W1), b1))
# Capa 2
W2 = tf.Variable(tf.random_normal([nn[1], nn[2]]), name='Weights_2')
b2 = tf.Variable(tf.random_normal([nn[2]]), name='bias_2')
l2 = tf.nn.relu(tf.add(tf.matmul(l1, W2), b2))
# Capa 3
W3 = tf.Variable(tf.random_normal([nn[2], nn[3]]), name='Weights_3')
b3 = tf.Variable(tf.random_normal([nn[3]]), name='bias_3')
# Vector de predicciones de Y.
pY = tf.nn.sigmoid(tf.add(tf.matmul(l2, W3), b3))[:, 0]
# Evaluación de las predicciones.
loss = tf.losses.mean_squared_error(pY, iY)
# Definimos al optimizador de la red, para que minimice el error.
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.05).minimize(loss)
n_steps = 1000 # Número de ciclos de entrenamiento.
iPY = [] # Aquí guardaremos la evolución de las predicción, para la animación.
with tf.Session() as sess:
# Inicializamos todos los parámetros de la red, las matrices W y b.
sess.run(tf.global_variables_initializer())
# Iteramos n pasos de entrenamiento.
for step in range(n_steps):
# Evaluamos al optimizador, a la función de coste y al tensor de salida pY.
# La evaluación del optimizer producirá el entrenamiento de la red.
_, _loss, _pY = sess.run([optimizer, loss, pY], feed_dict={ iX : X, iY : Y })
# Cada 25 iteraciones, imprimimos métricas.
if step % 25 == 0:
# Cálculo del accuracy.
acc = np.mean(np.round(_pY) == Y)
# Impresión de métricas.
print('Step', step, '/', n_steps, '- Loss = ', _loss, '- Acc =', acc)
# Obtenemos predicciones para cada punto de nuestro mapa de predicción _pX.
_pY = sess.run(pY, feed_dict={ iX : _pX }).reshape((res, res))
# Y lo guardamos para visualizar la animación.
iPY.append(_pY)
# ----- CÓDIGO ANIMACIÓN ----- #
ims = []
fig = plt.figure(figsize=(10, 10))
print("--- Generando animación ---")
for fr in range(len(iPY)):
im = plt.pcolormesh(_x0, _x1, iPY[fr], cmap="coolwarm", animated=True)
# Visualización de la nube de datos.
plt.scatter(X[Y == 0,0], X[Y == 0,1], c="skyblue")
plt.scatter(X[Y == 1,0], X[Y == 1,1], c="salmon")
# plt.title("Resultado Clasificación")
plt.tick_params(labelbottom=False, labelleft=False)
ims.append([im])
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000)
HTML(ani.to_html5_video())