MobileNetV1
MobileNetV1核心思想是采用深度可分离卷积操作。在相同的权值参数数量的情况下,相较标准卷积操作,可以减少数倍的计算量,从而达到提升网络运算速度的目的。
深度可分离卷积的构成:
常规卷积操作:
深度卷积:
与标准卷积网络不一样的是,深度卷积将卷积核拆分成为但单通道形式,在不改变输入特征图像的深度的情况下,对每一通道进行卷积操作,这样就得到了和输入特征图通道数一致的输出特征图。
逐点卷积:
depthwise卷积没有考虑到同一位置不同channel上的数据之间的关联.所以用一个1 x 1的卷积核对depthwise得到的输出再做卷积。
MobileNetV1网络结构
MobileNet的网络结构如上图所示。首先是一个3x3的标准卷积,s2进行下采样。然后就是堆积深度可分离卷积,并且其中的部分深度卷积会利用s2进行下采样。然后采用平均池化层将feature变成1x1,根据预测类别大小加上全连接层,最后是一个softmax层。整个网络有28层,其中深度卷积层有13层。
用深度可分离卷积与标准卷积,参数和计算量能下降为后者的九分之一到八分之一左右。但是准确率只有下降极小的1%。
MobileNetV2
在实际使用的时候, 深度卷积部分的卷积核比较容易训废掉:训完之后发现深度卷积训出来的卷积核有不少是空的:
主要改进:
一、Linear bottleneck
在 MobileNet V1 里面使用 ReLU6,ReLU6 就是普通的ReLU但是限制最大输出值为 6,这是为了在移动端设备 float16/int8 的低精度的时候,也能有很好的数值分辨率。对低维度做ReLU运算,很容易造成信息的丢失。而在高维度进行ReLU运算的话,信息的丢失则会很少。
二、Inverted residual block
深度卷积本身没有改变通道的能力,来的是多少通道输出就是多少通道。如果来的通道很少的话,DW深度卷积只能在低维度上工作,这样效果并不会很好,所以我们要“扩张”通道。既然我们已经知道PW逐点卷积也就是1×1卷积可以用来升维和降维,那就可以在DW深度卷积之前使用PW卷积进行升维(升维倍数为t,t=6),再在一个更高维的空间中进行卷积操作来提取特征:
也就是说,不管输入通道数是多少,经过第一个PW逐点卷积升维之后,深度卷积都是在相对的更高6倍维度上进行工作。
HybridSN 高光谱分类
这篇论文构建了一个 混合网络 解决高光谱图像分类问题,首先用 3D卷积,然后使用 2D卷积。
本论文的工作将空间光谱和光谱的互补信息分别以3D-CNN和2D-CNN层组合到了一起,从而充分利用了光谱和空间特征图,来克服以上缺点。HybirdSN模型比3D-CNN模型的计算效率更高。在小的训练数据上也显示出了优越的性能。
网络结构:
HybirdSN 网络代码:
class HybridSN(nn.Module):
def __init__(self, num_classes=16):
super(HybridSN, self).__init__()
self.conv1 = nn.Conv3d(1, 8, (7, 3, 3))
self.conv2 = nn.Conv3d(8, 16, (5, 3, 3))
self.conv3 = nn.Conv3d(16, 32, (3, 3, 3))
self.conv3_2d = nn.Conv2d(576, 64, (3,3))
self.dense1 = nn.Linear(18496,256)
self.dense2 = nn.Linear(256,128)
self.out = nn.Linear(128, num_classes)
self.drop = nn.Dropout(p=0.4)
self.soft = nn.Softmax(dim=1)
self.bn1=nn.BatchNorm3d(8)
self.bn2=nn.BatchNorm3d(16)
self.bn3=nn.BatchNorm3d(32)
self.bn4=nn.BatchNorm2d(64)
self.relu = nn.ReLU()
def forward(self, x):
out = self.relu(self.conv1(x))
out = self.relu(self.conv2(out))
out = self.relu(self.conv3(out))
out = out.view(-1, out.shape[1] * out.shape[2], out.shape[3], out.shape[4])
out = self.relu(self.conv3_2d(out))
out = out.view(out.size(0), -1)
out = self.dense1(out)
out = self.drop(out)
out = self.dense2(out)
out = self.drop(out)
out = self.out(out)
out = self.soft(out)
return out