Aprendizaje profundo 03-Red neuronal convolucional (CNN)

Introducción

CNN, o red neuronal convolucional, es un modelo de aprendizaje profundo comúnmente utilizado para el procesamiento de imágenes y videos. En comparación con las redes neuronales tradicionales, CNN tiene una mejor capacidad para procesar imágenes y secuenciar datos porque puede aprender automáticamente características de las imágenes y extraer la información más útil.

Una característica central de CNN es la operación de convolución, que puede realizar cálculos de ventana deslizante en la imagen y extraer características de la imagen a través de filtros (también llamados núcleos de convolución) y capas de agrupación (Max Pooling). La operación de convolución puede reducir efectivamente la cantidad de pesos y la cantidad de cálculo, al mismo tiempo que conserva la información de la estructura espacial de la imagen. La capa de agrupación puede reducir la cantidad de cálculo y mejorar la solidez del modelo sin cambiar la dimensión del mapa de características.

Las estructuras típicas de CNN incluyen capas convolucionales, capas de agrupación, capas completamente conectadas, etc. Al mismo tiempo, para evitar el sobreajuste, CNN también agregará algunas técnicas de regularización, como la regularización Dropout y L2.

CNN se usa ampliamente en clasificación de imágenes, detección de objetivos, reconocimiento de voz y otros campos. En las tareas de clasificación de imágenes, los modelos clásicos de CNN incluyen LeNet-5, AlexNet, VGG y GoogleNet/Inception. Las ideas de diseño y estructuras de red de estos modelos son diferentes, pero todos han hecho contribuciones importantes al desarrollo de redes neuronales convolucionales. contribuir.

camino de desarrollo

La red neuronal convolucional (CNN) es un modelo de aprendizaje profundo que se usa ampliamente en el reconocimiento de imágenes, la visión por computadora y otros campos. En el proceso de desarrollo de CNN, han surgido muchos modelos clásicos, aquí se presenta brevemente varios modelos famosos.

  1. LeNet-5

LeNet-5 fue propuesto por Yann LeCun y otros en 1998 y fue el primer modelo de red neuronal convolucional ampliamente utilizado. Se utiliza principalmente para el reconocimiento de dígitos escritos a mano y contiene capas convolucionales, capas de agrupación y capas completamente conectadas. El diseño de LeNet-5 le permite lograr un muy buen rendimiento en la tarea de reconocimiento de dígitos escritos a mano del MNIST. Se caracteriza por una pequeña cantidad de núcleos de convolución (6 y 16) y una pequeña cantidad de parámetros. La primera capa de convolución usa 6 núcleos de convolución con un tamaño de 5 × 5, y la segunda capa de convolución usa 16 Un núcleo de convolución de tamaño 5×5. Este diseño puede reducir efectivamente la cantidad de parámetros del modelo, pero es el creador de las redes neuronales convolucionales y sienta las bases para modelos posteriores.

  1. alexnet

AlexNet fue propuesto por Alex Krizhevsky y otros en 2012. Fue el primer modelo de red neuronal convolucional que logró excelentes resultados en la competencia de clasificación de imágenes ImageNet. Utiliza múltiples capas convolucionales y capas de agrupación, y utiliza la función de activación ReLU y la tecnología de regularización de abandono. El diseño de AlexNet lo situó significativamente por delante de otros modelos en la competencia de clasificación de imágenes de ImageNet, liderando así una nueva ronda de desarrollo de redes neuronales convolucionales. Se caracteriza por el uso de una gran cantidad de núcleos de convolución (casi 6000) y una gran cantidad de parámetros, pero tiene un buen rendimiento en términos de precisión y eficiencia.

  1. VGG

VGG fue propuesto por Karen Simonyan y Andrew Zisserman en 2014. Su principal contribución es proponer el uso de núcleos de convolución más pequeños (3x3) en lugar de núcleos de convolución más grandes. Este diseño hace que la red sea más profunda y tenga menos parámetros, mejorando así la eficiencia y la precisión. VGG contiene 16 o 19 capas convolucionales y capas de agrupación, y todas estas capas utilizan el mismo tamaño y paso del núcleo de convolución. VGG logró muy buenos resultados en la competencia de clasificación de imágenes ImageNet y también sirvió de inspiración para ResNet y otros modelos posteriores.

  1. GoogleNet/Inicio

GoogleNet fue propuesto por el equipo de Google en 2014. Su principal contribución es el módulo Inception, que puede aumentar la profundidad y el ancho de la red sin aumentar la cantidad de parámetros. El módulo Inception utiliza múltiples núcleos de convolución y capas de agrupación de diferentes tamaños para la extracción de características y luego los conecta para formar un módulo. GoogleNet también utiliza una capa de agrupación promedio global en lugar de una capa completamente conectada, lo que reduce aún más la cantidad de parámetros. GoogleNet logró muy buenos resultados en el concurso de clasificación de imágenes ImageNet y también sirvió de inspiración para ResNet, DenseNet y otros modelos posteriores.

  1. Resnet

ResNet fue propuesto por el equipo de Microsoft Research Asia en 2015. Su principal contribución es proponer un aprendizaje residual, que puede resolver el problema de degradación de las redes neuronales convolucionales profundas. El problema de la degradación se refiere al fenómeno de que a medida que aumenta la profundidad de la red, la precisión disminuye. El aprendizaje residual evita la pérdida de información al introducir conexiones entre capas para transferir directamente la entrada a la salida. ResNet contiene una estructura de red más profunda (152 capas), pero logra una mayor precisión. Las ideas de diseño de ResNet fueron heredadas por DenseNet, MobileNet y otros modelos posteriores.

  1. Red densa

DenseNet fue propuesto por Gao Huang y otros en 2017. Su principal contribución es proponer conexiones densas, que pueden aumentar la profundidad y el ancho de la red, mejorando así la eficiencia y la precisión. La conexión densa se refiere a conectar la salida de cada capa con las entradas de todas las capas posteriores para formar una estructura de conexión densa. Este diseño hace que la red sea más compacta, tenga menos parámetros y también puede mejorar la reutilización de las funciones. DenseNet logró muy buenos resultados en el concurso de clasificación de imágenes ImageNet y también sirvió de inspiración para modelos posteriores como ShuffleNet y EfficientNet.

  1. red móvil

MobileNet fue propuesto por el equipo de Google en 2017. Su principal contribución es proponer una convolución separable en profundidad, que puede reducir la cantidad de parámetros y mantener una buena precisión. La convolución separable en profundidad se refiere a dividir la operación de convolución en dos pasos: convolución en profundidad y convolución puntual, reduciendo así la cantidad de cálculos y parámetros. MobileNet utiliza múltiples capas convolucionales separables en profundidad y capas de agrupación para lograr una clasificación de imágenes y una detección de objetivos eficientes en entornos con recursos limitados, como los dispositivos móviles. Las ideas de diseño de MobileNet fueron heredadas por modelos posteriores como ShuffleNet y EfficientNet.

  1. ShuffleNet

