Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Hands-451-500 en Es

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 50

Traducido del inglés al español - www.onlinedoctranslator.

com

Figura 13-5. incrustaciones de palabras

Volvamos a la API de características. Así es como podrías codificar elocean_proxim ity


categorías como incrustaciones 2D:

ocean_proximity_embed=t.f..característica_columna.incrustar_columna(proximidad_océano,
dimensión=2)

cada uno de los cincoproximidad_océanolas categorías ahora se representarán como un vector 2D.
Estos vectores se almacenan en unmatriz de inclusióncon una fila por categoría y una columna por
dimensión incrustada, por lo que en este ejemplo es una matriz de 5×2. Cuando a una columna
incrustada se le da un índice de categoría como entrada (por ejemplo, 3, que corresponde a la
categoría "CERCA DE LA BAHÍA"),simplemente realiza una búsqueda en la matriz de incrustación y
devuelve la fila correspondiente (digamos, [0,331, 0,190]).Desafortunadamente, la matriz de
incrustación puede ser bastante grande, especialmente cuando tiene un vocabulario amplio: si este es
el caso, el modelo solo puede aprender buenas representaciones para las categorías para las que
tiene suficientes datos de entrenamiento. Para reducir el tamaño de la matriz de incrustación, por
supuesto, puede intentar reducir eldimensiónhiperparámetro, pero si reduce demasiado este
parámetro, las representaciones pueden no ser tan buenas. Otra opción es reducir el tamaño del
vocabulario (p. ej., si se trata de texto, puede intentar eliminar las palabras raras del vocabulario y
reemplazarlas todas con un token como "<desconocido>"o "<DESCONOCIDO>"). Si está utilizando
cubos de hash, también puede intentar reducir elhash_bucket_size (pero no demasiado, o de lo
contrario obtendrá colisiones).

La API de características | 425


Si no hay incrustaciones previamente entrenadas que pueda reutilizar para la tarea
que está tratando de abordar, y si no tiene suficientes datos de entrenamiento para
aprenderlas, entonces puede intentar aprenderlas en alguna tarea auxiliar para la
cual es más fácil. para obtener muchos datos de entrenamiento. Después de eso,
puede reutilizar las incrustaciones entrenadas para su tarea principal.

Uso de columnas de características para el análisis

Supongamos que ha creado columnas de funciones para cada una de sus funciones de entrada, así
como para el objetivo. ¿Qué puedes hacer con ellos? Bueno, por un lado puedes pasarlos al
make_parse_example_spec()función para generar descripciones de funciones (para que no tenga que
hacerlo manualmente, como hicimos antes):

columnas=[cuboizado_edad,.....,valor_mediano_de_la_casa]#todas las características + objetivo


características_descripciones=t.f..característica_columna.make_parse_example_spec(columnas)

No siempre tiene que crear una columna de función separada para cada
función. Por ejemplo, en lugar de tener 2 columnas de características
numéricas, puede optar por tener una sola columna 2D: solo
establecerforma=[2]al llamarcolumna_numérica().

A continuación, puede crear una función que analice ejemplos serializados utilizando estas
descripciones de funciones y separe la columna de destino de las funciones de entrada:

definitivamenteanalizar_ejemplos(ejemplos_serializados):
ejemplos=t.f..yo.analizar_ejemplo(ejemplos_serializados,características_descripciones)
objetivos=ejemplos.estallido("median_house_value")#separar los objetivos devolver
ejemplos,objetivos

A continuación, puede crear unTFRecordDatasetque leerá lotes de ejemplos serializados


(suponiendo que el archivo TFRecord contieneEjemploprotobufs con las características
adecuadas):

tamaño del lote=32


conjunto de datos=t.f..datos.TFRecordDataset(["mis_datos_con_funciones.tfrecords"]) conjunto de datos=
conjunto de datos.repetir().barajar(10000).lote(tamaño del lote).mapa(analizar_ejemplos)

Uso de columnas de características en sus modelos

Las columnas de características también se pueden usar directamente en su modelo, para convertir todas sus
características de entrada en un solo vector denso que la red neuronal puede procesar. Para esto, todo lo que
necesita hacer es agregar unkeras.layers.DenseFeaturescapa como la primera capa en su modelo, pasándole
la lista de columnas de características (excluyendo la columna de destino):

columnas_sin_objetivo=columnas[:-1]
modelo=queras.modelos.Secuencial([
queras.capas.Características densas(columnas_características=columnas_sin_objetivo),

426 | Capítulo 13: Carga y preprocesamiento de datos con TensorFlow


queras.capas.Denso(1)
])
modelo.compilar(pérdida="mse",optimizador="sgd",métrica=["precisión"])
pasos_por_época=Len(X_tren)//tamaño del lote
historia=modelo.adaptar(conjunto de datos,pasos_por_época=pasos_por_época,épocas=5)

losCaracterísticas densascapa se encargará de convertir cada característica de entrada en una


representación densa, y también aplicará cualquier transformación adicional que especifiquemos,
como escalar lavivienda_median_ageutilizando elnormalizador_fnfunción que proporcionamos. Puedes
echar un vistazo más de cerca a lo queCaracterísticas densascapa lo hace llamándolo directamente:

> > > algunas_columnas=[ocean_proximity_embed,ingresos_cubetados]


> > > características_densas=queras.capas.Características densas(algunas_columnas)
> > > características_densas({
... "proximidad_océano": [["CERCA DEL OCÉANO"], ["INTERIOR"], [
... "INTERIOR"]], "ingreso medio": [[3.], [7.2], [1.]]
. . . })
...
<tf.Tensor: id=559790, forma=(3, 7), dtype=float32, numpy=
array([[ 0. , 0. , 1. , 0. , 0. ,-0.36277947 , 0.30109018],
[ 0. , 0. , 0. , 0. , 1. , 0.22548223 , 0.33142096],
[ 1. , 0. , 0. , 0. , 0. , 0.22548223 , 0.33142096]], dtype=float32)>

En este ejemplo, creamos unCaracterísticas densascapa con solo dos columnas, y la llamamos
con algunos datos, en forma de diccionario de características. En este caso, desde labucke
tized_incomecolumna se basa en elingreso mediocolumna, el diccionario debe
incluir la "ingreso medio"clave, y de manera similar desde elocean_proximity_embed
columna se basa en laproximidad_océanocolumna, el diccionario debe incluir la
"proximidad_océano"llave. Las columnas se manejan en orden alfabético, por lo que primero
observamos la columna de ingresos divididos en cubos (su nombre es el mismo que elingreso medio
nombre de columna, más "_baldeizado").Los ingresos 3, 7,2 y 1 se asignan respectivamente a la
categoría 2 (para ingresos entre 1,5 y 3), categoría 0 (para ingresos inferiores a 1,5) y categoría 4 (para
ingresos superiores a 6). Luego, estos ID de categoría se codifican en caliente: la categoría 2 se
codifica como [0., 0., 1., 0., 0.]y así sucesivamente (tenga en cuenta que las columnas divididas en cubos
se codifican en caliente de forma predeterminada, no es necesario llamarindicador_columna()).Ahora
sobre laocean_proximity_embedcolumna. Los "CERCA DEL OCÉANO"y "INTERIOR"cate‐
las gorías simplemente se asignan a sus respectivas incrustaciones (que se inicializaron
aleatoriamente). El tensor resultante es la concatenación de los vectores one-hot y las
incrustaciones.

¡Ahora puede alimentar todo tipo de funciones a una red neuronal, incluidas funciones numéricas,
funciones categóricas e incluso texto (al dividir el texto en palabras y luego usar la incrustación de
palabras)! Sin embargo, realizar todo el preprocesamiento sobre la marcha puede ralentizar el
entrenamiento. Veamos cómo se puede mejorar esto.

La API de características | 427


Transformación TF

Si el preprocesamiento es costoso desde el punto de vista computacional, manejarlo antes del entrenamiento
en lugar de sobre la marcha puede brindarle una aceleración significativa: los datos se preprocesarán solo
una vez por instancia.antes deentrenamiento, en lugar de una vez por instancia y por épocadurante
capacitación. Herramientas como Apache Beam le permiten ejecutar canalizaciones de procesamiento de
datos eficientes en grandes cantidades de datos, incluso distribuidos en varios servidores, entonces, ¿por qué
no usarlo para preprocesar todos los datos de entrenamiento? Esto funciona muy bien y, de hecho, puede
acelerar el entrenamiento, pero hay un problema: una vez que su modelo esté entrenado, suponga que
desea implementarlo en una aplicación móvil: necesitará escribir algo de código en su aplicación para
encargarse del preprocesamiento. los datos antes de que se introduzcan en el modelo. Y suponga que
también desea implementar el modelo en TensorFlow.js para que se ejecute en un navegador web. Una vez
más, deberá escribir un código de preprocesamiento. Esto puede convertirse en una pesadilla de
mantenimiento: cada vez que desee cambiar la lógica de preprocesamiento, deberá actualizar su código
Apache Beam, el código de su aplicación móvil y su código Javascript. No solo lleva mucho tiempo, pero
también propenso a errores: puede terminar con diferencias sutiles entre las operaciones de
preprocesamiento realizadas antes del entrenamiento y las realizadas en su aplicación o en el navegador.
Estesesgo de entrenamiento/serviciodará lugar a errores o rendimiento degradado.

Una mejora sería tomar el modelo entrenado (entrenado con datos preprocesados por su código
Apache Beam) y, antes de implementarlo en su aplicación o navegador, agregar una capa de entrada
adicional para encargarse del preprocesamiento sobre la marcha ( ya sea escribiendo una capa
personalizada o usando unCaracterísticas densascapa). Eso es definitivamente mejor, ya que ahora solo
tiene dos versiones de su código de preprocesamiento: el código de Apache Beam y el código de la
capa de preprocesamiento.

Pero, ¿y si pudiera definir sus operaciones de preprocesamiento solo una vez? Esto es para lo
que se diseñó TF Transform. es parte deTensorFlow extendido(TFX), una plataforma integral
para la producción de modelos TensorFlow. Primero, para usar un componente TFX, como TF
Transform, debe instalarlo, no viene incluido con TensorFlow. Usted define su función de
preprocesamiento solo una vez (en Python), mediante el uso de funciones TF Transform para
escalar, dividir en cubos, cruzar características y más. También puede usar cualquier operación
de TensorFlow que necesite. Así es como se vería esta función de preprocesamiento si solo
tuviéramos dos características:

importartensorflow_transformcomotft

definitivamentepreprocesar(entradas):#entradas es un lote de características de entrada


Edad media=entradas["vivienda_median_age"]
proximidad_océano=entradas["proximidad_océano"]
edad_estandarizada=tft.scale_to_z_score(Edad media-tft.significar(Edad media))
ocean_proximity_id=tft.computar_y_aplicar_vocabulario(proximidad_océano)
devolver{
"edad_media_estandarizada":edad_estandarizada,

428 | Capítulo 13: Carga y preprocesamiento de datos con TensorFlow


"ocean_proximity_id":ocean_proximity_id
}

A continuación, TF Transform le permite aplicar estopreprocesar()función a todo el conjunto de


entrenamiento usando Apache Beam (proporciona unaAnalizarYTransformarConjuntoDeDatos
class que puede usar para este propósito en su tubería de Apache Beam). En el proceso,
también calculará todas las estadísticas necesarias sobre todo el conjunto de entrenamiento: en
este ejemplo, la media y la desviación estándar delvivienda_median_agefunción y el vocabulario
de laproximidad_océanorasgo. Los componentes que calculan estas estadísticas se llaman
analizadores.

Es importante destacar que TF Transform también generará una función TensorFlow equivalente que
puede conectar al modelo que implemente. Esta función TF contiene todas las estadísticas necesarias
calculadas por Apache Beam (la media, la desviación estándar y el vocabulario), simplemente incluidas
como constantes.

En el momento de escribir este artículo, TF Transform solo es compatible


con Tensor-Flow 1. Además, Apache Beam solo es compatible
parcialmente con Python 3. Dicho esto, es probable que ambas
limitaciones se solucionen cuando lea esto.

Con la API de datos, TFRecords, la API de características y TF Transform, puede crear canalizaciones de
entrada altamente escalables para la capacitación y también beneficiarse del preprocesamiento de
datos rápido y portátil en producción.

Pero, ¿qué sucede si solo desea utilizar un conjunto de datos estándar? Bueno, en ese caso, las cosas son mucho más
simples: ¡simplemente use TFDS!

El proyecto de conjuntos de datos de TensorFlow (TFDS)

losConjuntos de datos de TensorFlowEl proyecto hace que sea trivial descargar conjuntos de datos comunes, desde
pequeños como MNIST o Fashion MNIST, hasta grandes conjuntos de datos como ImageNet11(¡Necesitará bastante
espacio en disco!). La lista incluye conjuntos de datos de imágenes, conjuntos de datos de texto (incluidos los
conjuntos de datos de traducción), conjuntos de datos de audio y video, y más. Puedes visitarhttps://homl.info/tfds
para ver la lista completa, junto con una descripción de cada conjunto de datos.

TFDS no se incluye con TensorFlow, por lo que debe instalar elconjuntos de datos de flujo de tensor
biblioteca (por ejemplo, usando pip). Entonces todo lo que necesita hacer es llamar altfds.load()
y descargará los datos que desee (a menos que ya se haya descargado antes), y devolverá los
datos como un diccionario deConjuntos de datos (típicamente uno para entrenamiento,

11 Al momento de escribir este artículo, TFDS requiere que descargue algunos archivos manualmente para ImageNet (por razones legales),

pero espero que esto se resuelva pronto.

El proyecto de conjuntos de datos de TensorFlow (TFDS) | 429


y otro para pruebas, pero esto depende del conjunto de datos que elija). Por ejemplo,
descarguemos MNIST:

