YOLOv2源码分析--reorg layer
发布日期:2021-06-29 16:00:15 浏览次数:2 分类:技术文章

本文共 2431 字,大约阅读时间需要 8 分钟。

文章全部

reorg layer中最关键的代码如下

void reorg_cpu(float *x, int w, int h, int c, int batch, int stride, int forward, float *out){
int b,i,j,k; int out_c = c/(stride*stride); for(b = 0; b < batch; ++b){
for(k = 0; k < c; ++k){
for(j = 0; j < h; ++j){
for(i = 0; i < w; ++i){
int in_index = i + w*(j + h*(k + c*b)); int c2 = k % out_c; int offset = k / out_c; int w2 = i*stride + offset % stride; int h2 = j*stride + offset / stride; int out_index = w2 + w*stride*(h2 + h*stride*(c2 + out_c*b)); if(forward) out[out_index] = x[in_index]; else out[in_index] = x[out_index]; } } } }}

这一部分表述为数学公式就是

  • i n _ i n d e x = W 1 + W ∗ s t r i d e ∗ ( H 1 + H ∗ ( C 1 + C ∗ B ) ) in\_index=W_1+W*stride*(H_1+H*(C_1+C*B)) in_index=W1+Wstride(H1+H(C1+CB))

  • C 2 = C 1 % C o u t C_2=C_1\%C_{out} C2=C1%Cout

  • o f f s e t = C 1 / C o u t offset = C_1/C_{out} offset=C1/Cout

  • W 2 = W 1 ∗ s t r i d e + o f f s e t % s t r i d e W_2=W_1*stride+offset\%stride W2=W1stride+offset%stride

  • H 2 = H 1 ∗ s t r i d e + o f f s e t / s t r i d e H_2=H_1*stride+offset/stride H2=H1stride+offset/stride

  • o u t _ i n d e x = W 2 + W ∗ s t r i d e ∗ ( H 2 + H ∗ s t r i d e ∗ ( C 2 + C o u t ∗ B ) ) out\_index = W_2+W*stride*(H_2+H*stride*(C_2+C_{out}*B)) out_index=W2+Wstride(H2+Hstride(C2+CoutB))

对于前向传播,想要表达的意思就是下面这个图

那么我们知道,矩阵运算可以更加简洁的表示上面的代码中的循环,我这里给出pytorch下的代码示例

B,C,H,W = input.size()input = input.view(B, C, H/stride, stride, W/stride, stride).transpose(3,4).contiguous()input = input.view(B, C, H/stride*W/stride, stride*stride).transpose(2,3).contiguous()input = input.view(B, C, stride*stride, H/stride, W/stride).transpose(1,2).contiguous()input = input.view(B, stride*stride*C, H/stride, W/stride)

非常简洁的就解决了上述的问题,但是简洁背后的数学原理你要明白。

首先我先说一下这里的参数含义:

  • B:batch
  • C:通道数目
  • H:高
  • W:宽

按照论文中的做法,我们这里stride取2

input = input.view(B, C, H/stride, stride, W/stride, stride).transpose(3,4).contiguous()

这里的view函数的意义,我么可以理解为“看成”

这个式子想要表达的含义如下图:

input = input.view(B, C, H/stride*W/stride, stride*stride).transpose(2,3).contiguous()

这个式子想要表达的含义如下图:

从第一个式子到第二个式子的过程我们可以抽象为

input = input.view(B, C, stride*stride, H/stride, W/stride).transpose(1,2).contiguous()

这个式子想要表达的含义如下图:

最后抽象为

觉得不错,点个赞吧b( ̄▽ ̄)d

由于本人水平有限,文中有不对之处,希望大家指出,谢谢_!

转载地址:https://coordinate.blog.csdn.net/article/details/78948839 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:python如果获取windows管理员权限(一)
下一篇:torch.autograd.backward中的参数问题

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年05月02日 03时16分26秒