WOT

Thursday, August 24, 2017

Aplicación de la inteligencia artificial y el aprendizaje profundo al desarrollo de juegos


Se resume aquí un interesante artículo de Daniel Lange  sobre la aplicación de la inteligencia artificial y el aprendizaje profundo al desarrollo de juegos, cuyo título original es

Bringing gaming to life with AI and deep learning


cuyo autor es Danny Lange

El desarrollo de juegos es un proceso complejo en el que artistas gráficos, narradores y ingenieros de software deben trabajar de forma coordinada. Existen ahora nuevas técnicas que proceden del desarrollo de aspectos de la inteligencia artificial como el aprendizaje profundo y hay grandes esperanzas puestas en el aprendizaje automático.
Como siempre, el desarrollo se alimenta de la necesidad de aumentar los ingresos. El aprendizaje automático lo empezó a utilizar Amazon en el año 2000, desarrollando algoritmos para descubrir las preferencias de los usuarios, lo que supone un aumento de ventas. Amazon había estado trabajando duro en sus propios algoritmos de recomendación, tratando de descubrir las preferencias de los usuarios y a su vez convertir esas preferencias en ventas más altas.
Los algoritmos de recomendación, por ejemplo, han evolucionado desde la recomendación hasta aplicar una mezcla de exploración y explotación para obtener una visión más completa sobre las preferencias de los usuarios. Algoritmos como los bandidos utilizan esta capacidad de explorar y explotar. Estos algoritmos tienen presencia en muchas páginas cuando se visita Amazon.
DeepMind en 2015 introdujo en los juegos el concepto de aprendizaje profundo de refuerzo, capaz de aprender las secuencias de acciones necesarias para maximizar una recompensa acumulativa futura.
Es muy ilustrativo el video que aparece en el artículo sobre el juego en el que un pollo aprende a cruzar una carretera muy concurrida sin que acabe aplastado por un camión que se acerca mientras recoge paquetes de regalo. Se proporciona al pollo una recompensa positiva cuando recoge un paquete de regalo y una recompensa negativa cuando lo golpea un camión. Con cuatro movimientos del pollo, izquierda, derecha, hacia adelante y hacia atrás, los píxeles en bruto y una puntuación como entrada, y estas instrucciones muy sencillas, el pollo logra capacidades extraordinarias.
Para conseguirlo  se utilizó un API de Python que permitió conectar el juego Unity a un servicio TensorFlow que se ejecuta en Amazon Web Services (AWS). Cuando se inicia el proceso de entrenamiento, el pollo se dedica a explorar, pero a medida que avanza el proceso de aprendizaje, gradualmente cambia al proceso de explotación. Este mismo procedimiento es el que pueden utilizar Amazon, Netflix y Uber para mejorar el servicio a sus clientes.
Las posibilidades con respecto a los primeros pasos de aprendizaje automático, han aumentado con el desarrollo de redes neuronales recurrentes expresivas (RNN) tales como la memoria a largo plazo (LSTM) para el aprendizaje secuencial y las redes neuronales convolucionales (CNNs) para el aprendizaje espacial de rasgos, así como una potencia computacional combinada y el software escalable y sofisticado.
Si bien el uso del aprendizaje de refuerzo profundo en el desarrollo de juegos aún se encuentra en su fase inicial, será una tecnología de juego disruptiva. Los entornos de aprendizaje automático como TensorFlow que se ejecuta en la nube junto con API de integración están facilitando el acceso a los desarrolladores de juegos y a los investigadores de aprendizaje automático.

Saturday, August 12, 2017

La costosa eficiencia de los aceleradores de aprendizaje profundo personalizados

Nota: Este artículo es una traducción del original que aparece en THE NEXT PLATFORM: Wrenching Efficiency Out of Custom Deep Learning Accelerators

Muchas gracias a la autora Nicole Hemsoth por permitir su publicación en español.