importartensorflow_conjuntos de datoscomotfds

conjunto de datos=tfds.carga(nombre="mnista")
mnist_tren,prueba_mnist=conjunto de datos["tren"],conjunto de datos["prueba"]

A continuación, puede aplicar cualquier transformación que desee (por lo general, repetición, procesamiento por lotes
y captación previa), y estará listo para entrenar su modelo. Aquí hay un ejemplo simple:

mnist_tren=mnist_tren.repetir(5).lote(32).captación previa(1) por


artículoenmnist_tren:
imágenes=artículo["imagen"]
etiquetas=artículo["etiqueta"] [
...]

En general,carga()devuelve un conjunto de entrenamiento barajado, por lo que no hay


necesidad de barajarlo más.

Tenga en cuenta que cada elemento del conjunto de datos es un diccionario que contiene tanto las características
como las etiquetas. Pero Keras espera que cada elemento sea una tupla que contenga 2 elementos (nuevamente, las
características y las etiquetas). Podría transformar el conjunto de datos usando elmapa()método, así:

mnist_tren=mnist_tren.repetir(5).lote(32)
mnist_tren=mnist_tren.mapa(lambdaelementos: (elementos["imagen"],elementos["etiqueta"]))
mnist_tren=mnist_tren.captación previa(1)

O simplemente puede preguntarle alcarga()función para hacer esto por usted configurandocomo_supervisado=Verdadero (

obviamente esto funciona solo para conjuntos de datos etiquetados). También puede especificar el tamaño del lote si lo desea.

Luego, el conjunto de datos se puede pasar directamente a su modelo tf.keras:

conjunto de datos=tfds.carga(nombre="mnista",tamaño del lote=32,como_supervisado=


Verdadero) mnist_tren=conjunto de datos["tren"].repetir().captación previa(1) modelo=queras.
modelos.Secuencial([...])
modelo.compilar(pérdida="esparse_categorical_crossentropy",optimizador="sgd")
modelo.adaptar(mnist_tren,pasos_por_época=60000//32,épocas=5)

Este fue un capítulo bastante técnico, y puede sentir que está un poco lejos de la belleza abstracta de
las redes neuronales, pero el hecho es que el aprendizaje profundo a menudo involucra grandes
cantidades de datos, y saber cómo cargarlos, analizarlos y preprocesarlos de manera eficiente es una
habilidad crucial para tener. En el próximo capítulo, veremos las redes neuronales convolucionales,
que se encuentran entre las arquitecturas de redes neuronales más exitosas para el procesamiento de
imágenes y muchas otras aplicaciones.

430 | Capítulo 13: Carga y preprocesamiento de datos con TensorFlow


CAPÍTULO 14

Visión artificial profunda usando convolucional


Redes neuronales

Con los libros electrónicos Early Release, obtiene libros en su forma más
temprana, el contenido sin editar y sin editar del autor mientras escribe,
para que pueda aprovechar estas tecnologías mucho antes del
lanzamiento oficial de estos títulos. El siguiente será el Capítulo 14 en la
versión final del libro.

Aunque la supercomputadora Deep Blue de IBM venció al campeón mundial de ajedrez Garry
Kasparov en 1996, no fue hasta hace relativamente poco tiempo que las computadoras pudieron
realizar de manera confiable tareas aparentemente triviales, como detectar un cachorro en una
imagen o reconocer palabras habladas. ¿Por qué estas tareas son tan sencillas para nosotros los
humanos? La respuesta radica en el hecho de que la percepción tiene lugar en gran medida fuera del
ámbito de nuestra conciencia, dentro de módulos especializados visuales, auditivos y otros sensores
en nuestro cerebro. Cuando la información sensorial llega a nuestra conciencia, ya está adornada con
características de alto nivel; por ejemplo, cuando miras una foto de un lindo cachorro, no puedes
elegir nopara ver el cachorro, onopara notar su ternura. tampoco puedes explicarcómoreconoces un
lindo cachorro; es simplemente obvio para ti. Por lo tanto, no podemos confiar en nuestra experiencia
subjetiva: la percepción no es trivial en absoluto, y para comprenderla debemos observar cómo
funcionan los módulos sensoriales.

Las redes neuronales convolucionales (CNN) surgieron del estudio de la corteza visual del cerebro y se
han utilizado en el reconocimiento de imágenes desde la década de 1980. En los últimos años, gracias
al aumento de la potencia computacional, la cantidad de datos de entrenamiento disponibles y los
trucos presentados enCapítulo 11Para el entrenamiento de redes profundas, las CNN han logrado
lograr un rendimiento sobrehumano en algunas tareas visuales complejas. Impulsan servicios de
búsqueda de imágenes, automóviles autónomos, sistemas automáticos de clasificación de videos y
más. Además, las CNN no se limitan a la percepción visual: también tienen éxito

431
en muchas otras tareas, comoreconocimiento de vozoprocesamiento natural del lenguaje(PNL); sin embargo,
por ahora nos centraremos en las aplicaciones visuales.

En este capítulo, presentaremos de dónde provienen las CNN, cómo se ven sus componentes
básicos y cómo implementarlos usando TensorFlow y Keras. Luego discutiremos algunas de las
mejores arquitecturas de CNN, y discutiremos otras tareas visuales, incluyendo detección de
objetos(clasificar múltiples objetos en una imagen y colocar cuadros delimitadores alrededor de
ellos) ysegmentación semántica(clasificando cada píxel según la clase del objeto al que
pertenece).

La arquitectura de la corteza visual


David H. Hubel y Torsten Wiesel realizaron una serie de experimentos con gatos en 19581y19592(y un
unos años después en monos3), brindando información crucial sobre la estructura de la corteza visual
(los autores recibieron el Premio Nobel de Fisiología o Medicina en 1981 por su trabajo). En particular,
demostraron que muchas neuronas en la corteza visual tienen una pequeñacampo receptivo local, lo
que significa que reaccionan solo a los estímulos visuales ubicados en una región limitada del campo
visual (verFigura 14-1, en el que los campos receptivos locales de cinco neuronas están representados
por círculos discontinuos). Los campos receptivos de diferentes neuronas pueden superponerse y
juntos forman el campo visual completo. Además, los autores demostraron que algunas neuronas
reaccionan solo a imágenes de líneas horizontales, mientras que otras reaccionan solo a líneas con
diferentes orientaciones (dos neuronas pueden tener el mismo campo receptivo pero reaccionar a
diferentes orientaciones de línea). También notaron que algunas neuronas tienen campos receptivos
más grandes y reaccionan a patrones más complejos que son combinaciones de patrones de nivel
inferior. Estas observaciones llevaron a la idea de que las neuronas de nivel superior se basan en las
salidas de las neuronas vecinas de nivel inferior (enFigura 14-1, observe que cada neurona está
conectada solo a unas pocas neuronas de la capa anterior). Esta poderosa arquitectura es capaz de
detectar todo tipo de patrones complejos en cualquier área del campo visual.

1 “Actividad de una sola unidad en la corteza estriada de gatos sin restricciones”, D. Hubel y T. Wiesel (1958). 2 “Campos

receptivos de neuronas individuales en la corteza estriada del gato”, D. Hubel y T. Wiesel (1959).

3 "Campos receptivos y arquitectura funcional de la corteza estriada del mono", D. Hubel y T. Wiesel (1968).

432 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
Figura 14-1. Campos receptivos locales en la corteza visual

Estos estudios de la corteza visual inspiraron laneocognitrón, introducido en 1980,4


que gradualmente se convirtió en lo que ahora llamamosredes neuronales convolucionales. Un
hito importante fue unpapel de 19985de Yann LeCun, Léon Bottou, Yoshua Bengio y Patrick
Haffner, que presentó el famosoLeNet-5arquitectura, ampliamente utilizado para reconocer
números de cheques escritos a mano. Esta arquitectura tiene algunos componentes básicos
que ya conoce, como capas totalmente conectadas y funciones de activación sigmoide, pero
también presenta dos nuevos componentes básicos:capas convolucionalesycapas de
agrupación. Mirémoslos ahora.

¿Por qué no simplemente usar una red neuronal profunda regular con capas
completamente conectadas para tareas de reconocimiento de imágenes?
Desafortunadamente, aunque esto funciona bien para imágenes pequeñas (p.
ej., MNIST), falla para imágenes más grandes debido a la gran cantidad de
parámetros que requiere. Por ejemplo, una imagen de 100 × 100 tiene 10.000
píxeles, y si la primera capa tiene solo 1.000 neuronas (lo que ya restringe
mucho la cantidad de información que se transmite a la siguiente capa), esto
significa un total de 10 millones de conexiones. Y esa es solo la primera capa.
Las CNN resuelven este problema utilizando capas parcialmente conectadas y
peso compartido.

4 “Neocognitron: un modelo de red neuronal autoorganizado para un mecanismo de reconocimiento de patrones no afectado
de Shift in Position”, K. Fukushima (1980).

5 “Aprendizaje basado en gradientes aplicado al reconocimiento de documentos”, Y. LeCun et al. (1998).

La arquitectura de la corteza visual | 433


Capa convolucional
El bloque de construcción más importante de una CNN es elcapa convolucional:6Las neuronas en la
primera capa convolucional no están conectadas a cada píxel de la imagen de entrada (como lo
estaban en los capítulos anteriores), sino solo a los píxeles en sus campos receptivos (ver Figura 14-2).
A su vez, cada neurona en la segunda capa convolucional está conectada solo a las neuronas ubicadas
dentro de un pequeño rectángulo en la primera capa. Esta arquitectura permite que la red se
concentre en características pequeñas de bajo nivel en la primera capa oculta, luego las ensambla en
características más grandes de nivel superior en la siguiente capa oculta, y así sucesivamente. Esta
estructura jerárquica es común en las imágenes del mundo real, que es una de las razones por las que
las CNN funcionan tan bien para el reconocimiento de imágenes.

Figura 14-2. Capas CNN con campos receptivos locales rectangulares

Hasta ahora, todas las redes neuronales multicapa que analizamos tenían
capas compuestas por una larga línea de neuronas, y teníamos que aplanar las
imágenes de entrada a 1D antes de enviarlas a la red neuronal. Ahora cada
capa se representa en 2D, lo que facilita la combinación de neuronas con sus
entradas correspondientes.

Una neurona situada en filai, columnajde una capa dada está conectado a las salidas
de las neuronas en la capa anterior ubicadas en filasiai+Fh–1, columnasjaj+Fw–1,
dondeFhyFwson la altura y el ancho del campo receptivo (verFigura 14-3). Para que
una capa tenga la misma altura y anchura que la capa anterior, es com‐

6 Una convolución es una operación matemática que desliza una función sobre otra y mide la integral de
su multiplicación puntual. Tiene conexiones profundas con la transformada de Fourier y la transformada de Laplace, y se usa mucho en
el procesamiento de señales. Las capas convolucionales en realidad usan correlaciones cruzadas, que son muy similares a las
convoluciones (verhttps://homl.info/76para más detalles).

434 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
mon para agregar ceros alrededor de las entradas, como se muestra en el diagrama. Se llamarelleno cero.

Figura 14-3. Conexiones entre capas y relleno cero

También es posible conectar una capa de entrada grande a una capa mucho más pequeña
espaciando los campos receptivos, como se muestra enFigura 14-4. El cambio de un campo
receptivo al siguiente se llamapaso. En el diagrama, una capa de entrada de 5 × 7 (más relleno
cero) está conectada a una capa de 3 × 4, utilizando campos receptivos de 3 × 3 y una zancada
de 2 (en este ejemplo, la zancada es la misma en ambas direcciones, pero no tiene por qué ser
así). Una neurona situada en filai, columnajen la capa superior está conectado a las salidas de
las neuronas en la capa anterior ubicadas en filasi×shai×sh+Fh–1, columnasj×swaj×sw+Fw–
1, dondeshyswson los pasos verticales y horizontales.

Capa convolucional | 435


Figura 14-4. Reduciendo la dimensionalidad usando una zancada de 2

filtros
Los pesos de una neurona se pueden representar como una pequeña imagen del tamaño del
campo receptivo. Por ejemplo,Figura 14-5muestra dos posibles conjuntos de pesos, llamados
filtros(oNúcleos de convolución). El primero se representa como un cuadrado negro con una
línea blanca vertical en el medio (es una matriz de 7 × 7 llena de 0 excepto la columna central,
que está llena de 1); las neuronas que usen estos pesos ignorarán todo en su campo receptivo
excepto la línea vertical central (ya que todas las entradas se multiplicarán por 0, excepto las
ubicadas en la línea vertical central). El segundo filtro es un cuadrado negro con una línea
blanca horizontal en el medio. Una vez más, las neuronas que utilizan estos pesos ignorarán
todo en su campo receptivo excepto la línea horizontal central.

Ahora, si todas las neuronas en una capa usan el mismo filtro de línea vertical (y el mismo término de
sesgo), y alimenta la red con la imagen de entrada que se muestra enFigura 14-5(imagen inferior), la
capa generará la imagen superior izquierda. Observe que las líneas blancas verticales se realzan
mientras que el resto se vuelve borroso. De manera similar, la imagen superior derecha es lo que
obtienes si todas las neuronas usan el mismo filtro de línea horizontal; observe que las líneas blancas
horizontales se realzan mientras que el resto se difumina. Por lo tanto, una capa llena de neuronas
que usa el mismo filtro genera unamapa de características, que resalta las áreas de una imagen que
más activan el filtro. Por supuesto, no tiene que definir los filtros manualmente: en cambio, durante el
entrenamiento, la capa convolucional aprenderá automáticamente los filtros más útiles para su tarea,
y las capas superiores aprenderán a combinarlos en patrones más complejos.

436 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
Figura 14-5. Aplicar dos filtros diferentes para obtener dos mapas de características

Apilamiento de múltiples mapas de características

Hasta ahora, para simplificar, he representado la salida de cada capa convolucional como una capa 2D
delgada, pero en realidad una capa convolucional tiene varios filtros (usted decide cuántos) y genera un mapa
de características por filtro, por lo que es representado con mayor precisión en 3D (verFigura 14-6). Para
hacerlo, tiene una neurona por píxel en cada mapa de funciones, y todas las neuronas dentro de un mapa de
funciones determinado comparten los mismos parámetros (es decir, los mismos términos de ponderación y
sesgo). Sin embargo, las neuronas en diferentes mapas de características usan diferentes parámetros. El
campo receptivo de una neurona es el mismo que se describió anteriormente, pero se extiende a lo largo de
todos los mapas de características de las capas anteriores. En resumen, una capa convolucional aplica
simultáneamente múltiples filtros entrenables a sus entradas, lo que la hace capaz de detectar múltiples
características en cualquier parte de sus entradas.

El hecho de que todas las neuronas en un mapa de características compartan


los mismos parámetros reduce drásticamente la cantidad de parámetros en el
modelo. Además, una vez que la CNN ha aprendido a reconocer un patrón en
un lugar, puede reconocerlo en cualquier otro lugar. Por el contrario, una vez
que un DNN regular ha aprendido a reconocer un patrón en una ubicación,
solo puede reconocerlo en esa ubicación en particular.

Además, las imágenes de entrada también se componen de varias subcapas: una porcanal de color.
Por lo general, hay tres: rojo, verde y azul (RGB). Las imágenes en escala de grises acaban de

Capa convolucional | 437


un canal, pero algunas imágenes pueden tener mucho más, por ejemplo, imágenes satelitales que
capturan frecuencias de luz adicionales (como el infrarrojo).

Figura 14-6. Capas de convolución con múltiples mapas de características e imágenes con tres canales de
color

Concretamente, una neurona situada en filai, columnajdel mapa de característicasken una capa
convolucional dadayoestá conectado a las salidas de las neuronas en la capa anterioryo–1,
ubicado en filasi×shai×sh+Fh–1 y columnasj×swaj×sw+Fw–1, en todos los mapas de características
(en capayo–1). Tenga en cuenta que todas las neuronas ubicadas en la misma filaiy columnaj
pero en diferentes mapas de características están conectados a las salidas de las mismas
neuronas en la capa anterior.

Ecuación 14-1resume las explicaciones anteriores en una gran ecuación matemática:


muestra cómo calcular la salida de una neurona dada en una capa convolucional.

438 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
Es un poco feo debido a todos los diferentes índices, pero todo lo que hace es calcular la suma ponderada de
todas las entradas, más el término de sesgo.

Ecuación 14-1. Cálculo de la salida de una neurona en una capa convolucional

fh−1 F −1
adelante−1
i′ =i×sh+uj′ =j
zi,j,k=bk+∑ ∑ ∑X
norte′

i′,j′,k′
. wtu,v,k′,k con
tu=0 v=0 k′ =0 ×sw+v

• zyo, j, kes la salida de la neurona ubicada en la filai, columnajen el mapa de característicaskde la


capa convolucional (capayo).

• Como se explicó anteriormente,shyswson los pasos verticales y horizontales,FhyFwson la


altura y la anchura del campo receptivo, yFnorte′es el número de mapas de características en
la capa anterior (capayo–1).

• Xi′,j′,k′es la salida de la neurona ubicada en la capayo–1, filai′,columnaj′,mapa de


característicask′ (o canalk′si la capa anterior es la capa de entrada).
• bkes el término de sesgo para el mapa de característicask(en capayo). Puede pensar en él como una
perilla que ajusta el brillo general del mapa de característicask.

• wtu,v,k′,kes el peso de conexión entre cualquier neurona en el mapa de característicaskde la capa yoy su
entrada ubicada en la filatu, columnav(en relación con el campo receptivo de la neurona), y el mapa de
característicask′.

Implementación de TensorFlow

En TensorFlow, cada imagen de entrada generalmente se representa como un tensor 3D


deforma [alto, ancho, canales].Un mini-lote se representa como un tensor 4D deforma
[tamaño del mini lote, altura, ancho, canales].Los pesos de una convolucional
capa se representan como un tensor 4D de forma [Fh,Fw,Fnorte′,Fnorte]. Los términos de sesgo de una capa
convolucional se representan simplemente como un tensor 1D de forma [Fnorte].

Veamos un ejemplo sencillo. El siguiente código carga dos imágenes de muestra, usando Scikit-
Learn'scargar_imágenes_de_muestra() (que carga dos imágenes en color, una de un templo chino
y otra de una flor). Las intensidades de píxeles (para cada canal de color) se representan como
un byte de 0 a 255, por lo que escalamos estas características simplemente dividiéndolas por
255, para obtener valores flotantes que van de 0 a 1. Luego creamos dos filtros de 7 × 7 (uno
con una línea blanca vertical en el medio, y la otra con una línea blanca horizontal en el medio),
y las aplicamos a ambas imágenes usando eltf.nn.conv2d()función, que forma parte de la API de
aprendizaje profundo de bajo nivel de TensorFlow. En este ejemplo, usamos cero relleno (relleno
= "MISMO")y un paso de2.Finalmente, trazamos uno de los mapas de características resultantes
(similar a la imagen superior derecha enFigura 14-5).

Capa convolucional | 439


desklearn.conjuntos de datosimportarcargar_imagen_de_muestra

# Cargar imágenes de muestra


China=cargar_imagen_de_muestra("china.jpg")/255 flor=
cargar_imagen_de_muestra("flor.jpg")/255 imágenes=
notario público.formación([China,flor])
tamaño del lote,altura,ancho,canales=imágenes.forma

# Crear 2 filtros
filtros=notario público.ceros(forma=(7,7,canales,2),tipo de d=notario
# linea
público.flotar32) filtros[:,3, :,0]=1 vertical:, :,1]=1
filtros[3,
# linea horizontal

salidas=t.f..nn.conv2d(imágenes,filtros,zancadas=1,relleno="MISMO")

por favor.immostrar(salidas[0, :, :,1],cmap="gris")#trazar el segundo mapa de características de la primera imagen por favor.
mostrar()

La mayor parte de este código se explica por sí mismo, pero eltf.nn.conv2d()línea merece un poco de
explicación:

• imágeneses el mini lote de entrada (un tensor 4D, como se explicó anteriormente).

• filtroses el conjunto de filtros a aplicar (también un tensor 4D, como se explicó anteriormente).

• zancadases igual a 1, pero también podría ser una matriz 1D con 4 elementos, donde los dos
elementos centrales son los pasos verticales y horizontales (shysw). El primer y el último elemento
deben ser actualmente iguales a 1. Es posible que algún día se utilicen para especificar una
zancada por lotes (para omitir algunas instancias) y una zancada de canal (para omitir algunos de
los mapas de características o canales de la capa anterior).

• rellenodebe ser "VÁLIDO"o "MISMO":


— Si se establece en "VÁLIDO",la capa convolucional hacenouse cero relleno, y puede
ignorar algunas filas y columnas en la parte inferior y derecha de la imagen de entrada,
según el paso, como se muestra enFigura 14-7(Para simplificar, aquí solo se muestra la
dimensión horizontal, pero, por supuesto, la misma lógica se aplica a la dimensión
vertical).

— Si se establece en "MISMO",la capa convolucional usa cero relleno si es necesario. En este caso,
el número de neuronas de salida es igual al número de neuronas de entrada dividido por la
zancada, redondeado al alza (en este ejemplo, 13/5 = 2,6, redondeado a 3). Luego, se agregan
ceros de la manera más uniforme posible alrededor de las entradas.

440 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
Figura 14-7. Opciones de relleno: ancho de entrada: 13, ancho de filtro: 6, zancada: 5

En este ejemplo, definimos manualmente los filtros, pero en una CNN real normalmente definiría los
filtros como variables entrenables, de modo que la red neuronal pueda aprender qué filtros funcionan
mejor, como se explicó anteriormente. Sin embargo, en lugar de crear manualmente las variables,
simplemente puede usar elkeras.layers.Conv2Dcapa:

conversión=queras.capas.Conv2D(filtros=32,kernel_size=3,zancadas=1,
relleno="MISMO",activación="relu")

Este código crea unConv2Dcapa con 32 filtros, cada uno de 3 × 3, utilizando un paso de 1 (tanto
horizontal como verticalmente), el MISMO relleno, y aplicando la función de activación ReLU a
sus salidas. Como puede ver, las capas convolucionales tienen bastantes hiperparámetros: debe
elegir la cantidad de filtros, su altura y ancho, los pasos y el tipo de relleno. Como siempre,
puede usar la validación cruzada para encontrar los valores de hiperparámetro correctos, pero
esto lleva mucho tiempo. Discutiremos las arquitecturas comunes de CNN más adelante, para
darle una idea de qué valores de hiperparámetros funcionan mejor en la práctica.

Requisitos de memoria
Otro problema con las CNN es que las capas convolucionales requieren una gran cantidad de RAM.
Esto es especialmente cierto durante el entrenamiento, porque el pase inverso de la propagación
hacia atrás requiere todos los valores intermedios calculados durante el pase hacia adelante.

Por ejemplo, considere una capa convolucional con filtros de 5 × 5, generando 200 mapas de
características de tamaño 150 × 100, con paso 1 y el MISMO relleno. Si la entrada es un 150 × 100

Capa convolucional | 441


Imagen RGB (tres canales), entonces el número de parámetros es (5 × 5 × 3 + 1) × 200 = 15,200 (el +1
corresponde a los términos de sesgo), que es bastante pequeño en comparación con una capa
completamente conectada.7Sin embargo, cada uno de los 200 mapas de características contiene 150 ×
100 neuronas, y cada una de estas neuronas necesita calcular una suma ponderada de sus 5 × 5 × 3 =
75 entradas: eso es un total de 225 millones de multiplicaciones flotantes. No es tan malo como una
capa totalmente conectada, pero sigue siendo bastante intensivo desde el punto de vista
computacional. Además, si los mapas de características se representan mediante flotantes de 32 bits,
la salida de la capa convolucional ocupará 200 × 150 × 100 × 32 = 96 millones de bits (12 MB) de RAM.8
¡Y eso es solo por un ejemplo! Si un lote de entrenamiento contiene 100 instancias, ¡esta capa
consumirá 1,2 GB de RAM!

Durante la inferencia (es decir, al hacer una predicción para una nueva instancia), la RAM ocupada por
una capa puede liberarse tan pronto como se haya calculado la siguiente capa, por lo que solo
necesita la RAM requerida por dos capas consecutivas. Pero durante el entrenamiento, todo lo
calculado durante el paso hacia adelante debe conservarse para el paso hacia atrás, por lo que la
cantidad de RAM necesaria es (al menos) la cantidad total de RAM requerida por todas las capas.

Si el entrenamiento falla debido a un error de falta de memoria, puede intentar


reducir el tamaño del mini lote. Alternativamente, puede intentar reducir la
dimensionalidad con un paso o eliminar algunas capas. O puede intentar usar
flotantes de 16 bits en lugar de flotantes de 32 bits. O podría distribuir la CNN
a través de múltiples dispositivos.

Ahora veamos el segundo bloque de construcción común de las CNN: elcapa de agrupación.

Capa de agrupación

Una vez que comprende cómo funcionan las capas convolucionales, las capas de agrupación
son bastante fáciles de entender. Su objetivo essubmuestra(es decir, reducir) la imagen de
entrada para reducir la carga computacional, el uso de memoria y el número de parámetros
(limitando así el riesgo de sobreajuste).

Al igual que en las capas convolucionales, cada neurona en una capa de agrupación está conectada a
las salidas de un número limitado de neuronas en la capa anterior, ubicada dentro de un pequeño
campo receptivo rectangular. Debes definir su tamaño, la zancada y el tipo de relleno, como antes. Sin
embargo, una neurona agrupada no tiene pesos; todo lo que hace es agregar las entradas usando
una función de agregación como el máximo o la media.Figura 14-8muestra una capa de agrupación
máxima, que es el tipo más común de capa de agrupación. En este ejemplo,

7 Una capa completamente conectada con 150 × 100 neuronas, cada una conectada a las 150 × 100 × 3 entradas, tendría 1502
× 1002× 3 = 675 millones de parámetros!

8 En el sistema internacional de unidades (SI), 1 MB = 1000 kB = 1000 × 1000 bytes = 1000 × 1000 × 8 bits.

442 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
usamos un _kernel de agrupación_ 2 × 29, con zancada de 2, y sin relleno. Solo el valor de entrada
máximo en cada campo receptivo pasa a la siguiente capa, mientras que las otras entradas se
eliminan. Por ejemplo, en el campo receptivo inferior izquierdo enFigura 14-8, los valores de entrada
son 1, 5, 3, 2, por lo que solo el valor máximo, 5, se propaga a la siguiente capa. Debido al paso de 2, la
imagen de salida tiene la mitad de la altura y la mitad del ancho de la imagen de entrada (redondeado
hacia abajo ya que no usamos relleno).

Figura 14-8. Capa de agrupación máxima (núcleo de agrupación 2 × 2, zancada 2, sin relleno)

Una capa de agrupación normalmente funciona en cada canal de entrada de forma independiente,

por lo que la profundidad de salida es la misma que la profundidad de entrada.

Además de reducir los cálculos, el uso de la memoria y la cantidad de parámetros, una


capa de agrupación máxima también introduce cierto nivel deinvarianciaa pequeñas
traducciones, como se muestra enFigura 14-9. Aquí asumimos que los píxeles brillantes
tienen un valor más bajo que los píxeles oscuros, y consideramos 3 imágenes (A, B, C)
pasando por una capa de agrupación máxima con un núcleo de 2 × 2 y zancada 2. Las
imágenes B y C son iguales como la imagen A, pero desplazada uno y dos píxeles a la
derecha. Como puede ver, las salidas de la capa de agrupación máxima para las imágenes
A y B son idénticas. Esto es lo que significa la invariancia de traducción. Sin embargo, para
la imagen C, la salida es diferente: se desplaza un píxel hacia la derecha (pero todavía hay
una invariancia del 75 %). Al insertar una capa de agrupación máxima cada pocas capas en
una CNN, es posible obtener cierto nivel de invariancia de traducción a mayor escala.
Además, la agrupación máxima también ofrece una pequeña cantidad de invariancia
rotacional y una ligera invariancia de escala.

9 Otros kernels que discutimos hasta ahora tenían pesos, pero los kernels pooling no los tienen: son simplemente win‐ deslizantes sin estado.

bajas

Capa de agrupación | 443


Figura 14-9. Invariancia a pequeñas traslaciones

Pero la agrupación máxima tiene algunas desventajas: en primer lugar, obviamente es muy
destructiva: incluso con un kernel diminuto de 2 × 2 y un paso de 2, la salida será dos veces menor en
ambas direcciones (por lo que su área será cuatro veces menor), simplemente dejando caer el 75% de
los valores de entrada. Y en algunas aplicaciones, la invariancia no es deseable, por ejemplo para
segmentación semántica: esta es la tarea de clasificar cada píxel en una imagen según el objeto al que
pertenece ese píxel: obviamente, si la imagen de entrada se traslada 1 píxel a la derecha, la salida
también debe trasladarse 1 píxel a la derecha. El objetivo en este caso esequivalencia, no invariancia:
un pequeño cambio en las entradas debería conducir a un pequeño cambio correspondiente en la
salida.

Implementación de TensorFlow

Implementar una capa de agrupación máxima en TensorFlow es bastante fácil. El siguiente código crea una capa de
agrupación máxima utilizando un kernel de 2 × 2. Los pasos predeterminados son del tamaño del kernel, por lo que
esta capa usará un paso de 2 (tanto horizontal como verticalmente). De forma predeterminada, utiliza relleno VÁLIDO
(es decir, sin ningún tipo de relleno):

max_pool=queras.capas.MaxPool2D(tamaño de la piscina=2)

Para crear uncapa de agrupación promedio, Solo usaPromedioGrupo2Den vez deMaxPool2D.Como era de
esperar, funciona exactamente como una capa de agrupación máxima, excepto que calcula la media en lugar
del máximo. Las capas de agrupación promedio solían ser muy populares, pero la gente

444 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
En su mayoría, use capas de agrupación máximas ahora, ya que generalmente funcionan mejor. Esto puede
parecer sorprendente, ya que al calcular la media generalmente se pierde menos información que al calcular
el máximo. Pero, por otro lado, la agrupación máxima conserva solo la característica más fuerte, eliminando
todas las que no tienen sentido, por lo que las siguientes capas obtienen una señal más limpia para trabajar.
Además, la agrupación máxima ofrece una invariancia de traducción más fuerte que la agrupación promedio.

Tenga en cuenta que la agrupación máxima y la agrupación promedio se pueden realizar a lo largo de
la dimensión de profundidad en lugar de las dimensiones espaciales, aunque esto no es tan común.
Esto puede permitir que la CNN aprenda a ser invariable a varias características. Por ejemplo, podría
aprender múltiples filtros, cada uno detectando una rotación diferente del mismo patrón, como
dígitos escritos a mano (verFigura 14-10), y la capa de agrupación máxima en profundidad garantizaría
que la salida sea la misma independientemente de la rotación. De manera similar, la CNN podría
aprender a ser invariable a cualquier otra cosa: grosor, brillo, sesgo, color, etc.

Figura 14-10. La agrupación máxima en profundidad puede ayudar a la CNN a aprender cualquier invariancia

Capa de agrupación | 445


Keras no incluye una capa de agrupación máxima en profundidad, pero la API de aprendizaje
profundo de bajo nivel de TensorFlow sí: solo use eltf.nn.max_pool()y especifique el tamaño del núcleo
y los pasos como 4 tuplas. Los tres primeros valores de cada uno deben ser 1: esto indica que el
tamaño del grano y la zancada a lo largo de las dimensiones del lote, la altura y el ancho deben ser 1.
El último valor debe ser el tamaño del grano y la zancada que desee a lo largo de la dimensión de
profundidad, para ejemplo 3 (este debe ser un divisor de la profundidad de entrada; por ejemplo, no
funcionará si la capa anterior genera 20 mapas de características, ya que 20 no es un múltiplo de 3):

producción=t.f..nn.max_pool(imágenes,
ktamaño=(1,1,1,3),
zancadas=(1,1,1,3),
relleno="VÁLIDO")

Si desea incluir esto como una capa en sus modelos Keras, simplemente puede envolverlo en un
lambdacapa (o cree una capa Keras personalizada):

piscina_de_profundidad=queras.capas.lambda(
lambdaX:t.f..nn.max_pool(X,ktamaño=(1,1,1,3),zancadas=(1,1,1,3),
relleno="VÁLIDO"))

Un último tipo de capa de agrupación que verá con frecuencia en las arquitecturas modernas es la agrupación
promedio globalcapa. Funciona de manera muy diferente: todo lo que hace es calcular la media de cada mapa de
características completo (es como una capa de agrupación promedio que utiliza un núcleo de agrupación con las
mismas dimensiones espaciales que las entradas). Esto significa que solo genera un solo número por mapa de
características y por instancia. Aunque, por supuesto, esto es extremadamente destructivo (la mayor parte de la
información en el mapa de características se pierde), puede ser útil como capa de salida, como veremos más adelante
en este capítulo. Para crear una capa de este tipo, simplemente use el

keras.layers.GlobalAvgPool2Dclase:
global_avg_pool=queras.capas.GlobalAvgPool2D()

En realidad es equivalente a este simplelambácapa, que calcula la media sobre las


dimensiones espaciales (alto y ancho):
global_avg_pool=queras.capas.lambda(lambdaX:t.f..reducir_media(X,eje=[1,2]))

Ahora conoce todos los componentes básicos para crear una red neuronal convolucional.
Veamos cómo ensamblarlos.

Arquitecturas CNN
Las arquitecturas CNN típicas apilan algunas capas convolucionales (cada una generalmente seguida
por una capa ReLU), luego una capa de agrupación, luego otras pocas capas convolucionales (+ReLU),
luego otra capa de agrupación, y así sucesivamente. La imagen se vuelve más y más pequeña a
medida que avanza a través de la red, pero también se vuelve más y más profunda (es decir, con más
mapas de características) gracias a las capas convolucionales (verFigura 14-11). En la parte superior de
la pila, se agrega una red neuronal feedforward regular, compuesta por unos pocos

446 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
capas completamente conectadas (+ReLUs), y la capa final genera la predicción (por ejemplo, una capa
softmax que genera probabilidades de clase estimadas).

Figura 14-11. Arquitectura típica de CNN

Un error común es usar núcleos de convolución que son demasiado


grandes. Por ejemplo, en lugar de usar una capa convolucional con un
kernel de 5 × 5, generalmente es preferible apilar dos capas con kernels
de 3 × 3: usará menos parámetros y requerirá menos cálculos, y por lo
general funcionará mejor. Una excepción a esta recomendación es la
primera capa convolucional: normalmente puede tener un núcleo grande
(p. ej., 5 × 5), normalmente con zancadas de 2 o más: esto reducirá la
dimensión espacial de la imagen sin perder demasiado información, y
dado que la imagen de entrada solo tiene 3 canales en general, no será
demasiado costoso.

Así es como puede implementar una CNN simple para abordar el conjunto de datos MNIST de la moda
(presentado enCapítulo 10):

deherramientas funcionalesimportarparcial

DefaultConv2D=parcial(queras.capas.Conv2D,
kernel_size=3,activación='relú',relleno="MISMO")

modelo=queras.modelos.Secuencial([
DefaultConv2D(filtros=64,kernel_size=7,entrada_forma=[28,28,1]), queras.
capas.MaxPooling2D(tamaño de la piscina=2), DefaultConv2D(filtros=128),
DefaultConv2D(filtros=128),

queras.capas.MaxPooling2D(tamaño de la
piscina=2), DefaultConv2D(filtros=256),
DefaultConv2D(filtros=256),
queras.capas.MaxPooling2D(tamaño de la piscina=
2), queras.capas.Aplanar(),
queras.capas.Denso(unidades=128,activación='relú'),
queras.capas.Abandonar(0.5),
queras.capas.Denso(unidades=64,activación='relú'),
queras.capas.Abandonar(0.5),
queras.capas.Denso(unidades=10,activación='softmax'),
])

CNN Arquitecturas | 447


• En este código, comenzamos usando elparcial()función para definir una envoltura delgada
alrededor de laConv2Dclase, llamadoDefaultConv2D:simplemente evita tener que repetir los
mismos valores de hiperparámetro una y otra vez.

• La primera capa utiliza un tamaño de kernel grande, pero no avanza porque las imágenes de entrada no
son muy grandes. también estableceentrada_forma=[28, 28, 1],lo que significa que las imágenes son de
28 × 28 píxeles, con un solo canal de color (es decir, escala de grises).

• A continuación, tenemos una capa de agrupación máxima, que divide cada dimensión espacial por un
factor de dos (ya quepiscina_tamaño=2).

• Luego repetimos la misma estructura dos veces: dos capas convolucionales seguidas de una capa de
agrupación máxima. Para imágenes más grandes, podríamos repetir esta estructura varias veces (el
número de repeticiones es un hiperparámetro que puede ajustar).

• Tenga en cuenta que el número de filtros crece a medida que subimos por la CNN hacia la capa de
salida (inicialmente es 64, luego 128, luego 256): tiene sentido que crezca, ya que el número de
funciones de bajo nivel suele ser menor. bastante bajo (p. ej., círculos pequeños, líneas
horizontales, etc.), pero hay muchas maneras diferentes de combinarlos en funciones de nivel
superior. Es una práctica común duplicar la cantidad de filtros después de cada capa de
agrupación: dado que una capa de agrupación divide cada dimensión espacial por un factor de 2,
podemos permitirnos duplicar la cantidad de mapas de características en la siguiente capa, sin
temor a explotar. el número de parámetros, uso de memoria o carga computacional.

• Lo siguiente es la red totalmente conectada, compuesta por 2 capas densas ocultas y una capa de salida
densa. Tenga en cuenta que debemos aplanar sus entradas, ya que una red densa espera una matriz 1D
de funciones para cada instancia. También agregamos dos capas de abandono, con una tasa de
abandono del 50 % cada una, para reducir el sobreajuste.

Esta CNN alcanza más del 92 % de precisión en el conjunto de prueba. No es lo último en tecnología,
pero es bastante bueno y claramente mucho mejor que lo que logramos con redes densas en Capítulo
10.

A lo largo de los años, se han desarrollado variantes de esta arquitectura fundamental, lo que ha dado lugar a
avances sorprendentes en este campo. Una buena medida de este progreso es la tasa de error en
competencias como la ILSVRC.Desafío ImageNet. En esta competencia, la tasa de error de los 5 primeros en la
clasificación de imágenes cayó de más del 26 % a menos del 2,3 % en solo seis años. La tasa de error de los
cinco primeros es el número de imágenes de prueba para las cuales las cinco predicciones principales del
sistema no incluyeron la respuesta correcta. Las imágenes son grandes (256 píxeles de alto) y hay 1.000
clases, algunas de las cuales son realmente sutiles (intenta distinguir 120 razas de perros). Observar la
evolución de las entradas ganadoras es una buena manera de entender cómo funcionan las CNN.

Primero veremos la arquitectura clásica LeNet-5 (1998), luego tres de los


ganadores del desafío ILSVRC: AlexNet (2012), GoogLeNet (2014) y ResNet
(2015).

448 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
LeNet-5
losArquitectura LeNet-510es quizás la arquitectura CNN más conocida. Como se mencionó
anteriormente, fue creado por Yann LeCun en 1998 y se usa ampliamente para el reconocimiento de
dígitos escritos a mano (MNIST). Está compuesto por las capas que se muestran enTabla 14-1.

Tabla 14-1. Arquitectura LeNet-5

Capa Escribe mapas Tamaño Tamaño del núcleo Paso Activación


Afuera Totalmente conectado – 10 – – FBR
F6 Totalmente conectado – 84 – – bronceado

C5 Circunvolución 120 1×1 5×5 1 bronceado

S4 Agrupación promedio dieciséis 5×5 2×2 2 bronceado

C3 Circunvolución dieciséis 10 × 10 5×5 1 bronceado

S2 Agrupación promedio 6 14 × 14 2×2 2 bronceado

C1 Circunvolución 6 28 × 28 5×5 1 bronceado

En Aporte 1 32 × 32 – – –

Hay algunos detalles adicionales a tener en cuenta:

• Las imágenes MNIST tienen 28 × 28 píxeles, pero se rellenan con ceros a 32 × 32


píxeles y se normalizan antes de enviarse a la red. El resto de la red no utiliza
ningún relleno, por lo que el tamaño sigue reduciéndose a medida que la imagen
avanza por la red.
• Las capas de agrupación promedio son un poco más complejas de lo normal: cada neurona calcula
la media de sus entradas, luego multiplica el resultado por un coeficiente aprendible (uno por
mapa) y agrega un término de sesgo aprendible (nuevamente, uno por mapa), luego finalmente
aplica la función de activación.

• La mayoría de las neuronas en los mapas C3 están conectadas a neuronas en solo tres o cuatro
mapas S2 (en lugar de los seis mapas S2). Ver tabla 1 (página 8) en el artículo original10para
detalles.

• La capa de salida es un poco especial: en lugar de calcular la multiplicación matricial de las


entradas y el vector de peso, cada neurona genera el cuadrado de la distancia euclidiana
entre su vector de entrada y su vector de peso. Cada salida mide cuánto pertenece la
imagen a una clase de dígito particular. Ahora se prefiere la función de costo de entropía
cruzada, ya que penaliza mucho más las malas predicciones, produciendo gradientes más
grandes y convergiendo más rápido.

10 “Aprendizaje basado en gradientes aplicado al reconocimiento de documentos”, Y. LeCun, L. Bottou, Y. Bengio y P. Haffner
(1998).

CNN Arquitecturas | 449


Yann Le Cunsitio web(sección “LENET”) presenta excelentes demostraciones de los dígitos de clasificación de LeNet-5.

AlexNet
losAlexNetarquitectura CNN11ganó el desafío ImageNet ILSVRC de 2012 por un amplio margen:
¡logró una tasa de error del 17 % entre los 5 primeros, mientras que el segundo mejor logró
solo el 26 %! Fue desarrollado por Alex Krizhevsky (de ahí el nombre), Ilya Sutskever y Geoffrey
Hinton. Es bastante similar a LeNet-5, solo que mucho más grande y profundo, y fue el primero
en apilar capas convolucionales directamente una encima de la otra, en lugar de apilar una capa
de agrupación encima de cada capa convolucional.Tabla 14-2presenta esta arquitectura.

Tabla 14-2. Arquitectura de AlexNet

Capa Escribe mapas Tamaño Tamaño del núcleo Paso Relleno Activación

Afuera Totalmente conectado – 1,000 – – – softmax

F9 Totalmente conectado – 4,096 – – – ReLU


F8 Totalmente conectado – 4,096 – – – ReLU
C7 Circunvolución 256 13 × 13 3×3 1 MISMO ReLU
C6 Circunvolución 384 13 × 13 3×3 1 MISMO ReLU
C5 Circunvolución 384 13 × 13 3×3 1 MISMO ReLU
S4 Agrupación máxima 256 13 × 13 3×3 2 VÁLIDO –
C3 Circunvolución 256 27 × 27 5×5 1 MISMO ReLU
S2 Agrupación máxima 96 27 × 27 3×3 2 VÁLIDO –
C1 Circunvolución 96 55 × 55 11 × 11 4 VÁLIDO ReLU
En Aporte 3 (RGB) 227 × 227 – – – –

Para reducir el sobreajuste, los autores utilizaron dos técnicas de regularización: primero aplicaron abandono
(introducido enCapítulo 11) con una tasa de abandono del 50% durante el entrenamiento a las salidas de las
capas F8 y F9. En segundo lugar, realizaronaumento de datoscambiando aleatoriamente las imágenes de
entrenamiento en varios desplazamientos, volteándolas horizontalmente y cambiando las condiciones de
iluminación.

Aumento de datos
El aumento de datos aumenta artificialmente el tamaño del conjunto de entrenamiento al generar muchas
variantes realistas de cada instancia de entrenamiento. Esto reduce el sobreajuste, convirtiéndose en una técnica
de regularización. Las instancias generadas deben ser lo más realistas posible:

11 “Clasificación de ImageNet con redes neuronales convolucionales profundas”, A. Krizhevsky et al. (2012).

450 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
idealmente, dada una imagen del conjunto de entrenamiento aumentado, un ser humano no debería
poder saber si fue aumentado o no. Además, simplemente agregar ruido blanco no ayudará; las
modificaciones deben poder aprenderse (el ruido blanco no lo es).

Por ejemplo, puede desplazar, rotar y cambiar ligeramente el tamaño de cada imagen del conjunto de
entrenamiento en varias cantidades y agregar las imágenes resultantes al conjunto de entrenamiento
(consulte Figura 14-12). Esto obliga al modelo a ser más tolerante a las variaciones en la posición,
orientación y tamaño de los objetos en las imágenes. Si desea que el modelo sea más tolerante a
diferentes condiciones de iluminación, puede generar de manera similar muchas imágenes con varios
contrastes. En general, también puede voltear las imágenes horizontalmente (excepto el texto y otros
objetos no simétricos). Al combinar estas transformaciones, puede aumentar considerablemente el
tamaño de su conjunto de entrenamiento.

Figura 14-12. Generar nuevas instancias de entrenamiento a partir de las existentes

AlexNet también usa un paso de normalización competitivo inmediatamente después del paso
ReLU de las capas C1 y C3, llamadonormalización de la respuesta local. Las neuronas más
fuertemente activadas inhiben otras neuronas ubicadas en la misma posición en mapas de
características vecinas (tal activación competitiva se ha observado en neuronas biológicas). Esto
alienta a diferentes mapas de características a especializarse, separándolos y obligándolos a

CNN Arquitecturas | 451


para explorar una gama más amplia de funciones y, en última instancia, mejorar la generalización.Ecuación
14-2muestra cómo aplicar LRN.

Ecuación 14-2. Normalización de la respuesta local

−β r
jalto jalto= min i+
, Fnorte−1
2
bi=aik+α∑ a2j con
j=jbajo r
jbajo= máx. 0,i−
2

• bies la salida normalizada de la neurona ubicada en el mapa de característicasi, en alguna filatu y


columnav(tenga en cuenta que en esta ecuación consideramos solo las neuronas ubicadas en esta fila y
columna, por lo quetuyvno se muestran).

• aies la activación de esa neurona después del paso ReLU, pero antes de la normalización.

• k,α,β, yrson hiperparámetros.kse llama elparcialidad, yrse llama elradio de


profundidad.
• Fnortees el número de mapas de características.

Por ejemplo, sir=2 y una neurona tiene una fuerte activación, inhibirá la activación de las neuronas
ubicadas en los mapas de características inmediatamente por encima y por debajo de la suya.

En AlexNet, los hiperparámetros se establecen de la siguiente manera:r=2,α= 0,00002,β=


0.75, yk = 1. Este paso se puede implementar usando eltf.nn.local_response_normaliza tion()
función (que puede envolver en unlambdacapa si quieres usarla en un modelo de Keras).

Una variante de AlexNet llamadaRed ZFfue desarrollado por Matthew Zeiler y Rob Fergus y ganó el
desafío ILSVRC 2013. Es esencialmente AlexNet con algunos hiperparámetros modificados (número de
mapas de características, tamaño del kernel, zancada, etc.).

GoogleLeNet

losarquitectura GoogLeNetfue desarrollado por Christian Szegedy et al. de investigación de


Google,12y ganó el desafío ILSVRC 2014 al empujar la tasa de error de los 5 principales por
debajo del 7%. Este gran desempeño se debió en gran parte al hecho de que la red era mucho
más profunda que las CNN anteriores (verFigura 14-14). Esto fue posible gracias a las subredes
denominadasmódulos de inicio,13que permiten a GoogLeNet usar parámetros

12 “Profundizando con las circunvoluciones”, C. Szegedy et al. (2015).

13 En la película de 2010Comienzo, los personajes siguen profundizando más y más en múltiples capas de sueños,
de ahí el nombre de estos módulos.

452 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
mucho más eficiente que las arquitecturas anteriores: GoogLeNet en realidad tiene 10 veces menos
parámetros que AlexNet (aproximadamente 6 millones en lugar de 60 millones).

Figura 14-13muestra la arquitectura de un módulo de inicio. La notación “3 × 3 + 1(S)” significa que la


capa utiliza un núcleo de 3 × 3, zancada 1 y el MISMO relleno. La señal de entrada se copia primero y
se envía a cuatro capas diferentes. Todas las capas convolucionales usan la función de activación
ReLU. Tenga en cuenta que el segundo conjunto de capas convolucionales utiliza diferentes tamaños
de kernel (1 × 1, 3 × 3 y 5 × 5), lo que les permite capturar patrones en diferentes escalas. También
tenga en cuenta que cada capa usa un paso de 1 y el MISMO relleno (incluso la capa de agrupación
máxima), por lo que todas sus salidas tienen la misma altura y ancho que sus entradas. Esto hace
posible concatenar todas las salidas a lo largo de la dimensión de profundidad en el finalcapa de
concat de profundidad(es decir, apilar los mapas de características de las cuatro capas convolucionales
superiores). Esta capa de concatenación se puede implementar en TensorFlow usando eltf.concat()
operación, coneje=3 (el eje 3 es la profundidad).

Figura 14-13. Módulo de inicio

Quizás se pregunte por qué los módulos de inicio tienen capas convolucionales con kernels 1 × 1.
¿Seguramente estas capas no pueden capturar ninguna característica ya que miran solo un píxel a la
vez? De hecho, estas capas sirven para tres propósitos:

• Primero, aunque no pueden capturar patrones espaciales, pueden capturar patrones a lo largo de
la dimensión de profundidad.

• En segundo lugar, están configurados para generar menos mapas de características que sus entradas,
por lo que sirven comocapas de cuello de botella, lo que significa que reducen la dimensionalidad. Esto
reduce el costo computacional y la cantidad de parámetros, acelerando el entrenamiento y mejorando
la generalización.

• Por último, cada par de capas convolucionales ([1 × 1, 3 × 3] y [1 × 1, 5 × 5]) actúa como una
capa convolucional única y poderosa, capaz de capturar patrones más complejos. De
hecho, en lugar de barrer un clasificador lineal simple a través de la imagen (como un

CNN Arquitecturas | 453


una sola capa convolucional lo hace), este par de capas convolucionales barre una red neuronal
de dos capas a través de la imagen.

En resumen, puede pensar en todo el módulo de inicio como una capa convolucional con esteroides,
capaz de generar mapas de características que capturan patrones complejos en varias escalas.

El número de núcleos convolucionales para cada capa convolucional es un


hiperparámetro. Desafortunadamente, esto significa que tiene seis
hiperparámetros más para ajustar por cada capa de inicio que agregue.

Ahora veamos la arquitectura de GoogLeNet CNN (verFigura 14-14). El número de mapas de


características generados por cada capa convolucional y cada capa de agrupación se muestra
antes del tamaño del núcleo. La arquitectura es tan profunda que debe representarse en tres
columnas, pero GoogLeNet es en realidad una pila alta, que incluye nueve módulos iniciales (las
cajas con los trompos). Los seis números en los módulos de inicio representan el número de
mapas de características generados por cada capa convolucional en el módulo (en el mismo
orden que enFigura 14-13). Tenga en cuenta que todas las capas convolucionales utilizan la
función de activación de ReLU.

454 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
Figura 14-14. arquitectura GoogLeNet

Pasemos por esta red:

• Las dos primeras capas dividen la altura y el ancho de la imagen por 4 (por lo que su área se divide por
16), para reducir la carga computacional. La primera capa utiliza un tamaño de núcleo grande, por lo
que aún se conserva gran parte de la información.

• Luego, la capa de normalización de respuesta local asegura que las capas anteriores aprendan una amplia
variedad de características (como se discutió anteriormente).

• Siguen dos capas convolucionales, donde la primera actúa como uncapa de cuello de botella. Como se
explicó anteriormente, puede pensar en este par como una única capa convolucional más inteligente.

• Nuevamente, una capa de normalización de respuesta local asegura que las capas anteriores capturen
una amplia variedad de patrones.

CNN Arquitecturas | 455


• A continuación, una capa de agrupación máxima reduce la altura y el ancho de la imagen en 2, de nuevo para
acelerar los cálculos.

• Luego viene la pila alta de nueve módulos de inicio, intercalados con un par de capas de
agrupación máxima para reducir la dimensionalidad y acelerar la red.

• A continuación, la capa de agrupación de promedio global simplemente genera la media de cada


mapa de características: esto descarta cualquier información espacial restante, lo cual está bien
ya que no quedaba mucha información espacial en ese punto. De hecho, normalmente se espera
que las imágenes de entrada de GoogLeNet tengan 224 × 224 píxeles, por lo que después de un
máximo de 5 capas de agrupación, cada una dividiendo la altura y el ancho por 2, los mapas de
características se reducen a 7 × 7. Además, es una tarea de clasificación. , no localización, por lo
que no importa dónde esté el objeto. Gracias a la reducción de dimensionalidad que aporta esta
capa, no es necesario tener varias capas totalmente conectadas en la parte superior de la CNN
(como en AlexNet), y esto reduce considerablemente el número de parámetros en la red y limita
el riesgo de sobreajuste

• Las últimas capas se explican por sí mismas: abandono para la regularización, luego una capa
completamente conectada con 1000 unidades, ya que hay 1000 clases, y una función de
activación softmax para generar probabilidades de clase estimadas.

Este diagrama está ligeramente simplificado: la arquitectura original de GoogLeNet también incluía
dos clasificadores auxiliares conectados en la parte superior de los módulos de inicio tercero y sexto.
Ambos estaban compuestos por una capa de agrupación promedio, una capa convolucional, dos
capas completamente conectadas y una capa de activación softmax. Durante el entrenamiento, su
pérdida (reducida en un 70%) se agregó a la pérdida total. El objetivo era combatir el problema de los
gradientes que desaparecen y regularizar la red. Sin embargo, más tarde se demostró que su efecto
era relativamente menor.

Posteriormente, los investigadores de Google propusieron varias variantes de la arquitectura de


GoogLeNet, incluidas Inception-v3 e Inception-v4, utilizando módulos de inicio ligeramente
diferentes y alcanzando un rendimiento aún mejor.

VGGNet
El subcampeón del desafío ILSVRC 2014 fueVGGNet14, desarrollado por K. Simon‐yan y A.
Zisserman. Tenía una arquitectura muy simple y clásica, con 2 o 3 capas convolucionales, una
capa de agrupación, luego nuevamente 2 o 3 capas convolucionales, una capa de agrupación, y
así sucesivamente (con un total de solo 16 capas convolucionales), más una red densa final con
2 capas ocultas y la capa de salida. Usó solo filtros 3 × 3, pero muchos filtros.

14 “Redes convolucionales muy profundas para el reconocimiento de imágenes a gran escala”, K. Simonyan y A. Zisserman
(2015).

456 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
ResNet
El desafío ILSVRC 2015 se ganó usando unRed Residual(oResNet), desarrollado por Kaiming He
et al.,15que entregó una asombrosa tasa de error de los 5 primeros por debajo del 3,6%,
utilizando una CNN extremadamente profunda compuesta de 152 capas. Confirmó la tendencia
general: los modelos son cada vez más profundos, con cada vez menos parámetros. La clave
para poder entrenar una red tan profunda es usaromitir conexiones(también llamado
conexiones de acceso directo): la señal que alimenta una capa también se agrega a la salida de
una capa ubicada un poco más arriba en la pila. Veamos por qué esto es útil.

Al entrenar una red neuronal, el objetivo es hacer que modele una función objetivoh(X). Si
agregas la entradaXa la salida de la red (es decir, agrega una conexión de salto), entonces
la red se verá obligada a modelarF(X) =h(X) -Xmás bien queh(X). Se llamaaprendizaje
residual(verFigura 14-15).

Figura 14-15. aprendizaje residual

Cuando inicializa una red neuronal regular, sus pesos son cercanos a cero, por lo que la red solo
genera valores cercanos a cero. Si agrega una conexión de salto, la red resultante solo genera
una copia de sus entradas; en otras palabras, inicialmente modela la función identidad. Si la
función de destino está bastante cerca de la función de identidad (que suele ser el caso), esto
acelerará considerablemente el entrenamiento.

Además, si agrega muchas conexiones de salto, la red puede comenzar a progresar incluso si
varias capas aún no han comenzado a aprender (verFigura 14-16). Gracias a las conexiones
salteadas, la señal puede atravesar fácilmente toda la red. La red residual profunda puede verse
como una pila deunidades residuales, donde cada unidad residual es una pequeña red neuronal
con una conexión de salto.

15 “Aprendizaje residual profundo para el reconocimiento de imágenes”, K. He (2015).

CNN Arquitecturas | 457


Figura 14-16. Red neuronal profunda regular (izquierda) y red residual profunda (derecha)

Ahora veamos la arquitectura de ResNet (verFigura 14-17). En realidad, es sorprendentemente simple.


Comienza y termina exactamente como GoogLeNet (excepto sin una capa de abandono), y en el medio
hay solo una pila muy profunda de unidades residuales simples. Cada unidad residual se compone de
dos capas convolucionales (¡y ninguna capa de agrupación!), con normalización por lotes (BN) y
activación de ReLU, utilizando núcleos 3 × 3 y conservando las dimensiones espaciales (paso 1, relleno
MISMO).

Figura 14-17. arquitectura ResNet

Tenga en cuenta que la cantidad de mapas de características se duplica cada pocas unidades residuales, al
mismo tiempo que su altura y ancho se reducen a la mitad (usando una capa convolucional con paso 2).
Cuando esto sucede, las entradas no se pueden sumar directamente a las salidas de la unidad residual ya que
no tienen la misma forma (por ejemplo, este problema afecta el salto

458 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
conexión representada por la flecha discontinua enFigura 14-17). Para resolver este problema, las
entradas se pasan a través de una capa convolucional de 1 × 1 con paso 2 y el número correcto de
mapas de características de salida (verFigura 14-18).

Figura 14-18. Omitir conexión al cambiar el tamaño y la profundidad del mapa de características

ResNet-34 es ResNet con 34 capas (contando solo las capas convolucionales y la capa
completamente conectada) que contiene tres unidades residuales que generan 64 mapas de
características, 4 RU con 128 mapas, 6 RU con 256 mapas y 3 RU con 512 mapas.
Implementaremos esta arquitectura más adelante en este capítulo.

ResNets más profundas que eso, como ResNet-152, usan unidades residuales ligeramente diferentes.
En lugar de dos capas convolucionales de 3 × 3 con (digamos) 256 mapas de características, utilizan
tres capas convolucionales: primero, una capa convolucional de 1 × 1 con solo 64 mapas de
características (4 veces menos), que actúa como una capa de cuello de botella (como ya se discutió). ),
luego una capa de 3 × 3 con 64 mapas de características, y finalmente otra capa convolucional de 1 × 1
con 256 mapas de características (4 veces 64) que restaura la profundidad original. ResNet-152
contiene tres RU que generan 256 mapas, luego 8 RU con 512 mapas, 36 RU con 1024 mapas y
finalmente 3 RU con 2048 mapas.