ShuffleNet fue propuesto por el equipo de Microsoft Research Asia en 2018. Su principal contribución es proponer la reorganización de canales y la convolución de grupos, lo que puede reducir significativamente la cantidad de parámetros y cálculos manteniendo la precisión. La reorganización de canales se refiere a agrupar y reagrupar canales de entrada para permitir el intercambio de información entre diferentes grupos. La convolución grupal se refiere a dividir la operación de convolución en dos pasos: convolución intragrupo y convolución entre grupos, reduciendo así la cantidad de cálculos y parámetros. ShuffleNet utiliza reorganización de múltiples canales y capas convolucionales grupales para lograr una clasificación de imágenes eficiente y detección de objetivos en entornos con recursos limitados.

  1. Red eficiente

EfficientNet fue propuesto por el equipo de Google en 2019. Su principal contribución es proponer escalamiento de red y coeficientes compuestos, que pueden reducir significativamente la cantidad de parámetros y cálculos manteniendo la precisión. El escalado de la red se refiere al escalamiento de la profundidad, el ancho y la resolución de la red simultáneamente para optimizarla sin cambiar la estructura del modelo. Los coeficientes compuestos se refieren a la combinación de coeficientes de escala de profundidad, ancho y resolución para obtener un modelo más eficiente. EfficientNet logró muy buenos resultados en el concurso de clasificación de imágenes ImageNet y también sirvió de inspiración para la posterior optimización del modelo.

  1. RegNet

RegNet fue propuesto por el equipo de investigación de IA de Facebook en 2020. Su principal contribución es proponer reglas adaptativas para la estructura de la red, que pueden reducir significativamente la cantidad de parámetros y cálculos manteniendo la precisión. Las reglas adaptativas se refieren al ajuste automático de los hiperparámetros de la estructura de la red mediante búsqueda y optimización para obtener un modelo más eficiente. RegNet logró muy buenos resultados en la competencia de clasificación de imágenes de ImageNet y también sirvió de inspiración para la optimización posterior del modelo.

Los anteriores son varios modelos de redes neuronales convolucionales bien conocidos. Sus ideas de diseño y estructuras de red son diferentes, pero todos han hecho contribuciones importantes al desarrollo de redes neuronales convolucionales.

Principio esquemático

Las redes neuronales convolucionales brillan en el reconocimiento de imágenes, logran una precisión sin precedentes y tienen una amplia gama de aplicaciones. A continuación, utilizaremos el reconocimiento de imágenes como ejemplo para presentar los principios de las redes neuronales convolucionales.

Caso

Supongamos que dada una imagen (tal vez la letra X o la letra O), CNN se puede usar para identificar si es una X o una O, como se muestra en la siguiente figura, ¿cómo hacerlo?
Insertar descripción de la imagen aquí

Entrada de imagen

Si se utiliza un modelo de red neuronal clásico, la imagen completa debe leerse como entrada del modelo de red neuronal (es decir, completamente conectada). Cuando el tamaño de la imagen aumenta, los parámetros conectados a ella se convertirán en muchos, lo que dará como resultado en una gran cantidad de cálculo Muy grande.
Nuestro conocimiento humano del mundo exterior generalmente procede de lo local a lo global. Primero tenemos una comprensión perceptiva de la parte local y luego gradualmente ganamos un conocimiento del todo. Éste es el modelo de comprensión humana. La conexión espacial en la imagen es similar: los píxeles en el rango local están estrechamente conectados, mientras que la correlación entre los píxeles más alejados es más débil. Por lo tanto, cada neurona en realidad no necesita percibir la imagen global, solo necesita percibir la parte local y luego sintetizar la información local a un nivel superior para obtener la información global. Este modo es un artefacto importante para reducir la cantidad de parámetros en las redes neuronales convolucionales: el campo receptivo local.
Insertar descripción de la imagen aquí

Extracción de características

Si la letra, por ejemplo, traducción, escala, rotación, microdeformación, etc., como se muestra en la figura siguiente:
Insertar descripción de la imagen aquí
nuestro objetivo es identificar con precisión X y O en varios cambios morfológicos a través de CNN, lo que implica cómo extraer características de manera efectiva. como factor clave para la identificación.
Recuerde el modo de "campo receptivo local" mencionado anteriormente. Para CNN, consiste en comparar piezas pequeñas y encontrar algunas características aproximadas (pequeños parches de imagen) en aproximadamente la misma posición en las dos imágenes. Para hacer coincidir, en comparación con la comparación tradicional de Imagen completa una por una, el método de coincidencia de bloques pequeños de CNN puede comparar mejor las similitudes entre las dos imágenes. Como se muestra en la
Insertar descripción de la imagen aquí
: Tomando la letrasiguiente
Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

La extracción de características anterior es una suposición. De hecho, cuando hay varias imágenes como entrada, la red neuronal convolucional extraerá características para cada imagen. El proceso específico es el siguiente: la imagen de entrada pasa a través de la primera capa convolucional y la convolución El kernel estará en la imagen. Desliza hacia arriba para extraer algunas características de bajo nivel, como bordes, esquinas, etc.

En una red neuronal convolucional, si se utilizan varios núcleos de convolución diferentes, el tamaño del campo receptivo local de cada núcleo de convolución es el mismo, pero los pesos de los diferentes núcleos de convolución son diferentes, por lo que cada núcleo de convolución puede aprender diferentes características.

Por ejemplo, supongamos que usamos tres núcleos de convolución diferentes en la capa de convolución, donde el peso del primer núcleo de convolución se usa para detectar bordes, el peso del segundo núcleo de convolución se usa para detectar características de textura y el peso del tercer núcleo de convolución El núcleo se utiliza para detectar bordes y los pesos de los núcleos de convolución se utilizan para detectar la forma del objetivo. Los campos receptivos locales de estos tres núcleos de convolución son todos del mismo tamaño, pero debido a que sus pesos son diferentes, cada núcleo de convolución puede aprender características diferentes.

Cabe señalar que el tamaño y el tamaño del paso del núcleo de convolución también afectarán el tamaño del campo receptivo local de cada núcleo de convolución. Si el tamaño del núcleo de convolución es mayor, su campo receptivo local también será mayor en consecuencia; si el tamaño del paso es mayor, la distancia que se desliza el núcleo de convolución cada vez también será mayor en consecuencia, afectando así al núcleo de convolución. el campo receptivo local.

Por ejemplo, núcleo de convolución
[-1, 0, 1],
[-1, 0, 1],
[-1, 0, 1]]

