Análisis de detección de objetivos más rápido R-CNN

Introducción

Faster R-CNN es un algoritmo de detección de objetivos de dos etapas propuesto por Ross B. Girshick en 2016. Faster R-CNN integra la extracción de características, la red de propuesta de región para la extracción de la región de interés y la regresión y clasificación final del cuadro delimitador en una sola red, lo que mejora en gran medida el rendimiento general de la red.
Este artículo analiza Faster R-CNN desde los siguientes cuatro aspectos:

  1. Capas de conv. Faster R-CNN primero usa un conjunto de capas simples de conv+relu+pooling para extraer mapas de características de la imagen de entrada. Estos mapas de características se compartirán para la capa RPN subsiguiente y la capa completamente conectada;
  2. Región Propuesta Redes. La red RPN se usa para generar propuestas de regiones efectivas.Esta capa juzga si el ancla pertenece a positivo (fondo) o negativo (primer plano) a través de softmax, y luego usa la regresión de cuadro delimitador para corregir las anclas para obtener propuestas precisas;
  3. Puesta en común del retorno de la inversión. Esta capa recopila los mapas de características de entrada y las propuestas y, después de sintetizar esta información, extrae los mapas de características de la propuesta y los envía a la siguiente capa totalmente conectada;
  4. Clasificación y regresión Utilice los mapas de características de la propuesta para calcular la categoría de las propuestas y vuelva a realizar la regresión del cuadro delimitador para obtener la posición final precisa;

columna vertebral

Tomando VGG16 como ejemplo, presente la composición principal de Faster R-CNN. La columna vertebral contiene tres capas de conv, relu y pooling.Como se muestra en la siguiente figura, hay 13 capas de conv, 13 capas de relu y 4 capas de pooling.
imagen.png
La configuración de parámetros de todas las capas convolucionales es la misma, kernel_size=3, pad=1, stride=1, es decir, los tamaños del mapa de características de entrada y salida son los mismos, y los parámetros de la capa de agrupación se establecen en: kernel_size= 2, pad=0, stride =2, es decir, el tamaño de salida es solo la mitad del tamaño de entrada.
Dado que toda la red troncal contiene 4 capas de agrupación, se supone que el tamaño de la imagen de entrada es M ∗ NM *NMETRON , luego, después de la inferencia de la columna vertebral, el tamaño del mapa de características de salida esM 16 ∗ N 16 \frac{M}{16}*\frac{N}{16}dieciséismdieciséisnorte.

Redes de Propuestas Regionales(RPN)

Una vez que la red troncal proporciona las características de la imagen, la imagen de entrada ingresa a la red RPN. Los resultados específicos se muestran en la siguiente figura: La red RPN se divide
imagen.png
en dos ramas: clasificación y regresión. La rama de clasificación usa sotfmax para clasificar la red predeterminada. el anclaje del marco candidato es positivo o negativo; la rama de regresión es responsable de predecir el desplazamiento del cuadro objetivo real en relación con el cuadro candidato predeterminado. Finalmente, la capa Propuesta combina el ancla positiva y el desplazamiento de regresión correspondiente para obtener la propuesta.
El siguiente tamaño de imagen de entrada es C = 3, H = 576, W = 1024 C = 3, H = 576, W = 1024C=3 ,H=576 ,W=1024 casos, después de que la red troncal extrae la característica, el tamaño del mapa de características es1x512x36x64(disposición NCHW).

anclas

En Faster R-CNN, se proporcionan 9 anclas de diferentes tamaños y diferentes relaciones de aspecto, que contienen cuatro valores ( x 1 , y 1 , x 2 , y 2 ) (x_1,y_1,x_2,y_2)( X1,y1,X2,y2) representa las coordenadas de las esquinas superior izquierda e inferior derecha del rectángulo, y el ancla se muestra en la siguiente figura:

Una cosa a tener en cuenta es queel tamaño del ancla en Faster R-CNN es relativo al tamaño de entrada de la red. Tome el tamaño de la imagen de entrada comoC = 3, H = 576, W = 1024 C = 3, H = 576, W = 1024C=3 ,H=576 ,W=1024 casos, Faster R-CNN contiene un total de:
ceil ( 1024 / 16 ) ∗ ceil ( 576 / 16 ) ∗ 9 = 64 ∗ 36 ∗ 9 = 20736 ceil(1024/16)*ceil(576/16)*9 =64 *36*9=20736ce i l ( 1024/16 )ce i l ( 576/16 )9=64369=20,736
anclas, estas anclas se reflejan en la entrada de la red, como se muestra en la figura a continuación, para cada ancla se requiere una rama de clasificación para determinar si contiene objetos, y la inclusión de objetos es positiva, de lo contrario es negativa. Al mismo tiempo, dado que existe un desplazamiento entre la posición real del objetivo y el ancla, se necesita la rama de regresión para predecir el desplazamiento.
imagen.png

rama softmax