de GoogleOrigen-v4dieciséisLa arquitectura fusionó las ideas de GoogLe‐Net y


ResNet y logró una tasa de error de cerca del 3 % entre los 5 primeros en la
clasificación de ImageNet.

Xcepción
También vale la pena señalar otra variante de la arquitectura GoogLeNet:Xcepción17
(Lo que significaInicio extremo) fue propuesta en 2016 por François Chollet (el

16 “Inception-v4, Inception-ResNet y el impacto de las conexiones residuales en el aprendizaje”, C. Szegedy et al.


(2016).
17 “Xception: aprendizaje profundo con circunvoluciones separables en profundidad”, François Chollet (2016)

CNN Arquitecturas | 459


autor de Keras), y superó significativamente a Inception-v3 en una gran tarea de visión (350
millones de imágenes y 17 000 clases). Al igual que Inception-v4, también fusiona las ideas de
GoogLeNet y ResNet, pero reemplaza los módulos de inicio con un tipo especial de capa
llamadaconvolución separable en profundidad(oconvolución separablepara abreviar18). Estas
capas se habían utilizado antes en algunas arquitecturas de CNN, pero no eran tan centrales
como en la arquitectura de Xception. Mientras que una capa convolucional regular usa filtros
que intentan capturar simultáneamente patrones espaciales (p. ej., un óvalo) y patrones de
canales cruzados (p. ej., boca + nariz + ojos = cara), una capa convolucional separable asume
firmemente que los patrones espaciales y los canales cruzados Los patrones se pueden modelar
por separado (verFigura 14-19). Por lo tanto, se compone de dos partes: la primera parte aplica
un solo filtro espacial para cada mapa de características de entrada, luego la segunda parte
busca exclusivamente patrones de canales cruzados; es solo una capa convolucional normal con
filtros 1 × 1.