Esta matriz es en realidad un núcleo de convolución, también conocido como filtro de Sobel. Se puede utilizar para detectar bordes verticales en imágenes.
En visión por computadora, los bordes se refieren a áreas de una imagen con grandes cambios en el valor de gris. Los bordes verticales se refieren al cambio en el valor de gris de la parte superior a la parte inferior de la imagen o de la parte inferior a la superior.
El principio de funcionamiento del núcleo de convolución es convolucionarlo con los píxeles de la imagen para extraer las características de la imagen. En este ejemplo, el elemento central del núcleo de convolución es 0, lo que indica que no tiene nada que ver con el píxel central de la imagen. La fila superior de elementos [-1, 0, 1] del núcleo de convolución indica que realiza una operación de convolución con los píxeles superiores de la imagen. De la misma manera, los elementos en la fila inferior del núcleo de convolución [-1, 0, 1] indican que realiza una operación de convolución con los píxeles inferiores de la imagen.

Cuando el núcleo de convolución convoluciona los píxeles de la imagen, si hay bordes verticales en la imagen, los resultados de la convolución mostrarán cambios obvios. Específicamente, en un lado del borde vertical, el resultado de la convolución obtendrá un valor positivo mayor, mientras que en el otro lado del borde vertical, el resultado de la convolución obtendrá un valor negativo mayor. De esta manera, podemos identificar los bordes verticales de la imagen a través de los resultados de convolución umbralizados, y las partes negativas se devuelven directamente a 0.

Por ejemplo, digamos que tenemos una imagen en la que parte de ella es un borde vertical. Aplicamos el núcleo de convolución a la parte del borde vertical de esta imagen, y el resultado de la convolución mostrará valores positivos y negativos, de modo que podamos extraer la posición del borde vertical estableciendo un umbral en el resultado de la convolución.

Espero que este ejemplo pueda ayudarle a comprender por qué la matriz [-1, 0, 1] se puede utilizar para detectar bordes verticales.
Otro ejemplo es
[[-0.1111, -0.1111, -0.1111],
[-0.1111, 1.0000, -0.1111],
[-0.1111, -0.1111, -0.1111]]
que se llama filtro laplaciano o filtro de nitidez. Se puede utilizar para mejorar los bordes de las imágenes.
En esta matriz, el elemento central 1 significa que está relacionado con el píxel central de la imagen. Y los elementos circundantes -0.1111 significa que están relacionados con los píxeles circundantes de la imagen.

Cuando el núcleo de convolución convoluciona con la imagen, el valor del píxel central se amplificará, mientras que el valor de los píxeles circundantes se suprimirá. De esta manera, en el borde de la imagen, debido a los grandes cambios en los valores de los píxeles, el resultado de la convolución mostrará valores positivos y negativos más grandes, mejorando así el contraste del borde.

Por ejemplo, digamos que tenemos una imagen que contiene algunos bordes. Aplicamos este núcleo de convolución a la imagen y el resultado de la convolución mejorará el contraste de los bordes, haciéndolos más claros.

Por lo tanto, este núcleo de convolución puede detectar bordes y hacerlos más obvios mejorando el contraste de los bordes.

borde

El borde es el lugar donde el valor de gris del píxel en la imagen cambia significativamente y generalmente representa información como el borde, el contorno o la textura del objeto en la imagen. En el procesamiento de imágenes y la visión por computadora, la detección de bordes es una técnica comúnmente utilizada que se puede utilizar para segmentar imágenes, extraer características, etc.
Por ejemplo, como se muestra a continuación,
Insertar descripción de la imagen aquí
el efecto de la extracción de bordes
Insertar descripción de la imagen aquí

punto de esquina

Los puntos de esquina son puntos especiales en áreas locales de la imagen con cambios de ángulo obvios. Los puntos de esquina suelen estar formados por la intersección de bordes en diferentes direcciones, tienen curvatura gaussiana y son una de las características importantes de las imágenes. La detección de esquinas también es una tecnología comúnmente utilizada en el registro de imágenes, seguimiento de objetos, coincidencia de imágenes, etc. Los algoritmos de detección de esquinas más utilizados incluyen la detección de esquinas de Harris, la detección de esquinas de Shi-Tomasi, etc.
Como se muestra abajo
Insertar descripción de la imagen aquí

abiertocv

OpenCV (Biblioteca de visión por computadora de código abierto) es una biblioteca de software de aprendizaje automático y visión por computadora de código abierto. Puede ayudar a los desarrolladores a crear rápidamente aplicaciones de visión por computadora, como procesamiento de imágenes, detección de objetos, reconocimiento facial, análisis de video, etc.

OpenCV fue iniciado originalmente por Intel Corporation y ahora se ha convertido en un proyecto de código abierto multiplataforma que admite múltiples lenguajes de programación, incluidos C ++, Python, Java, etc., y puede ejecutarse en sistemas operativos como Windows, Linux, macOS, etc.

Opencv se utiliza aquí para extraer los bordes y esquinas de una determinada imagen, por ejemplo, la imagen es
Insertar descripción de la imagen aquí

No entraré en detalles sobre opencv aquí, lo explicaré más adelante en el artículo.
código

#%%
import cv2  #注意安装open-cv  conda install open-cv
import numpy as np
import matplotlib.pyplot as plt

# 读入lena图像
img = cv2.imread('d:/9.png')
# 将BGR图像转换为RGB图像,便于matplotlib显示
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 将图像转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
gray_ori=gray
# 使用Canny边缘检测函数检测图像的边缘
edges = cv2.Canny(gray, 100, 200)

