Ejemplo n.º 1
0
def test_fc():
    filt = FcFilterDim(3, 3, 3, 1)
    params = FcParameters("test", filt=filt)
    weights_q = QType(16, 2, True)
    in_q = QType(16, 2, True)
    acc_q = QType(16, 4, True)
    calc_q = QType(16, 4, True)
    qrec = FilterQuantizationRecord(in_qs=[in_q],
                                    out_qs=[in_q],
                                    calc_q=calc_q,
                                    acc_q=acc_q,
                                    biases_q=None,
                                    weights_q=weights_q)
    weights = weights_q.quantize(np.full([3, 1, 3, 3], 1.0))
    input_ = in_q.quantize(np.arange(9)).reshape([1, 3, 3])
    in_dims = Dim.named(c=1, h=3, w=3).impose_order(['c', 'h', 'w'])
    out_dims = params.get_output_size([in_dims])

    output_ = linear(params,
                     in_dims,
                     out_dims[0],
                     input_,
                     weights,
                     None,
                     qrec=qrec)
    output_ = in_q.dequantize(output_)
    assert np.array_equal(output_, [[[36]], [[36]], [[36]]])
Ejemplo n.º 2
0
def test_conf2d_q2(caplog):
    caplog.set_level(logging.INFO)
    weights_q = QType(16, 1, True)
    weights = weights_q.quantize(np.full([1, 1, 2, 2], 1.0))
    filt = Conv2DFilterDim(2, 2, 1, 1)
    stride = StrideDim(1)
    pad = PadDim.valid()
    dilation = DilationDim(1)
    params = Conv2DParameters("test",
                              filt=filt,
                              stride=stride,
                              padding=pad,
                              dilation=dilation,
                              in_dims_hint=[['c', 'h', 'w']],
                              out_dims_hint=[['c', 'h', 'w']])
    in_q = QType(16, 0, True)
    calc_q = QType(weights_q.bits + in_q.bits, weights_q.q + in_q.q, True)
    qrec = FilterQuantizationRecord(in_qs=[in_q],
                                    out_qs=[in_q],
                                    weights_q=weights_q,
                                    acc_q=calc_q,
                                    calc_q=calc_q)
    input_ = in_q.quantize(np.full([1, 2, 2], 1.0))
    in_dims = Dim.named(c=1, h=2, w=2).impose_order(['c', 'h', 'w'])
    out_dims = params.get_output_size([in_dims])
    output_ = conv2d(params,
                     in_dims,
                     out_dims[0],
                     input_,
                     weights,
                     None,
                     qrec=qrec)
    output_ = in_q.dequantize(output_)
    assert np.array_equal(output_, [[[4.]]])
Ejemplo n.º 3
0
def test_conf2d_depth_q():
    calc_q = QType(32, 9, True)
    biases_q = acc_q = out_q = QType(16, 4, True)
    weights_q = QType(16, 4, True)
    in_q = QType(16, 5, True)
    # TF Lite depthwise convolution
    biases = np.full([2], 0.5)
    qbiases = biases_q.quantize(biases)
    weights = np.full([3, 3], 0.5)
    weights = np.repeat(weights, 2).reshape([1, 3, 3, 2])
    qweights = weights_q.quantize(weights)
    filt = Conv2DFilterDim(3, 3, 2,
                           1).impose_order(["in_c", "h", "w", "out_c"])
    stride = StrideDim(1)
    pad = PadDim(0)
    dilation = DilationDim(1)
    params = Conv2DParameters("test",
                              filt=filt,
                              stride=stride,
                              padding=pad,
                              dilation=dilation,
                              groups=1,
                              multiplier=2,
                              tf_depthwise=True,
                              in_dims_hint=[['c', 'h', 'w']],
                              out_dims_hint=[['c', 'h', 'w']])
    qrec = FilterQuantizationRecord(in_qs=[in_q],
                                    out_qs=[out_q],
                                    weights_q=weights_q,
                                    biases_q=biases_q,
                                    acc_q=acc_q,
                                    calc_q=calc_q)
    input_ = np.full([1, 4, 4], 2)
    qinput_ = in_q.quantize(input_)
    in_dims = Dim.named(c=1, h=4, w=4).impose_order(['c', 'h', 'w'])
    out_dims = params.get_output_size([in_dims])
    output_ = conv2d(params, in_dims, out_dims[0], input_, weights, biases)
    qoutput_ = conv2d(params,
                      in_dims,
                      out_dims[0],
                      qinput_,
                      qweights,
                      qbiases,
                      qrec=qrec)
    dqoutput_ = out_q.dequantize(qoutput_)
    assert np.array_equal(output_, dqoutput_)
Ejemplo n.º 4
0
def test_activation():
    in_q = QType(16, 13, True)
    input_ = in_q.quantize(np.array([-1.2, 0.5, 0.5, -0.6])).reshape([4, 1, 1])
    in_dims = Dim.named(c=4, h=1, w=1).impose_order(['c', 'h', 'w'])
    params = ActivationParameters("test")
    qrec = QuantizationRecord([in_q], [in_q])
    out_dims = params.get_output_size([in_dims])
    output_ = activation(params, in_dims, out_dims[0], input_, qrec=qrec)
    output_ = in_q.dequantize(output_)
    assert np.array_equal(output_, [[[0]], [[0.5]], [[0.5]], [[0]]])