Figura 14-19. Capa convolucional separable en profundidad

Dado que las capas convolucionales separables solo tienen un filtro espacial por canal de
entrada, debe evitar usarlas después de las capas que tienen muy pocos canales, como la capa
de entrada (concedido, eso es lo queFigura 14-19representa, pero es solo con fines ilustrativos).
Por esta razón, la arquitectura Xception comienza con 2 capas convolucionales regulares, pero
luego el resto de la arquitectura usa solo convoluciones separables (34 pulgadas).

18 Este nombre a veces puede ser ambiguo, ya que las circunvoluciones separables espacialmente a menudo se denominan “circunvoluciones separables”.

circunvoluciones” también.

460 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
all), más algunas capas de agrupación máxima y las capas finales habituales (una capa de agrupación
promedio global y una capa de salida densa).

Quizás se pregunte por qué Xception se considera una variante de GoogLeNet, ya que no contiene
ningún módulo de inicio. Bueno, como comentamos anteriormente, un módulo de Inception contiene
capas convolucionales con filtros 1 × 1: estos buscan exclusivamente patrones de canales cruzados.
Sin embargo, las capas de convolución que se encuentran encima de ellas son capas convolucionales
regulares que buscan patrones tanto espaciales como de canales cruzados. Entonces, puede pensar
en un módulo Inception como un intermedio entre una capa convolucional regular (que considera
patrones espaciales y patrones de canales cruzados en conjunto) y una capa convolucional separable
(que los considera por separado). En la práctica, parece que las circunvoluciones separables
generalmente funcionan mejor.