# 创建SIFT对象
sift = cv2.xfeatures2d.SIFT_create()
# 检测图像的特征点
keypoints = sift.detect(gray, None)
# 在图像上绘制特征点
img_sift = cv2.drawKeypoints(img, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

# 检测图像的角点
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
# 将角点标记为红色
img_corner = img.copy()
img_corner[dst > 0.01 * dst.max()] = [255, 0, 0]

# 创建一个Matplotlib窗口并显示图像及其各种特征
plt.rcParams['font.family'] = 'SimHei'
fig, axs = plt.subplots(2, 2, figsize=(10, 10))
axs[0, 0].imshow(img)
axs[0, 0].set_title('原始图像')
axs[0, 1].imshow(edges, cmap='gray')
axs[0, 1].set_title('边缘')
axs[1, 0].imshow(img_sift)
#SIFT的全称是Scale Invariant Feature Transform,尺度不变特征变换。具有旋转不变性、尺度不变性、亮度变化保持不变性,是一种非常稳定的局部特征。
axs[1, 0].set_title('SIFT特征')
axs[1, 1].imshow(img_corner)
axs[1, 1].set_title('角点特征')
plt.show()

Efecto de salida
Insertar descripción de la imagen aquí

Principio de extracción de características

Lea esta sección después de leer el capítulo [Convolución].
Los núcleos de convolución más utilizados incluyen los siguientes:

  1. Filtro gaussiano: se utiliza para suavizar la imagen, lo que puede reducir el ruido de la imagen.
  2. Filtro de paso alto: se utiliza para resaltar información de alta frecuencia en la imagen, como bordes, esquinas, etc.
  3. Filtro de paso bajo: se utiliza para resaltar información de baja frecuencia en la imagen, como desenfoque, suavizado, etc.
  4. Filtro Sobel: utilizado para detectar información de bordes en imágenes.
  5. Filtro laplaciano: se utiliza para mejorar la información de alta frecuencia de las imágenes, como bordes, detalles, etc.
  6. Filtro Scharr: similar al filtro Sobel, pero responde mejor a los bordes.
  7. Filtro Prewitt: similar al filtro Sobel, pero tiene una respuesta más suave a los bordes.

Estos núcleos de convolución se pueden utilizar para diferentes tareas en el procesamiento de imágenes, como detección de bordes, suavizado de imágenes, mejora de imágenes, etc. Puede elegir núcleos de convolución apropiados para procesar imágenes en función de diferentes tareas.

El núcleo de convolución definido a continuación puede considerarse como un filtro de paso alto, porque a su píxel central se le asigna un peso mayor y los píxeles circundantes tienen pesos más pequeños. Esta distribución de peso permite que el núcleo de convolución detecte información de alta frecuencia en la imagen, como bordes, esquinas, etc. En la operación de convolución, el núcleo de convolución se multiplica por cada píxel de la imagen y los resultados se suman para obtener un nuevo valor de píxel. Si la diferencia entre los valores de píxel alrededor del píxel central del núcleo de convolución y el valor del píxel central es grande, el resultado de la operación de convolución será mayor, lo que indica que este píxel puede ser un punto de borde. Por lo tanto, este núcleo de convolución puede resaltar la información de los bordes en la imagen.

kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])

Hay la siguiente imagen:
Insertar descripción de la imagen aquí
use opencv para cargarlo y convolucionarlo con un núcleo de convolución.

import cv2
import numpy as np
from myutils.common import show,fillColor
# 读取图片
img = cv2.imread('./images/z.png')

# 将图像转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 定义卷积核
kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
# kernel = np.array([[-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1], [-1,-1,20,-1,-1],[-1,-1,-1,-1,-1], [-1,-1,-1,-1,-1]])
# kernel = cv2.getGaussianKernel(5, 1)

# 对灰度图像进行卷积操作,#注意如果-1 <0的值会被归一化为0
edges = cv2.filter2D(gray, cv2.CV_32F, kernel)
print(edges[:][edges<0])
# 对卷积结果进行ReLU处理
edges_relu = np.maximum(0, edges)
show(img,'Original Image',cmap="gray",debug=True)  
show(edges, 'Edges Image',cmap="gray",debug=True)
show(edges_relu, 'Edges ReLU Image',cmap="gray",debug=True)

def show(dilate, title, cmap=None, debug=False):
    if debug:
        plt.title(title)
        plt.imshow(dilate, cmap=cmap)
        plt.show()

Insertar descripción de la imagen aquí

¿Por qué se dice que la operación de convolución extrae características lineales en lugar de usar relu?

Tomemos un ejemplo simple para ilustrar que la operación de convolución en sí misma no puede extraer características no lineales.

Supongamos que tenemos una matriz de entrada X que contiene los siguientes valores:

X = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Ahora, usamos un núcleo de convolución K de tamaño 2x2 para convolucionar X. El valor del núcleo de convolución es el siguiente:

K = [[1, 1], [1, 1]]

Podemos usar la multiplicación de matrices para realizar operaciones de convolución. Específicamente, volteamos la matriz K y realizamos una operación de producto escalar con la matriz X para obtener una matriz de salida Y:

Y = K*X = [[12, 16], [24, 28]]

Se puede ver que la matriz de salida Y es una combinación lineal de la matriz de entrada X, por lo que la operación de convolución en sí solo puede extraer características lineales de la matriz de entrada X, como bordes y texturas.

Sin embargo, cuando usamos una función de activación no lineal, como la función de activación ReLU, para procesar la matriz de salida Y, podemos convertir características lineales en características no lineales. Por ejemplo, cuando aplicamos la función ReLU a Y, las características no lineales resultantes son:

ReLU(Y) = [[12, 16], [24, 28]]

Por lo tanto, la operación de convolución por sí sola solo puede extraer características lineales de la matriz de entrada, pero cuando se combina con una función de activación no lineal, se pueden extraer características no lineales.

circunvolución

Entonces, ¿cómo se calculan estas características para hacer coincidir? (¡No me digas que los píxeles coinciden uno por uno, sudor!)
En este momento, tenemos que invitar al invitado importante de hoy: la convolución. Entonces, ¿qué es la convolución? No te preocupes, lo explicaré lentamente a continuación.
Cuando se proporciona una nueva imagen, CNN no sabe exactamente qué partes de la imagen original deben coincidir estas características, por lo que intentará todas las posiciones posibles en la imagen original, lo que equivale a convertir esta característica en un filtro. Este proceso de coincidencia se denomina operación de convolución, que también es el origen del nombre de la red neuronal convolucional.
La operación de convolución se muestra en la siguiente figura:
Insertar descripción de la imagen aquí

