La clasificación de imágenes es una aplicación asombrosa del aprendizaje profundo. Podemos entrenar un poderoso algoritmo para modelar un gran conjunto de datos de imágenes. Este modelo se puede utilizar para clasificar un conjunto de imágenes similar pero desconocido.
No hay límite para las aplicaciones de clasificación de imágenes. Puede usarlo en su próxima aplicación o puede usarlo para resolver algún problema del mundo real. Eso depende de ti. Pero para alguien que es bastante nuevo en este ámbito, al principio puede parecer muy desafiante. ¿Cómo debo obtener mis datos? ¿Cómo debo construir mi modelo? ¿Qué herramientas debo utilizar?
En este artículo discutiremos todo eso, desde encontrar un conjunto de datos hasta entrenar su modelo. Intentaré hacer las cosas lo más simples posible evitando algunos detalles técnicos ( PD: tenga en cuenta que esto no significa que esos detalles no sean importantes. Mencionaré algunos recursos excelentes que puede consultar para obtener más información sobre esos temas ). El propósito de este artículo es explicar el proceso básico de construcción de un clasificador de imágenes y eso es en lo que nos centraremos más aquí.
Construiremos un clasificador de imágenes para el conjunto de datos Fashion-MNIST. El conjunto de datos Fashion-MNIST es una colección de imágenes de artículos de Zalando. Contiene 60,000 imágenes para el conjunto de entrenamiento y 10,000 imágenes para los datos del conjunto de prueba ( discutiremos los conjuntos de datos de prueba y entrenamiento junto con el conjunto de datos de validación más adelante ). Estas imágenes pertenecen a las etiquetas de 10 clases diferentes.

Importación de bibliotecas
Nuestro objetivo es entrenar un modelo de aprendizaje profundo que pueda clasificar un conjunto determinado de imágenes en una de estas 10 clases. Ahora que tenemos nuestro conjunto de datos, deberíamos pasar a las herramientas que necesitamos. Existen muchas bibliotecas y herramientas que puede elegir según los requisitos de su propio proyecto. Para este me ceñiré a lo siguiente:
- Numpy - biblioteca de Python para cálculo numérico
- Pandas : manipulación de datos de la biblioteca de Python
- Matplotlib : visualización de datos de la biblioteca de Python
- Keras : biblioteca de Python basada en tensorflow para crear modelos de aprendizaje profundo
- Jupyter : ejecutaré todo mi código en Jupyter Notebooks. Puede instalarlo a través del enlace. También puede utilizar Google Colabs si necesita una mejor potencia computacional.
Junto con estos cuatro, también usaremos scikit-learn. El propósito de estas bibliotecas será más claro una vez que nos sumerjamos en el código.
¡Bueno! Tenemos nuestras herramientas y bibliotecas listas. Ahora deberíamos comenzar a configurar nuestro código.
Empiece por importar todas las bibliotecas mencionadas anteriormente. Junto con la importación de bibliotecas, también he importado algunos módulos específicos de estas bibliotecas. Déjame repasarlos uno por uno.
import numpy as np import pandas as pd import matplotlib.pyplot as plt import keras from sklearn.model_selection import train_test_split from keras.utils import to_categorical from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D from keras.layers import Dense, Dropout from keras.layers import Flatten, BatchNormalization
train_test_split: este módulo divide el conjunto de datos de entrenamiento en datos de entrenamiento y validación. La razón detrás de esta división es verificar si nuestro modelo está sobreajustado o no. Usamos un conjunto de datos de entrenamiento para entrenar nuestro modelo y luego compararemos la precisión resultante con la precisión de la validación. Si la diferencia entre ambas cantidades es significativamente grande, entonces nuestro modelo probablemente esté sobreajustado. Reiteraremos a través de nuestro proceso de construcción de modelos y haremos los cambios necesarios en el camino. Una vez que estemos satisfechos con la precisión de nuestro entrenamiento y validación, haremos predicciones finales sobre nuestros datos de prueba.
to_categorical: to_categorical es una utilidad de keras. Se utiliza para convertir las etiquetas categóricas en codificaciones one-hot. Digamos que tenemos tres etiquetas ("manzanas", "naranjas", "plátanos"), luego una codificación activa para cada una de ellas sería [1, 0, 0] -> "manzanas", [0, 1, 0] -> "naranjas", [0, 0, 1] -> "plátanos".
El resto de los módulos de Keras que hemos importado son capas convolucionales. Discutiremos las capas convolucionales cuando comencemos a construir nuestro modelo. También daremos un vistazo rápido a lo que hace cada una de estas capas.
Preprocesamiento de datos
Por ahora, centraremos nuestra atención en obtener nuestros datos y analizarlos. Siempre debe recordar la importancia de preprocesar y analizar los datos. No solo le brinda información sobre los datos, sino que también ayuda a localizar inconsistencias.
Una variación muy leve en los datos a veces puede conducir a un resultado devastador para su modelo. Esto hace que sea importante preprocesar sus datos antes de usarlos para entrenamiento. Entonces, con eso en mente, comencemos el preprocesamiento de datos.
train_df = pd.read_csv('./fashion-mnist_train.csv') test_df = pd.read_csv('./fashion-mnist_test.csv')
En primer lugar, importemos nuestro conjunto de datos ( aquí está el enlace para descargar este conjunto de datos en su sistema ). Una vez que haya importado el conjunto de datos, ejecute el siguiente comando.
train_df.head()
Este comando le mostrará cómo se ven sus datos. La siguiente captura de pantalla muestra el resultado de este comando.

