Example #1
0
def quantize(data, shift_bits, target_bits=relay.const(7, dtype='int32')):
    """Quantize output of layer, to be consistent with source code @yx

    Question: should the shift_bits participating to network control flow?
            At mxnet quantization with truman's code, the bits number of max_v
            is converted to normal interger using function `asscalar()`. However,
            I cannot find the related function in relay.
            I am confused with the control flow logic in model network, whether
            the condition `shift_bits == -1` should join in model network or just
            left it in python code flow. By Longtao.Wang

    Parameters
    ----------
    shift_bits: tvm.relay.Expr
        The shift_bits parameter is never used according to @yx's source code,
        which always be constant Expr(-1).
    """
    max_v = relay.max(relay.abs(data))
    min_v = relay.min(data)

    ln_max_v = relay.log(relay.cast(max_v, 'float32'))
    ln_2 = relay.log(relay.const(2.))
    total_bits = relay.ceil(relay.divide(ln_max_v, ln_2)) # ceil( ln(max_v) / ln(2) )
    shift_bits = relay.subtract(total_bits.astype('int32'), target_bits)
    shift_bits = relay.maximum(shift_bits, relay.const(0))

    denominator = relay.left_shift(relay.const(1),
            relay.cast(shift_bits, 'int32'))
    out = relay.divide(data, denominator)
    # According to @yx's code, use divide operation instead of shift op for
    # possible negative number round.
    # out = relay.right_shift(data, shift_bits)

    out = relay.cast(relay.clip(out, a_min=-128, a_max=127), 'int8')
    return out, max_v, min_v, shift_bits
Example #2
0
 def approx_exp(x):
     x = relay.minimum(relay.maximum(x, C((- 88.0))), C(88.0))
     x = (C(127.0) + (x * C(1.44269504)))
     xf = relay.floor(x)
     i = relay.cast(xf, 'int32')
     x = (x - xf)
     Y = (C(0.99992522) + (x * (C(0.69583354) + (x * (C(0.22606716) + (x * C(0.078024523)))))))
     exponent = relay.left_shift(i, relay.expr.const(23, 'int32'))
     exponent = relay.reinterpret(exponent, 'float32')
     return (exponent * Y)
Example #3
0
 def approx_exp(x):
     # An approximation derived from Opus,
     # https://github.com/xiph/opus/blob/c1c247/celt/mathops.h#L147-L165
     x = relay.minimum(relay.maximum(x, C(-88.0)), C(88.0))
     x = C(127.0) + x * C(1.44269504)
     xf = relay.floor(x)
     i = relay.cast(xf, "int32")
     x = x - xf
     Y = C(0.99992522) + x * (C(0.69583354) + x * (C(0.22606716) + x * C(0.078024523)))
     exponent = relay.left_shift(i, relay.expr.const(23, "int32"))
     exponent = relay.reinterpret(exponent, "float32")
     return exponent * Y
Example #4
0
def _get_model(input_shape, dtype, var_names):
    """Return a model and any parameters it may have."""
    a = relay.var(next(var_names), shape=input_shape, dtype=dtype)
    b = relay.var(next(var_names), shape=input_shape, dtype=dtype)
    max = relay.maximum(a, b)
    return max
