对于两路输入来说,如果是通道数相同且后面带卷积的话,add等价于concat之后对应通道共享同一个卷积核。下面具体用式子解释一下。由于每个输出通道的卷积核是独立的,我们可以只看单个通道的输出。假设两路输入的通道分别为X1, X2, …, Xc和Y1, Y2, …, Yc。那么concat的单个输出通道为(*表示卷积):
而add的单个输出通道为:
因此add相当于加了一种prior,当两路输入可以具有“对应通道的特征图语义类似”(可能不太严谨)的性质的时候,可以用add来替代concat,这样更节省参数和计算量(concat是add的2倍)。FPN[1]里的金字塔,是
希望把分辨率最小但语义最强的特征图增加分辨率,从性质上是可以用add的
。如果用concat,因为分辨率小的特征通道数更多,计算量是一笔不少的开销
CPN[2]为了进一步减少计算量,对于分辨率小的特征图在add前用1x1的卷积减少了通道数。
又比如edge detection[3]的工作,里面不同层输出的edge map也通过weighted add融合在一起,这是因为这些输出的语义本来就是相同的,都用了label的loss来约束。
还有一个例子是ResNet[4]的skip connection。这里的add主要是为了保持mapping的identity性质,使梯度回传得更加容易。同样的操作在LSTM[5]里的cell state也能看到。
当然,如果不在乎计算量且数据足够的时候,用concat也是可以的,因为这两个本身就是包含关系。实际上concat在skip connection里用的也比add更普遍,比如题主提到的U-Net[6]、DenseNet[7]。
参考文献:
[1] Lin T Y, Dollár P, Girshick R B, et al. Feature Pyramid Networks for Object Detection[C]//CVPR. 2017, 1(2): 4.
[2] Chen Y, Wang Z, Peng Y, et al. Cascaded pyramid network for multi-person pose estimation[J]. arXiv preprint arXiv:1711.07319, 2017.
[3] Xie S, Tu Z. Holistically-nested edge detection[C]//Proceedings of the IEEE international conference on computer vision. 2015: 1395-1403.
[4] He K, Zhang X, Ren S, et al. Identity mappings in deep residual networks[C]//European conference on computer vision. Springer, Cham, 2016: 630-645.
[5] Hochreiter S, Schmidhuber J. Long short-term memory[J]. Neural computation, 1997, 9(8): 1735-1780.
[6] Ronneberger O, Fischer P, Brox T. U-net: Convolutional networks for biomedical image segmentation[C]//International Conference on Medical image computing and computer-assisted intervention. Springer, Cham, 2015: 234-241.
[7] Huang G, Liu Z, Van Der Maaten L, et al. Densely connected convolutional networks[C]//CVPR. 2017, 1(2): 3.
concat是肯定是计算量大于element-wise add的,但个人认为,concat避免了直接add对信息造成的负面影响。而且逐元素加和的方式要求不同层的feature map具有完全一致的channel数量,而cancat不受channel数量的限制(yolov3里就是concat,做concat操作的两层通道数不同)
add操作经典代表网络是ResNet,concate操作经典代表网络是Inception系统网络中的Inception结构和DenseNet。
正如之前的回答有人说的,add操作相当于加入一种先验知识。我觉得也就是相当于你对原始特征进行人为的特征融合。而你选择的特征处理的操作是element-wise add。
通过add操作,会得到新的特征,这个新的特征可以反映原始特征的一些特性,但是原始特征的一些信息也会在这个过程中损失。
但是
concate就是将原始特征直接拼接,让网络去学习,应该如何融合特征,这个过程中信息不会损失。
所以我认为add其实只是concate的一种特殊情况。但是concate带来的计算量较大,在明确原始特征的关系可以使用add操作融合的话,使用add操作可以节省计算代价。
我认为没有人能彻底回答这个问题。NN领域很多问题都这样。
add操作必然会带来信息损失。两头羊加两头羊等于四头羊,这时候加法没有损失信息。但是如果两个被加的向量不具备同类特征含义时怎么办?事实上,如果有了加法操作,训练过程会把加法之后那个特征分解为加法前的两个子特征。如果这两个子特征之和超过了某个阈值,哪怕一正一负,就有激活功能。这两个子特征未必需要是同类特征含义。信息损失如果“损失”得当,就是信息提取!
NN牛叉就牛叉在这里,说得清的话,早就用特征工程搞定了,还用什么NN。
add作为一种特征融合的方式在没有时序的网络中是无害的,concat是add的泛华形式,对比densenet和resnet即可知道。
但是在时序步共享的网络中,add简直是灾难性的,因为时序共享的网络诸如lstm和gru,要求每一个时间步共享参数,那么处在后时序步的网络输出值域要远远大于最开始前几部的值域,所以rnn会有梯度的问题,因此lstm和gru应运而生,不过个人觉得lstm和gru绝对称不上是好网络,解释性太差,每个门的动作仅仅基于启发式的yy来设计,我们需要有能力的学者探讨如何在时序网络中进行特征的融合。
总结:
Resnet是做值的叠加,通道数是不变的,DenseNet是做通道的合并。你可以这么理解,add是描述图像的特征下的信息量增多了,但是描述图像的维度本身并没有增加,只是每一维下的信息量在增加,这显然是对最终的图像的分类是有益的。而concatenate是通道数的合并,也就是说描述图像本身的特征增加了,而每一特征下的信息是没有增加。
cat和add 在pool上的例子(组合池化)
组合池化则是同时利用最大值池化与均值池化两种的优势而引申的一种池化策略。常见组合策略有两种:Cat与Add。其代码描述如下:
def add_avgmax_pool2d(x, output_size=1):
x_avg = F.adaptive_avg_pool2d(x, output_size)
x_max = F.adaptive_max_pool2d(x, output_size)
return 0.5 * (x_avg + x_max)
def cat_avgmax_pool2d(x, output_size=1):
x_avg = F.adaptive_avg_pool2d(x, output_size)
x_max = F.adaptive_max_pool2d(x, output_size)
return torch.cat([x_avg, x_max], 1)
在网络模型当
中
,经常要进行
不同
通道
特征
图的信息
融合
相加操作,以整合
不同
通道的信息,在具体实现方面
特征
的
融合
方式
一共有两种,一种是 ResNet 和 FPN 等当
中
采用的 element-wise
add
,另一种是 DenseNet 等
中
采用的
concat
。他们之间有什么区别呢?
以下是 keras
中
对
add
的实现源码:
def _merge_function(self, inputs):
output = inputs[0]
for i in range(1, le
原文链接:https://blog.csdn.net/xys430381_1/article/details/88355956
一、如何理解
concat
和
add
的
方式
融合
特征
在各个网络模型
中
,ResNet,FPN等采用的element-wise
add
来
融合
特征
,而DenseNet等则采用
concat
来
融合
特征
。那
add
与
concat
形式有什么
不同
呢?事实上两者都可以理解为整合
特征
图信息。只不过
concat
比较直观,而
add
理解起来比较生涩。
从图
中
可以发现,
concat
是通道数的增加;
add
是特
池化
操作(Pooling)是CNN
中
非常常见的一种操作,Pooling层是模仿人的视觉系统对数据进行降维,
池化
操作通常也叫做子采样(Subsampling)或降采样(Downsampling),在构建卷积
神经网络
时,往往会用在卷积层之后,通过
池化
来降低卷积层输出的
特征
维度,有效减少网络参数的同时还可以防止过拟合现象。
主要功能有以下几点:
抑制噪声,降低信息冗余
提升模型的尺度不变性、旋转不变形...
1. 如何理解
concat
和
add
:
实际上
add
与
concat
都可以理解为用于整合
特征
图信息,ResNet/FPN等网络结构逐元素做值的叠加而通道数是不变的,采用的
add
方式
来
融合
特征
;而DenseNet等网络结构则做通道的合并,采用
concat
方式
来
融合
特征
。
concat
方式
经常用于将
特征
联合、多个卷积
特征
提取框架提取的
特征融合
或者是将输出层的信息进行
融合
;而
add
层更像是信息之间的叠加。
可以理解为,
add
方式
在...
在Java集合
中
,要对BigDecimal进行相加,你可以使用BigDecimal的
add
方法。假设你有一个包含BigDecimal对象的List,你可以遍历这个List并对其
中
的BigDecimal对象逐一进行相加操作。
下面是一个示例代码:
```java
import java.math.BigDecimal;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<BigDecimal> numbers = List.of(
new BigDecimal("10.5"),
new BigDecimal("20.7"),
new BigDecimal("30.3")
BigDecimal sum = BigDecimal.ZERO;