当前位置:网站首页>Adaptiveavgpool2d does not support onnx export. Customize a class to replace adaptiveavgpool2d

Adaptiveavgpool2d does not support onnx export. Customize a class to replace adaptiveavgpool2d

2022-06-26 10:35:00 Master Yiwen

AdaptiveAvgPool2D I won't support it onnx export , The export process will tell you ,onnx The dynamic operation barabara... Is not supported

I use it pp_liteseg Export to onnx Model , Are all the same ,paddle and Torch Of Adaptive Pool2D It's all dynamic ,onnx Not supported for the time being , I use the following formula , take AdaptiveAvgPool2D Changed , It can be used onnx It is derived that , But you need to specify the size of the original image , And the size of the output graph

h s t a r t = f l o o r ( i ∗ H i n / H o u t ) h e n d = c e i l ( ( i + 1 ) ∗ H i n / H o u t ) w s t a r t = f l o o r ( j ∗ W i n / W o u t ) w e n d = c e i l ( ( j + 1 ) ∗ W i n / W o u t ) O u t p u t ( i , j ) = ∑ I n p u t [ h s t a r t : h e n d , w s t a r t : w e n d ] ( h e n d − h s t a r t ) ∗ ( w e n d − w s t a r t ) \begin{aligned} hstart &= floor(i * H_{in} / H_{out})\\ hend &= ceil((i + 1) * H_{in} / H_{out})\\ wstart &= floor(j * W_{in} / W_{out}) \\ wend &= ceil((j + 1) * W_{in} / W_{out}) \\ Output(i ,j) &= \frac{\sum Input[hstart:hend, wstart:wend]}{(hend - hstart) * (wend - wstart)} \end{aligned} hstarthendwstartwendOutput(i,j)=floor(iHin/Hout)=ceil((i+1)Hin/Hout)=floor(jWin/Wout)=ceil((j+1)Win/Wout)=(hendhstart)(wendwstart)Input[hstart:hend,wstart:wend]
Reference from :
AdaptiveAvgPool2D

class CostomAdaptiveAvgPool2D(nn.Layer):
    
    def __init__(self, output_size, input_size):
        
        super(CostomAdaptiveAvgPool2D, self).__init__()
        
        self.output_size = output_size
        self.input_size  = input_size
        
    def forward(self, x):
        
        H_in,  W_in  = self.input_size
        H_out, W_out = [self.output_size, self.output_size] \
                       if isinstance(self.output_size, int) \
                       else self.output_size
        
        out_i = []
        for i in range(H_out):
            out_j = []
            for j in range(W_out):
                
                hs = int(np.floor(i * H_in / H_out))
                he = int(np.ceil((i+1) * H_in / H_out))
                
                ws = int(np.floor(j * W_in / W_out))
                we = int(np.ceil((j+1) * W_in / W_out))
                
                # print(hs, he, ws, we)
                kernel_size = [he-hs, we-ws]
                
                out = F.avg_pool2d(x[:, :, hs:he, ws:we], kernel_size) 
                out_j.append(out)
                
            out_j = paddle.concat(out_j, -1)
            out_i.append(out_j)
            
        out_i = paddle.concat(out_i, -2)
        return out_i

use CostomAdaptiveAvgPool2D Exchange AdaptiveAvgPool2D, And you can specify the size of the original image and the output image

 Insert picture description here

[14,14] Is the size of the input graph , This is me. pp_liteseg Input shape yes 224 × 224 224\times 224 224×224, So on the upper floor shape yes

[-1, 512, 14, 14]

Then three at a time AdaptiveAvgPool2D become

[-1, 512,  1,   1]
[-1, 512,  2,   2]
[-1, 512,  4,   4]

then paddle2onnx Export it

paddle2onnx --model_dir . \
            --model_filename model.pdmodel \
            --params_filename model.pdiparams \
            --opset_version 11 \
            --save_file output.onnx
原网站

版权声明
本文为[Master Yiwen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206260945061413.html