小结
特征add的时候就是增加特征的信息量,特征concat的时候就是增加特征的数量,注重细节的时候使用add,注重特征数量的时候使用concat。
作用和注意事项
concate
-
作用:concate操作用于将两个或多个张量在某个维度上连接在一起,生成一个更大的张量。这可以用于在深度学习模型中增加通道数或特征维度,以便在后续层中更好地捕获不同特征之间的关系。
-
示例:在卷积神经网络中,特征图通常具有形状为
(batch_size, channels, height, width)
,如果要在通道维度上连接两个特征图,可以使用concatenate操作,结果将是形状为(batch_size, channels1 + channels2, height, width)
的特征图。 -
注意:在连接时,两个张量的维度(除了连接维度)必须保持一致。例如,在通道维度上连接时,其他维度的尺寸必须相同。
add
-
作用:add操作用于将两个张量逐元素相加在一起,生成一个新的张量。这可以用于实现跳跃连接(skip connection)或残差连接(residual connection),以促进梯度的流动,提高训练稳定性,以及在深层网络中减少梯度消失问题。
-
示例:在残差网络(resnet)中,残差块的输入特征与残差块的输出特征被相加在一起,以生成最终的块输出。这有助于网络在训练时更容易地学习恒等映射。
-
注意:相加操作要求相加的张量具有相同的形状,因为它们是逐元素相加的。
直观理解
concat作用
concat是通道数的增加,也就是说描述图像本身的特征数(通道数)增加了,而每一特征下的信息是没有增加;横向或纵向空间上的叠加。
add作用
add为简单的像素叠加,是描述图像的特征下的信息量增多了,但是描述图像的维度本身并没有增加,只是每一维下的信息量在增加,这显然是对最终的图像的分类是有益的。
数学表达
对于两路输入来说,如果是通道数相同且后面带卷积的话,add等价于concat之后对应通道共享同一个卷积核。下面具体用式子解释一下。由于每个输出通道的卷积核是独立的,我们可以只看单个通道的输出。假设两路输入的通道分别为和
。那么concat的单个输出通道为(*表示卷积):
而add的单个输出通道为:
因此add相当于加了一种prior,当两路输入可以具有“对应通道的特征图语义类似”(可能不太严谨)的性质的时候,可以用add来替代concat,这样更节省参数和计算量(concat是add的2倍)。fpn[1]里的金字塔,是希望把分辨率最小但语义最强的特征图增加分辨率,从性质上是可以用add的。如果用concat,因为分辨率小的特征通道数更多,计算量是一笔不少的开销。
cpn[2]为了进一步减少计算量,对于分辨率小的特征图在add前用1x1的卷积减少了通道数。
有一个例子是resnet[4]的skip connection。这里的add主要是为了保持mapping的identity性质,使梯度回传得更加容易。同样的操作在lstm[5]里的cell state也能看到。
当然,如果不在乎计算量且数据足够的时候,用concat也是可以的,因为这两个本身就是包含关系。实际上concat在skip connection里用的也比add更普遍,比如u-net[6]、densenet[7]。
其他理解
concatenate和add可以相互转化
concat是肯定是计算量大于element-wise add的,但个人认为,concat避免了直接add对信息造成的负面影响。而且逐元素加和的方式要求不同层的feature map具有完全一致的channel数量,而cancat不受channel数量的限制(yolov3里就是concat,做concat操作的两层通道数不同)。
resnet,densenet等神经网络中,常常采用add来连接特征层,unet中常常采用concatenate。因为unet是做图像分割的,图像分割是像素级分类,对特征的数量要求很高。而add是在一个特征上增加其语义信息,举个例子,一张脸,没有通过add话,你可能只会看到眼睛,通过add后你可以看见鼻子,眉毛,这样就可以增加置信度更好的判断这个人是谁,从而增加目标检测的准确率。
发表评论