Las convoluciones separables utilizan menos parámetros, menos memoria y menos


cálculos que las capas convolucionales normales y, en general, incluso funcionan
mejor, por lo que debería considerar usarlas de forma predeterminada (excepto
después de las capas con pocos canales).

El desafío ILSVRC 2016 fue ganado por el equipo CUImage de la Universidad China de
Hong Kong. Usaron un conjunto de muchas técnicas diferentes, incluido un sofisticado
sistema de detección de objetos llamadoGBD-Net19, para lograr una tasa de error de los 5
primeros por debajo del 3 %. Aunque este resultado es sin duda impresionante, la
complejidad de la solución contrasta con la sencillez de ResNets. Además, un año después,
otra arquitectura bastante simple funcionó aún mejor, como veremos ahora.

SENet
La arquitectura ganadora del desafío ILSVRC 2017 fue laRed de compresión y excitación
(SENet)20. Esta arquitectura amplía las arquitecturas existentes, como las redes de inicio o
ResNet, y aumenta su rendimiento. ¡Esto permitió a SENet ganar la competencia con una
asombrosa tasa de error de 2.25% entre los 5 primeros! Las versiones extendidas de
Inception Networks y ResNet se denominanSE-InicioySE-ResNetrespectivamente. El
impulso proviene del hecho de que SENet agrega una pequeña red neuronal, llamada
Bloque SE, a cada unidad en la arquitectura original (es decir, cada módulo de inicio o cada
unidad residual), como se muestra enFigura 14-20.

19 “Elaboración de GBD-Net para la detección de objetos”, X. Zeng et al.

(2016). 20 “Redes de compresión y excitación”, Jie Hu et al. (2017)

CNN Arquitecturas | 461


Figura 14-20. Módulo SE-Inception (izquierda) y Unidad SE-ResNet (derecha)

Un bloque SE analiza la salida de la unidad a la que está conectado, centrándose exclusivamente en la


dimensión de profundidad (no busca ningún patrón espacial) y aprende qué características suelen
estar más activas juntas. Luego usa esta información para recalibrar los mapas de características,
como se muestra enFigura 14-21. Por ejemplo, un Bloque SE puede aprender que la boca, la nariz y los
ojos generalmente aparecen juntos en las imágenes: si ve una boca y una nariz, debe esperar ver ojos
también. Entonces, si un SE Block ve una fuerte activación en los mapas de funciones de la boca y la
nariz, pero solo una activación leve en el mapa de funciones de los ojos, aumentará el mapa de
funciones de los ojos (más precisamente, reducirá los mapas de funciones irrelevantes). Si los ojos
estaban algo confundidos con otra cosa, esta recalibración del mapa de funciones ayudará a resolver
la ambigüedad.

462 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
Figura 14-21. Un bloque SE realiza la recalibración del mapa de características

Un bloque SE se compone de solo 3 capas: una capa de agrupación promedio global, una capa densa
oculta que usa la función de activación ReLU y una capa de salida densa que usa la función de
activación sigmoide (verFigura 14-22):

Figura 14-22. Arquitectura de bloque SE

CNN Arquitecturas | 463


Como antes, la capa de agrupación promedio global calcula la activación media para cada mapa de funciones:
por ejemplo, si su entrada contiene 256 mapas de funciones, generará 256 números que representan el nivel
general de respuesta para cada filtro. La siguiente capa es donde ocurre el "apretón": esta capa tiene mucho
menos de 256 neuronas, normalmente 16 veces menos que el número de mapas de características (por
ejemplo, 16 neuronas), por lo que los 256 números se comprimen en un pequeño vector ( por ejemplo, 16
dimensiones). Esta es una representación vectorial de baja dimensión (es decir, una incrustación) de la
distribución de respuestas de características. Este paso de cuello de botella obliga al bloque SE a aprender
una representación general de las combinaciones de características (veremos este principio en acción
nuevamente cuando discutamos los codificadores automáticos en???). Finalmente, la capa de salida toma la
incrustación y genera un vector de recalibración que contiene un número por mapa de características (por
ejemplo, 256), cada uno entre 0 y 1. Los mapas de características se multiplican luego por este vector de
recalibración, por lo que las características irrelevantes (con un baja puntuación de recalibración) se reducen
mientras que las características relevantes (con una puntuación de recalibración cercana a 1) se dejan solas.

Implementación de una CNN ResNet-34 usando Keras

La mayoría de las arquitecturas de CNN descritas hasta ahora son bastante sencillas de implementar
(aunque, como veremos, generalmente, en su lugar, cargaría una red preentrenada). Para ilustrar el
proceso, implementemos un ResNet-34 desde cero usando Keras. Primero, vamos a crear unUnidad
residualcapa:

DefaultConv2D=parcial(queras.capas.Conv2D,kernel_size=3,zancadas=1,
relleno="MISMO",use_bias=Falso)

claseUnidad residual(queras.capas.Capa):
definitivamente__en eso__(uno mismo,filtros,zancadas=1,activación="relu",**kwargs):
súper().__en eso__(**kwargs)
uno mismo.activación=queras.activaciones.obtener(activación) uno
mismo.capas_principales=[
DefaultConv2D(filtros,zancadas=zancadas),
queras.capas.Normalización por lotes(), uno
mismo.activación, DefaultConv2D(filtros),

queras.capas.Normalización por lotes()]


