concat与add操作辨析

省流结论

concat是通道数叠加

add为简单的像素叠加,通道不变


图示表达

在这里插入图片描述


concat作用

concat是通道数的增加,也就是说描述图像本身的特征数(通道数)增加了,而每一特征下的信息是没有增加;横向或纵向空间上的叠加。

add作用

add为简单的像素叠加,是描述图像的特征下的信息量增多了,但是描述图像的维度本身并没有增加,只是每一维下的信息量在增加,这显然是对最终的图像的分类是有益的。

数学表达

对于两路输入来说,如果是通道数相同且后面带卷积的话,add等价于concat之后对应通道共享同一个卷积核。下面具体式子解释一下,由于每个输出通道的卷积核是独立的,我们可以只看单个通道的输出。假设两路输入的通道分别为 X 1 , X 2 , . . . , X c 和 Y 1 , Y 2 , . . . , Y c . \mathrm{X}_{1},\mathrm{X}_{2},...,\mathrm{X}_{\mathrm{c}}和\mathrm{}Y_{1},\mathrm{Y}_{2},...\mathrm{,Y}_{\mathrm{ {c}}}. X1,X2,...,XcY1,Y2,...,Yc.

那么concat单个输出通道为:
在这里插入图片描述


add单个输出通道为:

在这里插入图片描述


联系

add相当于加了一种prior,当两路输入可以具有“对应通道的特征图语义类似”(可能不太严谨)的性质的时候,可以用add来替代concat,这样更节省参数和计算量(concat是add的2倍

代码

class Concat(nn.Module):
    # Concatenate a list of tensors along dimension
    def __init__(self, dimension=1):
        super().__init__()
        self.d = dimension

    def forward(self, x):
        return torch.cat(x, self.d)
t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 0) ==> [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 1) ==> [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]

# tensor t3 with shape [2, 3]
# tensor t4 with shape [2, 3]
tf.shape(tf.concat([t3, t4], 0)) ==> [4, 3]
tf.shape(tf.concat([t3, t4], 1)) ==> [2, 6]
import tensorflow as tf

x = tf.random.normal([1, 28, 28, 3]) # 输入张量
conv1 = tf.keras.layers.Conv2D(16, (3, 3), strides=2) # 卷积层1
conv2 = tf.keras.layers.Conv2D(16, (3, 3), strides=2) # 卷积层2

out1 = conv1(x) # 输出张量1
out2 = conv2(out1) # 输出张量2

out = tf.keras.layers.add([out1, out2]) # add操作

猜你喜欢

转载自blog.csdn.net/qq_44029998/article/details/129598748