La parte amarilla es un núcleo de convolución, que son todas [1,0,1]].[0,1,0]
[[1,0,1]las características 3 * posibles extraídas


En este caso, para calcular una característica (característica) y el resultado de un determinado parche pequeño correspondiente a ella en la imagen original, solo necesita multiplicar los valores de píxeles en las posiciones correspondientes en los dos parches pequeños y luego multiplicar todo el parche pequeño. Los resultados de la operación se acumulan y finalmente se dividen por el número total de píxeles en el bloque pequeño (nota: no es necesario dividir por el número total).
Si ambos píxeles son blancos (ambos tienen un valor de 1), entonces 1 1 = 1, si ambos son negros, entonces (-1) (-1) = 1, es decir, cada par de píxeles puede coincidir, el resultado de la multiplicación es 1. De manera similar, los píxeles que no coinciden se multiplican por -1. El proceso específico es el siguiente (resultados coincidentes del primer, segundo..., último píxel):
Primero, use una de las tres características que extrajimos anteriormente para la convolución
Insertar descripción de la imagen aquí
, por ejemplo, encierre en un círculo la primera característica con un marco verde. Comparación de partes es exactamente lo mismo.
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
De acuerdo con el método de cálculo de convolución, el cálculo de convolución después de la primera coincidencia de características es el siguiente y el resultado es 1. La
Insertar descripción de la imagen aquí
coincidencia de otras posiciones también es similar (como la coincidencia de la parte media)
Insertar descripción de la imagen aquí
y Así sucesivamente. Para los tres La imagen de característica repite continuamente el proceso anterior. A través de la operación de convolución de cada característica (característica), se obtendrá una nueva matriz bidimensional, llamada mapa de características (mapa de características ) . Cuanto más cerca esté el valor de 1, más completa será la coincidencia entre la posición correspondiente y la característica. Cuanto más cerca esté de -1, más completa será la coincidencia entre la posición correspondiente y el lado opuesto de la característica. Cuanto más cerca esté el valor es 0, más completa será la coincidencia entre la posición correspondiente y la característica. Cuanto más cerca esté el valor de 0, más completa será la coincidencia entre la posición correspondiente y la característica. Como se muestra en la siguiente figura:
Insertar descripción de la imagen aquí
Se puede ver que cuando aumenta el tamaño de la imagen, la cantidad de operaciones internas de suma, multiplicación y división aumentará muy rápidamente, y el tamaño de cada filtro y la cantidad de filtros crecerán linealmente. Con tantos factores en juego, la cantidad de cálculos puede llegar a ser bastante grande.

Agrupación

Para reducir eficazmente la cantidad de cálculo, otra herramienta eficaz utilizada por CNN se llama "Pooling". La agrupación consiste en reducir la imagen de entrada, reducir la información de píxeles y retener solo la información importante. La operación de agrupación también es muy simple: por lo general, el área de agrupación tiene un tamaño de
2 2 y luego se convierte en los valores correspondientes de acuerdo con ciertas reglas, como tomar el valor máximo (agrupación máxima) y la media (media). en el área de agrupación. -pooling), etc., utilice este valor como valor de píxel resultante.
La siguiente figura muestra
el resultado de la agrupación máxima del área de agrupación 2 2 en la esquina superior izquierda. Tome el máximo máximo (0,77, -0,11, -0,11,1,00) de esta área como resultado agrupado, como se muestra en la figura siguiente : Área de agrupación a la
Insertar descripción de la imagen aquí
izquierda, el segundo bloque pequeño toma el valor máximo max (0.11, 0.33, -0.11, 0.33) como resultado de la agrupación, como se muestra a continuación: Las otras áreas
Insertar descripción de la imagen aquí
son similares, tomando el valor máximo en el área como el resultado de la agrupación, y finalmente después de la agrupación, el resultado es el siguiente:
Insertar descripción de la imagen aquí
realice la misma operación en todos los mapas de características, el resultado es el siguiente:
Insertar descripción de la imagen aquí
max-pooling retiene el valor máximo en cada bloque pequeño, lo que equivale a retener el mejor valor de este bloque. El resultado de la coincidencia (ya que un valor más cercano a 1 significa una mejor coincidencia). En otras palabras, no se centrará específicamente en qué lugar de la ventana coincide, sino sólo en si hay una coincidencia en alguna parte.
Al agregar una capa de agrupación, la imagen se reduce, lo que puede reducir en gran medida la cantidad de cálculo y reducir la carga de la máquina.

Función de activación ReLU (Unidades Lineales Rectificadas)

Las funciones de activación comúnmente utilizadas incluyen sigmoide, tanh, relu, etc. Las dos primeras, sigmoide/tanh, son más comunes en capas completamente conectadas, y la última, ReLU, es común en capas convolucionales.
Mirando hacia atrás en el perceptrón mencionado anteriormente, el perceptrón recibe cada entrada, luego la suma y luego la emite después de pasar por la función de activación. La función de la función de activación es agregar factores no lineales y realizar un mapeo no lineal de los resultados de salida de la capa convolucional.
Insertar descripción de la imagen aquí
En las redes neuronales convolucionales, la función de activación generalmente utiliza ReLU (Unidad lineal rectificada, unidad lineal modificada), que se caracteriza por una convergencia rápida y un cálculo de gradiente simple. La fórmula de cálculo también es muy simple, max (0, T), es decir, para valores de entrada negativos, la salida es todo 0 y para valores positivos, la salida no cambia.
Echemos un vistazo al proceso de operación de la función de activación ReLU en este caso:
el primer valor se toma como max(0,0.77) y el resultado es 0.77, como se muestra a continuación. El
Insertar descripción de la imagen aquí
segundo valor se toma como max(0,0,77) y el resultado es 0,77, como se muestra a continuación. -0.11), y el resultado es 0, como se muestra a continuación Figura
Insertar descripción de la imagen aquí
Por analogía, después de pasar la función de activación ReLU, los resultados son los siguientes:
Insertar descripción de la imagen aquí
Ejecute la operación de la función de activación ReLU en todos los mapas de características, y los resultados son los siguientes:
Insertar descripción de la imagen aquí

red neuronal profunda

Al combinar la convolución, la función de activación y la agrupación mencionadas anteriormente, se obtiene la siguiente figura:
Insertar descripción de la imagen aquí
al aumentar la profundidad de la red y agregar más capas, se obtiene una red neuronal profunda, como se muestra a continuación:
Insertar descripción de la imagen aquí

Capas completamente conectadas

