ShuffleNet中add层和concatenate层的区别

最近学习轻量级网络:ShuffleNet V1,看论文过程中对其模型中add和concat层不理解,查看一番资料后,总结如下:
ShuffleNet中add层和concatenate层的区别_第1张图片

主流轻量级CNN网络

  1. ShuffleNet V1 和ShuffleNet V2;
  2. MobileNet V1 和 MobileNet V1;
  3. Xception
  4. SqueezeNet
    这几个模型是16年来比较流行的网络,值得去学习其论文,跑代码。
    参考链接: https://blog.csdn.net/u014451076/article/details/80162924

add层和concat层的区别

通俗讲: add层就是输出结果累加,其维度不变,但信息量增加了;concat层就是把数据结果级联,增加了维度,信息量不同。
举一个例子:
add:

a = [[1,2], [3, 4]]
b =  [[11,12], [13, 14]]
c = add(a, b)  # c = [[12,14], [16, 18]]  这里add表示add层操作,把输出结果值相加了

concat:

a = [[1,2], [3, 4]]
b =  [[11,12], [13, 14]]
c = concat(a, b)  # c = [[1,2], [3, 4], [11,12], [13, 14]]  这里concat表示concat层操作,把输出结果级联,增加了维度

DenseNet和Inception中更多采用的是concatenate操作,而ResNet更多采用的add操作,Resnet是做值的叠加,通道数是不变的,DenseNet是做通道的合并。你可以这么理解,add是描述图像的特征下的信息量增多了,但是描述图像的维度本身并没有增加,只是每一维下的信息量在增加,这显然是对最终的图像的分类是有益的。而concatenate是通道数的合并,也就是说描述图像本身的特征增加了,而每一特征下的信息是没有增加。

在代码层面就是ResNet使用的都是add操作,而DenseNet使用的是concatenate。

这些对我们设计网络结构其实有很大的启发。

通过看keras的源码,发现add操作,

def _merge_function(self, inputs):
    output = inputs[0]
    for i in range(1, len(inputs)):
        output += inputs[i]
    return output

执行的就是加和操作,举个例子

import keras
 
input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8, activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8, activation='relu')(input2)
added = keras.layers.add([x1, x2])
 
out = keras.layers.Dense(4)(added)
model = keras.models.Model(inputs=[input1, input2], outputs=out)
model.summary()

打印出来模型结构就是:


Layer (type) Output Shape Param Connected to

================================================================================
input_1 (InputLayer) (None, 16) 0


input_2 (InputLayer) (None, 32) 0


dense_1 (Dense) (None, 8) 136 input_1[0][0]


dense_2 (Dense) (None, 8) 264 input_2[0][0]


add_1 (Add) (None, 8) 0 dense_1[0][0]
dense_2[0][0]


dense_3 (Dense) (None, 4) 36 add_1[0][0]

=================================================================================
Total params: 436
Trainable params: 436
Non-trainable params: 0


这个比较好理解,add层就是接在dense_1,dense_2后面的是一个连接操作,并没有训练参数。

相对来说,concatenate操作比较难理解一点。

if py_all([is_sparse(x) for x in tensors]):
    return tf.sparse_concat(axis, tensors)
else:
    return tf.concat([to_dense(x) for x in tensors], axis)

通过keras源码发现,一个返回sparse_concate,一个返回concate,这个就比较明朗了,

concate操作,举个例子

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]

事实上,是关于维度的一个联合,axis=0表示列维,1表示行维,沿着通道维度连接两个张量。另一个sparse_concate则是关于稀疏矩阵的级联,也比较好理解。

你可能感兴趣的:(Deep,Learning)