Después del backbone, el tamaño del mapa de características es 1x512x36x64, primero a través de la convolución 1×1, el tamaño del mapa de características obtenido es 1x18x36x64, entre ellos 18=2*9, hay 9 anclas, y cada ancla puede ser positiva o negativa.
imagen.png
Luego hay una operación de remodelación, la dimensión del mapa de características obtenido 1x2x36*9x64es principalmente para la conveniencia de la clasificación softmax, y luego se remodela para restaurar el estado original. El fragmento de código de implementación de la rama de clasificación es el siguiente:

# define bg/fg classifcation score layer
self.nc_score_out = len(self.anchor_scales) * len(self.anchor_ratios) * 2 # 2(bg/fg) * 9 (anchors)
self.RPN_cls_score = nn.Conv2d(512, self.nc_score_out, 1, 1, 0)		# 1×1卷积

def forward():		# 前向推理
	# get rpn classification score
    rpn_cls_score = self.RPN_cls_score(rpn_conv1)
	# reshape + softmax + reshape
    rpn_cls_score_reshape = self.reshape(rpn_cls_score, 2)
    rpn_cls_prob_reshape = F.softmax(rpn_cls_score_reshape, 1)
    rpn_cls_prob = self.reshape(rpn_cls_prob_reshape, self.nc_score_out)

La clasificación sotfmax obtiene anclas positivas, lo que equivale a extraer inicialmente el área candidata al objetivo de detección.

rama de regresión

La regresión de rama de regresión obtiene el desplazamiento entre el ancla y la verdad del suelo, por lo que en la fase de entrenamiento, la señal de supervisión es la brecha entre el ancla y el marco real ( tx , ty , tw , th ) (t_x,t_y,t_w , t_h)( tx,ttu,tw,th),其中tx , ty t_x,t_ytx,ttues el valor de traslación del punto central, tw , th t_w,t_htw,thes el valor de escala de ancho y alto. ( tx , ty , tw , th ) (t_x,t_y,t_w,t_h)( tx,ttu,tw,th) se calcula de la siguiente manera:
tx = ( x − xa ) / wa ; ty = ( y − ya ) / ha t_x = (x - x_a)/w_a; t_y=(y-y_a)/h_atx=( XXun) / wun;ttu=( yyun) / horaun
tw = registro ( w / wa ) ; th = log ( h / ha ) t_w=log(w/w_a);t_h=log(h/h_a)tw=logaritmo ( w / w _ _un) ;th=log ( h / h _ _un)
de los cualesxa , ya , wa , ha x_a, y_a, w_a, h_aXun,yun,wun,hunEs el valor de la coordenada del ancla. El fragmento de código de la rama de regresión es el siguiente:

# define anchor box offset prediction layer
self.nc_bbox_out = len(self.anchor_scales) * len(self.anchor_ratios) * 4 # 4(coords) * 9 (anchors)
self.RPN_bbox_pred = nn.Conv2d(512, self.nc_bbox_out, 1, 1, 0)

def forward():
    # get rpn offsets to the anchor boxes
    rpn_bbox_pred = self.RPN_bbox_pred(rpn_conv1)

Capa de propuesta

La capa de propuesta calcula una propuesta precisa a través de los anclajes positivos y su compensación de regresión correspondiente, y la envía a la capa de agrupación de RoI posterior. La definición de la capa Propuesta es la siguiente:

# define proposal layer
self.RPN_proposal = _ProposalLayer(self.feat_stride, self.anchor_scales, self.anchor_ratios)
def forward():
    rois = self.RPN_proposal((rpn_cls_prob.data, rpn_bbox_pred.data, im_info, 
                              cfg_key))

La capa de propuesta tiene tres entradas: la salida de la rama softmax y la rama de regresión, más im_info. Donde im_info=[M,N,scale_factor], M y N son las dimensiones de entrada de la red, scale_factor es la información de escala de la imagen original PxQ, redimensionada a MxN.
El proceso de ejecución de la capa de propuesta es el siguiente:

  1. Obtenga el marco objetivo preliminar y retroceda todos los anclajes de acuerdo con el desplazamiento previsto para obtener el marco objetivo preliminar;
anchors = self._anchors.view(1, A, 4) + shifts.view(K, 1, 4)
anchors = anchors.view(1, K * A, 4).expand(batch_size, K * A, 4)

# Transpose and reshape predicted bbox transformations to get them
# into the same order as the anchors:

bbox_deltas = bbox_deltas.permute(0, 2, 3, 1).contiguous()
bbox_deltas = bbox_deltas.view(batch_size, -1, 4)
# Convert anchors into proposals via bbox transformations
proposals = bbox_transform_inv(anchors, bbox_deltas, batch_size)
  1. Elimine las anclas positivas que excedan los límites de la imagen;
 # 2. clip predicted boxes to image
