Aprendizaje automático: aprendizaje profundo en visión por computadora: introducción a las redes neuronales convolucionales

Fuente del código del artículo: "aprendizaje profundo en keras", un muy buen libro. Si eres bueno en inglés, se recomienda leer el libro directamente. Si tienes poco tiempo, puedes leer esta serie de artículos.

En este capítulo, estudiaremos las redes neuronales convolucionales, un tipo de modelo de aprendizaje profundo comúnmente utilizado en visión por computadora, y aprenderá a aplicarlas a problemas de clasificación.
Primero presentaremos algunas de las teorías detrás de las redes neuronales convolucionales, específicamente:

  • ¿Qué son la convolución y la agrupación máxima?
  • ¿Qué es una red convolucional?
  • ¿Qué aprendió la red convolucional?

A continuación generalizaremos el problema de clasificación de imágenes utilizando un pequeño conjunto de datos:

  • Entrena tu pequeña red convolucional desde cero
  • Utilice el aumento de datos para evitar el sobreajuste
  • Utilice redes convolucionales previamente entrenadas para la extracción de características
  • Ajustar los parámetros de la red convolucional previamente entrenada

Finalmente describiremos varias técnicas de visualización para aprender a clasificar.

La siguiente es nuestra primera sección, una introducción a las redes neuronales convolucionales.

Nos sumergimos en la teoría de las redes neuronales convolucionales y exploramos por qué tienen tanto éxito en tareas de visión por computadora. Primero, veamos un ejemplo simple de red convolucional en acción. Usaremos una red convolucional para clasificar los dígitos MNIST. Anteriormente logramos una tasa de reconocimiento del 97,8% usando redes completamente conectadas. Aunque nuestra red convolucional es muy básica, su tasa de precisión sigue siendo mejor que la de la red totalmente conectada original.
Las siguientes 6 líneas de código le mostrarán cómo se ve la red convolucional más básica, que en realidad es una pila de algunas capas de convolución bidimensional y de agrupación máxima bidimensional. Echaremos un vistazo a lo que hacen a continuación: La forma del tensor tomada por una convolución: (largo, ancho, número de canales) no incluye la dimensión del lote. En nuestro ejemplo, procesaremos datos de entrada de forma (28,28,1), que es el formato de los datos en MNIST.

from keras import layers
from keras import models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

A continuación veamos la estructura de la red convolucional:

>>> model.summary()
________________________________________________________________
Layer (type) Output Shape Param #
================================================================
conv2d_1 (Conv2D) (None, 26, 26, 32) 320
________________________________________________________________
maxpooling2d_1 (MaxPooling2D) (None, 13, 13, 32) 0
________________________________________________________________
conv2d_2 (Conv2D) (None, 11, 11, 64) 18496
________________________________________________________________
maxpooling2d_2 (MaxPooling2D) (None, 5, 5, 64) 0
________________________________________________________________
conv2d_3 (Conv2D) (None, 3, 3, 64) 36928
================================================================
Total params: 55,744
Trainable params: 55,744
Non-trainable params: 0

Podemos ver que la salida de cada capa convolucional y capa de agrupación es un tensor tridimensional. El ancho y la altura comienzan a reducirse a medida que la red se profundiza. El número de canales está controlado por el primer parámetro pasado a la capa convolucional.
El siguiente paso es introducir nuestro tensor de salida en una red de clasificación completamente conectada. El clasificador procesa un vector unidimensional y nuestra salida es un tensor tridimensional, por lo que necesitamos comprimir nuestra salida tridimensional en una unidimensional y luego agregamos una capa de densidad:

model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

A continuación, haremos una clasificación de clase 10. Elegimos softmax como función de activación y la dimensión de salida es 10. Nuestra red ahora se ve así:

>>> model.summary()
Layer (type) Output Shape Param #
================================================================
conv2d_1 (Conv2D) (None, 26, 26, 32) 320
________________________________________________________________
maxpooling2d_1 (MaxPooling2D) (None, 13, 13, 32) 0
________________________________________________________________
conv2d_2 (Conv2D) (None, 11, 11, 64) 18496
________________________________________________________________
maxpooling2d_2 (MaxPooling2D) (None, 5, 5, 64) 0
________________________________________________________________
conv2d_3 (Conv2D) (None, 3, 3, 64) 36928
________________________________________________________________
flatten_1 (Flatten) (None, 576) 0
________________________________________________________________
dense_1 (Dense) (None, 64) 36928
________________________________________________________________
dense_2 (Dense) (None, 10) 650
================================================================
Total params: 93,322
Trainable params: 93,322
Non-trainable params: 0