La costosa eficiencia de los aceleradores de aprendizaje profundo personalizados
7 de Agosto 7 de 2017. Nicole Hemsoth
Los aceleradores personalizados para el entrenamiento de redes neuronales han sido objeto de una gran atención en los últimos años, pero al no tener un software lo suficientemente ágil, la programación de muchos de ellos resulta difícil dando lugar a un funcionamiento poco eficiente. Esta dificultad se puede resolver mediante diferentes optimizaciones del modelo, pero como otras fuentes argumentan, la eficiencia y los ciclos de reposo  también se pueden abordar con un compilador a medida.
Eugenio Culurciello, ingeniero eléctrico de la Universidad de Purdue, afirma que es difícil conseguir una eficiencia total de cálculo de los aceleradores de aprendizaje profundo personalizados. Esta consideración ha impulsado a su equipo en Purdue a construir un acelerador basado en FPGA al que podrían no afectar las cargas de trabajo de redes neuronales convolucionales (CNN) y que podría conseguir la máxima utilización y eficiencia en una serie de tareas de aprendizaje profundo, incluyendo ResNet y AlexNet.
Snowflake es un acelerador escalable y programable de bajo consumo para aprendizaje profundo con un conjunto de instrucciones personalizadas basado en RISC. Lleva a cabo el control de la fuente de información para un conjunto personalizado de instrucciones a través de un compilador personalizado que genera instrucciones y administra los datos en la memoria principal. La estructura del software entrena la representación del modelo de alto nivel de Torch7, que alimenta un flujo de instrucciones que se ejecutan en Snowflake. El esquema del software Snowball permite la usabilidad y la utilización del hardware.

La arquitectura hardware de Snowflake se basa en una matriz de 16 bits para multiplicar y acumular unidades (MACs). Un vector MAC (vMAC) está compuesto de una MACs 16 que procesa 256 bits en un ciclo. Una unidad de cálculo (CU) tiene cuatro vMAC (y cada uno de ellos tiene su propio nucleo con buffer de memoria transitoria). El tiempo de transferencia de datos se superpone con el tiempo de cálculo MAC utilizando una estrategia de doble memoria intermedia. Estos grupos se asocian en racimos con su propia fuente de información basada en RISC. Dos procesadores ARM Cortex A9 sirven de hosts.

‘La arquitectura se ha diseñado para proporcionar un alto rendimiento dada la secuencia óptima de instrucciones. Sin embargo, la elaboración manual de instrucciones del tipo ensamblador puede ser engorrosa y propensa a errores, especialmente en el caso de modelos formados por varias capas, como ocurre con ResNet', explican sus creadores. 'Incluso si se es lo suficientemente paciente como para escribir código manualmente para algunos modelos de aprendizaje profundo de última generación, una mayor personalización, tanto en el hardware como en el software, requeriría modificar miles de líneas de código ensamblador, para evitar la experimentación en sistemas personalizados de aprendizaje profundo.'
'Snowflake es capaz de lograr una eficiencia de cálculo de más del 91% de la totalidad del modelo en modernos modelos CNN, y el 99% en algunas capas individuales', declara Culurciello. 'Implementado sobre un Xilinx Zynq XC7Z045 SoC es capaz de conseguir un rendimiento máximo de 128 Giga operaciones/s y un rendimiento medido de 100 tramas por segundo y 120 Giga operaciones/s sobre el modelo CNN AlexNet, 36 tramas por segundo y 116 Giga operaciones/s en el modelo CNN GoogLeNet y 17 tramas por segundo y 122 Giga operaciones/s en el modelo CNN ResNet-50. Hasta donde sabemos, Snowflake es el único sistema implementado capaz de conseguir una eficiencia superior al 91% en CNNs modernas y el único sistema implementado con GoogLeNet y ResNet como parte de la suite de aplicaciones de medidas de rendimiento.’


