Skip to content

Commit

Permalink
Remove non-tf parts
Browse files Browse the repository at this point in the history
  • Loading branch information
Detry322 committed Mar 15, 2018
1 parent ce4a8ac commit 560489e
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 117 deletions.
45 changes: 3 additions & 42 deletions lib/layer_utils/proposal_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,69 +15,30 @@


def proposal_layer(rpn_cls_prob, rpn_bbox_pred, im_info, cfg_key, _feat_stride, anchors, num_anchors):
"""A simplified version compared to fast/er RCNN
For details please see the technical report
"""
if type(cfg_key) == bytes:
cfg_key = cfg_key.decode('utf-8')
pre_nms_topN = cfg[cfg_key].RPN_PRE_NMS_TOP_N
post_nms_topN = cfg[cfg_key].RPN_POST_NMS_TOP_N
nms_thresh = cfg[cfg_key].RPN_NMS_THRESH

# Get the scores and bounding boxes
scores = rpn_cls_prob[:, :, :, num_anchors:]
rpn_bbox_pred = rpn_bbox_pred.reshape((-1, 4))
scores = scores.reshape((-1, 1))
proposals = bbox_transform_inv(anchors, rpn_bbox_pred)
proposals = clip_boxes(proposals, im_info[:2])

# Pick the top region proposals
order = scores.ravel().argsort()[::-1]
if pre_nms_topN > 0:
order = order[:pre_nms_topN]
proposals = proposals[order, :]
scores = scores[order]

# Non-maximal suppression
keep = nms(np.hstack((proposals, scores)), nms_thresh)

# Pick th top region proposals after NMS
if post_nms_topN > 0:
keep = keep[:post_nms_topN]
proposals = proposals[keep, :]
scores = scores[keep]

# Only support single image as input
batch_inds = np.zeros((proposals.shape[0], 1), dtype=np.float32)
blob = np.hstack((batch_inds, proposals.astype(np.float32, copy=False)))

return blob, scores


def proposal_layer_tf(rpn_cls_prob, rpn_bbox_pred, im_info, cfg_key, _feat_stride, anchors, num_anchors):
if type(cfg_key) == bytes:
cfg_key = cfg_key.decode('utf-8')
pre_nms_topN = cfg[cfg_key].RPN_PRE_NMS_TOP_N
post_nms_topN = cfg[cfg_key].RPN_POST_NMS_TOP_N
nms_thresh = cfg[cfg_key].RPN_NMS_THRESH

# Get the scores and bounding boxes
scores = rpn_cls_prob[:, :, :, num_anchors:]
scores = tf.reshape(scores, shape=(-1,))
rpn_bbox_pred = tf.reshape(rpn_bbox_pred, shape=(-1, 4))

proposals = bbox_transform_inv_tf(anchors, rpn_bbox_pred)
proposals = clip_boxes_tf(proposals, im_info[:2])

# Non-maximal suppression
indices = tf.image.non_max_suppression(proposals, scores, max_output_size=post_nms_topN, iou_threshold=nms_thresh)

boxes = tf.gather(proposals, indices)
boxes = tf.to_float(boxes)
scores = tf.gather(scores, indices)
scores = tf.reshape(scores, shape=(-1, 1))


# Only support single image as input
batch_inds = tf.zeros((tf.shape(indices)[0], 1), dtype=tf.float32)
blob = tf.concat([batch_inds, boxes], 1)

assert blob.get_shape()[1] == 5
return blob, scores
45 changes: 7 additions & 38 deletions lib/layer_utils/proposal_top_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
from __future__ import division
from __future__ import print_function

import numpy as np
from model.config import cfg
from model.bbox_transform import bbox_transform_inv, clip_boxes, bbox_transform_inv_tf, clip_boxes_tf
import numpy.random as npr

import tensorflow as tf

