Beispiel #1
0
 def forward(self, x):
     res=x
     res = self.relu0(res)
     res = pack_quant_tensor(res,torch.tensor(1.0, dtype=torch.float32),torch.tensor(4.0, dtype=torch.float32))
     res = self.linear1(res)
     res = pack_quant_tensor(res,torch.tensor(1.0, dtype=torch.float32),torch.tensor(4.0, dtype=torch.float32))
     res = self.relu1(res)
     res = pack_quant_tensor(res,torch.tensor(1.0, dtype=torch.float32),torch.tensor(4.0, dtype=torch.float32))
     res = self.linear2(res)
     return res
Beispiel #2
0
 def forward(self, input):
     input_tensor, input_scale, input_bit_width = self.unpack_input(input)
     x = super(QuantAvgPool2d, self).forward(input_tensor)
     if self.quant_type != QuantType.FP:
         x = x * (self.kernel_size * self.kernel_size)  # remove scaling introduced by average
         output_bit_width = self.max_output_bit_width(input_bit_width)
         x, output_scale, output_bit_width = self.accumulator_quant(x, input_scale, output_bit_width)
         return pack_quant_tensor(x, output_scale, output_bit_width)
     else:
         return pack_quant_tensor(x, input_scale, input_bit_width)
Beispiel #3
0
 def __init__(self):
     a = Tensor([0,0])
     b = Tensor([0,1])
     c = Tensor([1,0])
     d = Tensor([1,1])
     aq = pack_quant_tensor(a,torch.tensor(.125, dtype=torch.float32),torch.tensor(4.0, dtype=torch.float32))
     bq = pack_quant_tensor(b,torch.tensor(.125, dtype=torch.float32),torch.tensor(4.0, dtype=torch.float32))
     cq = pack_quant_tensor(c,torch.tensor(.125, dtype=torch.float32),torch.tensor(4.0, dtype=torch.float32))
     dq = pack_quant_tensor(d,torch.tensor(.125, dtype=torch.float32),torch.tensor(4.0, dtype=torch.float32))
     self.data=[aq,bq,cq,dq]
     self.key=[torch.tensor(0.0, dtype=torch.float32),torch.tensor(1.0, dtype=torch.float32),
               torch.tensor(1.0, dtype=torch.float32),torch.tensor(0.0, dtype=torch.float32)]
 def dropout_classifier(self, x, scale, bit_width):
     if self.training and self.dropout_steps > 0:
         out_list = []
         for i in range(self.dropout_steps):
             out = F.dropout(x, p=self.dropout_rate)
             out = self.output(pack_quant_tensor(out, scale, bit_width))
             quant_out, out_scale, out_bit_width = out
             out_list.append(quant_out)
         return tuple(out_list)
     else:
         out = self.output(pack_quant_tensor(x, scale, bit_width))
         quant_out, out_scale, out_bit_width = out
         if self.compute_micronet_cost:
             update_conv_or_linear_cost(self.output, bit_width,
                                        out_bit_width, quant_out)
         return quant_out,
 def forward(self, x):
     x = pack_quant_tensor(x, None, self.input_bit_width)
     x = self.features(x)
     quant_input, input_scale, input_bit_width = x
     x, scale, bit_width = self.final_pool(x)
     if self.compute_micronet_cost:
         update_avg_pool_cost(self.final_pool, x, input_bit_width)
     x = x.view(x.size(0), -1)
     x = self.dropout_classifier(x, scale, bit_width)
     return x
Beispiel #6
0
 def forward(self, x):
     x = self.features(x)
     x, scale, bit_width = self.final_pool(x)
     x = x.view(x.size(0), -1)
     x = self.output(pack_quant_tensor(x, scale, bit_width))
     return x
def test_brevitas_avg_pool_export(kernel_size, stride, signed, bit_width,
                                  input_bit_width, channels, idim):
    ishape = (1, channels, idim, idim)
    ibw_tensor = torch.Tensor([input_bit_width])

    b_avgpool = QuantAvgPool2d(
        kernel_size=kernel_size,
        stride=stride,
        bit_width=bit_width,
        quant_type=QuantType.INT,
    )
    # call forward pass manually once to cache scale factor and bitwidth
    input_tensor = torch.from_numpy(np.zeros(ishape)).float()
    scale = np.ones((1, channels, 1, 1))
    output_scale = torch.from_numpy(scale).float()
    input_quant_tensor = pack_quant_tensor(tensor=input_tensor,
                                           scale=output_scale,
                                           bit_width=ibw_tensor,
                                           signed=signed)
    bo.export_finn_onnx(b_avgpool,
                        ishape,
                        export_onnx_path,
                        input_t=input_quant_tensor)
    model = ModelWrapper(export_onnx_path)

    # determine input FINN datatype
    if signed is True:
        prefix = "INT"
    else:
        prefix = "UINT"
    dt_name = prefix + str(input_bit_width)
    dtype = DataType[dt_name]
    model = model.transform(InferShapes())
    model = model.transform(InferDataTypes())

    # execution with input tensor using integers and scale = 1
    # calculate golden output
    inp = gen_finn_dt_tensor(dtype, ishape)
    input_tensor = torch.from_numpy(inp).float()
    input_quant_tensor = pack_quant_tensor(tensor=input_tensor,
                                           scale=output_scale,
                                           bit_width=ibw_tensor,
                                           signed=signed)
    b_avgpool.eval()
    expected = b_avgpool.forward(input_quant_tensor).tensor.detach().numpy()

    # finn execution
    idict = {model.graph.input[0].name: inp}
    odict = oxe.execute_onnx(model, idict, True)
    produced = odict[model.graph.output[0].name]
    assert (expected == produced).all()

    # execution with input tensor using float and scale != 1
    scale = np.random.uniform(low=0, high=1,
                              size=(1, channels, 1, 1)).astype(np.float32)
    inp_tensor = inp * scale
    input_tensor = torch.from_numpy(inp_tensor).float()
    input_scale = torch.from_numpy(scale).float()
    input_quant_tensor = pack_quant_tensor(tensor=input_tensor,
                                           scale=input_scale,
                                           bit_width=ibw_tensor,
                                           signed=signed)
    # export again to set the scale values correctly
    bo.export_finn_onnx(b_avgpool,
                        ishape,
                        export_onnx_path,
                        input_t=input_quant_tensor)
    model = ModelWrapper(export_onnx_path)
    model = model.transform(InferShapes())
    model = model.transform(InferDataTypes())
    b_avgpool.eval()
    expected = b_avgpool.forward(input_quant_tensor).tensor.detach().numpy()
    # finn execution
    idict = {model.graph.input[0].name: inp_tensor}
    odict = oxe.execute_onnx(model, idict, True)
    produced = odict[model.graph.output[0].name]

    assert np.isclose(expected, produced).all()

    os.remove(export_onnx_path)