Finalmente usaremos el código que usamos antes para entrenar:

from keras.datasets import mnist
from keras.utils import to_categorical
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
model.compile(optimizer='rmsprop',
 loss='categorical_crossentropy',
 metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=5, batch_size=64)

Luego evaluar los resultados finales.

>>> test_loss, test_acc = model.evaluate(test_images, test_labels)
>>> test_acc
0.99080000000000001

¿Por qué una red neuronal convolucional simple puede funcionar mucho mejor que un modelo completamente conectado? Necesitamos continuar sumergiéndonos en la capa convolucional y la capa de agrupación máxima para comprender este asunto.

operador de convolución

Las capas completamente conectadas aprenden patrones globales, mientras que las capas convolucionales aprenden patrones locales.

Insertar descripción de la imagen aquí

Las imágenes se pueden dividir en patrones locales como bordes, texturas, etc.

Esta característica clave otorga a las redes convolucionales dos propiedades interesantes:

  • Los patrones aprendidos son invariantes de traducción y los patrones aprendidos en redes completamente conectadas dependen de la posición, mientras que las redes convolucionales tienen una mayor eficiencia de datos.

  • Puede aprender la jerarquía espacial de patrones, como se muestra a continuación: la primera capa aprende pequeños patrones locales, como bordes, pero la segunda capa convolucional aprenderá características más grandes basadas en la primera capa. Esto permitirá que la red convolucional aprenda a abstraer aún más características complejas de manera más efectiva.

    Insertar descripción de la imagen aquí

    El mundo visual forma una jerarquía espacial de módulos visuales: los bordes hiperlocales se combinan en objetos locales como ojos u oídos, que se combinan en conceptos de alto nivel como "gato".

    La operación de convolución en un tensor tridimensional se denomina "mapa de características", que tiene dos coordenadas espaciales (ancho y alto) y una coordenada de profundidad (también llamada número de canales). Para imágenes RGB, la dimensión de la profundidad la coordenada es 3. Para MNIST, la profundidad de las imágenes en blanco y negro es 1. El operador de convolución extrae parches del mapa de características de entrada y realiza algunas transformaciones en todos los parches, luego produce nuestro mapa de características de salida. El mapa de características de salida sigue siendo un tensor tridimensional, pero la profundidad aquí ya no representa un color específico, sino algo que llamamos filtro. Los filtros codifican un aspecto específico de los datos de entrada. En un nivel alto, un filtro simple puede codificar la presencia de una cara en la entrada.
    La convolución se define mediante los siguientes dos parámetros clave:

  • El tamaño de los fragmentos de parche extraídos de la entrada. En nuestro caso suele ser
    Insertar descripción de la imagen aquí

de.

  • La profundidad del mapa de características de salida, es decir, la cantidad de filtros. En nuestro ejemplo, comenzamos con una profundidad de 32 y terminamos con una profundidad de 64.

En la capa convolucional de keras, el primer parámetro pasado es Conv2D (profundidad_salida, (altura_ventana, ancho_ventana)).
Una convolución funciona deslizándose, deteniéndose en cada posición posible y extrayendo parches 3D de las características circundantes.
El diagrama esquemático es el siguiente:

Insertar descripción de la imagen aquí

Cómo funciona la convolución

Tenga en cuenta que el ancho y el alto de salida que obtenemos pueden ser diferentes del ancho y alto de entrada. Hay dos razones para esto:

  • Efectos de borde, causados ​​por el relleno del mapa de características de entrada.
  • El uso del deslizamiento, lo definiremos más adelante.

Echemos un vistazo a estas advertencias.

Comprender los efectos de borde y el relleno

considerar un

Insertar descripción de la imagen aquí

Mapa de características, un total de 25 bloques pequeños. Pero solo hay 9 piezas pequeñas diferentes, lo que significa que puedes concentrarte en

Insertar descripción de la imagen aquí

en la pequeña ventana. Entonces el mapa de características de salida será

Insertar descripción de la imagen aquí