La capa completamente conectada desempeña el papel de un "clasificador" en toda la red neuronal convolucional, es decir, después de pasar por redes profundas como convolución, función de activación y agrupación, los resultados se identifican y clasifican a través de la capa completamente conectada.
Primero, los resultados de la red profunda después de la convolución, la función de activación y la agrupación se unen, como se muestra en la siguiente figura:
Insertar descripción de la imagen aquí
Dado que la red neuronal pertenece al aprendizaje supervisado, durante el entrenamiento del modelo, el modelo se entrena en función de las muestras de entrenamiento para obtenga una conexión completa El peso de la capa (como el peso de todas las conexiones que predicen la
Insertar descripción de la imagen aquí
letra. Los resultados calculados se ponderan y suman para obtener el valor predicho de cada resultado, y luego el valor más grande se toma como resultado del reconocimiento (como se muestra En la figura siguiente, el valor de reconocimiento final calculado de la letra X es 0,92 y el valor de reconocimiento de la letra O es 0,51, entonces se considera que el resultado
Insertar descripción de la imagen aquí
es
Insertar descripción de la imagen aquí

Redes neuronales convolucionales

Después de encadenar todos los resultados anteriores, se forma una estructura de "red neuronal convolucional" (CNN), como se muestra en la siguiente figura: Finalmente, para
Insertar descripción de la imagen aquí
revisar y resumir, la red neuronal convolucional consta principalmente de dos partes, una parte es la extracción de características. (convolución, función de activación, agrupación) y la otra parte es el reconocimiento de clasificación (capa completamente conectada). La siguiente figura es el famoso diagrama de estructura de la red neuronal convolucional de reconocimiento de texto escrito a mano:
Insertar descripción de la imagen aquí

Referencia para el contenido de este capítulo: https://my.oschina.net/u/876354/blog/1620906

API de convolución

Conv2D

Conv2D es una de las capas centrales de las redes neuronales convolucionales y se utiliza para el procesamiento convolucional de imágenes u otros datos bidimensionales. La función de Conv2D es realizar una serie de operaciones de convolución en la imagen o datos bidimensionales de entrada a través del núcleo de convolución, extrayendo así las características de la imagen o los datos.

La entrada de la capa Conv2D es un tensor. La forma del tensor suele ser (tamaño de lote, altura, ancho, canal), donde tamaño de lote representa el número de datos de entrada, la altura y el ancho representan la altura y el ancho de los datos de entrada, y canal representa el número de canales de los datos de entrada (por ejemplo, el número de canales de una imagen RGB es 3).

La salida de la capa Conv2D también es un tensor, que representa el mapa de características obtenido después de la operación de convolución. La forma del tensor de salida suele ser (batch_size, conv_height, conv_width, filters), donde conv_height y conv_width representan la altura y el ancho del mapa de características obtenido después de aplicar el kernel de convolución, y los filtros representan el número de kernels de convolución, es decir , el número de canales del mapa de características de salida.

Durante el proceso de convolución, la capa Conv2D aplica el núcleo de convolución a los datos de entrada y, al calcular la operación de convolución entre cada núcleo de convolución y los datos de entrada uno por uno, se obtiene el mapa de características de salida convolucionada. Durante el proceso de convolución, los parámetros como el tamaño, el tamaño del paso y el método de llenado del núcleo de convolución se pueden configurar libremente para adaptarse a diferentes escenarios de aplicación.
En TensorFlow 2.0 y Keras, puedes crear una capa Conv2D con el siguiente código:

from tensorflow.keras.layers import Conv2D

conv_layer = Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu', input_shape=(height, width, channel))
  • filtros: el número de núcleos de convolución, es decir, el número de mapas de características de salida.
  • kernel_size: el tamaño del núcleo de convolución, que puede ser un número entero, que indica la longitud lateral de un núcleo de convolución cuadrado, o una tupla, que indica núcleos de convolución con diferentes longitudes y anchos.
  • zancadas: zancada, que es la distancia que se mueve el núcleo de convolución en el mapa de características de entrada. Puede ser un número entero, que indica la distancia entre dos núcleos de convolución adyacentes, o puede ser una tupla, que indica que el tamaño del paso es diferente en las direcciones de largo y ancho.
  • padding: método de relleno, puede ser "igual" o "válido". "igual" significa que el tamaño del mapa de características de salida es el mismo que el tamaño del mapa de características de entrada, y algunos valores deben rellenarse alrededor del mapa de características de entrada; "válido" significa que no se requiere relleno, y El tamaño del mapa de características de salida se basará en el mapa de características de entrada y el núcleo de convolución y varía con el tamaño.
  • activación: función de activación, utilizada para agregar transformación no lineal al mapa de características. Las funciones de activación comunes incluyen 'relu', 'sigmoide', 'tanh', etc.
  • input_shape: la forma del mapa de características de entrada, que puede ser un triplete que representa la altura, el ancho y el número de canales. Este parámetro debe especificarse en la primera capa convolucional.
  • kernel_regularizer: en el aprendizaje profundo, para evitar el sobreajuste del modelo, generalmente se usa tecnología de regularización para restringir el modelo. Uno de los métodos de regularización más utilizados es la regularización L2. La regularización L2 se refiere a agregar un término de penalización de norma L2 a la función de pérdida del modelo para limitar el tamaño del peso del modelo.
    En Keras, use regularizers.l2(0.001) para agregar una penalización de regularización L2. Entre ellos, 0.001 es el parámetro de regularización, que controla la fuerza de la regularización. Cuanto mayor sea el parámetro de regularización, mayor será el impacto del término de penalización en el peso y se reducirá la complejidad del modelo, evitando así eficazmente el sobreajuste.
    Específicamente, regularizers.l2(0.001) se puede aplicar a cualquier matriz de peso en redes neuronales, como capas completamente conectadas, capas convolucionales, etc. En la definición de la red, podemos agregar regularización L2 usando el parámetro kernel_regularizer en la capa correspondiente. Por ejemplo, el código para agregar una capa completamente conectada con regularización L2 en Keras es el siguiente:
layers.Conv2D(32, (3, 3), activation='relu', kernel_regularizer=regularizers.l2(0.001), input_shape=(28, 28, 1)),

Ejemplo de convolución

Tome fotografías de minist10 y utilice 10 núcleos de convolución para la convolución, genere mapas de características y muestre la imagen.
Debido a que cada imagen generará 10 núcleos de convolución, se generarán un total de 100 mapas de características.

#%%
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# 加载mnist数据集
mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# 取1张训练集图片
images = train_images[:10]

# 将图片转换为float类型
images = images.astype('float32') / 255.0
# 将图片reshape成4D张量,大小为(10, 28, 28, 1),也就是第一个维度表示有10张图像,每张图像由28行、28列和1个# 通道(灰度)组成
images = np.expand_dims(images, axis=3)
# 定义卷积核数量
num_filters = 10

# 定义卷积层
model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(num_filters, (3, 3), activation='relu', input_shape=(28, 28, 1)),
])

# 计算卷积后的特征图
features = model.predict(images)

# 绘制卷积后的特征图
fig, axs = plt.subplots(nrows=num_filters, ncols=10, figsize=(10, num_filters))
for i in range(num_filters):
    for j in range(10):
        axs[i][j].imshow(features[j, :, :, i], cmap='gray')
        axs[i][j].axis('off')
plt.show()

producción
Insertar descripción de la imagen aquí

La función np.expand_dims se utiliza para expandir las dimensiones de una matriz en el eje especificado. En este ejemplo, imágenes es una matriz de formas (10, 28, 28), que representa 10 imágenes en escala de grises de 28x28. Sin embargo, los modelos de aprendizaje automático generalmente necesitan ingresar una matriz de 4 dimensiones, es decir (número de muestras, altura de la imagen, ancho de la imagen, número de canales). Por lo tanto, necesitamos expandir la última dimensión (número de canales) de la matriz de imágenes en una dimensión y convertirla en una matriz de forma (10, 28, 28, 1).
Específicamente, eje = 3 significa expandir las dimensiones en el tercer eje de la matriz (contando desde 0), lo que agrega una dimensión a la última dimensión de cada imagen, convirtiendo cada imagen en una forma de (28, 28, 1) tres. matriz dimensional. Finalmente, la forma de la matriz de imágenes pasa a ser (10, 28, 28, 1), lo que significa que hay 10 imágenes en escala de grises de 28x28, cada imagen consta de un canal. De esta forma, las imágenes se pueden pasar como entrada al modelo de aprendizaje automático.

Como se puede ver en la imagen de salida anterior, la salida de algunos núcleos de convolución está sesgada hacia los bordes, algunas esquinas y algunas texturas.

MaxPooling2D

keras.layers.MaxPooling2D((2, 2)) es una capa en Keras que se utiliza para operaciones de agrupación máximas.
La agrupación máxima es una operación de red neuronal convolucional de uso común que puede reducir la cantidad de parámetros en una imagen sin cambiar el tamaño de la imagen, reduciendo así la cantidad de cálculo y el consumo de memoria. La operación de agrupación máxima divide la imagen de entrada en bloques que no se superponen y toma el valor máximo para cada bloque como salida. En las redes neuronales convolucionales, la agrupación máxima generalmente se usa indistintamente con capas convolucionales para extraer características espaciales de imágenes.