Ejemplo n.º 5
0
def test_concat_q():
    in_q = QType(16, 1, True)
    inputs = [
        in_q.quantize(np.full([1, 2, 2], 1.0)),
        in_q.quantize(np.full([2, 2, 2], 2.0))
    ]
    in_dims = [
        Dim.named(c=1, h=2, w=2).impose_order(['c', 'h', 'w']),
        Dim.named(c=1, h=2, w=2).impose_order(['c', 'h', 'w'])
    ]
    params = ConcatParameters("test", axis=0)
    out_dims = params.get_output_size(in_dims)
    output_ = concat(params, in_dims, out_dims[0], inputs)
    assert np.array_equal(output_, np.concatenate(inputs, 0))
Ejemplo n.º 6
0
def test_max_pool_q():
    filt = PoolFilterDim(2, 2)
    stride = StrideDim(1)
    pad = PadDim(0)
    params = PoolingParameters("test",
                               filt=filt,
                               stride=stride,
                               padding=pad,
                               pool_type="max")
    in_q = QType(16, 0, True)
    qrec = QuantizationRecord([in_q], [in_q])
    input_ = in_q.quantize(np.arange(9)).reshape([1, 3, 3])
    in_dims = Dim.named(c=1, h=3, w=3).impose_order(['c', 'h', 'w'])
    out_dims = params.get_output_size([in_dims])
    output_ = max_pool(params, in_dims, out_dims[0], input_)
    output_ = in_q.dequantize(output_)
    assert np.array_equal(output_, [[[4, 5], [7, 8]]])
Ejemplo n.º 7
0
    def new_load_filter_parameters(cls,
                                   G,
                                   params,
                                   input_tensor,
                                   weights_node,
                                   bias_node,
                                   output_tensor,
                                   opts,
                                   dw_to_pw=False):
        weights_node.meta['filter_params'] = True
        bias_node.meta['filter_params'] = True
        # if quantizaton is not loaded then the constants will already be dequantized
        if dw_to_pw:
            # Conv has been converted from depthwise to pointwise so reorder the weights tensor
            weights_node.value = np.transpose(weights_node.value,
                                              cls.TF_LITE_DW_FILTER_TRANSPOSE)
            weights_node.dims = Dim.unnamed(weights_node.value.shape)
        if not opts.get('load_quantization'):
            return
        wqtype = weights_node.qtype
        if wqtype is None:
            LOG.warning('quantization is missing on node %s', params.name)
            return
        # scale weights as requested. change asymmetric scaling to symmetric
        if wqtype.is_asymmetric:
            if opts.get('rescale_perchannel'):
                wqtype = cls.get_weights_qtype_by_channel(params, weights_node)
            else:
                wqtype = cls.get_weights_qtype_by_tensor(weights_node)
        else:
            if opts.get('rescale_perchannel'):
                if len(wqtype.scale) != params.filter.out_c:
                    wqtype = cls.get_weights_qtype_by_channel(
                        params, weights_node)
            else:
                if len(wqtype.scale) > 1:
                    wqtype = cls.get_weights_qtype_by_tensor(weights_node)

        iqtype = input_tensor.qtype
        # correct input qtype to symmetric tensor scaled
        if iqtype.is_asymmetric or len(iqtype.scale) > 1:
            iqtype = QType.from_min_max_sq(min_val=iqtype.min_val,
                                           max_val=iqtype.max_val)
        else:
            iqtype = deepcopy(iqtype)

        oqtype = output_tensor.qtype
        # correct output qtype to symmetric tensor scaled
        if oqtype.is_asymmetric or len(oqtype.scale) > 1:
            oqtype = QType.from_min_max_sq(min_val=oqtype.min_val,
                                           max_val=oqtype.max_val)
        else:
            oqtype = deepcopy(iqtype)

        dqbias = bias_node.dqvalue
        bias_scale = (iqtype.scale * wqtype.scale).astype(np.float32)
        bqtype = QType(dtype=np.int32, scale=bias_scale)
        # NOTE: In some tensorflow graphs the biases are hugely negative or hugely
        # positive. I've never seen this without a relun after and the weights on
        # these channels were 0. Actually they should be pruned.
        bias_node.value = bqtype.quantize(dqbias)
        bias_node.qtype = bqtype
        if dw_to_pw and wqtype.quantized_dimension:
            wqtype.quantized_dimension = 0

        mulbiases_q = MultMulBiasScaleQType.from_filter(
            iqtype, wqtype, oqtype, params)
        qrec = MultScalableFilterQuantizationRecord(
            in_qs=[iqtype, wqtype, bqtype],
            out_qs=[oqtype],
            mul_biases_q=mulbiases_q)
        # now set the quantization records on the node and its constants
        G.quantization[NodeId(params)] = qrec
        G.quantization[NodeId(weights_node)] = MultConstantQuantizationRecord(
            out_qs=[deepcopy(wqtype)])
        G.quantization[NodeId(bias_node)] = MultConstantQuantizationRecord(
            out_qs=[deepcopy(bqtype)])