论文阅读与视频学习
MobileNet V1:是由Google提出的轻量级卷积神经网络架构。它采用了深度意识卷积(Depthwise Convolution)来减少计算量,使得模型在保持较高准确性的情况下,具有更小的模型大小和更快的推理速度。
MobileNet V2:是MobileNet V1的改进版本。它在深度可分离卷积的基础上引入倒残差结构(Inverted Residuals),进一步提高了模型的准确性和效率。
MobileNet V3:是对MobileNet系列的进一步改进。MobileNet V3通过使用自适应激活函数(Hard Swish)和注意力机制((Squeeze-and-Excitation)来进一步提高模型的准确性和效率。MobileNet V3在计算资源有限的设备上,具有更好的性能表现。
ShuffleNet:是一种轻量级神经网络结构,旨在提高计算效率和模型压缩率。它通过使用通道重排(Channel Shuffle)可以降低计算复杂度的同时保持卷积和学习到不同组的特征。ShuffleNet在保持较高准确性的同时,具有更小的模型大小和更快的推理速度。
Channel Shuffle的具体实现方式是对于输入特征input[N,C,H,W]通过变换变为[N,g,C/g,H,W]然后对于第1和2维度进行转置变为[N,C/g,g,H,W],然后再通过变换变为[N,C,H,W]这样便完成了Channel Shuffle。
SENet:是一种注意力机制网络,专注于提高模型的感知能力。SENet通过在卷积神经网络中引入Squeeze-and-Excitation模块,自适应地学习每个通道的权重,从而使得网络能够更好地聚焦于重要的特征。SENet的引入有效地提高了模型的准确性,并在多个任务和数据集上取得了优秀的性能。
Squeeze-and-Excitation操作主要:输入input[N,C,H,W]经过全局池化变为[N,C,1,1]然后经过{全连接层,ReLU激活函数,全连接层,Sigmoid激活函数}得到每一个通道的权重,然后将权重成以input完成该操作。
代码作业
首先加载数据集,虽然因为安全原因导致数据集无法下载,但可以先在浏览器上下载到本地然后上传到colab。
下面是搭建的网络结构。
class_num = 16
class HybridSN(nn.Module):
def __init__(self, in_channels=1, out_channels=class_num):
super(HybridSN, self).__init__()
self.conv3d_features = nn.Sequential(
nn.Conv3d(in_channels,out_channels=8,kernel_size=(7,3,3)),
nn.ReLU(inplace=True),
nn.Conv3d(in_channels=8,out_channels=16,kernel_size=(5,3,3)),
nn.ReLU(inplace=True),
nn.Conv3d(in_channels=16,out_channels=32,kernel_size=(3,3,3)),
nn.ReLU(inplace=True),
)
self.conv2d_features = nn.Sequential(
nn.Conv2d(in_channels=32 * 18, out_channels=64, kernel_size=(3,3)),
nn.ReLU(inplace=True),
)
self.classifier = nn.Sequential(
nn.Linear(64 * 17 * 17, 256),
nn.ReLU(inplace=True),
nn.Dropout(p=0.4),
nn.Linear(256, 128),
nn.ReLU(inplace=True),
nn.Dropout(p=0.4),
nn.Linear(128, out_channels)
)
def forward(self, x):
x = self.conv3d_features(x)
x = x.view(x.size()[0],x.size()[1]*x.size()[2],x.size()[3],x.size()[4])
x = self.conv2d_features(x)
x = x.view(x.size()[0],-1)
x = self.classifier(x)
return x
训练完之后在测试集上的分类报告。大概可以看出样本数越多准确率和召回率越高。
下图是光谱分类图,感觉与groundtruth相比效果还是有点差距。
![]() | ![]() |
(a)得到的分类图 | (b)Groundtruth |
3D卷积和2D卷积的区别:2D卷积主要用于图像处理,考虑二维空间结构,输出为二维特征图。3D卷积主要用于视频数据或体积数据处理,考虑三维空间和时间(或其他额外维度)的结构,输出为三维特征图。2D卷积的输入形状为[N,C,H,W],3D卷积的输入形状为[N,C,D,H,W],N表示Batchsize,C为通道数,D为深度,H为高度,W为宽度。2D卷积的卷积核是没有深度的。
思考题
训练HybridSN,然后多测试几次,会发现每次分类的结果都不一样,请思考为什么?
因为dropout的原因代码中并没有写net.eval来告诉网络现在是测试,不应该再随机丢弃神经元了,这样就不会导致每次分类的结果不一样了。
如果想要进一步提升高光谱图像的分类性能,可以如何改进?
可以进行数据增强,通过对训练数据进行随机的旋转、翻转增加数据的多样性。
depth-wise conv 和 分组卷积有什么区别与联系?
depth-wise conv是分组卷积的特例,当分组卷积的组数等于输入特征的通道数是,分组卷积就是depth-wise conv。
SENet 的注意力是不是可以加在空间位置上?
SENet是用在通道上的,不使用在空间位置上的。
在 ShuffleNet 中,通道的 shuffle 如何用代码实现?
class ChannelShuffle(nn.Module):
def __init__(self, groups):
super(ChannelShuffle, self).__init__()
self.groups = groups
def forward(self, x):
batch_size, num_channels, height, width = x.size()
channels_per_group = num_channels // self.groups
# 将特征图切分成若干组
x = x.view(batch_size, self.groups, channels_per_group, height, width)
# 将每个组内的通道进行重排
x = x.permute(0, 2, 1, 3, 4)
# 将重排后的特征图展平
x = x.view(batch_size, num_channels, height, width)
return x