Example #5
0
def get_net(batch_size, image_shape, num_classes, dtype):
    height = image_shape[1]
    width = image_shape[2]
    data_shape = (batch_size,) + image_shape
    net = relay.var("data", shape=data_shape, dtype=dtype)

    net = conv_3x3(net, 3, 64, "conv1_1")
    net = conv_3x3(net, 64, 64, "conv1_2")
    net = relay.nn.max_pool2d(net, pool_size=(2, 2), strides=(2, 2), ceil_mode=True)

    net = conv_3x3(net, 64, 128, "conv2_1")
    net = conv_3x3(net, 64, 128, "conv2_2")
    net = relay.nn.max_pool2d(net, pool_size=(2, 2), strides=(2, 2), ceil_mode=True)

    net = conv_3x3(net, 128, 256, "conv3_1")
    net = conv_3x3(net, 256, 256, "conv3_2")
    net = conv_3x3(net, 256, 256, "conv3_3")
    net = relay.nn.max_pool2d(net, pool_size=(2, 2), strides=(2, 2), ceil_mode=True)

    net = conv_3x3(net, 256, 512, "conv4_1")
    net = conv_3x3(net, 512, 512, "conv4_2")
    net = conv_3x3(net, 512, 512, "conv4_3")
    net = relay.nn.max_pool2d(net, pool_size=(2, 2), strides=(2, 2), ceil_mode=True)

    net = conv_3x3(net, 512, 512, "conv5_1")
    net = conv_3x3(net, 512, 512, "conv5_2")
    net = conv_3x3(net, 512, 512, "conv5_3")

    net = relay.nn.dropout(net, rate=0.5)

    net = conv_3x3(net, 512, 72, "conv6", activation=False)
    net = relay.transpose(net, (0, 2, 3, 1))

    num_class_probs = 9 * 3
    num_confidence_scores = 9
    #num_box_delta = 9 * 4
    pred_class_probs, pred_conf, pred_box_delta = relay.split(net,
            (num_class_probs, num_class_probs + num_confidence_scores),
            axis=-1)

    # Probability
    pred_class_probs = relay.reshape(pred_class_probs, (-1, 3))
    pred_class_probs = relay.nn.softmax(pred_class_probs)
    pred_class_probs = relay.reshape(pred_class_probs, (batch_size, -1, 3))

    # Confidence
    pred_conf = relay.sigmoid(pred_conf)
    pred_conf = relay.reshape(pred_conf, (batch_size, -1, 1))

    # Bbox_delta
    pred_box_delta = relay.reshape(pred_box_delta, (batch_size, -1, 4))
    delta_x, delta_y, delta_w, delta_h = relay.split(pred_box_delta, (1, 2, 3), axis=2)
    delta_x = relay.reshape(delta_x, (batch_size, -1))
    delta_y = relay.reshape(delta_y, (batch_size, -1))
    delta_w = relay.reshape(delta_w, (batch_size, -1))
    delta_h = relay.reshape(delta_h, (batch_size, -1))

    anchor_box = set_anchors(height, width)
    anchor_x = relay.Constant(tvm.nd.array(anchor_box[:, 0]))
    anchor_y = relay.Constant(tvm.nd.array(anchor_box[:, 1]))
    anchor_w = relay.Constant(tvm.nd.array(anchor_box[:, 2]))
    anchor_h = relay.Constant(tvm.nd.array(anchor_box[:, 3]))

    box_center_x = anchor_x + delta_x * anchor_w
    box_center_y = anchor_y + delta_y * anchor_h
    '''
    box_width    = anchor_w * relay.exp(delta_w)
    box_height   = anchor_h * relay.exp(delta_h)
    '''
    box_width    = anchor_w + safe_exp(delta_w)
    box_height   = anchor_h + safe_exp(delta_h)

    xmins, ymins, xmaxs, ymaxs = bbox_transform(box_center_x, box_center_y, box_width, box_height)
    xmins = relay.minimum(relay.maximum(relay.const(0.0), xmins), relay.const(width - 1.0))
    ymins = relay.minimum(relay.maximum(relay.const(0.0), ymins), relay.const(height - 1.0))
    xmaxs = relay.maximum(relay.minimum(relay.const(width - 1.0), xmaxs), relay.const(0.0))
    ymaxs = relay.maximum(relay.minimum(relay.const(height - 1.0), ymaxs), relay.const(0.0))

    det_boxes = relay.stack(bbox_transform_inv(xmins, ymins, xmaxs, ymaxs), axis=-1)

    probs = relay.multiply(pred_class_probs, pred_conf)
    det_probs = relay.max(probs, axis=2)
    det_class = relay.argmax(probs, axis=2)

    out = relay.Tuple([det_boxes, det_probs, det_class])
    args = relay.analysis.free_vars(out)
    
    return relay.Function(args, out)