22. Reconocimiento facial con inteligencia artificial (2)
- Hola a todos.Una vez finalizado el curso de google, vamos a entrenar un modelo para hacer un ejemplo de reconocimiento facial.Este ejemplo lo dividiremos en tres vídeos, que estructuraremos de la siguiente manera.
- En el segundo vídeo que podéis ver a continuación nos centramos en definir y entrenar una red convolucional con Keras. También veremos el código necesario para este propósito.
- A continuación os dejo el código visto en el vídeo.
#Imporatamos el fichero utils que tiene la lógica necesaria para obtener 15 puntos
#representativos de las caras.
from utils import *
# load_data es un método definido en el fichero utils para cargar los csv que
#tenemos en la carpeta data:training.csv y
# test.csv'
X_train, y_train = load_data()
print("X_train.shape == {}".format(X_train.shape))
print("y_train.shape == {}; y_train.min == {:.3f}; y_train.max == {:.3f}".format(
y_train.shape, y_train.min(), y_train.max()))
# cargamos datos entrenamiento que son los dos csv que tene
X_test, _ = load_data(test=True)
print("X_test.shape == {}".format(X_test.shape))
#muestro los puntos 15 puntos representativos de las caras de del conjunto de entrenamiento
import matplotlib.pyplot as plt
%matplotlib inline
fig = plt.figure(figsize=(20,20))
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)
for i in range(9):
ax = fig.add_subplot(3, 3, i + 1, xticks=[], yticks=[])
plot_data(X_train[i], y_train[i], ax)
# Importamos librerias necesarias
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D, Dropout
from keras.layers import Flatten, Dense
# El modelo debe aceptar imágenes en escala de 96x96 píxeles.
# Debe tener una capa de salida totalmente conectada con 30 valores
#(2 para cada punto clave facial)
# Como funcion de activacion utilizamos relu que activa una neoruna solo si es mayor que cero.
shape = (96,96)
modelo = Sequential()
modelo.add(Convolution2D(16,(2,2),padding='same',input_shape=(96,96, 1), activation='relu'))
modelo.add(MaxPooling2D(pool_size=3, data_format="channels_first"))
modelo.add(Convolution2D(32,(3,3),padding='same', activation='relu'))
modelo.add(MaxPooling2D(pool_size=3))
modelo.add(Dropout(0.2))
modelo.add(Convolution2D(64,(3,3),padding='same',activation='relu'))
modelo.add(MaxPooling2D(pool_size=3))
modelo.add(Dropout(0.2))
modelo.add(Convolution2D(128,(3,3),padding='same', activation='relu'))
modelo.add(MaxPooling2D(pool_size=3))
modelo.add(Dropout(0.2))
modelo.add(Flatten())
modelo.add(Dense(256,activation='relu'))
modelo.add(Dropout(0.2))
modelo.add(Dense(30))
modelo.summary()
from keras.optimizers import SGD, RMSprop, Adagrad, Adadelta, Adam, Adamax, Nadam
from keras.callbacks import ModelCheckpoint, History
iteraciones = 50
histo = History()
## Compilamo el modelo
def compilarModelo(modelo, iteraciones):
ruta = 'model.hdf5'
modelo.compile(optimizer='adam', loss='mse', metrics=['accuracy'])
checkpointer = ModelCheckpoint(filepath=ruta,
verbose=1, save_best_only=True)
## Entrenamos el modelo
hist = modelo.fit(X_train, y_train, validation_split=0.2,
epochs=iteraciones, batch_size=20, callbacks=[checkpointer, histo], verbose=1)
modelo.save(ruta)
return hist
# Booleano con el controlamos si entrenar el modelo o no
entrenarModelo = False
if entrenarModelo is True:
hist = compilarModelo(modelo, iteraciones)
else:
modelo.load_weights('model.hdf5')
def obtenerPuntosClave(imagen, caras=None):
#lista parea (cara, puntosClave)
resultado = []
if caras is None:
caras = get_faces(imagen)
# mismo tamaño que los conjuntos de entrenamiento y validacion
carasForma = (96, 96)
copiaImagen = np.copy(imagen)
#Por cada cara detectamos puntos clave y características
for (x,y,w,h) in caras:
#Recortamos la región de la imagen donde esta la cara
cara = copiaImagen[y:y+h,x:x+w]
# Cara convertida a escala de grises y tamaño 96x96x1
caraGris = cv2.cvtColor(cara, cv2.COLOR_BGR2GRAY)
caraGrisRedimensionar = cv2.resize(caraGris, carasForma) / 255
# Adaptando entrada a (1, 96, 96, 1)
inputs = np.expand_dims(np.expand_dims(caraGrisRedimensionar, axis=-1), axis=0)
# obtener puntos clave
puntosClavePrediccion = modelo.predict(inputs)
# Todos los puntos clave en una sola matriz plana.
# Recuperaremos puntos clave como (x, y) con (idx, idx + 1) valores.
puntosClavePrediccion = np.squeeze(puntosClavePrediccion)
puntosClave = []
for idx in range(0, len(puntosClavePrediccion), 2):
#Factor de escala (revertir escala)
x_scale_factor = cara.shape[0]/carasForma[0]
y_scale_factor = cara.shape[1]/carasForma[1]
x_center_left_offset = puntosClavePrediccion[idx] * carasForma[0]/2 + carasForma[0]/2
y_center_left_offset = puntosClavePrediccion[idx + 1] * carasForma[1]/2 + carasForma[1]/2
x_center = int(x + (x_scale_factor * x_center_left_offset))
y_center = int(y + (y_scale_factor * y_center_left_offset))
puntosClave.append([x_center, y_center])
resultado.append([(x,y,w,h), puntosClave])
return resultado
def mostrarImagenCaracteristicas(image_path):
imagen = cargaImagen(image_path)
caras = dameCaras(imagen)
puntosClave = obtenerPuntosClave(imagen, caras)
imagenConCaras = pintarCaras(imagen, caras ,plot=False)
pintarPuntosClave(imagenConCaras, puntosClave)
mostrarImagenCaracteristicas('imagenes/clubdelalucha.jpg')
No hay comentarios:
Publicar un comentario