En este tutorial práctico desarrollaremos la clasificación de imágenes mediante redes neuronales convolucionales con Keras. Las redes neuronales convolucionales consiste en aplicar redes neuronales sobre imágenes, es decir básicamente consiste en detectar el contenido de la imagen, esto es posible mediante las redes neuronales convolucionales (convolutional neural networks - CNN en ingles). En este tutorial te voy a explicar qué son y cómo puedes crear una red neuronal convolucional en Keras con Python.
Cuando pensamos en imágenes que tiene colores blanco o negro, se determinan como una imagen monocromática - es decir consiste en una imagen con muchos píxeles juntos (forma de pequeños cuadros) y cada uno de esos píxeles guarda información; en los casos de las imágenes monocromáticas, por ejemplo, el pixel guarda dos valores: 1 si es blanco y 0 si es negro (o al revés). Al tratar a una imagen monocromática para la clasificación mediante redes neuronales convolucionales se estaría tratando por intermedio de un dataset que estaría conformado por grandes cantidades de unos y ceros.
El objetivo de CNN:
Consiste en la demostración del desarrollo de un modelo en base a un algoritmo de aprendizaje automático, basado en la clasificación y reconocimiento de imagenes entre niñas y niños. Mediante el procesamiento de imágenes haciendo uso de API Keras. Dada la naturaleza del problema, se debe hacer uso de redes neuronales convolutivas (CNN).
Arquitectura a aplicar - DenseNet:
Las imagen del niño y niña es este ejemplo práctico son fotos reales. |
Ahora bien, que pasa con las imágenes a color o también conocidos como cromático en ese sentido, para estos tipos de imágenes la lógica se determina en tres capas; una capa roja (R), una verde (G) y finalmente una capa azul (B), conocido como RGB (en inglés color red, green, blue, en español "rojo, verde y azul").
Recordemos que las redes neuronales son un algoritmo estocástico, lo que significa que el mismo algoritmo con los mismos datos puede entrenar un modelo diferente con habilidades diferentes. Esto es una característica, no un error.
Entrada: Serán los pixeles de la imagen. Serán alto, ancho y profundidad será 1 sólo color o 3 para Red, Green y Blue.
Capa de Convolución: procesará la salida de neuronas que están conectadas en “regiones locales” de entrada (es decir pixeles cercanos), calculando el producto escalar entre sus pesos (valor de pixel) y una pequeña región a la que están conectados en el volumen de entrada. Para el desarrollo usaremos por ejemplo 32 filtros o la cantidad que decidamos y ese será el volumen de salida.
Capa ReLU: Encargado de aplicar la función de activación en los elementos de la matriz.
Pool ó SubSampling: Hará una reducción en la dimensión alta y ancho, pero se mantiene la profundidad.
Capa Tradicional: Red de neuronas feedforward que conectará con la última capa de subsampling y finalizará con la cantidad de neuronas que queremos clasificar.
Para el desarrollo paso a paso de nuestro modelo haremos uso de la API de Keras de TensorFlow y Python considerando el aprendizaje profundo - Deep Learning:
Desarrollo Paso a Paso:
Iniciamos Creando el modelo de CNN desde Visual Stuio Code
1. Importar Librerías:
Referenciamos las librerías que utilizaremos para el proyecto.
import numpy as np
import os
import re
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import keras
from keras.utils import to_categorical
from keras.models import Sequential,Input,Model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.layers.advanced_activations import LeakyReLU
2. Cargar set de Imágenes:
Este proceso plt.imread(filepath) cargará a memoria en un array de imágenes.
dirname = os.path.join(os.getcwd(), 'ninhosimages')
imgpath = dirname + os.sep
images = []
directories = []
dircount = []
prevRoot=''
cant=0
for root, dirnames, filenames in os.walk(imgpath):
for filename in filenames:
if re.search("\.(jpg|jpeg|png|bmp|tiff)$", filename):
cant=cant+1
filepath = os.path.join(root, filename)
image = plt.imread(filepath)
images.append(image)
b = "Leyendo..." + str(cant)
if prevRoot !=root:
prevRoot=root
directories.append(root)
dircount.append(cant)
cant=0
dircount.append(cant)
dircount = dircount[1:]
dircount[0]=dircount[0]+1
print("Directorios leidos: ",len(directories))
print("Imagenes en cada directorio: ", dircount)
print("Total de imagenes en subdirectorio: ",sum(dircount))
3. Crear las etiquetas y clases:
labels=[]
indice=0
for cantidad in dircount:
for i in range(cantidad):
labels.append(indice)
indice=indice+1
print("Cantidad etiquetas creadas: ",len(labels))
ninhos=[]
indice=0
for directorio in directories:
name = directorio.split(os.sep)
print(indice , name[len(name)-1])
ninhos.append(name[len(name)-1])
indice=indice+1
y = np.array(labels)
X = np.array(images, dtype=np.uint8) #convierto de lista a numpy uint8
# Buscar los números únicos de las etiquetas del aprendizaje
classes = np.unique(y)
nClasses = len(classes)
print('Total de outputs : ', nClasses)
print('Output classes : ', classes)
4. Creamos Sets de Entrenamiento y Test – validación y preprocesamiento
#Mezclar todo y crear los grupos de entrenamiento y testing
train_X,test_X,train_Y,test_Y = train_test_split(X,y,test_size=0.2)
print('Datos de aprendizaje : ', train_X.shape, train_Y.shape)
print('Testing de aprendizaje : ', test_X.shape, test_Y.shape)
plt.figure(figsize=[5,5])
# Display the first image in training data
plt.subplot(121)
plt.imshow(train_X[0,:,:], cmap='gray')
plt.title("Ground Truth : {}".format(train_Y[0]))
# Display the first image in testing data
plt.subplot(122)
plt.imshow(test_X[0,:,:], cmap='gray')
plt.title("Ground Truth : {}".format(test_Y[0]))
5. Iniciamos el procesamiento de las imágenes
train_X = train_X.astype('float32')
test_X = test_X.astype('float32')
train_X = train_X / 255.
test_X = test_X / 255.
# Change the labels from categorical to one-hot encoding
train_Y_one_hot = to_categorical(train_Y)
test_Y_one_hot = to_categorical(test_Y)
# Display the change for category label using one-hot encoding
print('Etiqueta original:', train_Y[0])
print('Después de la conversión a one-hot:', train_Y_one_hot[0])
6. Creamos el set de Entrenamiento y validación
#Mezclar todo y crear los grupos de entrenamiento y testing
train_X,valid_X,train_label,valid_label = train_test_split(train_X, train_Y_one_hot, test_size=0.2, random_state=13)
print(train_X.shape,valid_X.shape,train_label.shape,valid_label.shape)
7. Creamos el modelo de CNN
#declaramos variables con los parámetros de configuración de la red
INIT_LR = 1e-3
epochs = 6
batch_size = 64
ninhos_model = Sequential()
ninhos_model.add(Conv2D(32, kernel_size=(3, 3),activation='linear',padding='same',input_shape=(21,28,3)))
ninhos_model.add(LeakyReLU(alpha=0.1))
ninhos_model.add(MaxPooling2D((2, 2),padding='same'))
ninhos_model.add(Dropout(0.5))
ninhos_model.add(Flatten())
ninhos_model.add(Dense(32, activation='linear'))
ninhos_model.add(LeakyReLU(alpha=0.1))
ninhos_model.add(Dropout(0.5))
ninhos_model.add(Dense(nClasses, activation='softmax'))
ninhos_model.summary()
ninhos_model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adagrad(lr=INIT_LR, decay=INIT_LR / 100),metrics=['accuracy'])
8. Entrenamiento del modelo CNN: Aprende a clasificar imágenes
# Iniciar entrenamiento
# Este paso puede tomar varios minutos, dependiendo del cpu y memoria ram
ninhos_train = ninhos_model.fit(train_X, train_label, batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(valid_X, valid_label))
# guardamos la red, para reutilizarla en el futuro, sin tener que volver a entrenar
ninhos_model.save("ninhos_mnist.h5py")
9. Evaluamos la red
test_eval = ninhos_model.evaluate(test_X, test_Y_one_hot, verbose=1)
print('TEST:')
print('Perdida:', test_eval[0])
print('Exactitud:', test_eval[1])
accuracy = ninhos_train.history['accuracy']
val_accuracy = ninhos_train.history['val_accuracy']
loss = ninhos_train.history['loss']
val_loss = ninhos_train.history['val_loss']
epochs = range(len(accuracy))
plt.plot(epochs, accuracy, 'bo', label='Precision de entrenamiento')
plt.plot(epochs, val_accuracy, 'b', label='Exactitud de la validacion')
plt.title('Precisión de entrenamiento y validación')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Perdida de entrenamiento')
plt.plot(epochs, val_loss, 'b', label='Perdida de validacion')
plt.title('Perdida de entrenamiento y validacion')
plt.legend()
plt.show()
predicted_classes2 = ninhos_model.predict(test_X)
predicted_classes=[]
for predicted_ninhos in predicted_classes2:
predicted_classes.append(predicted_ninhos.tolist().index(max(predicted_ninhos)))
predicted_classes=np.array(predicted_classes)
predicted_classes.shape, test_Y.shape
Conclusiones:
Para la creación de nuestro modelo basado en aprendizaje profundo - deep learning se esta haciendo uso de la API de Keras importado en nuestro entorno de Trabajando con Visual Studio Code, Anaconda Python y TensorFlow; además, la explicación paso a paso de la creación de la red neuronal convolucional (convolutional neural networks - CNN).
Gracias nuevamente 😊; comentarios y apreciaciones son bienvenido, un fuerte abrazo para todos ✌...!!!
1 Comentarios
esta reweno el blog
ResponderBorrar