proposals = clip_boxes(proposals, im_info, batch_size)
  1. Ordene las puntuaciones softmax positivas de entrada y seleccione los primeros anclajes RPN_PRE_NMS_TOP_N;
# # 4. sort all (proposal, score) pairs by score from highest to lowest
_, order = torch.sort(scores_keep, 1, True)
if pre_nms_topN > 0 and pre_nms_topN < scores_keep.numel():
    order_single = order_single[:pre_nms_topN]
proposals_single = proposals_single[order_single, :]
scores_single = scores_single[order_single].view(-1,1)
  1. Eliminar anclas positivas con tamaño muy pequeño;
  2. Realice NMS en los anclajes positivos restantes;
# 6. apply nms (e.g. threshold = 0.7)
# 7. take after_nms_topN (e.g. 300)
# 8. return the top proposals (-> RoIs top)

keep_idx_i = nms(torch.cat((proposals_single, scores_single), 1), nms_thresh, force_cpu=not cfg.USE_GPU_NMS)
keep_idx_i = keep_idx_i.long().view(-1)

if post_nms_topN > 0:
    keep_idx_i = keep_idx_i[:post_nms_topN]
proposals_single = proposals_single[keep_idx_i, :]
scores_single = scores_single[keep_idx_i, :]

La información de destino de la salida de propuesta por la capa de propuesta es relativa a la imagen de entrada M×N.

Agrupación de retorno de la inversión

La capa de RoI Pooling es responsable de recopilar propuestas y calcular los mapas de características correspondientes a las propuestas, y luego ingresarlos en la red posterior. Tiene dos entradas:

  • mapas de características compartidas;
  • Salida de buzones de propuestas por RPN (relativa a entrada de red M×N)
# define anchor target layer
self.RPN_anchor_target = _AnchorTargetLayer(self.feat_stride, self.anchor_scales, self.anchor_ratios)
def forward():
    rpn_data = self.RPN_anchor_target((rpn_cls_score.data, gt_boxes, im_info, num_boxes))

La razón para usar RoI Pooling:
dado que el tamaño y la forma de los cuadros de propuesta generados por RPN son diferentes, para un modelo entrenado, la entrada y la salida deben tener un tamaño fijo. Para cajas de diferentes formas, Faster R-CNN propone utilizar RoI Pooling para resolver este problema.
El flujo de trabajo de RoI Pooling:
Suponga que el mapa de características de entrada es como se muestra en la figura a continuación:
imagen.png
La posición de los cuadros de propuesta proyectados en el mapa de características es como se muestra en la figura:
imagen.png
Suponiendo que la salida es un mapa de características de 2 × 2, luego, el área de proyección se divide en secciones de 2 × 2, obtenga:
imagen.png
Luego haga una agrupación máxima para cada sección, obtenga:
imagen.png
Por lo tanto, la agrupación de RoI consiste en agrupar mapas de características de diferentes tamaños en mapas de características del mismo tamaño, lo que es beneficioso para la salida a la siguiente capa de red.
Dado que la posición de la propuesta generalmente se obtiene mediante la regresión del modelo, generalmente es un número de coma flotante, y el mapa de características después de la agrupación requiere un tamaño fijo. Hay dos cuantificaciones en este proceso:

  • Cuantifique los límites de la propuesta en coordenadas con valores enteros;
  • Dividir el área límite cuantificada en kxk secciones en promedio y cuantificar el límite de cada sección;

Después de las dos cuantificaciones anteriores, el marco candidato tiene una cierta desviación de la posición de regresión inicial en este momento, y esta desviación afectará la precisión de detección .

Clasificación y regresión

La salida del mapa de características 7×7 por RoI Pooling se envía luego a un módulo Clasificador, y luego se calcula la categoría específica de cada propuesta a través de la capa Lineal y softmax, y se genera la confianza del objetivo, y el desplazamiento de posición de la propuesta es obtenido además mediante el uso de la cantidad de regresión para retroceder cuadros objetivo más precisos. Como se muestra en la siguiente figura:
imagen.png
A continuación se muestra el código del módulo Clasificador, que forma parte del modelo VGG;

self.classifier = nn.Sequential(
    nn.Linear(512 * 7 * 7, 4096),
    nn.ReLU(True),
    nn.Dropout(p=dropout),
    nn.Linear(4096, 4096),
    nn.ReLU(True),
    nn.Dropout(p=dropout),
)

La capa totalmente conectada y la capa softmax determinan la categoría de la propuesta y generan la confianza correspondiente;

self.RCNN_cls_score = nn.Linear(4096, self.n_classes)
cls_prob = F.softmax(cls_score, 1)

El desplazamiento se obtiene utilizando la capa completamente conectada para refinar aún más la posición del objetivo.

self.RCNN_bbox_pred = nn.Linear(4096, 4 * self.n_classes) 

Link de referencia

Supongo que te gusta

Origin blog.csdn.net/hello_dear_you/article/details/129309592
Recomendado
Clasificación