El parámetro de la capa MaxPooling2D es una tupla (2, 2), lo que indica que el tamaño de la ventana de agrupación es 2x2. Esto significa que la imagen de entrada se dividirá en varios bloques de tamaño 2x2 y el valor máximo de cada bloque se tomará como salida. Si el tamaño de la ventana de agrupación se establece en (3, 3), la imagen de entrada se dividirá en varios bloques de tamaño 3x3 y el valor máximo de cada bloque se tomará como salida.

En resumen, la capa MaxPooling2D puede ayudar a la red neuronal convolucional a extraer las características espaciales de la imagen al tiempo que reduce la cantidad de cálculo y el consumo de memoria.

Aplanar

keras.layers.Flatten() es una capa en Keras que se utiliza para "aplanar" la entrada en un vector unidimensional.

En una red neuronal convolucional, las capas convolucionales y las capas de agrupación generalmente se usan para extraer características de las imágenes, y luego se usan capas completamente conectadas para la clasificación. La entrada de la capa completamente conectada es un vector unidimensional, por lo que el mapa de características anterior debe "aplanarse" en un vector unidimensional. Esto es lo que hace la capa Aplanar.

La capa Aplanar no tiene ningún parámetro, simplemente despliega el tensor de entrada en un vector unidimensional en orden. Por ejemplo, si el tensor de entrada tiene forma (batch_size, 7, 7, 64), la forma de salida de la capa Aplanar es (batch_size, 7 7 64 ).

Al construir una red neuronal convolucional, generalmente se agrega una capa Aplanar después de la capa convolucional y la capa de agrupación para aplanar el mapa de características en un vector unidimensional y luego conectarlo a la capa completamente conectada para su clasificación.

Denso|Abandono

Ver perceptrón multicapa

Reconocimiento de dígitos escritos a mano

Conjunto de datos mnist convolucional

Cargaremos el conjunto de datos MNIST y lo preprocesaremos, escalaremos los valores de píxeles entre 0 y 1 y dividiremos el conjunto de datos en conjuntos de entrenamiento y prueba.
Para obtener una explicación detallada del procesamiento de datos, consulte el perceptrón multicapa.

import tensorflow as tf
import tensorflow.keras
from tensorflow.keras import layers
from tensorflow.keras.datasets import mnist
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import regularizers
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.

x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

num_classes = 10

y_train = tf.keras.utils.to_categorical(y_train, num_classes)
y_test = tf.keras.utils.to_categorical(y_test, num_classes)

A continuación, definiremos un modelo de red neuronal convolucional. Usaremos dos capas convolucionales y dos capas de agrupación, seguidas de dos capas completamente conectadas y una capa de salida. También utilizaremos la deserción y la regularización L2 para evitar el sobreajuste.

model = tf.keras.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', kernel_regularizer=regularizers.l2(0.001), input_shape=(28, 28, 1)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu', kernel_regularizer=regularizers.l2(0.001)),
    layers.MaxPooling2D((2, 2)),
    layers.Flatten(),
    layers.Dense(128, activation='relu', kernel_regularizer=regularizers.l2(0.001)),
    layers.Dropout(0.5),
    layers.Dense(64, activation='relu', kernel_regularizer=regularizers.l2(0.001)),
    layers.Dropout(0.5),
    layers.Dense(num_classes, activation='softmax')
])

model.summary() es un método del objeto modelo en Keras, que se utiliza para imprimir la información estructural del modelo, incluido el nombre de cada capa, la forma de salida, la cantidad de parámetros, etc. Esto es útil para depurar, optimizar el modelo y comprender la estructura del modelo.

model.summary()

Luego compilaremos el modelo y utilizaremos técnicas de aumento de datos para evitar aún más el sobreajuste. La tecnología de aumento de datos aplicará una serie de transformaciones aleatorias, como rotación, traducción, escalado, etc., para generar nuevas muestras de entrenamiento. Esto hace que el modelo sea más robusto y evita el sobreajuste.

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

datagen = ImageDataGenerator(
    rotation_range=10,
    width_shift_range=0.1,
    height_shift_range=0.1,
    zoom_range=0.1
)

A continuación, usaremos el conjunto de entrenamiento para entrenar el modelo y el conjunto de prueba para evaluar el desempeño del modelo.

