human
Complete the below
def assign_anchor(feat_shape, gt_boxes, im_info, feat_stride=16, scales=(8, 16, 32), ratios=(0.5, 1, 2), allowed_border=0):

    ''''assign ground truth boxes to anchor positions
    :param feat_shape: infer output shape
    :param gt_boxes: assign ground truth
    :param im_info: filter out anchors overlapped with edges
    :param feat_stride: anchor position step
    :param scales: used to generate anchors, affects num_anchors (per location)
    :param ratios: aspect ratios of generated anchors
    :param allowed_border: filter out anchors with edge overlap > allowed_border
    :return: dict of label
    \'label\': of shape (batch_size, 1) <- (batch_size, num_anchors, feat_height, feat_width)
    \'bbox_target\': of shape (batch_size, num_anchors * 4, feat_height, feat_width)
    \'bbox_inside_weight\': *todo* mark the assigned anchors
    \'bbox_outside_weight\': used to normalize the bbox_loss, all weights sums to RPN_POSITIVE_WEIGHT'
    '''
 Can you provide a the Python program you requested?
assistant
#Here is the Python program you requested.
    def _unmap(data, count, inds, fill=0):
        '"    unmap    a    subset    inds    of    data    into    original    data    of    size    count    '
        if (len(data.shape) == 1):
            ret = np.empty((count,), dtype=np.float32)
            ret.fill(fill)
            ret[inds] = data
        else:
            ret = np.empty(((count,) + data.shape[1:]), dtype=np.float32)
            ret.fill(fill)
            ret[inds, :] = data
        return ret
    im_info = im_info[0]
    scales = np.array(scales, dtype=np.float32)
    base_anchors = generate_anchors(base_size=feat_stride, ratios=list(ratios), scales=scales)
    num_anchors = base_anchors.shape[0]
    (feat_height, feat_width) = feat_shape[(-2):]
    logger.debug(('anchors:    %s' % base_anchors))
    logger.debug(('anchor    shapes:    %s' % np.hstack(((base_anchors[:, 2::4] - base_anchors[:, 0::4]), (base_anchors[:, 3::4] - base_anchors[:, 1::4])))))
    logger.debug(('im_info    %s' % im_info))
    logger.debug(('height    %d    width    %d' % (feat_height, feat_width)))
    logger.debug(('gt_boxes    shape    %s' % np.array(gt_boxes.shape)))
    logger.debug(('gt_boxes    %s' % gt_boxes))
    shift_x = (np.arange(0, feat_width) * feat_stride)
    shift_y = (np.arange(0, feat_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()
    A = num_anchors
    K = shifts.shape[0]
    all_anchors = (base_anchors.reshape((1, A, 4)) + shifts.reshape((1, K, 4)).transpose((1, 0, 2)))
    all_anchors = all_anchors.reshape(((K * A), 4))
    total_anchors = int((K * A))
    inds_inside = np.where(((((all_anchors[:, 0] >= (- allowed_border)) & (all_anchors[:, 1] >= (- allowed_border))) & (all_anchors[:, 2] < (im_info[1] + allowed_border))) & (all_anchors[:, 3] < (im_info[0] + allowed_border))))[0]
    logger.debug(('total_anchors    %d' % total_anchors))
    logger.debug(('inds_inside    %d' % len(inds_inside)))
    anchors =...