特征融合目前有两种常用的方式,一种是addaddadd操作,这种操作广泛运用于ResNetResNetResNet与FPNFPNFPN中。一种是ConcatConcatConcat操作,这种操作最广泛的运用就是UNetUNetUNet,DenseNetDenseNetDenseNet等网络中。如下图所示:


也有如HRNetHRNetHRNet这样的,多分辨率之间使用addaddadd形式的特征融合。

代码演示
>>> import torch
>>> img1 = torch.randn(2, 3, 58, 58)
>>> img2 = torch.randn(2, 3, 58, 58)
>>> img3 = img1 + img2
>>> img4 = torch.cat((img1, img2), dim=1)
>>> img3.size()
torch.Size([2, 3, 58, 58])
>>> img4.size()
torch.Size([2, 6, 58, 58])
>>>
那么对于AddAddAdd操作与ConcatConcatConcat操作,它们中间有哪些区别与联系呢?
联系
addaddadd 和concatconcatconcat 形式都可以理解为整合多路分支featurefeaturefeature mapmapmap 的信息,只不过concatconcatconcat 比较直观(同时利用不同层的信息),而addaddadd 理解起来比较生涩(为什么两个分支的信息可以相加?)。concatconcatconcat 操作时时将通道数增加,addaddadd 是特征图相加,通道数不变。
对于两路通入而言,其大小(H,WH, WH,W )是一样的。假设两路输入的通道分别为X1,X2,…XcX_{1}, X_{2}, … X_{c}X1,X2,…Xc, Y1,Y2,…YnY_{1}, Y_{2},…Y_{n}Y1,Y2,…Yn。
则对于ConcatConcatConcat的操作,通道数相同且后面带卷积的话,addaddadd等价于concatconcatconcat之后对应通道共享同一个卷积核。
当我们需要聚合的两个分支的FeatureFeatureFeature叫做XXX与YYY的时候,我们可以使用ConcatConcatConcat, 概括为:
Zout=∑i=1cXi∗Ki+∑i=1cYi∗Ki+c
Z_{out}=\sum_{i=1}^{c} X_{i} * K_{i}+\sum_{i=1}^{c} Y_{i} * K_{i+c}
Zout=i=1∑cXi∗Ki+i=1∑cYi∗Ki+c
对于addaddadd的操纵,可以概括为:
Zadd =∑i=1c(Xi+Yi)∗Ki=∑i=1cXi∗Ki+∑i=1cYi∗Ki
Z_{\text {add }}=\sum_{i=1}^{c}\left(X_{i}+Y_{i}\right) * K_{i}=\sum_{i=1}^{c} X_{i} * K_{i}+\sum_{i=1}^{c} Y_{i} * K_{i}
Zadd =i=1∑c(Xi+Yi)∗Ki=i=1∑cXi∗Ki+i=1∑cYi∗Ki
因此,采用addaddadd操作,我们相当于加入一种先验。当两个分支的特征信息比较相似,可以用addaddadd来代替concatconcatconcat,这样可以更节省参数量。
区别
- 对于ConcatConcatConcat操作而言,通道数的合并,也就是说描述图像本身的特征增加了,而每一特征下的信息是没有增加。
- 对于addaddadd层更像是信息之间的叠加。这里有个先验,addaddadd前后的tensortensortensor语义是相似的。
结论
因此,像是需要将AAA与BBB的TensorTensorTensor进行融合,如果它们语义不同,则我们可以使用ConcatConcatConcat的形式,如UNetUNetUNet, SegNetSegNetSegNet这种编码与解码的结构,主要还是使用ConcatConcatConcat。
而如果AAA与BBB是相同语义,如AAA与BBB是不同分辨率的特征,其语义是相同的,我们可以使用addaddadd来进行融合,如FPNFPNFPN等网络的设计。

特征融合在深度学习中至关重要,主要分为Add和Concat两种方式。Add操作通过相加整合特征,常用于ResNet和FPN;Concat操作则是通道拼接,常见于UNet和DenseNet。Add操作假设特征语义相似,节省参数,而Concat则能保留更多特征信息。在选择融合方式时,若特征语义不同,适合用Concat;若语义相同或分辨率不同,Add更为合适。
746

被折叠的 条评论
为什么被折叠?



