示例#1
0
def passReorderMaxPooling(pipeline):
    "Move max pooling layers past thresholding layers."
    inStages = pipeline
    inStages.reverse()
    numChanges = 0
    ret = []
    while len(inStages) > 1:
        layerA = inStages.pop()
        layerB = inStages.pop()
        if lb.isMaxPoolingLayer(layerA) and lb.isThresholdLayer(layerB):
            # need to check that the threholding preserves max to reoder
            for t in range(len(layerB.thresholds) - 1):
                if not (layerB.thresholds[t + 1] >=
                        layerB.thresholds[t]).all():
                    raise Exception("Threshold does not preserve max")
            # re-insert layers in reversed order
            ret += [layerB, layerA]
            numChanges += 1
        else:
            ret += [layerA]
            inStages.append(layerB)
    # pop final element, if any left
    if len(inStages) == 1:
        ret += [inStages.pop()]

    return (ret, numChanges)
示例#2
0
def passAbsorbLinearIntoThreshold(pipeline):
    "Absorb linear transformations into the following threshold layer."
    inStages = pipeline
    inStages.reverse()
    numChanges = 0
    ret = []
    while len(inStages) > 1:
        layerA = inStages.pop()
        layerB = inStages.pop()
        if lb.isLinearLayer(layerA) and lb.isThresholdLayer(layerB):
            # absorb the linear transform Ax+B into the threshold layer
            # by updating each threshold T as Tnew = (T-B)/A
            A = layerA.A
            B = layerA.B
            T = layerB.thresholds
            Tnew = np.asarray([(t - B) / A for t in T])
            layerBThresClass = layerB.__class__
            ret += [layerBThresClass(Tnew)]
            numChanges += 1
        else:
            ret += [layerA]
            inStages.append(layerB)
    # pop final element, if any left
    if len(inStages) == 1:
        ret += [inStages.pop()]
    return (ret, numChanges)
示例#3
0
def passRoundUpIntThresholds(pipeline):
    "Round up thresholds of ThresholdingLayers with integer inputs."
    inStages = pipeline
    ret = []
    for L in inStages:
        # TODO this is not a good way to check for integer input --
        # fix this once we have i/o data types specified
        if lb.isThresholdLayer(L) and L.ibits <= 16:
            L.thresholds = np.ceil(L.thresholds).astype(np.int16)
        ret += [L]
    return (ret, 0)
示例#4
0
def passConvertToCaffeLayers(pipeline, qnnengine):
    "Convert layers to corresponding Caffe-equivalent implementation layers."
    inStages = pipeline
    ret = []
    default_engine_maxbits = 4
    gemmlowp_maxbits = 8
    if qnnengine == "float":
        # force all layers to be generated as vanilla Caffe layers
        default_engine_maxbits = 0
        gemmlowp_maxbits = 0
    # note that layer, in and out buf names are empty -- we'll set those later
    for L in inStages:
        if lb.isFCLayer(L):
            if (L.wbits * L.ibits) <= default_engine_maxbits:
                ret += [lcaffe.CaffeIntegerInnerProductLayer("", L, qnnengine)]
            elif L.wbits <= gemmlowp_maxbits:
                ret += [
                    lcaffe.CaffeIntegerInnerProductLayer("", L, "gemmlowp")
                ]
            else:
                ret += [lcaffe.CaffeInnerProductLayer("", L)]
        elif lb.isConvLayer(L):
            if (L.wbits * L.ibits) <= default_engine_maxbits:
                ret += [lcaffe.CaffeIntegerConvolutionLayer("", L, qnnengine)]
            elif L.wbits <= gemmlowp_maxbits:
                ret += [lcaffe.CaffeIntegerConvolutionLayer("", L, "gemmlowp")]
            else:
                ret += [lcaffe.CaffeConvolutionLayer("", L)]
        elif lb.isPoolingLayer(L):
            ret += [lcaffe.CaffePoolLayer("", L)]
        elif lb.isThresholdLayer(L):
            ret += [lcaffe.CaffeMultiThresholdLayer("", L)]
        elif lb.isLinearLayer(L):
            ret += [lcaffe.CaffeScaleLayer("", L)]
        elif lb.isReLULayer(L):
            ret += [lcaffe.CaffeReLULayer("")]
        elif lb.isSoftmaxLayer(L):
            ret += [lcaffe.CaffeSoftmaxLayer("")]
        elif lcaffe.isCaffeLayer(L):
            ret += [L]
        else:
            raise Exception("Unsupported layer type for Caffe backend: %s" %
                            L.get_type())

    return (ret, 0)
示例#5
0
def passFuseActivations(pipeline):
    "Replace (Matrix, Threshold) layer pairs with fused equivalents."
    inStages = pipeline
    inStages.reverse()
    numChanges = 0
    ret = []
    while len(inStages) > 1:
        layerA = inStages.pop()
        layerB = inStages.pop()
        if lb.isMatrixLayer(layerA) and lb.isThresholdLayer(layerB):
            ret += [lb.MatrixThresholdLayer("", layerA, layerB)]
            numChanges += 1
        else:
            ret += [layerA]
            inStages.append(layerB)
    # pop final element, if any left
    if len(inStages) == 1:
        ret += [inStages.pop()]
    return (ret, numChanges)