Esta es una comparación interesante con la TPU de Google en el rendimiento por vatio. El equipo de trabajo no explica los resultados de la TPU, pero indica que ' mantuvo una cifra optimista para la TPU, con un porcentaje de utilización mucho menor que el 100% cuando se ejecutan modelos para los que no está optimizada.' Culurciello señala que el Snowflake SoC 1k tendrá la misma capacidad de cómputo que la última versión de GPU Nvidia Titan X.
Culurciello concluye que Snowflake y el esquema de Snowball abordan algunos de los principales puntos de diseño de software que llevan a muchos aceleradores de hardware a tener lagunas en cuanto a la eficiencia. Estos incluyen análisis de estructura de modelo, desglose de carga de la trabajo, reordenamiento de bucle y equilibrio del acceso a memoria. Estos se han probado con resultados positivos en su propio acelerador de Snowflake, pero el equipo confía en que estos puedan aplicarse a otros aceleradores personalizados. Puede encontrar  aquí una descripción en profundidad  tanto de la arquitectura Snowflake como del esquema de software de Snowball.
Los problemas técnicos con los aceleradores personalizados representan un desafío. La otra gran cuestión en el horizonte es hasta qué punto se habrán hecho imprescindibles estos chips personalizados a medida que las grandes empresas trabajen para integrar funciones valiosas en en ámbito de aprendizaje profundo en chips estándar (como lo está haciendo Intel con su familia de procesadores Knights, por ejemplo). Con funciones de aprendizaje profundo de mayor alcance en entornos de software común, la necesidad y el uso de aceleradores personalizados para estas tareas podrían comenzar a desaparecer. Sin embargo, el trabajo para hacer que los FPGAs se acerquen más a esa línea de partida es interesante ya que aumenta la amalgama arquitectónica.


Thursday, March 30, 2017

Aprendizaje profundo para principiantes (Parte2)

Nota: Este artículo es una traducción del original que aparece en HACKERNOON: Deep Learning for Noobs [Part 2]

Muchas gracias al autor Debarko De por permitir su publicación en español.


Aprendizaje profundo para principiantes (Parte 2)
¿Cómo podemos configurar nuestra propia red neuronal convolucional? En esta exposición vamos a tratar de responder a esta pregunta. Trabajaremos sobre el problema de segmentación de imágenes que discutimos en la primera parte de esta serie.
Hay muchas bibliotecas disponibles para crear una red neuronal convolucional. Elegimos Keras y Tensorflow. La primera pregunta que viene a la mente es:
¿Por qué estos dos en concreto? ¿Por qué no sólo Tensorflow?
En lo que sería la biblioteca general de aprendizaje automático hay muchas bibliotecas. Tensorflow, Theano, PyTorch, Caffe y Torch son algunas de los más importantes. Desde aquí quiero expresar el profundo reconocimiento a PyTorch gracias a Soumith Chintala y a su equipo, que han creado una biblioteca impresionante. Esperemos que se puedan hacer cargo del mundo (** sonrisa maliciosa **).

PyTorch planea hacerse con el mundo: P Andrej Karpathy tiene grandes esperanzas en Tensorflow
Todas ellas son bibliotecas de bajo nivel. Lo que implica tener que acelerar los procesos mediante GPU o CPU y optimizar cálculos matriciales. Por lo tanto, construir redes que utilicen estas bibliotecas podría convertirse en un importante reto. Keras es una biblioteca de alto nivel. Ayuda a crear capas neuronales  y simplifica las complejidades de las operaciones de cálculo. Keras trabaja con Theano o Tensorflow como respaldo. He elegido Tensorflow como respaldo porque tiene un mejor apoyo de la comunidad.
KEras & TEnsorflow (KETE) es la combinación perfecta.
Instalación
Vamos a decidir los componentes que hay que instalar. Y lo vamos a ir haciendo según avanzamos. Los sistemas tradicionales se eternizarían entrenando conjuntos de datos. Así que vamos a conseguir un servidor AWS. Si disponemos de un equipo para videojuegos podemos programarlo en local. Utilizaremos el sistema g2.2xLarge de AWS. Tiene 26 núcleos de GPU y cuesta 0,65 dólares / hora. ¿Por qué lo elegimos? Nos decidimos por él porque es el sistema de GPU más barato disponible en la nube, y funcionará mejor que la mayor parte del hardware que tengamos en casa. Lo siguiente es decidir el sistema operativo que vamos a emplear. Definitivamente tiene sentido utilizar Ubuntu 16.04 LTS pero ¡un momento! Vamos a utilizar una AMI pre-horneado que tiene un montón de herramientas incorporadas. De esta manera podemos dejar acabada la mayor parte de la configuración. Busquemos Deep Learning AMI de AWS. Hay otras buenas AMIs en aprendizaje automático que se pueden encontrar en la red. Necesitamos que Python 2.7 y Tensorflow estén instalados al menos en la AMI.



   Instancia GPU y aprendizaje profundo AMI en AWS