uno mismo.saltar_capas=[] sizancadas>1:

uno mismo.saltar_capas=[
DefaultConv2D(filtros,kernel_size=1,zancadas=zancadas),
queras.capas.Normalización por lotes()]

definitivamentellamar(uno mismo,entradas):

Z=entradas
porcapaenuno mismo.capas_principales:
Z=capa(Z)
saltar_Z=entradas
porcapaenuno mismo.saltar_capas:

464 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
saltar_Z=capa(saltar_Z) devolveruno
mismo.activación(Z+saltar_Z)

Como puede ver, este código coincideFigura 14-18muy de cerca En el constructor, creamos
todas las capas que necesitaremos: las capas principales son las del lado derecho del diagrama
y las capas de salto son las del lado izquierdo (solo son necesarias si el paso es mayor que 1).
Entonces en elllamar()método, simplemente hacemos que las entradas pasen por las capas
principales, y las capas de salto (si las hay), luego agregamos ambas salidas y aplicamos la
función de activación.

A continuación, podemos construir el ResNet-34 simplemente usando unSecuencialmodelo, ya que en


realidad es solo una larga secuencia de capas (podemos tratar cada unidad residual como una sola capa
ahora que tenemos laUnidad residualclase):

modelo=queras.modelos.Secuencial()
modelo.agregar(DefaultConv2D(64,kernel_size=7,zancadas=2,
entrada_forma=[224,224,3]))
modelo.agregar(queras.capas.Normalización por lotes())
modelo.agregar(queras.capas.Activación("relu"))
modelo.agregar(queras.capas.MaxPool2D(tamaño de la piscina=3,zancadas=2,relleno="MISMO"))
filtros_anteriores=64
porfiltrosen[64]*3+[128]*4+[256]*6+[512]*3:
zancadas=1sifiltros==filtros_anterioresmás2 modelo.
agregar(Unidad residual(filtros,zancadas=zancadas))
filtros_anteriores=filtros
modelo.agregar(queras.capas.GlobalAvgPool2D())
modelo.agregar(queras.capas.Aplanar())
modelo.agregar(queras.capas.Denso(10,activación="softmax"))

La única parte un poco complicada en este código es el ciclo que agrega elUnidad residualcapas al
modelo: como se explicó anteriormente, las primeras 3 RU tienen 64 filtros, luego las siguientes 4 RU
tienen 128 filtros y así sucesivamente. Luego establecemos los pasos a 1 cuando el número de filtros
es el mismo que en la RU anterior, o bien lo establecemos a 2. Luego agregamos elunidad residual, y
finalmente actualizamosfiltros_anteriores.

¡Es bastante sorprendente que en menos de 40 líneas de código podamos construir el modelo
que ganó el desafío ILSVRC 2015! Demuestra tanto la elegancia del modelo ResNet como la
expresividad de la API de Keras. Implementar las otras arquitecturas de CNN no es mucho más
difícil. Sin embargo, Keras viene con varias de estas arquitecturas integradas, entonces, ¿por
qué no usarlas en su lugar?

Uso de modelos preentrenados de Keras


En general, no tendrá que implementar modelos estándar como GoogLeNet o ResNet
manualmente, ya que las redes preentrenadas están disponibles con una sola línea de
código, en elkeras.aplicacionespaquete. Por ejemplo:

modelo=queras.aplicaciones.resnet50.ResNet50(pesos="imagenet")

Uso de modelos preentrenados de Keras | 465


¡Eso es todo! Esto creará un modelo ResNet-50 y descargará pesos previamente entrenados en el conjunto de
datos de ImageNet. Para usarlo, primero debe asegurarse de que las imágenes tengan el tamaño correcto.
Un modelo ResNet-50 espera imágenes de 224 × 224 (otros modelos pueden esperar otros tamaños, como
299 × 299), así que usemos TensorFlowtf.imagen.redimensionar()función para cambiar el tamaño de las
imágenes que cargamos anteriormente:

imágenes_redimensionadas=t.f..imagen.cambiar el tamaño(imágenes, [224,224])

lostf.imagen.redimensionar()no conservará la relación de aspecto. Si esto es un


problema, puede intentar recortar las imágenes a la relación de aspecto adecuada
antes de cambiar el tamaño. Ambas operaciones se pueden hacer en una
tiro contf.image.crop_and_resize().

Los modelos preentrenados asumen que las imágenes son preprocesadas de una manera específica.
En algunos casos, pueden esperar que las entradas se escalen de 0 a 1, o de -1 a 1, y así
sucesivamente. Cada modelo proporciona unaentrada_preprocesamiento()función que puede utilizar
para preprocesar sus imágenes. Estas funciones asumen que los valores de los píxeles van de 0 a 255,
por lo que debemos multiplicarlos por 255 (ya que antes los escalamos al rango de 0 a 1):

entradas=queras.aplicaciones.resnet50.entrada_preprocesamiento(imágenes_redimensionadas*255)

Ahora podemos usar el modelo preentrenado para hacer predicciones:

Y_proba=modelo.predecir(entradas)

Como de costumbre, la salidaY_probaes una matriz con una fila por imagen y una columna por
clase (en este caso, hay 1000 clases). Si desea mostrar las K predicciones principales, incluido el
nombre de la clase y la probabilidad estimada de cada clase pronosticada, puede usar el
decodificar_predicciones()función. Para cada imagen, devuelve una matriz que contiene las
principales K predicciones, donde cada predicción se representa como una matriz que contiene
el identificador de clase.21, su nombre y la puntuación de confianza correspondiente:

arriba_K=queras.aplicaciones.resnet50.decodificar_predicciones(Y_proba,parte superior=3)
poríndice_imagenenrango(Len(imágenes)):
impresión("Imagen #{}".formato(índice_imagen))
poridentificador de clase,nombre,y_probaenarriba_K[índice_imagen]:
impresión(" {} - {:12s} {:.2f}%".formato(identificador de clase,nombre,y_proba*100)) impresión
()

La salida se ve así:
Imagen #0
n03877845 - palacio 42,87%
n02825657 - bell_cote 40,57%
n03781244 - monasterio 14,56%

21 En el conjunto de datos de ImageNet, cada imagen está asociada a una palabra en elConjunto de datos de WordNet: el ID de clase es solo un

Identificación de WordNet.

466 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
Imagen #1
n04522168 - florero 46,83%
n07930864 - taza 7,78%
n11939491 - margarita 4,87%

Las clases correctas (monasterio y margarita) aparecen en los 3 primeros resultados para ambas imágenes.
Eso es bastante bueno teniendo en cuenta que el modelo tuvo que elegir entre 1000 clases.

Como puede ver, es muy fácil crear un clasificador de imágenes bastante bueno usando un
modelo previamente entrenado. Otros modelos de visión están disponibles en
keras.aplicaciones,incluidas varias variantes de ResNet, variantes de GoogLeNet como
InceptionV3 y Xception, variantes de VGGNet, MobileNet y MobileNetV2 (modelos livianos para
usar en aplicaciones móviles) y más.

Pero, ¿qué sucede si desea utilizar un clasificador de imágenes para clases de imágenes que no forman parte
de ImageNet? En ese caso, aún puede beneficiarse de los modelos preentrenados para realizar transferencias
de aprendizaje.

Modelos preentrenados para el aprendizaje por transferencia

Si desea crear un clasificador de imágenes, pero no tiene suficientes datos de entrenamiento, a menudo es
una buena idea reutilizar las capas inferiores de un modelo previamente entrenado, como discutimos en
Capítulo 11. Por ejemplo, entrenemos un modelo para clasificar imágenes de flores, reutilizando un modelo
Xception previamente entrenado. Primero, carguemos el conjunto de datos usando TensorFlow Datasets (ver
Capítulo 13):

importartensorflow_conjuntos de datoscomotfds

conjunto de datos,información=tfds.carga("tf_flores",como_supervisado=Verdadero,con_info=Verdadero)
dataset_size=información.divisiones["tren"].num_ejemplos#3670 nombres_de_clase=información.
caracteristicas["etiqueta"].nombres# ["diente de león", "margarita", ...] n_clases=información.
caracteristicas["etiqueta"].num_clases#5

Tenga en cuenta que puede obtener información sobre el conjunto de datos configurandowith_info=Verdadero.Aquí,
obtenemos el tamaño del conjunto de datos y los nombres de las clases. Desafortunadamente, solo hay un

"tren"conjunto de datos, ningún conjunto de prueba o conjunto de validación, por lo que necesitamos dividir el

conjunto de entrenamiento. El proyecto TF Datasets proporciona una API para esto. Por ejemplo, tomemos el primer
10 % del conjunto de datos para pruebas, el siguiente 15 % para validación y el 75 % restante para entrenamiento:

prueba_dividida,división_válida,tren_dividido=tfds.Separar.TREN.subdividir([10,15,75])

equipo de prueba=tfds.carga("tf_flores",separar=prueba_dividida,como_supervisado=Verdadero)
conjunto_valido=tfds.carga("tf_flores",separar=división_válida,como_supervisado=Verdadero) juego de
trenes=tfds.carga("tf_flores",separar=tren_dividido,como_supervisado=Verdadero)

modelos preentrenados para transferencia de aprendizaje | 467


A continuación debemos preprocesar las imágenes. La CNN espera imágenes de 224 × 224, por lo que
debemos cambiar su tamaño. También necesitamos ejecutar la imagen a través de Xceptionpreprof
cess_input()función:
definitivamentepreprocesar(imagen,etiqueta):

imagen_redimensionada=t.f..imagen.cambiar el tamaño(imagen, [224,224])


imagen_final=queras.aplicaciones.xcepción.entrada_preprocesamiento(imagen_redimensionada)
devolverimagen_final,etiqueta

Apliquemos esta función de preprocesamiento a los 3 conjuntos de datos, y también mezclemos y repitamos el conjunto de entrenamiento,

y agreguemos procesamiento por lotes y búsqueda previa a todos los conjuntos de datos:

tamaño del lote=32


juego de trenes=juego de trenes.barajar(1000).repetir()
juego de trenes=juego de trenes.mapa(preprocesar).lote(tamaño del lote).captación previa(1)
conjunto_valido=conjunto_valido.mapa(preprocesar).lote(tamaño del lote).captación previa(1) equipo
de prueba=equipo de prueba.mapa(preprocesar).lote(tamaño del lote).captación previa(1)

Si desea realizar algún aumento de datos, simplemente puede cambiar la función de preprocesamiento para
el conjunto de entrenamiento, agregando algunas transformaciones aleatorias a las imágenes de
entrenamiento. Por ejemplo, usetf.imagen.random_crop()para recortar aleatoriamente las imágenes, utilice
tf.imagen.random_flip_left_right()para voltear aleatoriamente las imágenes horizontalmente, y así
sucesivamente (consulte el cuaderno para ver un ejemplo).

A continuación, carguemos un modelo Xception, previamente entrenado en ImageNet. Excluimos la


parte superior de la red (estableciendoinclude_top=Falso):esto excluye la capa de agrupación promedio
global y la capa de salida densa. Luego agregamos nuestra propia capa de agrupación promedio
global, basada en la salida del modelo base, seguida de una capa de salida densa con 1 unidad por
clase, usando la función de activación softmax. Por último, creamos las Keras.Modelo:

modelo_base=queras.aplicaciones.xcepción.Xcepción(pesos="imagenet",
include_top=Falso)
promedio=queras.capas.GlobalAveragePooling2D()()modelo_base.producción)
producción=queras.capas.Denso(n_clases,activación="softmax")(promedio) modelo=
queras.modelos.Modelo(entradas=modelo_base.aporte,salidas=producción)

Como se explica enCapítulo 11, suele ser una buena idea congelar los pesos de las capas
preentrenadas, al menos al comienzo del entrenamiento:

porcapaenmodelo_base.capas:
capa.entrenable=Falso

Dado que nuestro modelo utiliza las capas del modelo base directamente, en lugar de

lamodelo_baseobjeto en sí mismo, ajustebase_model.trainable=Falso


no tendría ningún efecto.

Finalmente, podemos compilar el modelo y comenzar a entrenar:

468 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
optimizador=queras.optimizadores.USD(yo=0.2,impulso=0.9,decadencia=0.01) modelo.compilar
(pérdida="esparse_categorical_crossentropy",optimizador=optimizador,
métrica=["precisión"])
historia=modelo.adaptar(juego de trenes,
pasos_por_época=En t(0.75*dataset_size/tamaño del lote),
datos_de_validación=conjunto_valido,
pasos_de_validación=En t(0.15*dataset_size/tamaño del lote),
épocas=5)

Esto será muy lento, a menos que tenga una GPU. Si no lo hace, debe ejecutar
el cuaderno de este capítulo en Colab, usando un tiempo de ejecución de GPU
(¡es gratis!). Consulte las instrucciones enhttps://github.com/ageron/handson-
ml2.

Después de entrenar el modelo durante algunas épocas, su precisión de validación debería alcanzar
alrededor del 75-80 % y dejar de progresar mucho. Esto significa que las capas superiores ahora están
bastante bien entrenadas, por lo que estamos listos para descongelar todas las capas (o puede intentar
descongelar solo las superiores) y continuar con el entrenamiento (no olvide compilar el modelo cuando
congele o descongele capas ). Esta vez usamos una tasa de aprendizaje mucho más baja para evitar dañar los
pesos preentrenados:

porcapaenmodelo_base.capas:
capa.entrenable=Verdadero