: Esto lo reduce mucho, en dos pequeños bloques en cada dimensión, y verá el "efecto de límite" en el ejemplo anterior.
Insertar descripción de la imagen aquí

Ubicaciones válidas de parches de 3x3 en un mapa de características de entrada de 5x5

Si desea obtener un mapa de características de salida que sea idéntico a la entrada original, puede optar por utilizar relleno. Complete agregando el número apropiado de vectores de fila y columna, para

Insertar descripción de la imagen aquí

Ventana, puede optar por agregar una columna en los lados izquierdo y derecho, y agregar una fila en la parte superior e inferior. para

Insertar descripción de la imagen aquí

La ventana tiene sólo dos líneas.

Insertar descripción de la imagen aquí

Rellenar una entrada de 5x5 para poder extraer 25 parches de 3x3

En la capa convolucional, el relleno se puede configurar a través del parámetro "padding". El parámetro "padding" contiene dos valores: "válido" e "igual". El primero significa que no hay relleno y el segundo significa que la entrada y la salida tienen la misma mismo ancho y alto, y el valor predeterminado del parámetro de relleno es "válido".

Comprender el deslizamiento de convolución

Otro factor que afecta el tamaño de la producción es el "zancada". En nuestra descripción de la convolución hasta ahora, hemos asumido que el bloque central de la ventana de convolución está configurado. Sin embargo, en realidad existe un parámetro de convolución entre dos ventanas consecutivas, llamado "zancada", con un valor predeterminado de 1. En la siguiente imagen puedes ver la zancada establecida en 2.

Insertar descripción de la imagen aquí

Parches de convolución 3x3 con zancadas 2x2

Usar una zancada de 2 significa que tanto el ancho como el alto se reducen en un factor de 2. Las convoluciones deslizantes rara vez se utilizan en la práctica, aunque pueden resultar útiles en una variedad de modelos y siempre es bueno estar familiarizado con ellas.
Para reducir la muestra de funciones, además del deslizamiento, también se puede realizar a través del operador de agrupación máxima.

operador de agrupación máxima

En nuestro ejemplo de convolución, habrá notado que la cantidad de mapas de características se reduce a la mitad después de la agrupación máxima, lo cual, al igual que la convolución deslizante, es muy agresivo en la reducción de resolución.
La agrupación máxima consiste en extraer una ventana de las funciones de entrada y generar el valor máximo de cada canal. Esto es muy similar a la convolución.
¿Por qué hacemos pooling? ¿Qué pasaría si se eliminara el paso de agrupación?

model_no_max_pool = models.Sequential()
model_no_max_pool.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model_no_max_pool.add(layers.Conv2D(64, (3, 3), activation='relu'))
model_no_max_pool.add(layers.Conv2D(64, (3, 3), activation='relu'))

Estructura de salida:

>>> model_no_max_pool.summary()
Layer (type) Output Shape Param #
================================================================
conv2d_4 (Conv2D) (None, 26, 26, 32) 320
________________________________________________________________
conv2d_5 (Conv2D) (None, 24, 24, 64) 18496
________________________________________________________________
conv2d_6 (Conv2D) (None, 22, 22, 64) 36928
================================================================
Total params: 55,744
Trainable params: 55,744
Non-trainable params: 0

¿Hay algún problema con esta configuración? Hay dos puntos:

  • Esto no favorece el aprendizaje de características a nivel espacial.
    Insertar descripción de la imagen aquí

La ventana en la capa 3 solo contendrá la entrada.

Insertar descripción de la imagen aquí

Información. Las características de alto nivel que las redes convolucionales pueden aprender son todavía demasiado pequeñas. Necesitamos que la última capa convolucional contenga toda la información de entrada.

  • La característica final tiene demasiados coeficientes.

Brevemente, la reducción de resolución se utiliza para reducir la cantidad de coeficientes de características, al tiempo que permite que capas convolucionales sucesivas procesen ventanas más grandes para reducir la cantidad de filtros espaciales.
Tenga en cuenta que la agrupación máxima no es la única forma de lograr una reducción de resolución. También sabes que también se puede utilizar la zancada y también puedes utilizar la agrupación media. Sin embargo, la agrupación máxima suele funcionar mejor que estas alternativas.

Supongo que te gusta

Origin blog.csdn.net/lijunhcn/article/details/135073031
Recomendado
Clasificación