Expand All @@ -21,52 +19,23 @@ def proposal_top_layer(rpn_cls_prob, rpn_bbox_pred, im_info, _feat_stride, ancho
"""
rpn_top_n = cfg.TEST.RPN_TOP_N

scores = rpn_cls_prob[:, :, :, num_anchors:]

rpn_bbox_pred = rpn_bbox_pred.reshape((-1, 4))
scores = scores.reshape((-1, 1))

length = scores.shape[0]
if length < rpn_top_n:
# Random selection, maybe unnecessary and loses good proposals
# But such case rarely happens
top_inds = npr.choice(length, size=rpn_top_n, replace=True)
else:
top_inds = scores.argsort(0)[::-1]
top_inds = top_inds[:rpn_top_n]
top_inds = top_inds.reshape(rpn_top_n, )

# Do the selection here
anchors = anchors[top_inds, :]
rpn_bbox_pred = rpn_bbox_pred[top_inds, :]
scores = scores[top_inds]

# Convert anchors into proposals via bbox transformations
proposals = bbox_transform_inv(anchors, rpn_bbox_pred)

# Clip predicted boxes to image
proposals = clip_boxes(proposals, im_info[:2])

# Output rois blob
# Our RPN implementation only supports a single input image, so all
# batch inds are 0
batch_inds = np.zeros((proposals.shape[0], 1), dtype=np.float32)
blob = np.hstack((batch_inds, proposals.astype(np.float32, copy=False)))
return blob, scores

def proposal_top_layer_tf(rpn_cls_prob, rpn_bbox_pred, im_info, _feat_stride, anchors, num_anchors):
rpn_top_n = cfg.TEST.RPN_TOP_N

scores = rpn_cls_prob[:, :, :, num_anchors:]
rpn_bbox_pred = tf.reshape(rpn_bbox_pred, shape=(-1, 4))
scores = tf.reshape(scores, shape=(-1,))

# Do the selection here
top_scores, top_inds = tf.nn.top_k(scores, k=rpn_top_n)
top_scores = tf.reshape(top_scores, shape=(-1, 1))
top_anchors = tf.gather(anchors, top_inds)
top_rpn_bbox = tf.gather(rpn_bbox_pred, top_inds)
proposals = bbox_transform_inv_tf(top_anchors, top_rpn_bbox)

# Clip predicted boxes to image
proposals = clip_boxes_tf(proposals, im_info[:2])

# Output rois blob
# Our RPN implementation only supports a single input image, so all
# batch inds are 0
proposals = tf.to_float(proposals)
batch_inds = tf.zeros((rpn_top_n, 1))
blob = tf.concat([batch_inds, proposals], 1)
Expand Down
20 changes: 1 addition & 19 deletions lib/layer_utils/snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,7 @@
import numpy as np
from layer_utils.generate_anchors import generate_anchors

def generate_anchors_pre(height, width, feat_stride, anchor_scales=(8,16,32), anchor_ratios=(0.5,1,2)):
""" A wrapper function to generate anchors given different scales
Also return the number of anchors in variable 'length'
"""
anchors = generate_anchors(ratios=np.array(anchor_ratios), scales=np.array(anchor_scales))
A = anchors.shape[0]
shift_x = np.arange(0, width) * feat_stride
shift_y = np.arange(0, height) * feat_stride
shift_x, shift_y = np.meshgrid(shift_x, shift_y)
shifts = np.vstack((shift_x.ravel(), shift_y.ravel(), shift_x.ravel(), shift_y.ravel())).transpose()
K = shifts.shape[0]
# width changes faster, so here it is H, W, C
anchors = anchors.reshape((1, A, 4)) + shifts.reshape((1, K, 4)).transpose((1, 0, 2))
anchors = anchors.reshape((K * A, 4)).astype(np.float32, copy=False)
length = np.int32(anchors.shape[0])

return anchors, length

def generate_anchors_tf(height, width, feat_stride=16, anchor_scales=(8, 16, 32), anchor_ratios=(0.5, 1, 2)):
def generate_anchors_pre(height, width, feat_stride=16, anchor_scales=(8, 16, 32), anchor_ratios=(0.5, 1, 2)):
shift_x = tf.range(width) * feat_stride # width
shift_y = tf.range(height) * feat_stride # height
shift_x, shift_y = tf.meshgrid(shift_x, shift_y)
Expand Down
30 changes: 12 additions & 18 deletions lib/nets/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

import numpy as np

from layer_utils.snippets import generate_anchors_pre, generate_anchors_tf
from layer_utils.proposal_layer import proposal_layer, proposal_layer_tf
from layer_utils.proposal_top_layer import proposal_top_layer, proposal_top_layer_tf
from layer_utils.snippets import generate_anchors_pre
from layer_utils.proposal_layer import proposal_layer
from layer_utils.proposal_top_layer import proposal_top_layer
from layer_utils.anchor_target_layer import anchor_target_layer
from layer_utils.proposal_target_layer import proposal_target_layer
from utils.visualization import draw_bounding_boxes
Expand Down Expand Up @@ -87,26 +87,22 @@ def _softmax_layer(self, bottom, name):

def _proposal_top_layer(self, rpn_cls_prob, rpn_bbox_pred, name):
with tf.variable_scope(name) as scope:
rois, rpn_scores = proposal_top_layer_tf(
rois, rpn_scores = proposal_top_layer(
rpn_cls_prob,
rpn_bbox_pred,
self._im_info,
self._feat_stride,
self._anchors,
self._num_anchors
)
# rois, rpn_scores = tf.py_func(proposal_top_layer,
# [rpn_cls_prob, rpn_bbox_pred, self._im_info,
# self._feat_stride, self._anchors, self._num_anchors],
# [tf.float32, tf.float32], name="proposal_top")
rois.set_shape([cfg.TEST.RPN_TOP_N, 5])
rpn_scores.set_shape([cfg.TEST.RPN_TOP_N, 1])

return rois, rpn_scores

def _proposal_layer(self, rpn_cls_prob, rpn_bbox_pred, name):
with tf.variable_scope(name) as scope:
rois, rpn_scores = proposal_layer_tf(
rois, rpn_scores = proposal_layer(
rpn_cls_prob,
rpn_bbox_pred,
self._im_info,
Expand All @@ -115,10 +111,6 @@ def _proposal_layer(self, rpn_cls_prob, rpn_bbox_pred, name):
self._anchors,
self._num_anchors
)
# rois, rpn_scores = tf.py_func(proposal_layer,
# [rpn_cls_prob, rpn_bbox_pred, self._im_info, self._mode,
# self._feat_stride, self._anchors, self._num_anchors],
# [tf.float32, tf.float32], name="proposal")
rois.set_shape([None, 5])
rpn_scores.set_shape([None, 1])

Expand Down Expand Up @@ -206,11 +198,13 @@ def _anchor_component(self):
# just to get the shape right
height = tf.to_int32(tf.ceil(self._im_info[0] / np.float32(self._feat_stride[0])))
width = tf.to_int32(tf.ceil(self._im_info[1] / np.float32(self._feat_stride[0])))
anchors, anchor_length = generate_anchors_tf(height, width, self._feat_stride, self._anchor_scales, self._anchor_ratios)
# anchors, anchor_length = tf.py_func(generate_anchors_pre,
# [height, width,
# self._feat_stride, self._anchor_scales, self._anchor_ratios],
# [tf.float32, tf.int32], name="generate_anchors")
anchors, anchor_length = generate_anchors_pre(
height,
width,
self._feat_stride,
self._anchor_scales,
self._anchor_ratios
)
anchors.set_shape([None, 4])
anchor_length.set_shape([])
self._anchors = anchors
Expand Down

0 comments on commit 560489e

Please sign in to comment.