optimizador=queras.optimizadores.USD(yo=0.01,impulso=0.9,decadencia=0.001)
modelo.compilar(...) historia=modelo.adaptar(...)

Tomará un tiempo, pero este modelo debería alcanzar alrededor del 95 % de precisión en el equipo de
prueba. ¡Con eso, puedes comenzar a entrenar increíbles clasificadores de imágenes! Pero hay más en
la visión artificial que solo la clasificación. Por ejemplo, ¿qué pasa si también quieres saberdónde la
flor esta en la foto? Veamos esto ahora.

Clasificación y Localización
La localización de un objeto en una imagen se puede expresar como una tarea de regresión, como se
explica en Capítulo 10: para predecir un cuadro delimitador alrededor del objeto, un enfoque común
es predecir las coordenadas horizontales y verticales del centro del objeto, así como su altura y ancho.
Esto significa que tenemos 4 números para predecir. No requiere muchos cambios en el modelo, solo
necesitamos agregar una segunda capa de salida densa con 4 unidades (generalmente encima de la
capa de agrupación promedio global), y se puede entrenar usando la pérdida MSE:

modelo_base=queras.aplicaciones.xcepción.Xcepción(pesos="imagenet",
include_top=Falso)
promedio=queras.capas.GlobalAveragePooling2D()()modelo_base.producción)
clase_salida=queras.capas.Denso(n_clases,activación="softmax")(promedio)

Clasificación y Localización | 469


salida_loc=queras.capas.Denso(4)(promedio)
modelo=queras.modelos.Modelo(entradas=modelo_base.aporte,
salidas=[clase_salida,salida_loc])
modelo.compilar(pérdida=["esparse_categorical_crossentropy","mse"],
perdida_de_peso=[0.8,0.2],#depende de lo que mas te importe
optimizador=optimizador,métrica=["precisión"])

Pero ahora tenemos un problema: el conjunto de datos de flores no tiene cuadros delimitadores
alrededor de las flores. Así que tenemos que agregarlos nosotros mismos. Esta suele ser una de las
partes más difíciles y costosas de un proyecto de Machine Learning: obtener las etiquetas. Es una
buena idea dedicar tiempo a buscar las herramientas adecuadas. Para anotar imágenes con cuadros
delimitadores, es posible que desee utilizar una herramienta de etiquetado de imágenes de código
abierto como VGG Image Annotator, LabelImg, OpenLabeler o ImgLab, o quizás una herramienta
comercial como LabelBox o Supervisely. También puede considerar plataformas de crowdsourcing
como Amazon Mechanical Turk o CrowdFlower si tiene una gran cantidad de imágenes para anotar.
Sin embargo, es bastante trabajo configurar una plataforma de crowdsourcing, preparar el formulario
para enviar a los trabajadores, para supervisarlos y asegurarse de que la calidad de los cuadros
delimitadores que producen sea buena, así que asegúrese de que valga la pena el esfuerzo: si solo hay
unos pocos miles de imágenes para etiquetar, y no planea hacerlo con frecuencia, puede ser
preferible hacerlo uno mismo. Adriana Kovashka et al. escribió una muy prácticapapel22sobre el
crowdsourcing en Computer Vision, te recomiendo que le eches un vistazo, aunque no tengas
pensado utilizar el crowdsourcing.

Así que supongamos que obtuvo los cuadros delimitadores para cada imagen en el conjunto de datos
de flores (por ahora supondremos que hay un solo cuadro delimitador por imagen), luego necesita
crear un conjunto de datos cuyos elementos serán lotes de imágenes preprocesadas junto con sus
etiquetas de clase y sus cuadros delimitadores. Cada elemento debe ser una tupla de la forma:
(imágenes, (class_labels,bounding_boxes)).Entonces estás listo para entrenar a tu
¡modelo!

Los cuadros delimitadores deben normalizarse para que las coordenadas


horizontales y verticales, así como la altura y el ancho, oscilen entre 0 y 1.
Además, es común predecir la raíz cuadrada de la altura y el ancho en lugar de
la altura y el ancho directamente. : de esta forma, un error de 10 píxeles para
un cuadro delimitador grande no se penalizará tanto como un error de 10
píxeles para un cuadro delimitador pequeño.

El MSE a menudo funciona bastante bien como una función de costo para entrenar el modelo, pero no
es una gran métrica para evaluar qué tan bien el modelo puede predecir los cuadros delimitadores. La
métrica más común para esto es la Intersección sobre Unión (IoU): es el área de superposición entre el
cuadro delimitador predicho y el cuadro delimitador objetivo, dividido por el

22 “Crowdsourcing en Computer Vision”, A. Kovashka et al. (2016).

470 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
área de su unión (verFigura 14-23). En tf.keras, es implementado por el
tf.keras.metrics.MeanIoUclase.

Figura 14-23. Métrica de intersección sobre unión (IoU) para cuadros delimitadores

Clasificar y localizar un único objeto está bien, pero ¿qué pasa si las imágenes contienen varios objetos
(como suele ser el caso en el conjunto de datos de flores)?

Detección de objetos

La tarea de clasificar y localizar múltiples objetos en una imagen se denominadetección de objetos.


Hasta hace unos años, un enfoque común era tomar una CNN que estaba entrenada para clasificar y
ubicar un solo objeto, luego deslizarla por la imagen, como se muestra enFigura 14-24. En este
ejemplo, la imagen se cortó en una cuadrícula de 6 × 8 y mostramos una CNN (el rectángulo negro
grueso) deslizándose por todas las regiones de 3 × 3. Cuando la CNN estaba mirando la parte superior
izquierda de la imagen, detectó parte de la rosa más a la izquierda, y luego detectó esa misma rosa
nuevamente cuando se movió por primera vez un paso a la derecha. En el siguiente paso, comenzó a
detectar parte de la rosa más alta, y luego la volvió a detectar una vez que se movió un paso más hacia
la derecha. Luego continuaría deslizando la CNN a través de toda la imagen, observando todas las
regiones de 3 × 3. Además, dado que los objetos pueden tener diferentes tamaños, también deslizaría
la CNN a través de regiones de diferentes tamaños. Por ejemplo, una vez que haya terminado con las
regiones de 3 × 3, es posible que también desee deslizar la CNN en todas las regiones de 4 × 4.

Detección de objetos | 471


Figura 14-24. Detección de múltiples objetos deslizando una CNN a través de la imagen

Esta técnica es bastante sencilla, pero como puede ver, detectará el mismo objeto varias veces,
en posiciones ligeramente diferentes. Luego será necesario un procesamiento posterior para
deshacerse de todos los cuadros delimitadores innecesarios. Un enfoque común para esto se
llamasupresión no máxima:

• Primero, debe agregar un extraobjetividadsalida a su CNN, para estimar la probabilidad de que


una flor esté realmente presente en la imagen (alternativamente, podría agregar una clase "sin
flor", pero esto generalmente no funciona tan bien). Debe usar la función de activación sigmoide
y puedes entrenarlo usando el "tropía binaria_crossen"pérdida. Luego, deshágase de todos los
cuadros delimitadores para los que la puntuación de objetividad está por debajo de cierto
umbral: esto eliminará todos los cuadros delimitadores que en realidad no contienen una flor.

• En segundo lugar, busque el cuadro delimitador con la puntuación de objetividad más alta y elimine
todos los demás cuadros delimitadores que se superponen mucho con él (p. ej., con un IoU superior al
60%). por ejemplo, enFigura 14-24, el cuadro delimitador con la puntuación máxima de objetividad es el
cuadro delimitador grueso sobre la rosa superior (la puntuación de objetividad está representada por el
grosor de los cuadros delimitadores). El otro cuadro delimitador sobre esa misma rosa se superpone
mucho con el cuadro delimitador máximo, por lo que nos desharemos de él.

472 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales
• En tercer lugar, repita el paso dos hasta que no haya más cuadros delimitadores de los que deshacerse.

Este enfoque simple para la detección de objetos funciona bastante bien, pero requiere ejecutar la CNN
muchas veces, por lo que es bastante lento. Afortunadamente, existe una manera mucho más rápida de
deslizar una CNN a través de una imagen: usando unRed completamente convolucional.

Redes totalmente convolucionales (FCN)

La idea de FCN se introdujo por primera vez en unpapel de 201523de Jonathan Long et al., para la
segmentación semántica (la tarea de clasificar cada píxel de una imagen según la clase del objeto al
que pertenece). Señalaron que podría reemplazar las capas densas en la parte superior de una CNN
por capas convolucionales. Para entender esto, veamos un ejemplo: supongamos que una capa densa
con 200 neuronas se asienta sobre una capa convolucional que genera 100 mapas de características,
cada uno de tamaño 7 × 7 (este es el tamaño del mapa de características, no el tamaño del kernel).
Cada neurona calculará una suma ponderada de las 100 × 7 × 7 activaciones de la capa convolucional
(más un término de sesgo). Ahora veamos qué sucede si reemplazamos la capa densa con una capa de
convolución usando 200 filtros, cada uno de 7 × 7, y con relleno VÁLIDO. Esta capa generará 200
mapas de características, cada uno 1 × 1 (dado que el núcleo es exactamente del tamaño de los mapas
de características de entrada y estamos usando relleno VÁLIDO). En otras palabras, generará 200
números, tal como lo hizo la capa densa, y si observa detenidamente los cálculos realizados por una
capa convolucional, notará que estos números serán exactamente los mismos que los producidos por
la capa densa. La única diferencia es que la salida de la capa densa fue un tensor de forma [tamaño de
lote, 200] mientras que la capa convolucional generará un tensor de forma [tamaño de lote, 1, 1, 200].

Para convertir una capa densa en una capa convolucional, el número de filtros
en la capa convolucional debe ser igual al número de unidades en la capa
densa, el tamaño del filtro debe ser igual al tamaño de los mapas de
características de entrada y usted debe usar relleno VÁLIDO. El paso puede
establecerse en 1 o más, como veremos en breve.

¿Porque es esto importante? Bueno, mientras que una capa densa espera un tamaño de entrada específico
(ya que tiene un peso por función de entrada), una capa convolucional procesará felizmente imágenes de
cualquier tamaño.24(sin embargo, espera que sus entradas tengan un número específico de canales, ya que
cada núcleo contiene un conjunto diferente de pesos para cada canal de entrada). Dado que un FCN contiene
solo capas convolucionales (y capas de agrupación, que tienen la misma propiedad), se puede entrenar y
ejecutar en imágenes de cualquier tamaño.

23 “Redes totalmente convolucionales para la segmentación semántica”, J. Long, E. Shelhamer, T. Darrell (2015).

24 Hay una pequeña excepción: una capa convolucional que usa relleno VÁLIDO se quejará si el tamaño de entrada es
más pequeño que el tamaño del núcleo.

Detección de objetos | 473


Por ejemplo, supongamos que ya entrenamos a una CNN para la clasificación y localización de
flores. Fue entrenado en imágenes de 224 × 224 y emite 10 números: las salidas 0 a 4 se envían
a través de la función de activación softmax, y esto da las probabilidades de clase (una por
clase); la salida 5 se envía a través de la función de activación logística, y esto da la puntuación
de objetividad; las salidas 6 a 9 no utilizan ninguna función de activación y representan las
coordenadas del centro del cuadro delimitador, su altura y anchura. Ahora podemos convertir
sus capas densas en capas convolucionales. De hecho, ni siquiera necesitamos volver a
entrenarlo, ¡solo podemos copiar los pesos de las capas densas a las capas convolucionales!
Alternativamente, podríamos haber convertido la CNN en una FCN antes del entrenamiento.

Ahora suponga que la última capa convolucional antes de la capa de salida (también llamada capa de cuello
de botella) genera mapas de características de 7 × 7 cuando la red recibe una imagen de 224 × 224 (ver el lado
izquierdo deFigura 14-25). Si alimentamos al FCN con una imagen de 448 × 448 (ver el lado derecho deFigura
14-25), la capa de cuello de botella ahora generará mapas de características de 14 × 14.25
Dado que la capa de salida densa se reemplazó por una capa convolucional que usa 10 filtros de
tamaño 7 × 7, relleno VÁLIDO y zancada 1, la salida estará compuesta por 10 mapas de
características, cada uno de tamaño 8 × 8 (ya que 14 - 7 + 1 = 8). En otras palabras, el FCN
procesará la imagen completa solo una vez y generará una cuadrícula de 8 × 8 donde cada celda
contiene 10 números (5 probabilidades de clase, 1 puntaje de objetividad y 4 coordenadas de
cuadro delimitador). Es exactamente como tomar la CNN original y deslizarla por la imagen
utilizando 8 pasos por fila y 8 pasos por columna: para visualizar esto, imagine cortar la imagen
original en una cuadrícula de 14 × 14 y luego deslizar una ventana de 7 × 7 a lo largo de esta
cuadrícula. : habrá 8 × 8 = 64 ubicaciones posibles para la ventana, por lo tanto, 8 × 8
predicciones. Sin embargo, el enfoque FCN esmuchomás eficiente, ya que la red solo mira la
imagen una vez. En realidad,Solo miras una vez(YOLO) es el nombre de una arquitectura de
detección de objetos muy popular.

25 Esto supone que usamos solo el MISMO relleno en la red: de hecho, el relleno VÁLIDO reduciría el tamaño de
los mapas de características. Además, 448 se puede dividir claramente por 2 varias veces hasta llegar a 7, sin ningún error de redondeo. Si alguna

capa usa una zancada diferente a 1 o 2, entonces puede haber algún error de redondeo, por lo que nuevamente los mapas de características pueden

terminar siendo más pequeños.

474 | Capítulo 14: Visión artificial profunda utilizando redes neuronales convolucionales

También podría gustarte