Diverse Branch Block论文中对于串联卷积的融合中的一些理解点

首先我们用一个小的具体的例子来具象化

假设输入是 (N,3,5,5);
第一层卷积是(2,3,1,1),我们设pad=0,stride=1,那么得到的输出结果应该就是(N,2,5,5)
第二层卷积是(2,2,3,3),pad=0,stride=1,那么得到的输出结果应该是(N,2,3,3)
在这里插入图片描述

REP(b)的意思是什么呢

如果按照一般的处理方法比如 DFQ——前后两层卷积核数量不一样是否可以进行均衡.md

def conv_forward_naive(x, w, b, conv_param):
    """
    A naive implementation of the forward pass for a convolutional layer.

    The input consists of N data points, each with C channels, height H and
    width W. We convolve each input with F different filters, where each filter
    spans all C channels and has height HH and width WW.

    Input:
    - x: Input data of shape (N, C, H, W)
    - w: Filter weights of shape (F, C, HH, WW)
    - b: Biases, of shape (F,)
    - conv_param: A dictionary with the following keys:
      - 'stride': The number of pixels between adjacent receptive fields in the
        horizontal and vertical directions.
      - 'pad': The number of pixels that will be used to zero-pad the input. 


    During padding, 'pad' zeros should be placed symmetrically (i.e equally on both sides)
    along the height and width axes of the input. Be careful not to modfiy the original
    input x directly.

    Returns a tuple of:
    - out: Output data, of shape (N, F, H', W') where H' and W' are given by
      H' = 1 + (H + 2 * pad - HH) / stride
      W' = 1 + (W + 2 * pad - WW) / stride
    - cache: (x, w, b, conv_param)
    """
    out = None
    ###########################################################################
    # TODO: Implement the convolutional forward pass.                         #
    # Hint: you can use the function np.pad for padding.                      #
    ###########################################################################
    pad = conv_param['pad']
    stride = conv_param['stride']
    N, C, H, W = x.shape
    F, C, FH, FW = w.shape

    assert (H - FH + 2 * pad) % stride == 0
    assert (W - FW + 2 * pad) % stride == 0
    #outH = 1 + (H - FH + 2 * pad) / stride
    #outW = 1 + (W - FW + 2 * pad) / stride
    outH = int(1 + (H - FH + 2 * pad) / stride)
    outW = int(1 + (W - FW + 2 * pad) / stride)


    # create output tensor after convolution layer
    out = np.zeros((N, F, outH, outW))

    # padding all input data
    x_pad = np.pad(x, ((0,0), (0,0),(pad,pad),(pad,pad)), 'constant')
    H_pad, W_pad = x_pad.shape[2], x_pad.shape[3]    

    # create w_row matrix
    w_row = w.reshape(F, C*FH*FW)                            #[F x C*FH*FW]

    # create x_col matrix with values that each neuron is connected to
    x_col = np.zeros((C*FH*FW, outH*outW))                   #[C*FH*FW x H'*W']
    for index in range(N):
        neuron = 0 
        for i in range(0, H_pad-FH+1, stride):
            for j in range(0, W_pad-FW+1,stride):
                x_col[:,neuron] = x_pad[index,:,i:i+FH,j:j+FW].reshape(C*FH*FW)
                neuron += 1
        out[index] = (w_row.dot(x_col) + b.reshape(F,1)).reshape(F, outH, outW)
    ###########################################################################
    #                             END OF YOUR CODE                            #
    ###########################################################################
    cache = (x_pad, w, b, conv_param)
    return out, cache

从这个过程来看,卷积核在生成feature map的每一个点的时候,都是有偏置参与运算的。也就是点积之后再加上偏置。
但是我们可以做这样一个等效的变换,在生成feature map的每个点的时候先不用bias参与运算。仅仅计算点积,最后feature map上所有的点一口气都加上偏置,也就是这种感觉
在这里插入图片描述

那么偏置如何和卷积核进行卷积

通过REP操作我们把b扩展成一个和输出的h和w的一样矩阵,之后这个矩阵再和卷积核进行卷积,还拿上面例子来演示
在这里插入图片描述
第一层卷积核中的bias经过rep变成了(1,2,5,5)这样的数据体和第二层卷积核中的w(2,2,3,3)进行卷积得到的(2,2,3,3)这样的数据体也就是 R E P ( b ^ ) REP(\hat b) REP(b^)
这个REP(\hat b)正好和第二层卷积核中的偏置做REP的结果尺寸(2,3,3)正好一样,就可以加在一起。
这就解释了原文中的公式14和公式15

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值