Podemos ver cómo se almacenan nuestros datos de imagen en forma de valores de píxeles. Pero no podemos enviar datos a nuestro modelo en este formato. Entonces, tendremos que convertirlo en matrices numpy.
train_data = np.array(train_df.iloc[:, 1:]) test_data = np.array(test_df.iloc[:, 1:])
Ahora es el momento de obtener nuestras etiquetas.
train_labels = to_categorical(train_df.iloc[:, 0]) test_labels = to_categorical(test_df.iloc[:, 0])
Aquí, puede ver que hemos utilizado to_categorical para convertir nuestros datos categóricos en codificaciones one hot.
Ahora cambiaremos la forma de los datos y los convertiremos en tipo float32 para que podamos usarlos convenientemente.
rows, cols = 28, 28 train_data = train_data.reshape(train_data.shape[0], rows, cols, 1) test_data = test_data.reshape(test_data.shape[0], rows, cols, 1) train_data = train_data.astype('float32') test_data = test_data.astype('float32')
Casi terminamos. Terminemos de preprocesar nuestros datos normalizándolos. La normalización de los datos de la imagen asignará todos los valores de píxeles de cada imagen a los valores entre 0 y 1. Esto nos ayuda a reducir las inconsistencias en los datos. Antes de la normalización, los datos de la imagen pueden tener grandes variaciones en los valores de los píxeles, lo que puede dar lugar a un comportamiento inusual durante el proceso de entrenamiento.
train_data /= 255.0 test_data /= 255.0
Redes neuronales convolucionales
Entonces, el preprocesamiento de datos está hecho. Ahora podemos empezar a construir nuestro modelo. Construiremos una red neuronal convolucional para modelar los datos de la imagen. Las CNN son versiones modificadas de redes neuronales normales. Estos se modifican específicamente para datos de imágenes. Alimentar imágenes a redes neuronales regulares requeriría que nuestra red tenga una gran cantidad de neuronas de entrada. Por ejemplo, solo para una imagen de 28x28 necesitaríamos 784 neuronas de entrada. Esto crearía un gran lío de parámetros de entrenamiento.
Las CNN solucionan este problema asumiendo que la entrada será una imagen. El propósito principal de las redes neuronales convolucionales es aprovechar la estructura espacial de la imagen y extraer características de alto nivel de eso y luego entrenar en esas características. Lo hace realizando una operación de convolución en la matriz de valores de píxeles.

The visualization above shows how convolution operation works. And the Conv2D layer we imported earlier does the same thing. The first matrix (from the left) in the demonstration is the input to the convolutional layer. Then another matrix called "filter" or "kernel" is multiplied (matrix multiplication) to each window of the input matrix. The output of this multiplication is the input to the next layer.
Other than convolutional layers, a typical CNN also has two other types of layers: 1) a pooling layer, and 2) a fully connected layer.
Pooling layers are used to generalize the output of the convolutional layers. Along with generalizing, it also reduces the number of parameters in the model by down-sampling the output of the convolutional layer.
As we just learned, convolutional layers represent high level features from image data. Fully connected layers use these high level features to train the parameters and to learn to classify those images.
We will also use the Dropout, Batch-normalization and Flatten layers in addition to the layers mentioned above. Flatten layer converts the output of convolutional layers into a one dimensional feature vector. It is important to flatten the outputs because Dense (Fully connected) layers only accept a feature vector as input. Dropout and Batch-normalization layers are for preventing the model from overfitting.
train_x, val_x, train_y, val_y = train_test_split(train_data, train_labels, test_size=0.2) batch_size = 256 epochs = 5 input_shape = (rows, cols, 1)
def baseline_model(): model = Sequential() model.add(BatchNormalization(input_shape=input_shape)) model.add(Conv2D(32, (3, 3), padding="same", activation="relu")) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2))) model.add(Dropout(0.25)) model.add(BatchNormalization()) model.add(Conv2D(32, (3, 3), padding="same", activation="relu")) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation="relu")) model.add(Dropout(0.5)) model.add(Dense(10, activation="softmax")) return model
The code that you see above is the code for our CNN model. You can structure these layers in many different ways to get good results. There are many popular CNN architectures which give state of the art results. Here, I have just created my own simple architecture for the purpose of this problem. Feel free to try your own and let me know what results you get :)
Training the model
Once you have created the model you can import it and then compile it by using the code below.
model = baseline_model() model.compile(loss='categorical_crossentropy', optimizer="sgd", metrics=['accuracy'])
model.compile configures the learning process for our model. We have passed it three arguments. These arguments define the loss function for our model, optimizer and metrics.
history = model.fit(train_x, train_y, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(val_x, val_y))
And finally by running the code above you can train your model. I am training this model for just five epochs but you can increase the number of epochs. After your training process is completed you can make predictions on the test set by using the following code.
predictions= model.predict(test_data)
Conclusion
Congrats! You did it, you have taken your first step into the amazing world of computer vision.
You have created a your own image classifier. Even though this is a great achievement, we have just scratched the surface.
There is a lot you can do with CNNs. The applications are limitless. I hope that this article helped you to get an understanding of how the process of training these models works.
Working on other datasets on your own will help you understand this even better. I have also created a GitHub repository for the code I used in this article. So, if this article was useful for you please let me know.
If you have any questions or you want to share your own results or if you just want to say "hi", feel free to hit me up on twitter, and I'll try to do my best to help you. And finally Thanks a lot for reading this article!! :)