当前位置:   article > 正文

海思开发:yolo v5的 focus层 移植到海思上的方法_focus层 caffe

focus层 caffe

一、前言

经网友提醒,yolo v2的 passthrough 层与 v5 的 focus 层很像,因为海思是支持 passthrough 层的,鉴于此,花了点时间了解了一下,提出一些浅见,抛砖引玉。另附:yolo v5 海思开发

二、区别

上文我说的是,二者很像,说明它们还是有区别的,现在说说区别。

1. passthrough 层

出于严谨,结合海思文档图片与 passthrough 源码来一起理解,先看看 passthrough 源码:

// 它的源码是 c++ 的,不是 python 格式
int reorg_cpu(THFloatTensor *x_tensor, int w, int h, int c, int batch, int stride, int forward, THFloatTensor *out_tensor)
 3 {
   
 4     // Grab the tensor
 5     float * x = THFloatTensor_data(x_tensor);
 6     float * out = THFloatTensor_data(out_tensor);
 7 
 8     // https://github.com/pjreddie/darknet/blob/master/src/blas.c
 9     int b,i,j,k;
10     int out_c = c/(stride*stride);
11
12     for(b = 0; b < batch; ++b){
     //batch_size
13         
14         for(k = 0; k < c; ++k){
     //channel
15            
16             for(j = 0; j < h; ++j){
     //height
17                 
18                 for(i = 0; i < w; ++i){
     //width,可以看见passthrough 是行优先 !
19                     
20                     int in_index  = i + w*(j + h*(k + c*b));
21                     int c2 = k % out_c;
22                     int offset = k / out_c;
23                     int w2 = i*stride + offset % stride;
24                     int h2 = j*stride + offset / stride;
25                     int out_index = w2 + w*stride*(h2 + h*stride*(c2 + out_c*b));
26                     if(forward) out[out_index] = x[in_index]; // 压缩channel
27                     else out[in_index] = x[out_index];        // 扩展channel
28                 }
29             }
30         }
31     }
32 
33     return 1;
34 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

在这里插入图片描述
再结合海思的文档的图示来看,更加清晰,上图可以看见数据重新排布的顺序是 红色 -> 天蓝色 -> 淡绿(左下) -> 深绿(右下),即行优先。再结合上文第18行代码可得出,passthrough 层确实是行优先,这个先记住。

2. focus 层

focus层没有上面的图示,只有代码,我们根据源码举个例子加强理解一下。

# 源码镇楼
class Focus(nn.Module):
    # Focus wh information into c-space
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
        super(Focus, self).__init__()
        self.conv = Conv(c1 * 4, c2, k, s, p, g, act)

    def forward(self, x):  # x(b,c,h,w) -> y(b,4c,h/2,w/2)
        return self.conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

下面举例:

a = np.array(range(8)).reshape(1, 2, 2, 2)
print(a.shape)
print(a)

d = np.concatenate([a[..., ::2, ::2], a
  • 1
  • 2
  • 3
  • 4
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/161662
推荐阅读
相关标签
  

闽ICP备14008679号