Descripción general
El análisis antropométrico del rostro humano es un estudio fundamental para la realización de cirugías plásticas y reconstructivas craneofaciales. La antropometría facial se ve afectada por varios factores, como la edad, el género, el origen étnico, el nivel socioeconómico, el entorno y la región.
Los cirujanos plásticos que emprenden la reparación y reconstrucción de deformidades faciales encuentran útiles las dimensiones anatómicas de las estructuras faciales para sus cirugías. Estas dimensiones son el resultado de la apariencia física o facial de un individuo. Junto con factores como la cultura, la personalidad, el origen étnico, la edad; La apariencia y la simetría de los ojos contribuyen en gran medida a la apariencia o estética facial.
Mi objetivo es construir un modelo para escanear la imagen de un ojo de un paciente y encontrar si el género del paciente es masculino o femenino.
Evaluación
El modelo se evaluará utilizando Accuracy Score.
Enlace del conjunto de datos: https://drive.google.com/file/d/1f7uslI-ZHidriQFZR966_aILjlkgDN76/view?usp=sharing
Descomprimir el archivo descargado
from zipfile import ZipFile
with ZipFile('eye_gender_data.zip', 'r') as zf:
zf.extractall('')
Cargando bibliotecas
Para poder realizar análisis sobre las imágenes, necesitaríamos hacer uso de bibliotecas. Las bibliotecas son como ayudas proporcionadas por python para llevar a cabo tareas específicas.
# Data analysis and manipultion tool
import pandas as pd
# Fundamental package for linear algebra and multidimensional arrays
import numpy as np
# Deep Learning Tool
import tensorflow as tf
# OS module in Python provides a way of using operating system dependent functionality
import os
# Library for image processing
import cv2
# For splitting the data into train and validation set
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score
from sklearn.preprocessing import LabelEncoder
import matplotlib.pyplot as plt
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
Cargando Imágenes y Adjuntando la Etiqueta correspondiente
Nuestro conjunto de datos se ha dividido en dos conjuntos: conjunto de entrenamiento y conjunto de datos de prueba. El conjunto de datos de prueba se utilizará como evaluación del nivel de precisión de mi modelo.
Primero, cargaré las imágenes del conjunto de entrenamiento en un marco de datos con filas y columnas. Esto serviría como la mejor estructura para analizar las imágenes y crear un modelo. También reduciré el tamaño de las imágenes para reducir el espacio que ocupa la RAM al analizar los patrones.
#loading the labels
labels = pd.read_csv("eye_gender_data/Training_set.csv") file_paths = [[fname, 'eye_gender_data/train/' + fname] for fname in labels['filename']]
images = pd.DataFrame(file_paths, columns=['filename', 'filepaths'])
train_data = pd.merge(images, labels, how = 'inner', on = 'filename')
#initialize an empty numpy array
data = []
#image size taken is 50 here. one can take other size too
image_size = 100
dsize = (image_size, image_size)
for i in range(len(train_data)):
# converting the image to gray scale
img_array = cv2.imread(train_data['filepaths'][i], cv2.IMREAD_GRAYSCALE)
# resizing the image array
new_img_array = cv2.resize(img_array, dsize)
data.append([new_img_array, train_data['label'][i]])
Preprocesamiento de datos
Es necesario traer todas las imágenes en la misma forma y tamaño, también convertirlas a sus valores de píxeles porque todos los modelos de aprendizaje automático o aprendizaje profundo aceptan solo los datos numéricos. También necesitamos convertir todas las etiquetas de valores categóricos a valores numéricos.
print(data[0])
plt.imshow(data[0][0])
plt.title(data[0][1])
[array([[188, 188, 189, ..., 176, 175, 175],
[189, 189, 188, ..., 174, 173, 172],
[190, 189, 188, ..., 168, 167, 167],
...,
[133, 137, 144, ..., 168, 167, 166],
[134, 138, 145, ..., 165, 164, 163],
[135, 139, 146, ..., 163, 162, 162]], dtype=uint8), 'male']
Text(0.5, 1.0, 'male')
#Initialize an empty numpy array
data2 = []#image size taken is 100 here. one can take other size too
image_size = 100
for i in range(len(train_data)):
# converting the image to gray scale
img_array = cv2.imread(train_data['filepaths'][i], cv2.IMREAD_GRAYSCALE)
# resizing the image array
new_img_array = cv2.resize(img_array, (image_size, image_size))
data2.append([new_img_array])
train_im = np.array(data2,dtype='uint8')
train_im.shape
(9220, 1, 100, 100)
train_im = train_im.reshape(9220,100,100,1)
print(train_im.shape)
print(train_im.dtype)
(9220, 100, 100, 1)
uint8
for i in range(len(data)):
a=pd.DataFrame(data)
a.columns= ['images','gender']
labelencoder = LabelEncoder()
a['gender_cat'] = labelencoder.fit_transform(a['gender'])
a.head()
plt.imshow(train_im[5].reshape(100,100))
plt.title(a['gender'][5])
Text(0.5, 1.0, 'male')
Desde la biblioteca de preprocesamiento de Sklearn, puedo usar Label Encoder para codificar cada categoría de género en 1 y 0. Esto facilita que la computadora registre un determinado patrón de imagen para un género específico representado por 1 o 0. A continuación, Dividiré los datos en datos de entrenamiento y conjunto de datos de validación. Los datos de entrenamiento se usarían para entrenar el modelo y los datos de validación se usarían para validar la precisión del modelo.
X = train_im /255
y = a['gender_cat']
Modelo de construcción y ajuste de hiperparámetros
Ahora finalmente estoy listo para entrenar al modelo. Usando keras de tensorflow, crearé 10 capas de redes neuronales con capas convolutivas 2D, maxpooling, Dense y Dropout. Luego, compilo el modelo usando el optimizador ‘adam’, configurando la precisión como mi métrica de evaluación y configurando una característica para mi pérdida.
# define input shape
INPUT_SHAPE = (100,100,1)# define sequential model
model = tf.keras.models.Sequential()
# define conv-pool layers - set 1
model.add(tf.keras.layers.Conv2D(filters=16, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='valid', input_shape=INPUT_SHAPE))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
# define conv-pool layers - set 2
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1),
activation='relu', padding='valid', input_shape=INPUT_SHAPE))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
# add flatten layer
model.add(tf.keras.layers.Flatten())
# add dense layers with some dropout
model.add(tf.keras.layers.Dense(256, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=0.3))
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=0.3))
# add output layer
model.add(tf.keras.layers.Dense(2, activation='sigmoid'))
# compile model
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# view model layers
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 98, 98, 16) 160 max_pooling2d (MaxPooling2D (None, 49, 49, 16) 0
)
conv2d_1 (Conv2D) (None, 47, 47, 32) 4640
max_pooling2d_1 (MaxPooling (None, 23, 23, 32) 0
2D)
flatten (Flatten) (None, 16928) 0
dense (Dense) (None, 256) 4333824
dropout (Dropout) (None, 256) 0
dense_1 (Dense) (None, 128) 32896
dropout_1 (Dropout) (None, 128) 0
dense_2 (Dense) (None, 2) 258
=================================================================
Total params: 4,371,778
Trainable params: 4,371,778
Non-trainable params: 0
_________________________________________________________________
Validar el modelo
A continuación, configuro la cantidad de épocas que quiero que mi modelo se ejecute mientras se ajusta, y también configuro la pérdida que pretendo monitorear. El conjunto de datos de validación se utiliza para medir la precisión después de cada época.
EPOCHS = 10es_callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss',
patience=3,
restore_best_weights=True,
verbose=1)
history = model.fit(X,
y,
batch_size=5,
callbacks=[es_callback],
validation_split=0.2,
epochs=EPOCHS,verbose =1)
Epoch 1/10
1476/1476 [==============================] - 1189s 792ms/step - loss: 0.5331 - accuracy: 0.7314 - val_loss: 0.4226 - val_accuracy: 0.8134
Epoch 2/10
1476/1476 [==============================] - 1296s 878ms/step - loss: 0.3896 - accuracy: 0.8312 - val_loss: 0.4120 - val_accuracy: 0.8194
Epoch 3/10
1476/1476 [==============================] - 1282s 868ms/step - loss: 0.3341 - accuracy: 0.8609 - val_loss: 0.3146 - val_accuracy: 0.8693
Epoch 4/10
1476/1476 [==============================] - 999s 677ms/step - loss: 0.2911 - accuracy: 0.8787 - val_loss: 0.3120 - val_accuracy: 0.8774
Epoch 5/10
1476/1476 [==============================] - 1014s 687ms/step - loss: 0.2437 - accuracy: 0.9001 - val_loss: 0.3055 - val_accuracy: 0.8753
Epoch 6/10
1476/1476 [==============================] - 755s 512ms/step - loss: 0.2147 - accuracy: 0.9117 - val_loss: 0.3290 - val_accuracy: 0.8726
Epoch 7/10
1476/1476 [==============================] - 980s 664ms/step - loss: 0.1774 - accuracy: 0.9298 - val_loss: 0.3612 - val_accuracy: 0.8861
Epoch 8/10
1476/1476 [==============================] - ETA: 0s - loss: 0.1489 - accuracy: 0.9425Restoring model weights from the end of the best epoch: 5.
1476/1476 [==============================] - 1272s 862ms/step - loss: 0.1489 - accuracy: 0.9425 - val_loss: 0.3741 - val_accuracy: 0.8802
Epoch 8: early stopping
A partir del resultado, el modelo deja de ajustarse en la época deseada para evitar el sobreajuste. Esto sucede cuando logramos una alta precisión tanto para el entrenamiento como para la validación de datos con muy poca pérdida y pérdida de validación.
Predecir la salida para el conjunto de datos de prueba
Hemos entrenado nuestro modelo, lo evaluamos y ahora finalmente predeciremos el resultado/objetivo para los datos de prueba (es decir, Test.csv).
Conjunto de prueba de carga
Cargue los datos de prueba sobre los que se realizará el envío final.
# loading the labels
test_labels = pd.read_csv("eye_gender_data/Testing_set.csv")
file_paths2 = [[fname2, 'eye_gender_data/test/' + fname2]
for fname2 in test_labels['filename']]
images_t = pd.DataFrame(file_paths, columns=['filename', 'filepaths'])
test_data = pd.merge(images_t, test_labels, how = 'inner', on = 'filename')# initialize an empty numpy array
data_t = []
image_size = 100
# image size taken is 100 here. one can take other size too
for i in range(len(test_data)):
# converting the image to gray scale
img_array_t = cv2.imread(test_data['filepaths'][i], cv2.IMREAD_GRAYSCALE)
# resizing the image array
new_img_array_t = cv2.resize(img_array_t, (image_size, image_size))
data_t.append([new_img_array_t])
Preprocesamiento de datos en datos de prueba
test_im = np.array(data_t,dtype='uint8')
test_im.shape
(2305, 1, 100, 100)
test_im = test_im.reshape(2305,100,100,1)
print(test_im.shape)
print(test_im.dtype)
(2305, 100, 100, 1)
uint8plt.imshow(test_im[5].reshape(100,100))
<matplotlib.image.AxesImage at 0x1e316618a00>
test_norm = test_im / 255
Hacer predicciones sobre conjuntos de datos de prueba
Es hora de hacer una presentación!!!
prediction2 = model.predict(test_norm)
prediction2[:5]
73/73 [==============================] - 53s 682ms/steparray([[1.5717943e-01, 9.8344243e-01],
[8.6765045e-01, 1.7700831e-03],
[7.1922296e-01, 9.4394431e-02],
[9.2397380e-01, 3.9275724e-04],
[1.5497887e-01, 9.9005252e-01]], dtype=float32)
Guardar la predicción como archivo .CSV
pred2_label = np.argmax(prediction2,axis=1)
submission_22=pd.DataFrame({'filename':test_labels['filename'], 'label_num':pred2_label})submission_22["label"] = labelencoder.inverse_transform(submission_22['label_num'])
submission22 = submission_22[['filename','label']]
submission22.to_csv('submission3.csv', index = False)
print(submission22.head())
filename label
0 Image_1.jpg male
1 Image_2.jpg female
2 Image_3.jpg female
3 Image_4.jpg female
4 Image_5.jpg male
En este proyecto pudimos conocer una de las diversas aplicaciones de la visión artificial que es el análisis de imágenes. Pude analizar un conjunto de datos de imágenes, entrenar un modelo usando redes neuronales complicadas (CNN). También podemos hacer uso del modelo para hacer predicciones. Este proyecto muestra aplicaciones prometedoras para la visión artificial.
[post_relacionado id=»1231″]