Documentos de Académico
Documentos de Profesional
Documentos de Cultura
especies de monos
utilizando redes
neuronales artificiales
Con todo y lo anterior, resolvemos el entrenamiento y la clasificación de la red neuronal por medio
del lenguaje de programación Python, unas robustas librería para el ‘Deep Learning’ que son
Tensorflow y Keras, además utilizamos como modelo base la técnica del transfer learning para
aprovechar la información de un modelo base ‘VVG16’.
Metodología
Una manera cómoda de explicar la metodología es viajando atreves del código, sin embargo
resaltamos una síntesis así:
1. Importación de las librerías requeridas
2. Cargar el set de datos y procesarlo
3. Aumentar los datos
4. Modelar la red neuronal
5. Obtener el modelo y los pesos
El Dataset
El conjunto de datos lo encontramos en como: ’10 Monkey Species’ consta de dos archivos,
entrenamiento y validación. Cada carpeta contiene 10 subfolders etiquetados como n0 hasta n9, cada
uno correspondiente a una especie de la cladograma de monos de Wikipedia . Las imágenes son de
400x300px o más grandes y en formato JPEG (casi 1400 imágenes). Las imágenes se descargaron
con la ayuda del código fuente abierto de googliser .
Fuente https://www.kaggle.com/aakashnain/what-does-a-cnn-see
Leeremos el archivo monkey_labels.txt para extraer la información sobre las etiquetas. Podemos
almacenar esta información en una lista que luego se puede convertir en un marco de datos de
pandas.
labels_info = []
Las etiquetas son n0, n1, n2, .... Crearemos un mapeo de estas etiquetas donde cada clase estará
representada por un número entero comenzando desde 0 hasta el número de clases. También
crearemos un mapeo para los nombres correspondientes a una clase. Usaremos la columna Common
Name para la última parte.
# Directorio para mapear las etiquetas a enteros
labels_dict= {'n0':0, 'n1':1, 'n2':2, 'n3':3, 'n4':4, 'n5':5, 'n6':6, 'n7':7,
'n8':8, 'n9':9}
Este es un conjunto de datos muy pequeño. Puede cargar los datos en matrices numerosas que luego
se pueden usar directamente para el entrenamiento. Pero este no es siempre el escenario. La mayoría
de las veces no se podrá cargar el conjunto de datos completo en la memoria. Es por eso que siempre
es buena práctica almacenar sobre el conjunto de datos en marcos de datos y luego usar un
generador para cargar los datos sobre la marcha. Haremos lo mismo aquí
# Creando un dataframe para las imagenes de entrenamiento
train_df = []
for folder in os.listdir(training_data):
# Definirir la ruta de las imagenes
imgs_path = training_data / folder
#############################################################################
#######################
#############################################################################
#######################
Recién se crearon 2 Dataframes una para los datos de validación y otro para el entrenamiento.
# El tamaño de lote
batch_size=8
Aumento de Datos
El detalle de este set de datos es que realmente no es muy grande entonces, los modelos profundos
no funcionan muy bien asi. Los modelos de aprendizaje profundo están hambrientos de datos.
Cuantos más datos proporcione a un modelo de aprendizaje profundo, más mejorará el rendimiento
(hasta que su algoritmo haya alcanzado un límite). Aquí es donde el aumento de datos es realmente
útil. Usaremos imgaug, una biblioteca muy poderosa para aumentar nuestras imágenes. Definiremos
una secuencia de aumentos y para cada imagen, uno de estos aumentos se aplicará a la imagen
durante el entrenamiento.
# Secuencia de aumento
seq = iaa.OneOf([
iaa.Fliplr(), # horizontal flips
iaa.Affine(rotate=20), # roatación
iaa.Multiply((1.2, 1.5))]) # Brillo aleatorio
# Obtencion de una matriz numpy de todos los índices de los datos de entrada
indices = np.arange(n)
# Definimos dos matrices numpy para contener etiquetas y datos por lotes
batch_data = np.zeros((batch_size, img_rows, img_cols, img_channels),
dtype=np.float32)
batch_labels = np.zeros((batch_size, nb_classes), dtype=np.float32)
while True:
if not is_validation_data:
# Desordenar indices de los datos de validación
np.random.shuffle(indices)
for i in range(nb_batches):
# Pasar al siguiente lote
next_batch_indices = indices[i*batch_size:(i+1)*batch_size]
batch_data = preprocess_input(batch_data)
yield batch_data, batch_labels
base_model = get_base_model()
# Compilamos y chequeamos
optimizer = RMSprop(0.001)
model.compile(loss='categorical_crossentropy', optimizer=optimizer,
metrics=['accuracy'])
model.summary()
Entrenamiento de la RN
# Entrenamiento del modelo
history1 = model.fit_generator(train_data_gen,
epochs=nb_epochs,
steps_per_epoch=nb_train_steps,
validation_data=valid_data_gen,
validation_steps=nb_valid_steps,
callbacks=[es,chkpt])
Epoch 1/5
137/137 [==============================] - ETA: 0s - loss: 1.3320 - accura
cy: 0.7108
137/137 [==============================] - 303s 2s/step - loss: 1.3320 - accu
racy: 0.7108 - val_loss: 0.0430 - val_accuracy: 0.9890
Epoch 2/5
137/137 [==============================] - 299s 2s/step - loss: 0.3195 - accu
racy: 0.9188 - val_loss: 0.0501 - val_accuracy: 0.9743
Epoch 3/5
137/137 [==============================] - ETA: 0s - loss: 0.2494 - accuracy:
0.9443INFO:tensorflow:Assets written to: model1\assets
137/137 [==============================] - 317s 2s/step - loss: 0.2494 - accu
racy: 0.9443 - val_loss: 0.0408 - val_accuracy: 0.9853
Epoch 4/5
137/137 [==============================] - ETA: 0s - loss: 0.1439 - accuracy:
0.9672INFO:tensorflow:Assets written to: model1\assets
137/137 [==============================] - 318s 2s/step - loss: 0.1439 - accu
racy: 0.9672 - val_loss: 0.0325 - val_accuracy: 0.9890
Epoch 5/5
137/137 [==============================] - ETA: 0s - loss: 0.1644 - accuracy:
0.9653INFO:tensorflow:Assets written to: model1\assets
137/137 [==============================] - 318s 2s/step - loss: 0.1644 - accu
racy: 0.9653 - val_loss: 0.0121 - val_accuracy: 0.9963
Resultados
# Graficamos la perdida y la precisión
# Obtenemos la perdida
train_loss = history1.history['loss']
valid_loss = history1.history['val_loss']
# Visualizamos
f,ax = plt.subplots(1,2, figsize=(10,5))
ax[0].plot(xvalues, train_loss)
ax[0].plot(xvalues, valid_loss)
ax[0].set_title("Loss curve")
ax[0].set_xlabel("Epoch")
ax[0].set_ylabel("loss")
ax[0].legend(['train', 'validation'])
ax[1].plot(xvalues, train_acc)
ax[1].plot(xvalues, valid_acc)
ax[1].set_title("Accuracy")
ax[1].set_xlabel("Epoch")
ax[1].set_ylabel("accuracy")
ax[1].legend(['train', 'validation'])
plt.show()
Guardamos la topología del modelo y los
pesos de la RN
# ¿Cuál es la pérdida final y la precisión de nuestros datos de validación?
valid_loss, valid_acc = model.evaluate_generator(valid_data_gen,
steps=nb_valid_steps)
print(f"Final validation accuracy: {valid_acc*100:.2f}%")