datagen.fit(x_train)
batch_size = 1024
epochs = 10
checkpoint = tf.keras.callbacks.ModelCheckpoint('./model.h5', save_best_only=True, save_weights_only=False, monitor='val_loss')
history = model.fit(datagen.flow(x_train, y_train, batch_size=batch_size),
                    epochs=epochs,
                    validation_data=(x_test, y_test),
                    steps_per_epoch=len(x_train) // batch_size,callbacks=[checkpoint])

score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

La diferencia entre pasos_por_época y tamaño de lote
es que el tamaño de lote se refiere a la cantidad de muestras incluidas en cada lote de entrenamiento (lote). En el aprendizaje profundo, el conjunto de entrenamiento generalmente se divide en varios lotes y cada lote contiene varias muestras. La ventaja de esto es que las operaciones matriciales se pueden utilizar para acelerar los cálculos y el orden de las muestras también se puede alterar aleatoriamente durante el proceso de entrenamiento para evitar el sobreajuste.

steps_per_epoch se refiere a la cantidad de lotes que el modelo necesita entrenar en una época. Dado que cada época contiene varios lotes, es necesario configurar pasos_per_epoch para especificar cuántos lotes deben pasarse en una época. Por lo general, el valor de step_per_epoch se puede calcular a partir del tamaño del conjunto de entrenamiento y del tamaño del lote. Por ejemplo, si el tamaño del conjunto de entrenamiento es 1000 y el tamaño del lote es 32, entonces se deben entrenar 1000/32 = 31 lotes en una época, por lo que los pasos_por_época deben establecerse en 31.

Cabe señalar que los pasos_por_época no son necesariamente iguales al tamaño del conjunto de entrenamiento dividido por el tamaño del lote. Si el tamaño del conjunto de entrenamiento no es divisible por el tamaño del lote, entonces el último lote puede contener menos muestras que el tamaño del lote. Para evitar esta situación, puede utilizar la operación de redondeo hacia abajo // para calcular los pasos_por_época y garantizar que todo el conjunto de entrenamiento pueda procesarse en cada época.

sintonia FINA

El ajuste fino se refiere al método de ajustar un modelo ya entrenado para tareas específicas o conjuntos de datos específicos para lograr un mejor rendimiento. Por lo general, utilizaremos un modelo previamente entrenado en un conjunto de datos a gran escala, como ImageNet y otros conjuntos de datos. Este modelo ha aprendido muchas características y patrones comunes durante el proceso de entrenamiento. Podemos ajustar este modelo, ajustar algunos parámetros o agregar algunas capas nuevas para que este modelo sea más adecuado para nuevas tareas o nuevos conjuntos de datos. Este enfoque suele ser más eficiente que entrenar un modelo desde cero porque el modelo previamente entrenado ya tiene buenos pesos iniciales y capacidades de extracción de características.

conjunto de datos mnist-c

MNIST-C es una variante del conjunto de datos MNIST, que es un conjunto de datos MNIST al que se le ha agregado ruido artificial. El conjunto de datos MNIST es un conjunto de datos de reconocimiento de dígitos escritos a mano que contiene 60.000 muestras de entrenamiento y 10.000 muestras de prueba, cada muestra es una imagen en escala de grises de 28 x 28 píxeles. El conjunto de datos MNIST-C se crea agregando ruido aleatorio a las imágenes del conjunto de datos MNIST, que incluyen desenfoque, distorsión, cambios de brillo, etc., lo que hace que el modelo sea más robusto.

El conjunto de datos MNIST-C es muy útil para probar la solidez de los modelos de aprendizaje automático porque puede probar la robustez del modelo ante diferentes tipos de ruido. Cada imagen del conjunto de datos MNIST-C contiene una etiqueta que indica el número que representa. Estas etiquetas son idénticas a las etiquetas correspondientes en el conjunto de datos MNIST, por lo que puede utilizar el mismo proceso de entrenamiento y prueba para entrenar y probar su modelo.

Descargue el conjunto de datos en https://github.com/google-research/mnist-c/. Esta dirección de github es la dirección del código fuente. La dirección de descarga real se menciona en el archivo Léame: https://zenodo.org/record /3239543# .ZF2rzXZByUl, descargar y descomprimir.
Insertar descripción de la imagen aquí
Estas carpetas son todas exportaciones de matrices numerosas en formato npy.
Lea las primeras 10 imágenes de cada carpeta para mostrar

# 数据集的开源地址:https://github.com/google-research/mnist-c/
import os
import numpy as np
import matplotlib.pyplot as plt
#加载数据集并打印每个子文件夹前10个数据集
data_root = './mnist_c'
dirlist=os.listdir(data_root)
fig, axs = plt.subplots(len(dirlist), 10, figsize=(10, 10))

for i, folder_name in enumerate(dirlist):
    folder_path = os.path.join(data_root, folder_name)
    if os.path.isdir(folder_path):
        file_path = os.path.join(folder_path, 'train_images.npy')
        data = np.load(file_path)
        for j in range(0,10):
            axs[i, j].imshow(data[j].reshape(28,28), cmap='gray')
            axs[i, j].axis('off')
plt.tight_layout()
plt.show()

producción
Insertar descripción de la imagen aquí

entrenamiento del método de ajuste fino

Supongamos que comenzamos a probar el modelo entrenado de minist en ./model.h5. Necesitamos cargar el modelo y luego probarlo para continuar entrenando los datos de minist-c.

#%%

import os
import numpy as np
import tensorflow.keras as layers
import tensorflow as tf
import datetime

TARGET_MODEL_DIR="./"
MODEL_NAME="model.h5"
epochs_count=5
"""
   jupyter打印的日志太大导致ipynb打开很慢,这里写个一模一样代码的py运行
"""
def againTrain(x_train, y_train, x_test, y_test):
    targetModel=os.path.join(TARGET_MODEL_DIR,MODEL_NAME)
    #记载CNN模型
    model=tf.keras.models.load_model(targetModel)
    """
    在使用Fine-tuning方法微调预训练模型时,通常会冻结模型的前几层,只调整模型的后面几层,这是因为:
    1.预训练模型的前几层通常是针对原始数据集的通用特征提取器,这些特征对于不同的任务和数据集都是有用的,因此我们可以直接保留这些特征提取器,不需要进行微调。
    2.预训练模型的后几层通常是针对特定任务进行的微调,这些层的参数需要根据具体任务和数据集进行调整,以使模型更好地适应特定的任务和数据集。
    3.如果我们将整个模型的所有层都进行微调,会导致训练时间较长,而且可能会出现过拟合等问题。因此,冻结前几层可以有效地减少训练时间,并提高模型的泛化能力。
    总之,冻结模型的前几层可以节省计算资源和训练时间,同时还可以提高模型的泛化能力,使其更好地适应新的任务和数据集。
    """
    model.layers[0].trainable = False
    model.layers[1].trainable = False
    # 对输入图像进行预处理
    x_train = x_train.reshape(-1, 28, 28, 1)
    x_train = x_train.astype('float32') / 255.0
    x_test = x_test.reshape(-1, 28, 28, 1)
    x_test = x_test.astype('float32') / 255.0
    y_train = tf.keras.utils.to_categorical(y_train, num_classes=10)
    y_test = tf.keras.utils.to_categorical(y_test, num_classes=10)
    now = datetime.datetime.now()  # 获取当前时间
    format_time = now.strftime("%Y-%m-%d%H-%M-%S")  # 转换为指定格式
    checkpoint = tf.keras.callbacks.ModelCheckpoint(targetModel, save_best_only=True, save_weights_only=False, monitor='val_loss')
    # 继续训练模型
    history = model.fit(x_train, y_train, batch_size=128, epochs=epochs_count, validation_data=(x_test, y_test),
                        callbacks=[checkpoint])
    test_loss, test_acc = model.evaluate(x_test, y_test)
    print('Test accuracy:', test_acc)
"""
  传入mnist-c,数据会非常大加载数据很慢,这里每加载一份子目录就训练一次,节省内存开销。
"""
def loadDataMnistC(data_root,func):
    dirlist=os.listdir(data_root)
    for i, folder_name in enumerate(dirlist):
        folder_path = os.path.join(data_root, folder_name)
        if os.path.isdir(folder_path):
            print("开始读取:"+folder_path)
            train_images = np.load(os.path.join(folder_path, 'train_images.npy'))
            train_labels = np.load(os.path.join(folder_path, 'train_labels.npy'))
            test_images = np.load(os.path.join(folder_path, 'test_images.npy'))
            test_labels = np.load(os.path.join(folder_path, 'test_labels.npy'))
            print("开始训练:"+folder_path)
            func(train_images,train_labels,test_images,test_labels)
            print("训练完成:"+folder_path)
# 加载 MNIST-C 数据集
data_root = './mnist_c'
model=None;
loadDataMnistC(data_root,againTrain)
print("全部训练完成")

Aquí, se lee un determinado tipo una vez cada vez y luego el modelo se vuelve a escribir en la subcarpeta para el entrenamiento y se obtiene el modelo final hasta que se completa el entrenamiento.

Supongo que te gusta

Origin blog.csdn.net/liaomin416100569/article/details/130597944
Recomendado
Clasificación