Después de seleccionar el tipo de instancia (máquina virtual de Amazon) y la AMI hay que crear una clave. Puede utilizar cualquier clave que ya tenga preparada. Pero para este caso crearemos una. Vamos a utilizar una clave con el siguiente nombre: deepkey.pem. Descargue la clave y guárdela en un lugar seguro. Inicie la instancia. Para crearla se necesitan entre 5 y 10 minutos. Mientras tanto, hay que cambiar el permiso de la clave a 400. De lo contrario ssh no le permitirá iniciar sesión.
Chmod 400 ~ / deepkey.pem
A continuación, hay que ir a la lista de instancias de EC2. Desde allí, seleccionar la instancia que se ha creado. Hay que copiar la DNS pública de la instancia de AWS. Se parecerá a esto: ec2-52-24-183-62.us-west-2.compute.amazonaws.com
# A continuación entramos en el sistema
Ssh ec2-user@ec2-52-24-183-62.us-west-2.compute.amazonaws.com -i ~ / deepkey.pem
# La AMI podría estar desafasada por lo que siempre es mejor ponerla al día
Sudo yum update
# Instalamos pip para obtener Keras
sudo yum install python-pip
# Actualizamos el pip master instalado
sudo /usr/local/bin/pip install — upgrade pip
# Instalamos Keras
sudo /usr/local/bin/pip install keras
Por defecto, la configuración básica Keras se instala con Theano. Vamos a usar Tensorflow. Así que vamos a cambiarlo. Abrir ~ / .keras / keras.conf y actualizarlo como se muestra a continuación. El archivo se debe ver como se muestra en la sección siguiente.
{
“image_dim_ordering”: “tf”,
“epsilon”: 1e-07,
“floatx”: “float32”,
“backend”: “tensorflow”
}
Espero que todos los pasos se hayan seguido sin cometer errores. Vamos ahora a probar nuestra instalación. Abrimos python y luego importamos keras para probarlo. La salida debe tener un aspecto como el que se muestra a continuación.


    Prueba de instalación Keras
Así que ahora tenemos Python, Tensorflow y Keras instalados. La AMI también proporciona Theano y otros recursos pre instalados, pero no los vamos a utilizar. No es necesario desinstalarlos ya que no interfieren en el funcionamiento. Terminada la instalación, vayamos con el código.

No hay que perder el tiempo en la instalación, sino que hay que aprovecharlo en  aprender y en realizar la implementación.
Vamos a entrenar una red que podamos usar para clasificar imágenes de perros y gatos de Kaggle. Antes de esto comenzaremos a escribir un modelo sencillo. Esto ayudará a entender cómo funciona Keras. Comenzaré con el código. Si lo observamos, hay comentarios antes de cada línea de código. Estos comentarios explican en cierta medida lo que sucede en esa línea particular de código. Para ejecutar el código, se puede utilizar cualquier base de datos conteniendo imágenes de perros y gatos, o podemos descargar los datos de la muestra de Kaggle. Para poder descargar los datos de la muestra es necesario registrarse en Kaggle. Aquí está el enlace de Kaggle.
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense


