# 用简单代码看卷积组块发展

``````defconv(x, f, k=3, s=1, p='same', d=1, a='relu'):
return Conv2D(filters=f, kernel_size=k, strides=s,

def dense(x, f, a='relu'):
return Dense(f, activation=a)(x)

defmaxpool(x, k=2, s=2, p='same'):

defavgpool(x, k=2, s=2, p='same'):

defgavgpool(x):
return GlobalAveragePooling2D()(x)

defsepconv(x, f, k=3, s=1, p='same', d=1, a='relu'):
return SeparableConv2D(filters=f, kernel_size=k, strides=s,

``````defconv(x, f, k=3, s=1, p='same', d=1, a='relu'):
return Conv2D(filters=f, kernel_size=k, strides=s,

def dense(x, f, a='relu'):
return Dense(f, activation=a)(x)

defmaxpool(x, k=2, s=2, p='same'):

defavgpool(x, k=2, s=2, p='same'):

defgavgpool(x):
return GlobalAveragePooling2D()(x)

defsepconv(x, f, k=3, s=1, p='same', d=1, a='relu'):
return SeparableConv2D(filters=f, kernel_size=k, strides=s,

#### 瓶颈（Bottleneck）组块

``````def bottleneck(x, f=32, r=4):
x = conv(x, f//r, k=1)
x = conv(x, f//r, k=3)
return conv(x, f, k=1)``````

#### Inception模块

``````defnaive_inception_module(x, f=32):
a = conv(x, f, k=1)
b = conv(x, f, k=3)
c = conv(x, f, k=5)
d = maxpool(x, k=3, s=1)
return concatenate([a, b, c, d])``````

``````definception_module(x, f=32, r=4):
a = conv(x, f, k=1)
b = conv(x, f//3, k=1)
b = conv(b, f, k=3)
c = conv(x, f//r, k=1)
c = conv(c, f, k=5)
d = maxpool(x, k=3, s=1)
d = conv(d, f, k=1)
return concatenate([a, b, c, d])
``````

#### 剩余组块（ResNet）

ResNet是由微软的研究人员提出的一种体系结构，它允许神经网络具有任意多的层数，同时还提高了模型的准确度。现在你可能已经习惯使用它了，但在ResNet之前，情况并非如此。

``````defresidual_block(x, f=32, r=4):
m = conv(x, f//r, k=1)
m = conv(m, f//r, k=3)
m = conv(m, f, k=1)

ResNet的思路是将初始的激活添加到卷积组块的输出结果中。利用这种方式，网络可以通过学习过程决定用于输出的新卷积的数量。值得注意的是，Inception模块连接这些输出，而剩余组块是用于求和。

#### ResNeXt组块

``````defresnext_block(x, f=32, r=2, c=4):
l = []
for i in range(c):
m = conv(x, f//(c*r), k=1)
m = conv(m, f//(c*r), k=3)
m = conv(m, f, k=1)
l.append(m)

#### 密集（Dense）组块

``````defdense_block(x, f=32, d=5):
l = x
for i in range(d):
x = conv(l, f)
l = concatenate([l, x])
return l``````

#### SENet（Squeeze-and-Excitation）组块

SENet曾经在短期内代表着ImageNet的较高水平。它是建立在ResNext的基础之上的，主要针对网络通道信息的建模。在常规的卷积层中，每个通道对于点积计算中的加法操作具有相同的权重。

SENet引入了一个非常简单的模块，可以添加到任何现有的体系结构中。它创建了一个微型神经网络，学习如何根据输入对每个过滤器进行加权。正如你看到的那样，SENet本身不是一个卷积组块，但是因为它可以被添加到任何卷积组块中，并且可能会提高它的性能，因此我想将它添加到混合体中。

``````defse_block(x, f, rate=16):
m = gavgpool(x)
m = dense(m, f // rate)
m = dense(m, f, a='sigmoid')
return multiply([x, m])``````

SENets只用了很小的计算开销，同时还可能会改进卷积模型。在我看来，这个组块并没有得到应有的重视。

#### NASNet标准单元

``````defnormal_cell(x1, x2, f=32):
a1 = sepconv(x1, f, k=3)
a2 = sepconv(x1, f, k=5)
b1 = avgpool(x1, k=3, s=1)
b2 = avgpool(x1, k=3, s=1)
c2 = avgpool(x2, k=3, s=1)
d1 = sepconv(x2, f, k=5)
d2 = sepconv(x1, f, k=3)
e2 = sepconv(x2, f, k=3)
return concatenate([a, b, c, d, e])``````

#### 倒置剩余（Inverted Residual）组块

``````definv_residual_block(x, f=32, r=4):
m = conv(x, f*r, k=1)
m = sepconv(m, f, a='linear')

#### 结论

原文作者：阿里云云栖社区
原文地址: https://segmentfault.com/a/1190000017247505
本文转自网络文章，转载此文章仅为分享知识，如有侵权，请联系博主进行删除。