1.MobileNet模型基于深度可分解卷积(depthwise separable convolutions),它由分解后的卷积组成,分解后的卷积就是将标准卷积分解成一个深度卷积(depthwise convolution)和一个1x1的点卷积(pointwise convolution)。深度卷积将每个卷积核应用于输入的每一个通道;然后,深度卷积的输出作为点卷积的输入,点卷积用1x1卷积来组合这些输入。大大减少了运算量和参数数量。结构如下图所示:
2.引入控制模型大小的超参数:
注:α,ρ是人为手动设置的,在给出的测试代码中,α,ρ均设置为1。
注:如果真实复现MobileNetV1网络结构,需将代码中的
cfg = [(64, 1), (128, 2), (128, 1), (256, 2), (256, 1), (512, 2), (512, 1),
(1024, 2), (1024, 1)]
修改成
cfg = [(64, 1), (128, 2), (128, 1), (256, 2), (256, 1), (512, 2), (512, 1),
(512, 1),(512, 1),(512, 1),(512, 1),(1024, 2), (1024, 1)]
参考文章:
论文笔记:MobileNet v1
【深度学习】经典分类网络 亮点及结构
MobileNet网络详解
MobileNets: Efficient CNN for Mobile Vision Applications[1704.04861]
网络为全卷积的,使得模型可以适应不同尺寸的图像;使用 RELU6(最高输出为 6)激活函数,使得模型在低精度计算下具有更强的鲁棒性
Linear Bottlenecks,去掉 Narrow layer(low dimension or depth) 后的 ReLU,保留特征多样性,增强网络的表达能力。
注:针对于论文中给出的shortcut连接表述是有误的,只有当stride=1且输入特征矩阵与输出特征矩阵的shape相同时,满足这两个条件的时候,才会有shortcut连接,其他情况均没有。
注:
代码细节部分:
cfg = [(1, 16, 1, 1),
#根据MobileNetV2网络结构,应将老师给出的代码中,(6, 24, 2, 1)应改成(6, 24, 2, 2)
(6, 24, 2, 2),
(6, 32, 3, 2),
(6, 64, 4, 2),
(6, 96, 3, 1),
(6, 160, 3, 2),
(6, 320, 1, 1)]
应该使用nn.ReLU6代替F.relu激活函数
参考文章:
MobileNetV1 & MobileNetV2 简介
轻量级网络–MobileNetV2论文解读
论文阅记 MobileNetV2:Inverted Residuals and Linear Bottlenecks
MobileNet网络详解
关于shortcut的一点思考
1.高光谱图像(HyperSpectral Image,简称HSI)是三维立体数据,包含两个空间维度和一个光谱维度。
作者提出HybirdSN模型:将空间光谱和光谱的互补信息分别以3D-CNN和2D-CNN层组合到了一起,从而充分利用了光谱和空间特征图,结合二维和三维卷积的优势,设计的网络结构中先使用三维卷积,再堆叠二维卷积,最后连接分类器。既发挥了三维卷积的优势,充分提取光谱-空间特征,也避免了完全使用三维卷积而导致的模型复杂。
2.网络结构
网络首先进行的PCA降维操作,然后由3层三维卷积(3D Conv)→ 1层二维卷积(2D Conv)→ 2层全连接层(Fc) → 1层softmax分类层组成。
根据给出的网络结构,搭建网络。参考网上代码,Batch Norm适合用于分类任务,所以在搭建网络的时候,添加Batch Norm可以使训练更容易、加速收敛、防止模型过拟合。
class HybridSN(nn.Module):
def __init__(self):
super(HybridSN, self).__init__()
self.conv3d_1 = nn.Sequential(
nn.Conv3d(1, 8, kernel_size=(7, 3, 3), stride=1, padding=0),
nn.BatchNorm3d(8),
nn.ReLU(inplace = True),
)
self.conv3d_2 = nn.Sequential(
nn.Conv3d(8, 16, kernel_size=(5, 3, 3), stride=1, padding=0),
nn.BatchNorm3d(16),
nn.ReLU(inplace = True),
)
self.conv3d_3 = nn.Sequential(
nn.Conv3d(16, 32, kernel_size=(3, 3, 3), stride=1, padding=0),
nn.BatchNorm3d(32),
nn.ReLU(inplace = True)
)
self.conv2d_4 = nn.Sequential(
nn.Conv2d(576, 64, kernel_size=(3, 3), stride=1, padding=0),
nn.BatchNorm2d(64),
nn.ReLU(inplace = True),
)
self.fc1 = nn.Linear(18496,256)
self.fc2 = nn.Linear(256,128)
self.fc3 = nn.Linear(128,16)
self.dropout = nn.Dropout(p = 0.4)
def forward(self,x):
out = self.conv3d_1(x)
out = self.conv3d_2(out)
out = self.conv3d_3(out)
out = self.conv2d_4(out.reshape(out.shape[0],-1,19,19))
out = out.reshape(out.shape[0],-1)
out = F.relu(self.dropout(self.fc1(out)))
out = F.relu(self.dropout(self.fc2(out)))
out = self.fc3(out)
return out
测试结果:
1.2D卷积和3D卷积的区别?
2、每次分类的结果为什么都不一样?
(1)首先,权重初始化都是随机的,经过梯度下降以后最后的权值肯定也不是相同的。
(2)其次,就是在网络中,为了防止过拟合,采用了Dropout,随机dropout掉不同的隐藏神经元来进行网络训练,所以最终的分类结果也不一样。可以通过model.train(),model.eval()来解决和这个问题。
3、如果想要进一步提升高光谱图像的分类性能,可以如何改进?
添加注意力机制,自从Transformer提出之后,自注意力机制也随即在CV领域大放异彩。Attention是从大量信息中有筛选出少量重要信息,并聚焦到这些重要信息上,忽略大多不重要的信息。权重越大越聚焦于其对应的Value值上,即权重代表了信息的重要性,而Value是其对应的信息。
# 通道注意力机制
class ChannelAttention(nn.Module):
def __init__(self, in_planes, ratio=16):
super(ChannelAttention, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.max_pool = nn.AdaptiveMaxPool2d(1)
self.fc1 = nn.Conv2d(in_planes, in_planes // 16, 1, bias=False)
self.relu1 = nn.ReLU()
self.fc2 = nn.Conv2d(in_planes // 16, in_planes, 1, bias=False)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x))))
max_out = self.fc2(self.relu1(self.fc1(self.max_pool(x))))
out = avg_out + max_out
return self.sigmoid(out)
# 空间注意力机制
class SpatialAttention(nn.Module):
def __init__(self, kernel_size=7):
super(SpatialAttention, self).__init__()
assert kernel_size in (3, 7), 'kernel size must be 3 or 7'
padding = 3 if kernel_size == 7 else 1
self.conv1 = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
avg_out = torch.mean(x, dim=1, keepdim=True)
max_out, _ = torch.max(x, dim=1, keepdim=True)
x = torch.cat([avg_out, max_out], dim=1)
x = self.conv1(x)
return self.sigmoid(x)
测试结果,相比较未添加注意力机制的代码,准确率竟然从0.9822下降到0.9771:
参考文章:
[HSI论文阅读] | HybridSN: Exploring 3-D–2-D CNN Feature Hierarchy for Hyperspectral Image Classification
《HybridSN: Exploring 3-D–2-DCNN Feature Hierarchy for Hyperspectral Image Classification》论文阅读
【AI】高光谱图像分类 — HybridSN模型
高光谱图像分类 HybridSN
参考文章:
【论文略读40】DnCNNs——经典去噪方法
【图像去噪】DnCNN论文详解(Beyond a Gaussian Denoiser: Residual Learning of Deep CNN for Image Denoising)
SENet的核心思想在于建模通道之间的相互依赖关系,通过网络的全局损失函数自适应的重新矫正通道之间的特征相应强度。
1)挤压(squeeze)部分,对卷积后的特征图做全局平均池化,这一步相当于得到所有特征通道的数值分布;
2)激励(excitation)部分,对各个特征通道进行交互,捕获通道间的依赖关系,为每个特征通道生成权重;
3)scale(attention)部分,将生成的权重乘回到原输入特征图中。
通道域的注意力机制一般需要对输入的特征图C×H×W进行全局池化得到一个一维向量1×1×C,然后对这个一维向量进行特征交互,计算相关性,最后将交互之后的特征向量进行归一化得到通道权重向量,将通道权重向量施加到原特征图中
参考文章:
深度学习论文翻译解析(十六):Squeeze-and-Excitation Networks
Squeeze-and-Excitation Networks
本文旨在找到一个通用的表示空间,在其中可以直接比较来自不同模态的样本。
Contribution:
网络结构:
目标函数:
1.分类的损失,其中 Y Y Y 是 l a b e l label label 的 o n e − h o t one-hot one−hot表示,计算一下分类结果与 Y Y Y 的差别。
2.损失函数包括三项,分别代表模态间的,图像模态的和文本模态的负对数似然。最小化负对数似然相当于最大化概率,这里的概率指的是两个特征属于同一个类别的概率。
3.为了消除跨模态差异,我们建议最小化所有图像-文本对的表示之间的距离,两种模态公共空间中的距离度量
参考文章:
论文阅读:深度监督跨模态检索 Deep Supervised Cross-modal Retrieval, CVPR 2019
CVPR2019跨模态检索-Deep Supervised Cross-modal Retrieval
深度监督跨模态检索(DSCMR)