# tamaño esperado de la imagen
img_width, img_height = 150, 150
# carpeta que contiene las imágenes sobre
# las que se entrenará la red. La carpeta de entrenamiento
# tiene dos subcarpetas, perros y gatos.
train_data_dir = 'data/train'
# carpeta que contiene las muestras de validación
# la estructura de la carpeta es la misma que la de la carpeta de entrenamiento
validation_data_dir = 'data/validation'
# número de imágenes que se consideran para el entrenamiento
train_samples = 2000
# número de imágenes se utilizan en la validación
validation_samples = 800
# número de veces que se ejecutará la red # sobre el conjunto de entrenamiento antes
# de empezar con la validación
epoch = 50
# ** Inicio del modelo **
model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(3, img_width, img_height)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
# ** Fin del modelo **
model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# esta es la mejora de la configuración que utilizaremos para el entrenamiento
# en el que generamos un gran número de imágenes transformadas de manera que el
# modelo puede tratar con una gran variedad de escenarios del mundo real
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

# esta es la mejora de la configuración que utilizaremospara la prueba:
# sólo para reajuste
test_datagen = ImageDataGenerator(rescale=1./255)
# esta sección toma imágenes de la carpeta
# y las pasa al ImageGenerator que crea entonces
# un gran número de versiones transformadas
train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width, img_height),
        batch_size=32,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=32,
        class_mode='binary')
# aquí es donde se produce el proceso real
# y llevará algún tiempo ejecutar este paso.
model.fit_generator(
        train_generator,
        samples_per_epoch=train_samples,
        nb_epoch=epoch,
        validation_data=validation_generator,
        nb_val_samples=validation_samples)

model.save_weights('trial.h5')
El código es autoexplicativo. Se puede reemplazar la sección entre 'Inicio del modelo' y 'Final del modelo' para usar otros modelos. Tendremos nuestro propio código clasificador, y yo serviré de guía en el código.
Primero importamos algunas dependencias de Keras. A continuación, definimos las dimensiones de la imagen que pasará a la red. Después de eso informamos el código donde están los conjuntos de imágenes: el conjunto de datos de entrenamiento y el conjunto de datos de validación. Después se construye el modelo desde el principio hasta el final. No voy a entrar en profundidad en el modelo, ya que es una implementación VGGNet estándar. Los detalles sobre la arquitectura de red se pueden encontrar en el siguiente documento arXiv:
Very Deep Convolutional Networks for Large-Scale Image Recognition
K. Simonyan, A. Zisserman
arXiv:1409.1556
A continuación, el código genera transformaciones en los datos. Aquí se puede acortar, estirar, inclinar el conjunto de datos para que la red no entre en sobre entrenamiento. Creamos generadores para que el código pueda leer imágenes de las carpetas especificadas. Después se inicia el procesamiento. El sistema realiza el entrenamiento y la validación el número veces que se mencionan en 'epoch'. Finalmente almacenamos estos pesos para  usarlos en el futuro y evitar que la red tenga que entrenarse de nuevo. Si tiene  dudas, por favor, decídase y  formule las preguntas que considere. Intentaré contestarlas según mi leal saber y entender.
El modelo anterior es sencillo y sólo existe por una explicación más sencilla aún. La clasificación de gatos y perros podría no tener tanto éxito debido a la cantidad de datos que tenemos. Así que tenemos que acudir al aprendizaje de transferencia. En el aprendizaje de transferencia trabajamos en modelos que entrenamos para resolver cuestiones similares. Tomamos los pesos de entrenamiento y los reutilizamos para resolver cuestiones completamente diferentes. Entrenamos modelos que pre-entrenamos sobre imágenes para clasificar diferentes cosas. ¿Por qué funciona esto? Es porque el modelo que vamos a utilizar fue entrenado para hacer la clasificación de imágenes. Las capas más profundas siempre serán capaces de clasificar de forma genérica, y trabajarán en el nivel de detección de bordes y curvas. De ahí el término transferencia de aprendizaje, ya que se transfiere el aprendizaje del planteamiento de un problema al de otro problema distinto. Esto podría funcionar bien en nuestro caso. Pero podemos hacer que funcione mejor. A continuación entrenamos las capas superiores. Estas capas realmente se preocupan por los elementos reales que se clasifican. Las entrenamos con nuestro conjunto de datos de entrenamiento. Podemos llamar a este conjunto de datos dominio específico. Esto le permite a la red comprender que es exactamente lo que queremos clasificar. Así que el código es el siguiente:
import os
import h5py
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D, ZeroPadding2D
from keras.layers import Activation, Dropout, Flatten, Dense

# ruta a los archivos de pesos del modelo.
weights_path = 'vgg16_weights.h5'
top_model_weights_path = 'fc_model.h5'
# dimensiones de las imágenes.
img_width, img_height = 150, 150

train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
nb_train_samples = 2000
nb_validation_samples = 800
nb_epoch = 50

# creación de la red VGG16
model = Sequential()
model.add(ZeroPadding2D((1, 1), input_shape=(3, img_width, img_height)))

model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_2'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_2'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_1'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_2'))
model.add(ZeroPadding2D((1, 1)))
model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_3'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))

# cargar los pesos de las redes VGG16 networks
# (entrenadas sobre ImageNet, ganaron la competición ILSVRC en 2014)
# nota: cuando hay una correspondencia completa entre la definición del modelo
# y el archivo de pesos, se puede llamar a model.load_weights(filename)
imponer os.path.exists(weights_path), 'Los pesos del modelo no se encuentran (ver la variable "weights_path" en el script).'
f = h5py.File(weights_path)
for k in range(f.attrs['nb_layers']):
    if k >= len(model.layers):
        # no miramos las últimas capas (completamente conectadas) del archivo
        break
    g = f['layer_{}'.format(k)]
    weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
    model.layers[k].set_weights(weights)
f.close()
print('Model loaded.')

# creación de un modelo clasificador para situarlo encima del modelo convolucional top_model = Sequential()
top_model.add(Flatten(input_shape=model.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(1, activation='sigmoid'))

# hay que notar que es necesario empezar con un clasificador
# completamente entrenado, incluyendo el clasificador situado arriba,
# para realizar con éxito un ajuste fino
top_model.load_weights(top_model_weights_path)

# añadir el modelo en la parte superior de la base convolucional
model.add(top_model)

# establecer las primeras 25 capas (hasta el último bloque de convolución)
# a las no entrenables (los pesos no se actualizarán)
for layer in model.layers[:25]:
    layer.trainable = False

# compilar el modelo con un SDG/ momento optimizador
# y a una tasa de aprendizaje muy baja.
model.compile(loss='binary_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])

# preparación de los datos de mejora de la configuración
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_height, img_width),
        batch_size=32,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_height, img_width),
        batch_size=32,
        class_mode='binary')

# ajuste fino del modelo
model.fit_generator(
        train_generator,
        samples_per_epoch=nb_train_samples,
        nb_epoch=nb_epoch,
        validation_data=validation_generator,
        nb_val_samples=nb_validation_samples)
Los pesos para VGG16 se pueden conseguir en mi Github. También se puede conseguir el archivo de pesos del fc_model ejecutando este programa sobre el conjunto de datos dataset. Se puede utilizar el mismo conjunto de pesos del enlace compartido VGG16. Se puede ajustar el número de epoch para conseguir un mejor aprendizaje, pero tener cuidado porque esto podría llevar a la sobrealimentación. Yo he utilizado esta técnica en una gran cantidad de casos prácticos en mi trabajo. Un caso práctico es distinguir entre prescripciones y no prescripciones. Utilizamos exactamente el mismo modelo entrenado en los datos de ImageNet de gatos y perros para clasificar las recetas. Espero que lo puedan usar en casos prácticos en el mundo real. Comuníquenos cualquier caso interesante que haya resuelto utilizando este método.
Gran parte del contenido de este artículo está extraído de una entrada de blog de Keras.
Puede seguirme en twitter y también puede registrarse en una pequeña lista de correo mailing list. Si le ha gustado este artículo, pulse el botón ❤ para recomendarlo. Esto ayudará a otros usuarios de Medium a encontrarlo.